Commit Graph
3943 Commits
Author SHA1 Message Date
affaan-m 7c9c44736b fix(release): bind trusted checks and signed tag identity on current main 2026-09-27 22:48:51 -04:00
affaan-m 57841ab3e6 test(plan-canvas): canonicalize temporary fixture paths 2026-09-27 22:47:46 -04:00
affaan-m e9911d6668 fix(opencode): preserve primary failures through complete lock cleanup 2026-09-27 22:41:08 -04:00
affaan-m d811349224 fix(gateguard): detect stdin dd writes and launcher-wrapped shells 2026-09-27 22:25:29 -04:00
affaan-m dbeb723218 fix(plan-canvas): bind bounded artifact reads to verified descriptors 2026-09-27 22:23:33 -04:00
affaan-m 429384f80c fix(opencode): refuse known legacy hooks without consent 2026-09-27 22:12:34 -04:00
affaan-m 1c41fa7c00 docs(codex): clarify explicit MCP pin refresh and verify shared recommendation 2026-09-27 22:08:43 -04:00
affaan-m 1394cf6f0a Merge current main and verify PowerShell foreach classification 2026-09-27 22:05:48 -04:00
affaan-m d12c5a584d fix(context): refresh manual trigger binding after Plankton docs update
Rebind the unchanged manually curated trigger payload to the current registry. Preserve all trigger entries, provenance and timestamps; no provider generation is implied.
2026-09-27 21:55:17 -04:00
affaan-m a74c743370 fix(gateguard): classify literal dd execution without matching passive text
Preserve the contributor repair and current main protections. Handle operand ordering, bounded literal command wrappers, executable containers and find actions while keeping quoted prose and option values passive.

Source-PR: https://github.com/affaan-m/ECC/pull/2829
Source-Head: c88b3f879a
Integration-Main: d3b8a3e908
2026-09-27 21:50:09 -04:00
affaan-m 503e2ef331 fix(mcp): reconcile reviewed chrome-devtools pin with current main
Preserve the contributor pin and current main. Keep both default connector declarations at the exact official 1.10.1 release and retain user-managed configuration behavior.

Source-PR: https://github.com/affaan-m/ECC/pull/3233
Source-Head: 62bf2b2910
Integration-Main: d3b8a3e908
2026-09-27 21:41:47 -04:00
affaan-m 506f25fb54 fix(plan-canvas): confine artifact assets and sandbox SVG documents
Preserve the contributor security repair and current main. Apply the artifact sandbox to SVG document responses and report unavailable symlink checks separately from passing assertions.

Source-PR: https://github.com/affaan-m/ECC/pull/3241
Source-Head: d237e1972f
Integration-Main: d3b8a3e908
2026-09-27 21:39:24 -04:00
affaan-m f5d0fcc7e1 fix(install): reconcile UTF-8 BOM support with current main
Preserve the contributor commits and current main changes.

Source-PR: https://github.com/affaan-m/ECC/pull/3210
Source-Head: 94ca2de35e
Integration-Main: d3b8a3e908
2026-09-27 21:35:30 -04:00
affaan-m d4047a4d2f docs: reconcile manual install prerequisites with current main
Preserve the contributor commits and current main changes.

Source-PR: https://github.com/affaan-m/ECC/pull/3246
Source-Head: a3e9bc5184
Integration-Main: d3b8a3e908
2026-09-27 21:35:29 -04:00
affaan-m 6dc706fe85 fix(install): distinguish user plugins from ECC aliases
Attribute unrecorded OpenCode aliases only to exact trusted ECC source or build bytes while keeping planned and recorded destinations strict. Pass the trusted source root through repair plans and preserve unrelated user plugin files.
2026-09-27 21:23:11 -04:00
affaan-m 9f6c16fe02 fix(tests): make guarded parent replacement portable to Windows 2026-09-27 21:04:21 -04:00
affaan-m aff9c64560 fix(control-pane): preserve snapshot integrity during failed refreshes 2026-09-27 21:03:37 -04:00
affaan-m 5ffe239ee5 fix(tests): reconcile launcher coverage with current main 2026-09-27 21:03:37 -04:00
affaan-m 533f5ff20a fix(docs): format complexity sources as Markdown links 2026-09-27 21:03:37 -04:00
affaan-m 9f64ff2c3d fix(context): refresh registry binding for Polish docs module 2026-09-27 20:50:50 -04:00
Affaan Mustafa ac27e096f5 Merge branch 'main' into docs/oxlint-complexity-ratchet 2026-09-27 19:42:49 -05:00
dependabot[bot] d3b8a3e908 chore(deps): bump actions/stale from 10.4.0 to 11.0.0 (#3005)
Bumps [actions/stale](https://github.com/actions/stale) from 10.4.0 to 11.0.0.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/1e223db275d687790206a7acac4d1a11bd6fe629...4391f3da665fdf50b6810c1a66712fb9ba21aa93)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: 11.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-27 19:38:49 -05:00
affaan-m 610495474a Merge current main while preserving reviewed OpenCode consent guards 2026-09-27 20:32:22 -04:00
affaan-m 923019d99f fix(opencode): preserve consent ownership through guarded install and repair 2026-09-27 20:32:22 -04:00
affaan-m 72c7ca5387 Merge current main into PR #3013, preserving reviewed contribution 2026-09-27 20:26:27 -04:00
affaan-m 80b9339727 Merge current main into PR #3121, preserving reviewed contribution 2026-09-27 20:26:25 -04:00
affaan-m f8c604d37e Merge current main into PR #3060, preserving reviewed contribution 2026-09-27 20:24:52 -04:00
affaan-m 7eb1e32ae0 merge: preserve Turkish guide link fixes with reviewed main 2026-09-27 20:16:02 -04:00
Tushar PanchalandClaude Sonnet 5 042924e1f4 fix(install): support invocation through POSIX sh (#3014)
* fix(install): make install.sh robust to sh/dash invocation

Two related portability fixes so `sh install.sh` behaves correctly
even though the script is written for bash:

- The cygpath detection used the bash-only `&>/dev/null` redirection.
  dash misparses `&>`, so `command -v cygpath &>/dev/null` always took
  the true branch and tried to run the nonexistent `cygpath` binary,
  failing with "cygpath: not found". Switched to the POSIX-portable
  `>/dev/null 2>&1` form.

- Some dash builds don't support `set -o pipefail`, so `sh install.sh`
  can fail immediately at that line before even reaching the cygpath
  check (or the `[[ ... ]]` symlink-resolution logic further down).
  Added a guard that re-execs the script under bash when the current
  shell lacks bash capabilities, so the rest of the bash-only syntax
  always runs under a real bash regardless of the invoking shell. The
  guard probes for the `[[` compound command directly (via
  `eval '[[ 1 == 1 ]]'`) rather than trusting the $BASH_VERSION
  environment variable, since that variable could be inherited or
  spoofed under a non-bash shell and cause the guard to be skipped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XBaBRjaZgwhrZtYoqcQfp

* test(install): cover the sh install.sh re-exec path

Greptile flagged that the bash re-exec guard added in install.sh has
no automated coverage, since the existing test helper only invoked
the wrapper via `bash`. Adds two regression tests:

- "delegates to the Node installer when invoked via a POSIX sh
  wrapper" — runs the script via `sh` and asserts the args/cwd still
  reach the Node installer correctly.
- "re-execs into bash under sh even when BASH_VERSION is spoofed in
  the environment" — exercises the eval '[[ 1 == 1 ]]' capability
  probe directly, guarding against a regression back to trusting the
  (spoofable) $BASH_VERSION variable.

CodeRabbit then pointed out that the second test used generic `sh`,
which could trivially pass without exercising the re-exec branch at
all if `sh` ever resolves to bash on some system. Added a
findPosixOnlyShell() helper that prefers `dash` (falling back to
checking `sh`, and skipping with an explicit message if neither
genuinely lacks bash's `[[`), so the test reliably exercises the
branch it claims to cover instead of passing vacuously.

CodeRabbit then flagged that the skip path itself was miscounted as
a pass (the callback returned normally, so `test()` reported success
and `passed` was incremented even though nothing executed). Moved
the findPosixOnlyShell() check outside the test() registration, so
the test is only registered — and only counted — when a genuinely
POSIX-only shell is actually available; otherwise it's excluded from
both the passed and failed counts with an explicit skip line.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019XBaBRjaZgwhrZtYoqcQfp

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-27 19:04:10 -05:00
haelyra eaeef53a15 Merge pull request #3234 from haelyra/feat/ecc-029-production-acceptance
feat(profiles): add opt-in Lean/Full with hybrid Auto skill selection
2026-09-27 18:34:29 -04:00
haelyra befde0d2cd fix(profiles): bind routing receipts and harden review paths 2026-09-27 18:01:40 -04:00
haelyra a9e3ecb77f fix(ci): allow slow Windows test cleanup 2026-09-27 17:37:47 -04:00
haelyra 874883c728 fix(profiles): make evaluator permissions and Windows checks portable 2026-09-27 17:03:28 -04:00
haelyra 0765f7a2ca feat(profiles): add opt-in Lean/Full and hybrid Auto selection 2026-09-27 16:46:07 -04:00
pasmudandCommandCodeBot d42d918bd3 fix(control-pane): stop a stale poll lowering the staleness mark
The settled-token guard correctly ignored an older poll, but that poll
still set settledPoll to its own token on the way out. With three polls
settling in the order 3, 1, 2, the ignored poll 1 pulled the mark back
to 1, so the even older poll 2 then passed the guard and replaced poll
3's counts, or marked a healthy view offline.

The mark now only moves forward. A poll that settles late is itself
stale, so it has no business moving the mark at all.

Covered by a new runtime case that settles three polls out of order as
3, 1, 2, once with an older success and once with an older failure. The
success case catches the counts regressing, the failure case catches a
healthy view being marked offline. Reverting the fix trips each of them
independently, and the unmutated file passes all 21.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-09-27 14:03:13 +00:00
vam 995d3c4934 docs: update skill counts for agent-security-hardening
Run catalog:sync and update the Japanese and Turkish counts that the
sync script does not cover, so the catalog reports 293 skills.
2026-09-27 21:08:55 +08:00
vam 3ade64aa43 Merge origin/main into feat/2885-agent-security-hardening 2026-09-27 20:43:42 +08:00
vam c196dc7d51 fix(skills): reject Windows-unsafe components in workspace_path example
Reject reserved device names (including with extensions and the
superscript COM/LPT variants), trailing dots or spaces, and colon
stream syntax on every platform, and execute the documented snippet
in a regression test.
2026-09-27 20:34:49 +08:00
Seekers2001 2b35e299ea test: cover launcher error handling 2026-09-27 17:32:44 +08:00
pasmudandCommandCodeBot cee58ba39e fix(control-pane): settle the poll guard against the last settled request
The staleness guard compared a poll against the newest poll STARTED, and
only the failure path used it. Two orderings were wrong.

An older success settling after a newer one had no guard at all, so it
overwrote the newer counts, the canvas label and the announcement with
older data. Both paths now check the token.

An older failure settling while a newer poll was still in flight was
discarded, because a newer poll had merely started. The page then kept
the last successful counts and its no-steering message as if they were
current. Anchoring the guard to the newest poll that has SETTLED fixes
that: the older failure is still the newest thing to have settled, so it
lands, and the pending poll restores the view when it answers.

That single change covers both orderings, so the guard no longer needs
to know which path it is on. Each poll records itself as settled when it
finishes, whatever the outcome.

A poll also had no timeout, so a request that never answered left the
last steering guidance on screen indefinitely. Each poll now aborts
after ten seconds through an AbortController, and that abort is what
wakes the poll, so a timeout is reported as an outage instead of
silently leaving stale guidance.

The test harness can now hold a request open indefinitely and fire
pending timers on demand, so the timeout is exercised without waiting.
New assertions cover an older success losing to a newer one, an older
failure landing while a newer poll is in flight and then being
recovered by it, and a hung poll timing out into the offline state.
Removing the success guard, re-anchoring the guard to the last started
poll, and removing the timeout each fail one of those assertions, and
the unmutated file passes all of them.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-09-27 08:11:44 +00:00
wzc 91e31a032e fix(install): refine preflight comment and cross-reference package.json engines 2026-09-27 14:08:33 +08:00
Matt Van HornandClaude Opus 5.5 6e15d45467 test(ci): pin that identifiers containing CLAUDE_PROJECT_DIR still pass
Add the mirror fixture for the fence scan: $MY_CLAUDE_PROJECT_DIR,
${MY_CLAUDE_PROJECT_DIR}, $CLAUDE_PROJECT_DIR_TMP and
${CLAUDE_PROJECT_DIR_TMP} in a bash fence must not fail. The scan
already requires the `$` to be attached and ends on a word boundary, so
this pins the pass side as firmly as the fail side.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EzFUaXW84Y6LHzKysc5mTc
2026-09-26 22:34:06 -07:00
Yann Roberto a3e9bc5184 docs: fix prerequisites in manual install examples 2026-09-27 12:38:39 +08:00
Seekers2001 9d1e05a06e fix: normalize markdown link path separators 2026-09-27 11:05:25 +08:00
Seekers2001 5b65751bd5 fix: restore plan canvas process launcher 2026-09-27 11:02:31 +08:00
pasmudandCommandCodeBot e97e333040 fix(control-pane): keep the canvas label and live region consistent
Two ways the outage state could mislead an operator reading either
channel.

The failure branch cleared the live region but left the canvas
aria-label holding the counts from the last successful poll, so landing
on the canvas during an outage reported stale counts. It now sets the
same unavailable wording on the canvas. apply() already restores the
count label on the next valid poll, and there is now a test for that.

Polls run every 5000ms and are not sequenced, so a slow older request
can settle after a newer one has succeeded. Its catch block then
announced an outage while the canvas showed the newer counts, and the
two channels contradicted each other. Each poll now takes a monotonic
token and only the newest one may touch the view, so a superseded
failure is dropped.

The runtime test can park a response, which lets it settle an older
failure after a newer success. New assertions cover the canvas label
after an outage, the restored label after recovery, and the
superseded-failure case. Removing the canvas reset, the token guard, or
the restore in apply() each fail an assertion, and the unmutated view
passes all of them.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-09-27 02:44:18 +00:00
pasmudandCommandCodeBot 9e0996c6d6 fix(control-pane): replace stale live-region guidance when a poll fails
The live region announced the advisory and steering state on every
change, but a failed or invalid poll only set the visible status to
offline. The live region kept the last known message, so during an
outage a screen-reader user could still hear "No steering is required"
from a poll that had already failed. That is worse than silence,
because stale guidance reads as current.

Route announcements through a single helper and have the failure path
replace the guidance with a message saying the data is unavailable and
the counts are unknown. The helper still suppresses a repeat of the
same message, so a continuing outage stays quiet and recovery speaks
again.

Cover the success then failure and failure then recovery sequences at
runtime. Reverting just the failure-path announcement fails the new
assertion, and the unmutated view passes all of them.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-09-27 02:01:44 +00:00
pasmudandCommandCodeBot 6744a01748 fix(control-pane): announce polled advisories through a live region
The control-plane view polls every few seconds and rewrites the canvas
aria-label with the new counts, but neither the canvas nor #status is a
live region, so a screen-reader user working elsewhere never hears an
advisory appear.

Add a visually hidden polite live region that speaks only when the
advisory and steering counts actually move. Re-announcing an unchanged
summary every five seconds would talk over the operator without saying
anything new, so the last announced pair is remembered and a no-change
poll writes nothing. The canvas keeps its own label as the on-demand
description.

Also give the runtime test a recording canvas context and a populated
view, so the rendered risk words, the marker shapes, and the live region
are asserted at runtime rather than only against template source. The
risk-level assertion now reads the rendered risk cells instead of the
whole panel, where a level word could be satisfied by a task id.

The populated assertions were mutation checked: collapsing the marker
shapes, dropping the risk words, freezing the canvas label, announcing
on every poll, emptying the live region, and removing the steering cue
each fail at least one assertion.

Fixes the no-regex-spaces lint error on the riskColor match, which used
two literal spaces in a row.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-09-27 00:46:39 +00:00
pasmudandCommandCodeBot 18e78da390 test(control-pane): derive the a11y palette from the rendered view
CodeRabbit correctly noted that hard-coding #2ea043 and #ff7b72 in the
test decoupled the contrast assertions from the colors the view
actually renders, so a palette change could leave them passing.

The test now reads the legend glyphs, the legend colors, the
riskColor() returns, and the body background back out of the rendered
HTML, and asserts that the legend and canvas palettes agree before
checking any ratio. Verified both directions: a mismatched canvas
color fails the palette check, and a full revert to #3fb950 fails the
luminance check at 1.01:1.

Extends the coverage to the traffic level and the body background,
which were previously unchecked.

Co-Authored-By: CommandCodeBot <noreply@commandcode.ai>
2026-09-26 22:59:22 +00:00
pasmudandCommandCodeBot 3052732f28 fix(control-pane): add non-color risk cues to the control-plane view
The control-plane projection encoded risk with hue alone. The clear
green #3fb950 and the resolution red #ff7b72 differ by only 1.01:1 in
relative luminance, so a red-green color-blind operator saw the same
grey for "clear" and "steer now".

Risk now carries a second, non-color channel, matching the pattern
merged for the sibling airspace view in #3193:

- markers are drawn as a circle, square, or triangle per risk level
- the legend shows the matching glyph instead of color-only dots
- the Lanes panel prints the level name next to the percentage
- the canvas gets role="img" and a live aria-label describing counts

The clear green also moves to #2ea043 so it stays separable from the
resolution red by luminance (1.34:1) while keeping 5.73:1 against the
#0b0e14 background.

Adds tests/lib/control-plane-view-ui-a11y.test.js covering the roles,
the shapes, the legend, and the contrast ratios. The existing test
harness needed a setAttribute stub for the new aria-label update.

Co-Authored-By: CommandCodeBot <noreply@commandcode.ai>
2026-09-26 22:52:34 +00:00