Skip to content

D4: fold the four F2 flat_decision adapters onto the engine - #98

Merged
open-coder-ai merged 2 commits into
mainfrom
w41/d4-f2-flat-decision-engine
Sep 1, 2026
Merged

D4: fold the four F2 flat_decision adapters onto the engine#98
open-coder-ai merged 2 commits into
mainfrom
w41/d4-f2-flat-decision-engine

Conversation

@open-coder-ai

Copy link
Copy Markdown
Owner

What this changes

gemini_cli, tabnine, junie and grok are no longer hand-written adapter modules: the D3 engine executes their data/vendors/<agent>.json entries (dialect-families.md §6, wave D4), and bundle() composes engine + inlined VENDOR literal for them. Wire output through the dispatcher is unchanged — the golden fixture suite passes byte-for-byte with zero fixture edits.

Claim check

  • No capability claim is widened without a mechanism behind it — no MATRIX row changes; every new config gate (junie's PermissionRequest) was recounted by replaying the real dispatcher against the frozen D1 payload, and test_config_gates_are_a_subset_of_matrix_block_capable_events still gates it
  • Any new/changed MATRIX row carries a verified record — no matrix rows touched
  • Payload shapes come from a primary source — no new payload shapes; every renderer string in the new config sections is verbatim from the deleted adapters and frozen in tests/fixtures/golden/<agent>.json

Checks

  • pytest -q passes (1348 passed, 4 skipped; includes the golden replay and the 12-agent test_bundler_subprocess.py replay)
  • ruff check . and ruff format --check . pass (ruff check --select I --fix was a no-op)
  • Runtime path is still stdlib-only (PYTHONNOUSERSITE=1 python tests/check_stdlib_only.py clean; examples/generate.py --check and docs/assets/gen_brand_assets.py --check also run clean)
  • Commits are signed off (git commit -s)

Notes for the reviewer

Two-stage history, each commit green. Stage 1 adds the schema fields, engine devices and tools/recount tables and regenerates the four entries via recount_vendor_config.py --write (modules still bound, so the enrichment is derived, not hand-typed — F1 and singleton entries regenerate byte-identical). Stage 2 flips _CONFIG_DRIVEN, deletes the four modules (465 lines), and removes the transitional gemini fields override.

Every engine device is an opt-in config key, absent from all F1 entries (checked: every F1 G1 gate has honours_escalate: false, no F1 entry carries the new keys), so F1 wire cannot move: escalate word path in _g1; hook_specific_tool_input (gemini, emits tool_input: null on a rewrite with no input, as the fixture pins) and top_level_updated_input (junie) transform bodies; template degrade notes filling (reason-or-default, wire event) (gemini's "cannot prompt from a hook"); gate_reason_defaults (junie's Stop "not finished"); allow_context_key/allow_silent_events (junie's additionalContext and silent Stop-allow); missing_wire: reverse_map (tabnine answers hand-built events, and a hand-built UNKNOWN event stays silent); a fields.tool_input envelope chain (grok's toolInput, derived by the recount walker from the deleted module's own ti = assignment); content_only_for_write_tools (gemini); literal entry_extra values (tabnine's name: agentseam).

One designed test retirement. test_the_unverified_vocabulary_is_still_only_tabnine grepped per-vendor source files that no longer exist; dialect-families.md §5's table names it as dying at this wave with its intent re-homed — the re-homed derivation (test_vendor_config.py::test_vocabulary_basis_is_unverified_only_for_tabnine) already exists and passes.

Two respond()-direct behaviours did not survive, both unreachable through handle() (called out in the CHANGELOG): tabnine no longer answers the undocumented BeforeModel/AfterModel wire names (they map to no canonical event, so handle() short-circuited before respond(), and a config gate for them would fail the matrix-subset test), and gemini_cli no longer honours a rewrite at gates the recount classified deny-only (through the dispatcher, degrade() already converted those to escalates). W38's handback note also asked for a flat_entries hook-entry style for tabnine — tabnine's wrapper is actually hooks_map with a name extra, so only the literal-extra device was needed; flat_entries rendering stays for the wave that folds its real users (vscode_copilot/windsurf, D5).

Bundle sizes (design §7 updated with the same numbers): gemini_cli 458→690, tabnine 409→664, junie 429→664, grok 439→664 (+51–62%, above the §4 estimate of 470–500 because an engine bundle inlines the whole shared engine, G2 included — the trade D3 already made; D6 owns bundle composition). Source tree: −465 adapter lines, +~40 engine lines, no new modules.


Generated by Claude Code

…r data

The four F2 vendors' data/vendors entries gain the G1 renderer tables
(words, degrade notes, reason defaults) via tools/recount, and the engine
gains the table-driven devices those dialects need: an escalate word path
in _g1, the hook_specific_tool_input and top_level_updated_input transform
bodies, template degrade notes, per-gate reason defaults, allow-body
context, allow-silent events, a reverse-map fallback for payloads with no
wire event name, a tool-input envelope chain, write-gated content, and
literal hook-entry extras. All opt-in config keys absent from every F1
entry; full suite green with golden fixtures byte-identical.

Signed-off-by: Open Coder AI <250249270+open-coder-ai@users.noreply.github.com>
…ion engine

The four F2 modules are deleted; adapters.get() binds each to the D3
engine over its data/vendors entry, and bundle() composes engine + inlined
VENDOR literal for them. Golden fixtures byte-for-byte unchanged; the
12-agent bundler subprocess replay is green. The tabnine source-grep
vocabulary test is retired per design §5, its intent already re-homed as
test_vocabulary_basis_is_unverified_only_for_tabnine. junie's
PermissionRequest alias gate joins _EXTRA_GATE_NAMES; the transitional
gemini fields override in tools/recount is removed now that the entry is
the source.

Signed-off-by: Open Coder AI <250249270+open-coder-ai@users.noreply.github.com>
@open-coder-ai
open-coder-ai marked this pull request as ready for review September 1, 2026 13:23
@open-coder-ai
open-coder-ai merged commit 38023f4 into main Sep 1, 2026
14 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.

1 participant