D6: bundle composition — legacy splice path deleted, engine trimmed per entry - #100
Merged
Conversation
…y uses The legacy adapter-splice path is deleted. bundle() now has exactly two compositions: bundle_entry(cfg) -- public, so a thirteenth vendor's entry bundles without being registered -- renders contract + one family-engine section + the inlined VENDOR literal + the runtime; vscode_copilot keeps a dedicated dialect composition whose output is byte-identical to the legacy splice it replaces. The engine section is trimmed by composition, never by editing engine code: the family's bound entry points plus their transitive dependencies are extracted from the shared modules, minus the grammar renderers no gate of the entry speaks, the TOML emitter unless config_format is toml, and the probe/windows helpers the entry does not cite (same base: cursor 883->608, windsurf 814->581, antigravity 796->643, F1 -11-15%, F2 -14%). Golden fixtures byte-for-byte unchanged; the 12-agent bundler subprocess replay is green before and after the trim. New tests: every bundle replays the whole golden set (payloads x outcomes plus both hook_config paths) through its own main(); exactly one family-engine section and one VENDOR literal per config-driven bundle; trimmed-device presence derived from the entry; and the design §5.4 thirteenth-vendor test adds a synthetic vendor by config alone -- schema-validated, bound, wired and bundled with no code. The dead adapters/_common.py helper is removed with the legacy path that fed it. Signed-off-by: Claude <noreply@anthropic.com>
…rim numbers README, AGENTS.md and CONTRIBUTING now describe adding an agent as a data/vendors entry (plus its _CONFIG_DRIVEN registration, matrix row and fixtures), with a family module only for a genuinely new dialect. The design doc's §7 gains the measured D6 bundle sizes with the honest caveat that F1/F2 members stay above their own wave-base numbers because the D4/D5 devices live inside shared function bodies. CHANGELOG carries the D6 entry under Unreleased; no version bump, release stays frozen. Signed-off-by: Claude <noreply@anthropic.com>
open-coder-ai
marked this pull request as ready for review
September 1, 2026 15:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
bundle()now has exactly two compositions and no filesystem-probed legacy splice path:bundle_entry(cfg)(public) renders contract + one family-engine section trimmed to what the entry uses + the inlinedVENDORliteral + the runtime for all eleven config-driven vendors, andvscode_copilot— the deliberate dialect-module exception — keeps a dedicated composition whose output is byte-identical to the legacy splice it replaces. Docs' "adding an agent" paths now describe the config entry; design §7 records the measured numbers.Trimming (
dialect-families.md§7's open item, owned by D6) is composition logic only — no engine module changed: the family's bound entry points (hj_*/<family>_*+hook_entry_config) plus their transitive dependencies are extracted from the shared modules, minus_g2leaves devin and every F2 bundle;_g1leaves kimi_code),hj_respondmachinery the singleton dialects never call,config_formatistoml,Measured sizes (lines, same base — before is main
6838d69, where every engine bundle inlined the whole engine):The singletons give back most of D5's growth (cursor −31%, windsurf −29%, antigravity −19%). F1/F2 members give back 11–15% but stay above their own wave-base numbers (claude_code 698 vs 650 at D3's base): the D4/D5 devices live inside shared function bodies (
_g1,hj_parse), where line-level trimming would mean per-vendor engine variants — §3.1's config/code line says no, so those lines stay, recorded in design §7.Also: the dead
adapters/_common.py(last user deleted in D3–D5) is removed; CHANGELOG Unreleased entry added; no version bump.New tests (design §5, D6's rows):
test_bundle_equivalence.py— every bundle replays the whole golden set (every frozen payload × outcome through the bundle's ownmain(), plus bothhook_configpaths) — the §5.5 equivalence proof, on top of the existing 12-agent × outcome subprocess replay, which passes identically before and after the trim.test_bundler.py— exactly one family-engine section and exactly oneVENDORliteral per config-driven bundle (the re-homed intent of the retired cross-adapter splice test, per §5); trimmed-device presence derived from the entry's own gates/config_format; probes inlined exactly where cited.test_thirteenth_vendor.py— §5.4: a synthetic vendor added by config alone is schema-validated, bound, claims/parses/responds/wires, and bundles viabundle_entrywith the bundle matching the library's wire truth — no code.Claim check
MATRIXrow (the test's synthetic row is injected and removed by a fixture)Checks
pytest -qpasses — 1399 passed, 4 skipped (was 1348: +51 new tests); golden fixtures byte-for-byte untouchedruff check .andruff format --check .passtests/check_stdlib_only.pygreen; bundler change is compose-time only)git commit -s)Notes for the reviewer
hj_respondstill readsif gate["grammar"] == "G2": return _g2(...)with_g2absent. That branch is unreachable for the inlined entry's data — the same pattern_hook_entry.py's own comment already documents forpowershell_command— and the golden-set equivalence test plus the subprocess replay pin the behavior. If you'd rather fail-closed on it, the alternative is rewriting the dispatch in the emitted source, which I judged worse than a provably-dead name._g2); the engine modules stay fully shared.render_config(kimi's TOML emitter) is kept in bundles whoseconfig_formatistomland trimmed elsewhere — bundles never call it at runtime, but it is part of that vendor's config surface.Generated by Claude Code