Skip to content

Derive in-agent membership from the matrix; extend the surface to seven new vendors (C3) - #98

Merged
open-coder-ai merged 3 commits into
mainfrom
feat/c3-derived-membership-nine-vendors
Sep 2, 2026
Merged

Derive in-agent membership from the matrix; extend the surface to seven new vendors (C3)#98
open-coder-ai merged 3 commits into
mainfrom
feat/c3-derived-membership-nine-vendors

Conversation

@open-coder-ai

@open-coder-ai open-coder-ai commented Sep 2, 2026

Copy link
Copy Markdown
Owner

What

Design C3 of docs/design/derive-from-vendor-config.md: IN_AGENT_TODAY, SURFACE_AGENTS, RUNTIME_AGENTS and VENDORED_RUNTIMES stop being hand lists and derive in chock.vendors from agentseam 0.2.0's matrix.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 own hook_config, one shape-agnostic merge installer (hooks/in_agent_generic.py), and a vendored runtime from bundle(). Day-one coverage cells are basis-capped per §3.4: every new cell reads best-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 what chock sync --repo may write. They stay advisory-only; tests/test_vendor_wire_facts.py pins 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:

  • Byte-identity for the four already-enforced vendors: a full before/after tree diff over all 78 pre-existing generated artifacts (.claude/, .cursor/, .github/hooks/, .chock/ minus log/gate-events.jsonl) shows the only changed file is coverage.json, and within it only 24 new-vendor cells moved (advisory → basis-capped best-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/bin copies (chock sync --check clean).
  • Six new honours_ask claim rows record each new runtime's crash-guard wire word, tested live against the bundled runtimes in tests/test_guard_fail_to_ask.py; block (devin's spelling) and exit-2 (windsurf's G5 exit-code grammar, golden-tested first per §9) join the wire-verdict vocabulary. witnessed stays false for every new vendor — no live client run exists.
  • Known upstream gaps keep their marked overrides (repo-root token, vscode agent-hooks shape, shell-tool vocabulary); nothing re-filed, nothing hand-copied. Fragment commands for the new vendors therefore use repo-relative paths: the guard resolves under the same condition the relative adapter path resolves at all (vendor runs hooks from the repo root). Installs are unwitnessed best-effort claims until a live run lands in the witness ledger.

New tests: per-vendor fragment goldens in the emitter-stability tree; frozen per-vendor runtime bytes (tests/fixtures/runtime_goldens/, regen only via CHOCK_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 from IN_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 PR
  • chock check --only matrix passes; matrix updated in this PR if behavior changed
  • chock sync --repo . --check clean (compiled artifacts match their manifests)
  • chock check --only verify clean (lockfile matches packs and compiled artifacts)
  • Registry rescanned; no stale entries
  • pytest -q green (1034 passed, 1 skipped); new checks have attack + ordinary-data tests
  • pytest acceptance/ -c acceptance/pytest.ini --rootdir=acceptance green (21 passed)
  • Existing artifacts migrated in this PR (repo re-synced: new vendor configs, runtimes, coverage cells)
  • Touched manifests: none touched; CHANGELOG Unreleased entry added (no version bump under the release freeze)
  • ruff check . and ruff format --check . clean

Claims

  • No surface is described as enforcing more than it installs. INSTALLED_SURFACES unchanged; the coverage table and docs/enforcement-surfaces.md / README matrices are regenerated-against-code (test_surface_doc_matches_code), and every new vendor's cell carries its basis with witnessed: false.

🤖 Generated with Claude Code

…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>
@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: e9fb4250-2a64-457e-9cb5-67ad7814eb11


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

elif isinstance(value, dict) and value:
_strip_ours(value, marker)
if not value:
del node[key]

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread tests/fixtures/runtime_goldens/antigravity.py Fixed
Comment thread tests/fixtures/runtime_goldens/claude_code.py Fixed
Comment thread tests/fixtures/runtime_goldens/codex_cli.py Fixed
Comment thread tests/fixtures/runtime_goldens/cursor.py Fixed
Comment thread tests/fixtures/runtime_goldens/gemini_cli.py Fixed
Comment thread tests/fixtures/runtime_goldens/grok.py Fixed
Comment thread tests/fixtures/runtime_goldens/tabnine.py Fixed
Comment thread tests/fixtures/runtime_goldens/vscode_copilot.py Fixed
Comment thread tests/fixtures/runtime_goldens/windsurf.py Fixed
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>
@open-coder-ai
open-coder-ai marked this pull request as ready for review September 2, 2026 01:01
@open-coder-ai
open-coder-ai merged commit 25d9e96 into main Sep 2, 2026
15 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants