The default chrome-devtools connector is launched with `npx -y` and
`@latest`, so every session start can silently install whatever version
was most recently published to npm. Pinning makes the default connector
reproducible and removes the unpinned-npx finding that /security-scan
(AgentShield) reports against ECC's own .mcp.json.
The same spec is pinned in the Codex merge script so both harnesses
stay in sync, and the Codex merge test is updated to match.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- pre-push: send skip diagnostic to stderr (not stdout) so consumers
relying on stderr for warnings receive the message
- pre-push: move ECC_PREPUSH_AUDIT outside RUN_CHECKS gate so audit-only
configurations still check dependencies
- mcp-health-check: classify home config paths as trusted before applying
workspace opt-in gate; when cwd == home, ~/.claude.json was incorrectly
blocked as untrusted workspace config
- install-global-git-hooks: check conflicting global core.hooksPath in
dry-run mode too, so dry-run accurately reflects what apply would do
- orchestrate-codex-worker: pass approval policy via --ask-for-approval,
not -p profile
- codex global hooks: validate conflicting global hooksPath before backup/copy,
so refused install is side-effect free
- claw: reject percent-delimited Windows paths in cmd.exe fallback to avoid
%NAME% expansion
- codex-hooks: opt into ECC_PREPUSH_RUN_CHECKS=1 in existing verification
fixtures and add default-skip coverage
* fix(hooks): fail open on oversized stdin instead of echoing truncated JSON (#2222)
run-with-flags.js capped stdin at 1MB but every fallthrough path still
echoed the truncated string to stdout. The harness parses hook stdout as
JSON, got a document cut mid-stream, and blocked the tool call — so any
Edit/Write with a >1MB hook payload was permanently blocked by every
registered pre-write hook, before ECC_HOOK_PROFILE / ECC_DISABLED_HOOKS
gating could run.
- Exit 0 with empty stdout (no opinion) when the stdin cap trips, before
any echo or gating logic.
- Flush stdout via write callback before process.exit: exiting right
after stdout.write() dropped everything past the ~64KB pipe buffer,
cutting even sub-cap pass-through payloads mid-JSON.
Regression tests cover the enabled, disabled, and missing-arg paths for
oversized payloads plus full echo of sub-cap >64KB payloads.
* fix(codex): stop emitting invalid exa url entry, align merge with connector policy (#2224)
The Codex MCP merge declared exa with a url key, but Codex's
[mcp_servers.*] TOML schema is stdio-only — the url key makes the
entire config.toml fail to load, bricking both the codex CLI and the
desktop app. Every install/update re-injected the line because the
urlEntry branch treated the broken entry as present.
- ECC_SERVERS now emits only the current default set per
docs/MCP-CONNECTOR-POLICY.md: chrome-devtools (stdio, command/args).
Retired servers (supabase, playwright, context7, exa, github, memory,
sequential-thinking) are never re-emitted; existing user-managed
entries are untouched.
- The merge now repairs the exact ECC-emitted broken form (url-only
exa entry) on every run so re-running the installer fixes broken
configs instead of preserving them. User stdio exa entries
(command + mcp-remote) are left alone.
- check-codex-global-state.sh requires chrome-devtools instead of the
retired set, and flags url-only exa entries with a repair hint.
Tests cover repair, re-run idempotence, stdio-entry preservation, and
no-retired-server emission in add, update, dry-run, and disabled modes.
* fix(hooks): never echo truncated stdin from Stop hooks (#2090)
Stop hooks follow the ECC pass-through convention (echo stdin on
stdout), but every echoing Stop hook capped stdin and echoed the capped
string. The Stop payload carries last_assistant_message, so a long
final assistant message produced a JSON document cut mid-stream on
stdout, which the harness reports as 'Stop hook error: JSON validation
failed' across the whole Stop chain.
Reproduced: a Stop payload with a >64KB last_assistant_message run
through run-with-flags + cost-tracker emitted exactly 65536 bytes of
invalid JSON (cost-tracker capped stdin at 64KB — far below realistic
Stop payloads).
- cost-tracker: raise the cap to 1MB (matching all other hooks) and
suppress the pass-through echo when stdin was truncated.
- check-console-log, stop-format-typecheck, desktop-notify: suppress
the echo when stdin was truncated; flush stdout before process.exit
so sub-cap payloads are not cut at the ~64KB pipe buffer.
- All hooks keep exiting 0 (fail-open); diagnostics go to stderr.
New stop-hooks-stdout test asserts the contract for every registered
Stop hook: stdout is empty or valid JSON, exit code 0 — for realistic
100KB payloads and oversized >1MB payloads, via the production runner
and via direct invocation. Updated the old hooks.test.js case that
codified the truncated-echo behavior.
* fix(hooks): dampen GateGuard fact-force repetition in long sessions (#2142)
In long autonomous sessions the fact-force gate produced 10+
near-identical 'state facts -> blocked -> restate -> retry' blocks in
one context window, which measurably raises the odds of the model
collapsing into a degenerate single-token repetition loop.
- Track a per-session fact_force_denials counter in GateGuard state
(merged max across concurrent writers, reset with the session, robust
to malformed on-disk values).
- The first GATEGUARD_FACT_FORCE_FULL_DENIALS denials (default 3) keep
the full four-fact block; later denials emit a condensed single-line
message that carries the denial ordinal, so consecutive denials are
structurally different and never textually identical.
- True retries of the same target remain allowed without re-prompting
(unchanged). Destructive-Bash and routine-Bash gates are unchanged,
as are the ECC_GATEGUARD=off / ECC_DISABLED_HOOKS escape hatches.
Eight new tests cover budget counting, condensed format, ordinal
advancement, retry pass-through, env tuning, malformed state, MultiEdit
dampening, and destructive-gate exemption.
* fix(hooks): keep security hooks able to block on oversized stdin (#2222)
Refine the truncation fail-open: instead of skipping the hook entirely,
the runner now suppresses only its own raw-echo when stdin was
truncated. The hook still executes and receives the truncated flag
(run() context / ECC_HOOK_INPUT_TRUNCATED), so config-protection keeps
blocking truncated protected-config payloads (its test requires exit 2)
while pass-through hooks fail open with empty stdout as before.
* style: apply repo formatter to touched hook files
* fix(ci): resolve cross-platform test failures
- Sanity check script (check-codex-global-state.sh) now falls back to
grep -E when ripgrep is not available, fixing the codex-hooks sync
test on all CI platforms. Patterns converted to POSIX ERE for
portability.
- Unicode safety test accepts both / and \ path separators so the
executable-file assertion passes on Windows.
- Gacha test sets PYTHONUTF8=1 so Python uses UTF-8 stdout encoding on
Windows instead of cp1252, preventing UnicodeEncodeError on box-drawing
characters.
- Quoted-hook-path test skipped on Windows where NTFS disallows
double-quote characters in filenames.
* feat: port remotion-video-creation skill (29 rules), restore missing files
New skill:
- remotion-video-creation: 29 domain-specific Remotion rules covering 3D/Three.js,
animations, audio, captions, charts, compositions, fonts, GIFs, Lottie,
measuring, sequencing, tailwind, text animations, timing, transitions,
trimming, and video embedding. Ported from personal skills.
Restored:
- autonomous-agent-harness/SKILL.md (was in commit but missing from worktree)
- lead-intelligence/ (full directory restored from branch commit)
Updated:
- manifests/install-modules.json: added remotion-video-creation to media-generation
- README.md + AGENTS.md: synced counts to 139 skills
Catalog validates: 30 agents, 60 commands, 139 skills.
* fix(security): pin MCP server versions, add dependabot, pin github-script SHA
Critical:
- Pin all npx -y MCP server packages to specific versions in .mcp.json
to prevent supply chain attacks via version hijacking:
- @modelcontextprotocol/server-github@2025.4.8
- @modelcontextprotocol/server-memory@2026.1.26
- @modelcontextprotocol/server-sequential-thinking@2025.12.18
- @playwright/mcp@0.0.69 (was 0.0.68)
Medium:
- Add .github/dependabot.yml for weekly npm + github-actions updates
with grouped minor/patch PRs
- Pin actions/github-script to SHA (was @v7 tag, now pinned to commit)
* feat: add social-graph-ranker skill — weighted network proximity scoring
New skill: social-graph-ranker
- Weighted social graph traversal with exponential decay across hops
- Bridge Score: B(m) = Σ w(t) · λ^(d(m,t)-1) ranks mutuals by target proximity
- Extended Score incorporates 2nd-order network (mutual-of-mutual connections)
- Final ranking includes engagement bonus for responsive connections
- Runs in parallel with lead-intelligence skill for combined warm+cold outreach
- Supports X API + LinkedIn CSV for graph harvesting
- Outputs tiered action list: warm intros, direct outreach, network gap analysis
Added to business-content install module. Catalog validates: 30/60/140.
* fix(security): npm audit fix — resolve all dependency vulnerabilities
Applied npm audit fix --force to resolve:
- minimatch ReDoS (3 vulnerabilities, HIGH)
- smol-toml DoS (MODERATE)
- brace-expansion memory exhaustion (MODERATE)
- markdownlint-cli upgraded from 0.47.0 to 0.48.0
npm audit now reports 0 vulnerabilities.
* fix: resolve markdown lint and yarn lockfile sync
- MD047: ensure single trailing newline on all remotion rule files
- MD012: remove consecutive blank lines in lottie, measuring-dom-nodes, trimming
- MD034: wrap bare URLs in angle brackets (tailwind, transcribe-captions)
- yarn.lock: regenerated to sync with npm audit changes in package.json
* fix: replace unicode arrows in lead-intelligence (CI unicode safety check)
Add @latest suffix to '@upstash/context7-mcp' in ECC_SERVERS so the
generated merge spec matches .codex/config.toml exactly, preventing
configDiffers from flagging false drift on --update-mcp runs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
The rg pattern anchored at line start (^persistent_instructions) would
miss indented TOML entries. Use ^\s* prefix to match both top-level and
indented configurations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
The global sanity check (check-codex-global-state.sh) hard-fails when
persistent_instructions is missing from ~/.codex/config.toml, but neither
the baseline .codex/config.toml nor the sync script ever define this field.
This causes a clean install to report a failing sanity check even though the
sync otherwise succeeds (#967).
- Add persistent_instructions to the baseline .codex/config.toml so that
users who cp the config get a working default.
- Downgrade the sanity check from fail to warn, since persistent_instructions
is additive and optional — users who rely solely on AGENTS.md should not be
blocked.
Fixes#967 (persistent_instructions part; context7 naming addressed by #970)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
Reviewers identified that merge-mcp-config.js --update-mcp would
silently strip the startup_timeout_sec from config.toml because the
ECC_SERVERS spec did not include it. Add startup_timeout_sec = 30 to
playwright, context7-mcp, github, memory, and sequential-thinking.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
Codex CLI reads skills natively from ~/.agents/skills/ (installed by
ECC installer / npx skills). The sync script was redundantly copying
the same skills from .agents/skills/ to ~/.codex/skills/.
Changes:
- Remove skill copy loop, variables, and path validation from sync script
- Update sanity checker to validate ~/.agents/skills/ instead of
~/.codex/skills/, downgrade missing skills from FAIL to WARN
- Update test assertions to verify skill sync removal
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* fix: replace bash TOML surgery with Node add-only MCP merge
The old sync script used awk/sed to remove and re-append MCP server
sections in config.toml, causing credential extraction races, duplicate
TOML tables, and 3 fragile code paths with 9 remove_section_inplace
calls each.
Replace with a Node script (scripts/codex/merge-mcp-config.js) that
uses @iarna/toml to parse the config, then appends only missing ECC
servers — preserving all existing content byte-for-byte. Warns on
config drift, supports legacy aliases (context7 → context7-mcp), and
adds --update-mcp flag for explicit refresh.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* fix: address PR #723 review findings for Codex MCP merge
- Use package-manager abstraction (scripts/lib/package-manager.js)
instead of hardcoding pnpm — respects CLAUDE_PACKAGE_MANAGER,
lock files, and project config
- Add Yarn 1.x fallback to npx (yarn dlx unsupported in classic)
- Add missing exa server to match .codex/config.toml baseline
- Wire up findSubSections for --update-mcp nested subtable removal
(fixes Greptile P1: Object.keys only returned top-level keys)
- Fix resolvedLabel to prefer canonical entry over legacy alias
when both exist (fixes context7/context7-mcp spurious warning)
- Fix removeSectionFromText to handle inline TOML comments
- Fix dry-run + --update-mcp to show removals before early return
- Update README parity table: 4 → 7 servers, TOML-parser-based
- Add non-npm install variants to README Codex quick start
- Update package-lock.json for @iarna/toml
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* fix: address PR #723 review comments (preflight, marker validation)
- Add Node.js and merge-mcp-config.js to preflight checks so the
script fails fast before partial writes (CodeRabbit)
- Validate marker counts: require exactly 1 BEGIN + 1 END in correct
order for clean replacement (CodeRabbit)
- Corrupted markers: strip all marker lines and re-append fresh block,
preserving user content outside markers instead of overwriting
- Move MCP_MERGE_SCRIPT to preflight section, remove duplicate
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>