Skip to content

feat: phase 2 wave 1 — dispatch by registry lookup (F-01/F-02/F-03/F-04/F-17/F-14) - #146

Merged
pacphi merged 7 commits into
developfrom
feat/phase-2-wave-1-registry-dispatch
Aug 15, 2026
Merged

feat: phase 2 wave 1 — dispatch by registry lookup (F-01/F-02/F-03/F-04/F-17/F-14)#146
pacphi merged 7 commits into
developfrom
feat/phase-2-wave-1-registry-dispatch

Conversation

@pacphi

@pacphi pacphi commented Aug 15, 2026

Copy link
Copy Markdown
Owner

The shell-to-spine wave: every remaining reach-by-name dispatch site becomes a registry lookup.

  • F-01: the execution-adapter map's bidirectional import-time invariant (which bricked ak run the moment a fourth routable host registered) becomes built-ins-one-directional, with executionAdapterFor() as the seam external adapters will join; unwired routable hosts degrade per worker via the pre-existing cli_unavailable path.
  • F-02: a construction-validated lifecycle registry replaces the five OPENCODE_LIFECYCLE_ADAPTER named imports; source-text guards pin that no command names an adapter again.
  • F-03: uninstall tears down every lifecycle host through runLifecycle undo, honoring ownership receipts.
  • F-04: setup's permission manifest unions auto-approve trust changes across all enabled hosts. Stated tradeoff: byte-identical at the claude-only default; on opencode-enabled machines, opencode's four MCP tool-name rules join the disclosed/authorized set (disclosed pre-write by the trust manifest).
  • F-17: guidance targets derive from the registry (byte-identical pins for every enablement combination), with id-shape hardening on the generic fallback.
  • F-14: unknown top-level kit.json keys warn once by name on stderr — preserved, never dropped.

Review-caught and fixed before merge: an uninstall save-gate that stranded stale ownership markers on the quiet-success path (regression test added), and a latent path-traversal escape in the guidance fallback (proven by the reviewer, closed at the use site; schema-level validation lands with wave 4's admission gate).

Full gate green: 1,571 tests, 0 failures.

🤖 Generated with Claude Code

pacphi added 7 commits August 14, 2026 20:30
…r row

Phase 1 provider axis (ADR-0028, F-28): providerEntries is six explicit
records — capabilities live on each entry instead of being derived from
identity comparisons, matching hostEntries; the five pre-existing providers
are pinned deep-equal to the old construction. local-openai names any
OpenAI-compatible server the user runs: billing local, no credentials, the
openai-compatible transport only, projections ruflo/codex/opencode (no aqe —
AQE's provider set is upstream's; no claude — that projection expects an
anthropic-compatible surface), no discovery claims, no builtin bindings.
Remote-endpoint policy pinned: local is a billing claim, not topology —
https off-box is legal, plain http stays loopback-only.
Phase 1 provider axis (F-29): when kit.json declares a binding whose provider
is local and not AQE-projected, status prints one info row naming provider,
host, and endpoint with the not-an-AQE-provider-type fact. Registry-driven
(billing + projections), so ollama never triggers it and a future provider of
the same shape gets the same treatment; no bindings means no new output.
…openai recipe

Proposed by adrianco in PR #131; accepted with the api_mode citation
annotated as invalid per Hermes v0.20.0 source and the ollama/local-openai
AQE-projection asymmetry stated as an intentional decision. PROVIDERS.md adds
a brief current-state section on declaring a local-openai binding.
…r unwired routable hosts

Phase 2 Wave 1 (F-01): the frozen adapter map's bidirectional import-time
invariant becomes built-ins-one-directional (a built-in adapter wired to a
non-routable or absent host still throws — the in-tree mistake), and
executionAdapterFor() is the lookup seam externally-admitted adapters will
join. A routable host with no adapter imports cleanly and degrades per worker
via the pre-existing cli_unavailable path, which escalation ladders already
step past. Built-in behavior byte-identical (same object references).
…e contract, permissions key by host

Phase 2 Wave 1 (F-02, F-03, F-04): a lifecycle registry (construction-
validated, one-way import) replaces the five OPENCODE_LIFECYCLE_ADAPTER named
imports; source-text guards pin that no command names the adapter again.
Uninstall tears down every lifecycle host through runLifecycle undo honoring
ownership receipts — and persists nulled markers unconditionally like
x/host.mjs always has (review-caught: gating the save on file changes
stranded a stale mcp:ak receipt forever on the quiet-success path; regression
test added). Setup's permission manifest unions auto-approve trust changes
across ALL enabled hosts instead of claude's alone — byte-identical at the
claude-only default; on opencode-enabled machines its four MCP tool-name
rules join the disclosed/authorized set (stated tradeoff, disclosed pre-write
by the trust manifest).
Phase 2 Wave 1 (F-17): guidanceTargets() loops nativeGuidance hosts and their
legacy.guidanceFile instead of a closed four-name literal; output pinned
byte-identical across every enablement combination. retiredForTarget stops
force-stripping targets outside the derived universe. The generic fallback
accepts id-shaped names only — a traversal-shaped guidanceFile contributes no
target at all (review-caught latent escape; schema-level validation is the
wave-4 admission gate's job).
…hem silently

Phase 2 Wave 1 (F-14): loadKitConfig warns once per distinct unknown key-set
on stderr — 'preserved, ignored' — so a future hostAdapters key on an older
ak is a named no-op, not a silent one. Keys still round-trip untouched; clean
configs warn nothing; legacy pre-migration shapes live nested inside
recognized envelopes and never trip it.
@pacphi
pacphi merged commit 6f6a7da into develop Aug 15, 2026
14 checks passed
@pacphi
pacphi deleted the feat/phase-2-wave-1-registry-dispatch branch August 15, 2026 22:15
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