Derive in-agent membership from the matrix; extend the surface to seven new vendors (C3) - #98
Conversation
…en new vendors (C3) IN_AGENT_TODAY, SURFACE_AGENTS, RUNTIME_AGENTS and VENDORED_RUNTIMES stop being hand lists: membership derives in chock.vendors from agentseam 0.2.0's matrix.can_block(V, PRE_TOOL), capped by what the repo-scoped installer may touch (a repo-relative JSON hook config). Wire facts keep coming from the vendor entries; capability enters from the matrix only. New in-agent vendors: antigravity, codex_cli (repo-level, beside its plugin store), devin, gemini_cli, grok, tabnine, windsurf. Each gets per-policy pre-tool fragments rendered by agentseam's own hook_config, one shape-agnostic merge installer (hooks/in_agent_generic.py: strip-ours + deep-merge keyed on the vendored runtime path, interpreter baking as before), and a vendored runtime from bundle(). junie and kimi_code block per the matrix but their recorded configs are home-anchored (kimi_code's TOML), outside chock sync --repo's writes: excluded by derivation, pinned by a test that fails when upstream records repo-level JSON for them. junie joins the alias table, advisory surfaces and both published matrices. Day-one coverage is basis-capped and honest: every new cell reads best-effort (<its recorded basis>), witnessed: false; no word moved for the four previously enforced vendors and their artifacts are byte-identical (before/after tree diff: only new-vendor coverage cells changed). Six new tested honours_ask claim rows record each new runtime's crash-guard wire word (block and exit-2 join the wire vocabulary for devin's spelling and windsurf's G5 exit-code grammar). New goldens freeze per-vendor fragments (emitter-stability tree) and per-vendor runtime bytes (tests/fixtures/runtime_goldens/). Fragment commands for the new vendors use repo-relative paths: no repo-root token is recorded upstream for them (known gap, filed), so the hooks resolve where the vendor runs them from the repo root, and installs stay unwitnessed best-effort claims until a live run lands in the witness ledger. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| elif isinstance(value, dict) and value: | ||
| _strip_ours(value, marker) | ||
| if not value: | ||
| del node[key] |
There was a problem hiding this comment.
Verified — false positive, leaving the code as is. _strip_ours(value, marker) mutates value in place through the recursive call (its list branch dels keys from the dict it was handed), so a non-empty inner dict can come back empty and del node[key] executes. The analyzer doesn't model the interprocedural mutation.
Two pieces of evidence:
- Direct probe: antigravity-shaped settings (
{"agentseam": {"PreToolUse": [<ours>]}, "keep": 1}) end as{"keep": 1}— only line 102 removes that inner key. - Deleting the line fails
tests/test_generic_hooks_install.py::test_removal_deletes_only_what_chock_owns[antigravity](the config file would be left non-empty and not removed).
Dismissing the code-scanning alert is the owner's call; no code change is warranted.
Generated by Claude Code
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
…y freeze Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Claude <noreply@anthropic.com>
What
Design C3 of
docs/design/derive-from-vendor-config.md:IN_AGENT_TODAY,SURFACE_AGENTS,RUNTIME_AGENTSandVENDORED_RUNTIMESstop being hand lists and derive inchock.vendorsfrom agentseam 0.2.0'smatrix.can_block(V, PRE_TOOL)(§3.3), capped by what the repo-scoped installer may touch (a repo-relative JSON hook config). Capability enters from the matrix only; vendor entries contribute wire facts. The in-agent surface extends to seven new vendors — antigravity, codex_cli (repo-level, beside its existing plugin store), devin, gemini_cli, grok, tabnine, windsurf — each getting per-policy fragments rendered by agentseam's ownhook_config, one shape-agnostic merge installer (hooks/in_agent_generic.py), and a vendored runtime frombundle(). Day-one coverage cells are basis-capped per §3.4: every new cell readsbest-effort (+ its recorded basis +),witnessed: false.Two of the nine dispatched vendors are deliberately not wired, by the derivation itself: junie and kimi_code can block per the matrix, but their recorded hook configs are home-anchored (
~/.junie/config.json,~/.kimi-code/config.toml— TOML at that), outside whatchock sync --repomay write. They stay advisory-only;tests/test_vendor_wire_facts.pypins the exclusion to those recorded facts and fails the day upstream records repo-level JSON for them. junie (previously absent from chock entirely) joins the alias table, advisory surfaces, and both published matrices.Evidence honesty:
.claude/,.cursor/,.github/hooks/,.chock/minuslog/gate-events.jsonl) shows the only changed file iscoverage.json, and within it only 24 new-vendor cells moved (advisory→ basis-cappedbest-effort); zero claude/cursor/copilot/vscode cells moved and no word changed. All ten runtime renders are frozen as goldens; the four pre-C3 ones are byte-identical to the committed.chock/bincopies (chock sync --checkclean).honours_askclaim rows record each new runtime's crash-guard wire word, tested live against the bundled runtimes intests/test_guard_fail_to_ask.py;block(devin's spelling) andexit-2(windsurf's G5 exit-code grammar, golden-tested first per §9) join the wire-verdict vocabulary.witnessedstays false for every new vendor — no live client run exists.New tests: per-vendor fragment goldens in the emitter-stability tree; frozen per-vendor runtime bytes (
tests/fixtures/runtime_goldens/, regen only viaCHOCK_REGEN_GOLDENS=1); the generic installer's merge/idempotence/removal/foreign-preservation/stale-interpreter behavior across all seven shapes (tests/test_generic_hooks_install.py); the derived-set predicate recomputed and the junie/kimi_code exclusion pinned. Re-homed (intent kept): the fail-to-ask lift tests now recompute expected words through the basis caps instead of assuming every fail-open agent lifts; the "codex has no in-agent surface" pin moves to kimi-code; the end-to-end witness map derives fromIN_AGENT_TODAY. The 300-line exemption for.chock/bin/*generalizes from four named files to the directory prefix (same generated class) plus the runtime-goldens fixtures.Note for release: the emitter-output shape grew (new fragment files), which the golden test's own rule grades MINOR-worthy; no version bump here (release freeze — owner cuts versions).
Definition of done
chock check→ 0 errors, 0 warnings — one pre-existing[INFO](SEC-4 pattern inside injection-defense's own eval fixture) present on main before this PRchock check --only matrixpasses; matrix updated in this PR if behavior changedchock sync --repo . --checkclean (compiled artifacts match their manifests)chock check --only verifyclean (lockfile matches packs and compiled artifacts)pytest -qgreen (1034 passed, 1 skipped); new checks have attack + ordinary-data testspytest acceptance/ -c acceptance/pytest.ini --rootdir=acceptancegreen (21 passed)ruff check .andruff format --check .cleanClaims
INSTALLED_SURFACESunchanged; the coverage table anddocs/enforcement-surfaces.md/ README matrices are regenerated-against-code (test_surface_doc_matches_code), and every new vendor's cell carries its basis withwitnessed: false.🤖 Generated with Claude Code