Commit Graph
1110 Commits
Author SHA1 Message Date
Seekers2001 4494ffc1e5 fix(docs-governance): audit UNC markdown links 2026-09-29 17:41:36 +08:00
Seekers2001 71c812686c Merge upstream/main into codex/docs-governance-audit-foundation 2026-09-28 17:36:09 +08:00
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 befde0d2cd fix(profiles): bind routing receipts and harden review paths 2026-09-27 18:01:40 -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
Seekers2001 9d1e05a06e fix: normalize markdown link path separators 2026-09-27 11:05:25 +08:00
Seekers2001 89448e75cc Merge remote-tracking branch 'upstream/main' into codex/docs-governance-audit-foundation 2026-09-22 17:32:07 +08:00
xsfandGitHub bf70150eb2 fix(gateguard): sanitize dangerous invisible unicode in denial paths (#3103)
* fix(gateguard): sanitize dangerous invisible unicode in denial paths

sanitizePath only stripped control characters and bidi overrides, so
the 394 codepoints that the repo-wide unicode safety policy classifies
as dangerous-invisible (zero-width U+200B-200D, U+2060, U+2061-2064,
variation selectors U+FE00-FE0F, tag block U+E0000-E007F, Hangul
fillers, U+FEFF, U+180E, U+3164) plus the U+2028/U+2029 line and
paragraph separators passed verbatim into Edit/Write denial messages.
Invisible characters in a quoted file path let a malicious path look
clean to a human reviewer.

Align sanitizePath with the CI policy list and cover it with a
hook-output regression test that asserts no dangerous invisible
character survives into the denial reason while visible path text
stays intact.

* refactor(gateguard): name the sanitizePath unicode policy constants

Address review feedback: move the code points and ranges out of
sanitizePath into descriptive constants mirroring
scripts/ci/check-unicode-safety.js, so the policy is auditable in one
place. Also seed the regression test input with U+2029 so the
paragraph-separator assertion is exercised rather than vacuous.

* fix(gateguard): sanitize C1 control characters in denial paths

Follow-up on the sanitizePath policy alignment: the Unicode C1 control
block (U+0080..U+009F) is invisible in every renderer like the ASCII
controls below 0x20, but the strip only covered the ASCII range. Add
C1_CONTROLS to the policy constants and seed U+0091 into the
regression test input.
2026-09-21 14:40:16 -04:00
Varun GoreandGitHub 7b7dfc6412 fix(gateguard): detect destructive SQL passed quoted to SQL clients (#3107)
* fix(gateguard): detect destructive SQL passed quoted to SQL clients

Quoted SQL like psql -c "drop table users" was stripped before the DESTRUCTIVE_SQL_DD regex ran, making it unreachable. Check dequoted tokens for known SQL clients (psql, mysql, sqlite3, ...) so real invocations are gated while git commit -m / echo mentions stay allowed. Fixes affaan-m/ECC#3024.

* fix(gateguard): unwrap sudo/env flags and ignore SQL string literals

Address review: sudo -u/env VAR= wrappers now resolve to the real SQL client; SQL single/double/dollar-quoted literals are stripped before the destructive regex so SELECT 'drop table' stays allowed. Adds deny/allow regression tests for quoted SQL, wrappers, literals, and non-SQL clients.

* test(gateguard): cover env PGPASSWORD wrapper variant

* fix(gateguard): close wrapper sh-c, env dir, tagged literal gaps

Review 5189686662: recurse sh -c from unwrapped wrapper index (sudo/doas/env + sh -c now denied); consume env -C/--chdir separate values; strip tagged dollar-quoted literals ($tag$...\baseline). Tests: 200 passed.
2026-09-21 14:39:17 -04:00
Sedat DağandGitHub c056ae7df2 fix(hooks): support python style comments in pre-commit quality checks (#3194)
* fix(hooks): support python style comments in pre-commit quality checks

fix(hooks): support python style comments in pre-commit quality checks

* fix: reject whitespace-only TODO messages

* fix: reject whitespace-only TODO messages

* test: add cases for hash-prefixed comments and string limitations
2026-09-21 14:33:19 -04:00
aspandGitHub d7cf4584cf fix: restore Claude plugin setup compatibility (#3205)
* fix: stop passing removed Claude plugin config flags

* test: cover current Claude plugin install arguments

* docs: add beginner Windows install walkthrough
2026-09-21 14:32:26 -04:00
Seekers2001 9feabe7841 Merge remote-tracking branch 'upstream/main' into codex/docs-governance-audit-foundation 2026-09-21 17:32:04 +08:00
TamerandGitHub 2b6e839771 Fix/proximity a11y risk cues (#3193)
* fix(control-plane): add non-color airspace risk cues

* test(control-plane): cover airspace accessibility cues
2026-09-20 15:37:57 -04:00
TamerandGitHub 651118bd50 Fix/control plane canvas size (#3192)
* fix(control-plane): constrain visualization canvas layout

* fix(control-plane): constrain visualization canvas layout

* test(control-plane): guard bounded canvas layout
2026-09-20 15:37:51 -04:00
9ac593b55c fix(scripts): extract cross-platform openBrowser helper with structured launch result (#3180)
scripts/plan-canvas.js and scripts/control-pane.js both define their own
openBrowser helpers for launching the user's default browser. The two
implementations have diverged:

- plan-canvas.js dispatches across darwin/win32/linux but its
  try/spawn try/catch does not catch async child errors (ENOENT/EACCES
  on hosts without the launcher command). Returns a bare true/false.
- control-pane.js is darwin-only and silently returns early on
  Windows/Linux, so the two scripts behave inconsistently across
  platforms.

When the launcher command is missing (e.g. headless CI without xdg-open)
the JSON output still says 'browser: opened', lying to the agent.

Changes:
- scripts/lib/platform-launch.js: shared openBrowser helper that
  dispatches per platform, wires child 'error' so ENOENT/EACCES
  propagate, and returns {opened, reason} instead of a bare boolean.
- scripts/plan-canvas.js: drops its local helper, imports the shared
  one, and adds browserReason to its JSON output.
- scripts/control-pane.js: replaces its darwin-only branch with the
  shared helper and logs the structured reason on failure.
- tests/lib/platform-launch.test.js: 7 node:test cases covering
  opener-command selection, invalid-URL guard, structured-result
  shape, and a smoke run for the actual spawn.

Verification: node --test tests/lib/platform-launch.test.js → 7/7 pass.

Co-authored-by: auyua9 <auyua9@users.noreply.github.com>
2026-09-20 14:26:52 -04:00
EasternandGitHub 95448ad81d fix: isolate Claude project hooks from ESM hosts (#3184)
* fix: isolate Claude project hooks from ESM hosts

* fix: handle user-owned Claude scripts package
2026-09-20 14:26:49 -04:00
Seekers2001 6c24ccc642 Merge remote-tracking branch 'upstream/main' into codex/docs-governance-audit-foundation
# Conflicts:
#	.claude-plugin/marketplace.json
#	.claude-plugin/plugin.json
2026-09-20 17:39:23 +08:00
Affaan MustafaandGitHub fc9273e5e0 Merge pull request #3126 from VarunGore36/fix/reviewer-followups
fix(security): security follow-ups for worker, installer, claw, hooks
2026-09-19 19:58:43 -04:00
Affaan MustafaandGitHub a0600a00fb Merge pull request #3125 from kapelame/audit/ecc-opencode-output-contract
fix(opencode): write hook results through the output contract
2026-09-19 19:58:40 -04:00
Affaan MustafaandGitHub b2279eb1d7 Merge pull request #3130 from shoyann/fix/preserve-codex-user-config
fix: preserve edited Codex user configuration during reinstall and repair
2026-09-19 17:09:20 -04:00
Affaan MustafaandGitHub 1ec2263b3f Merge pull request #3137 from iyertalks/fix/pi-doctor-scoped-companion
fix(pi): recognize @scope/pi-subagents in /ecc-doctor companion check
2026-09-19 17:09:18 -04:00
Affaan MustafaandGitHub 0a5207b6f2 Merge pull request #3102 from wellkilo/perf/metrics-tail-read
perf(metrics): cache cumulative session costs
2026-09-19 17:00:05 -04:00
Affaan MustafaandGitHub ada4db1157 Merge pull request #3111 from Fibilisim-Tekno/fix/memory-initialized-metadata
fix(memory-mcp): accept metadata on initialized notifications
2026-09-19 16:51:53 -04:00
Affaan MustafaandGitHub 91ba9b4cf6 Merge pull request #3133 from affaan-m/release/ecc-universal-2.2.2
release: ecc-universal 2.2.2
2026-09-19 16:41:20 -04:00
Frank_zhu 08813f49ff test(security): Layer-1 observe.sh entrypoint allowlist evidence (#3171)
Add focused security regression for sdk-cli allowlisting and document
IOC scan + allowlist probe output under .pr/security-evidence-3171.md.

Signed-off-by: Frank_zhu <58329837+Frank-zhu0404@users.noreply.github.com>
2026-09-19 20:56:34 +08:00
Seekers2001 e715751cf5 Merge remote-tracking branch 'upstream/main' into codex/docs-governance-audit-foundation 2026-09-19 17:31:57 +08:00
Affaan MustafaandGitHub 07756cee15 fix(gateguard): gate ref- and history-destroying git commands (#3154, #3151) (#3170)
branch -D, stash drop/clear, reflog expire/delete, update-ref -d, restore (except --staged alone), and force-with-lease pushes to shared branches now hit the destructive gate. 238 hook tests pass; 49 CI checks green.
2026-09-19 02:58:33 -04:00
Affaan MustafaandGitHub f6eb800474 fix(session-start): scope summary lookup to repository identity (#3160) (#3168)
Windows: compare repo identity via normalizeRepoPath/sameRepoIdentity (8.3 short names, case, separators; inode fallback). All nine windows-latest jobs green on 52587005.
2026-09-19 02:08:50 -04:00
Affaan MustafaandGitHub ce7a4847ca Merge pull request #3147 from AniruddhaAdak/fix/ollama-generation-token-limit
fix(llm): forward max_tokens to Ollama num_predict
2026-09-18 21:10:31 -04:00
Affaan MustafaandGitHub 4007e25b58 Merge pull request #3157 from Frank-zhu0404/fix/issue-2886-heredoc-gateguard
fix(gateguard): ignore heredoc prose for tee and path-qualified sinks
2026-09-18 21:10:25 -04:00
Affaan MustafaandGitHub 27dbe41b09 Merge pull request #3159 from jgaribay01/fix/prepush-venv-pytest
fix(hooks): pre-push skipped every Python project that uses a virtualenv
2026-09-18 21:10:20 -04:00
Affaan MustafaandGitHub 4755a56bc0 Merge pull request #3164 from affaan-m/fix/3136-gateguard-batch-consistency
fix(gateguard): warn that parallel-batch siblings may already be applied
2026-09-18 21:10:02 -04:00
Affaan MustafaandGitHub e7e491a94d Merge branch 'main' into fix/ollama-generation-token-limit 2026-09-18 21:03:46 -04:00
Affaan MustafaandGitHub 09ae8be2bd Merge branch 'main' into fix/issue-2886-heredoc-gateguard 2026-09-18 21:03:40 -04:00
Affaan MustafaandGitHub 1bb31dfeae Merge branch 'main' into fix/prepush-venv-pytest 2026-09-18 21:03:34 -04:00
Affaan MustafaandGitHub 66462a5bf1 Merge branch 'main' into fix/3136-gateguard-batch-consistency 2026-09-18 21:03:31 -04:00
Affaan MustafaandGitHub c023a8e5a7 Merge branch 'main' into fix/3116-home-install-exclusions 2026-09-18 21:03:28 -04:00
Affaan MustafaandGitHub d14cf18549 Merge pull request #3166 from affaan-m/fix/ci-node18-test-job
fix(tests): feed guided install PTY answers only after each prompt
2026-09-18 20:45:08 -04:00
Affaan MustafaandGitHub c2d4196d8f Merge pull request #3167 from affaan-m/fix/opencode-plugin-entry
fix(opencode): add resolvable package entry and loadable in-place sources
2026-09-18 20:45:06 -04:00
Affaan Mustafa 8cfbc26797 fix: reconcile pre-exclusion .agents installs on claude and codex home upgrades 2026-09-18 20:13:11 -04:00
Affaan Mustafa f0378ccdb6 fix(tests): feed guided install PTY answers only after each prompt
The real-PTY test piped answers on fixed sleeps, typing them ahead of
readline. Under CI load the first answer could land before the interface
listened, shifting every later answer onto the wrong question: the
ubuntu-latest Node 18.x npm job installed Claude only, exited 0, and never
printed the Kimi profile prompt while the sibling yarn, pnpm, and bun jobs
on the same Node version passed. Answer each prompt once it appears on
screen instead; spawned stdio goes through cat because the macOS script(1)
refuses a socket stdin.
2026-09-18 18:47:05 -04:00
He DongandGitHub 8bf16ccfec fix(hooks): keep silent hook paths silent (#2987)
* fix(hooks): keep silent hook paths silent

* fix(hooks): harden stream failure handling

* fix(hooks): settle interrupted input streams

* test(hooks): name stream input limits

* test(hooks): isolate PostToolUse dispatcher fixtures
2026-09-18 18:42:20 -04:00
Affaan Mustafa 1a8beb71c5 fix(opencode): add resolvable package entry and loadable in-place sources
Root package.json declared no main or exports, so OpenCode npm plugin
resolution (import.meta.resolve) failed and the plugin was silently
skipped (#3127). The .opencode TypeScript sources imported siblings
with .js specifiers that only exist after compilation, so the home
install, which loads the .ts files in place, crashed the tool registry
with ERR_MODULE_NOT_FOUND (#3112).

Declare main/types/exports on the root package pointing at the
compiled plugin entry, switch the sources to .ts specifiers, and
enable allowImportingTsExtensions with rewriteRelativeImportExtensions
so the emitted dist keeps working .js specifiers. Add smoke tests that
build the package, resolve and import the entry by name from a temp
install, and verify every in-place relative import resolves.

Fixes #3127
Fixes #3112
2026-09-18 18:39:57 -04:00
Affaan MustafaandGitHub 34de45f210 fix(hooks): enforce loader-documented keys in shipped hooks configs (#3163)
hooks/hooks.json already ships only schema-valid keys with metadata in the
hooks.metadata.json sidecar. Add scripts/ci/check-hooks-schema-keys.js, a
strict allowlist check that fails when hooks/hooks.json or
hooks/codex-hooks.json carry any key outside their loader's documented set,
wire it into the npm test chain, and cover it with fixture tests.

Refs #3138, #3114
2026-09-18 18:37:40 -04:00
Affaan Mustafa da214d73b7 fix: stop home installs copying .agents into ~/.claude and ~/.codex 2026-09-18 18:37:05 -04:00
Affaan Mustafa db61d1c76a fix(gateguard): warn that parallel-batch siblings may already be applied (#3136)
A first-touch Edit/Write denial marks the file checked so the retry
passes. Sibling edits to the same file in the same parallel batch are
therefore judged against post-denial state and silently apply, leaving
the file in a state neither version intended.

Hooks see tool calls one at a time, so a batch-wide lock is not
possible. Instead make the partial application explicit: the Edit,
Write, MultiEdit, and condensed denials now name the file and warn
that other edits from the same batch may already have been applied,
and SKILL.md tells agents to send dependent edits sequentially and
re-read the file after a gated batch.
2026-09-18 18:37:01 -04:00
Affaan MustafaandGitHub b15f7d8171 docs(mcp): expose memory auth boundary (#3134)
* fix(memory): classify directory traversal failures

* docs(mcp): expose memory auth boundary
2026-09-18 17:01:14 -04:00
Juan Garibay 4869db30c4 fix(hooks): match the index case-insensitively, and isolate the pytest probe
Red-teaming the guard from 3c317470 found two more ways to get a repository's own
code executed. Both are demonstrated by a planted binary that appends to a witness
file, counted before and after.

Case folding. git matches index pathspecs case-sensitively even where
core.ignorecase is set, but APFS does not -- so a repository that commits
`.venv/bin/Python` gets `$venv/bin/python` opening and running that file while the
guard's lowercase query finds nothing in the index and reports it untracked. The
witness logged two invocations. It applies to `venv` and `env` as well, and to any
folding of the name. The query now uses a `:(icase)` pathspec; all nine
directory-by-spelling combinations are refused, and an untracked venv still runs.

Module shadowing. `python -c "import pytest"` puts the working directory first on
sys.path, so a repository that commits a `pytest.py` in its root has that file
imported, and executed, by a check whose only job is to answer whether pytest is
installed. The probe is now `python -I -c "import pytest"` on the virtualenv, uv
and poetry paths alike. Isolation does not hide a real pytest -- it lives in the
interpreter's own site-packages, confirmed against a venv holding pytest 9.1.1.

Still true, and not something this hook can fix: running the repository's declared
suite runs the repository's code. `pytest` imports conftest.py, and the Node arm
runs package.json scripts. That is what a pre-push verification hook is for. The
line this guard draws is narrower and worth keeping -- a capability probe, and the
choice of which interpreter to trust, should not be things the pushed repository
gets to decide.
2026-09-17 17:17:19 -04:00
Juan Garibay 3c31747016 fix(hooks): resolve the venv path before asking git whether it is tracked
The guard added in 9cdc40e6 was incomplete. `git ls-files` reports paths as they
are indexed and does not follow symlinks, so a repository that commits `.venv` as
a symlink to its own root alongside a tracked `bin/python` gets asked about
`.venv/bin/python` -- a path git has never heard of -- and the answer is
"untracked". The interpreter then runs. Measured on that shape: the planted
executable logged two invocations against 9cdc40e6 and none against this commit.

`repo_ships_interpreter` now resolves the bin directory with `cd -P`/`pwd -P`,
resolves the worktree root the same way, and asks git about the resolved path
relative to it. The three cases that matter all hold: a plainly committed venv is
still refused, the symlink shape is now refused, and a developer's own untracked
venv still resolves and runs.

`cd -P`/`pwd -P` rather than `realpath` or `readlink -f`, because neither is
portable to a stock macOS.
2026-09-17 16:55:11 -04:00