Merge develop→main: Wave 2 (enforcers/evidence/runtime GT-534·526·438) + coordination ledger#182
Conversation
The 3rd READ→CONTROL surface: block an offending edit IN-FLIGHT as an AI
agent writes, before the PR. Core (evaluateEdit/EditBoundaryRule) was done;
this lands the vendor-neutral per-agent ADAPTER in the CLI.
- edit-hook payload normalizer: a VendorHookAdapter registry (claude-code
PreToolUse Write/Edit/MultiEdit + a generic canonical shape for Cursor/
Copilot/custom), repo-relativizing absolute paths against cwd. Adding a
vendor is adding one adapter, not a switch branch.
- boundary-rules loader: reads the compiled contract (EditBoundaryRule[] /
{boundaryRules}/{rules}) with validation.
- edit-hook service: normalize → evaluateEdit → deterministic allow/block +
human verdict; block exit code 2 (Claude Code veto), allow 0.
- `evolith enforce edit --rules <contract> [--payload|stdin] [--vendor]`:
reads the hook payload from stdin (or --payload), emits ADR-0073 envelope
(--format json) or a stderr verdict, exits 2 on block.
- docs + Claude Code settings.json hook snippet + wrapper script + sample
boundary-rules.
Tests: 45 focused (normalizer, service, boundary-rules, command allow/block);
CLI suite 967/967. Verified with the real binary over stdin: domain→infra
edit → exit 2 with Violation on stderr; conforming edit → exit 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 12781ebd5f8936307293c364b512a332cf74f40f)
…PROFILE (GT-438)
Introduce a single AGENT_RUNTIME_PROFILE=production|dev switch that governs the
whole adapter set in the runtime factory, replacing the ad-hoc per-var opt-ins:
- dev (default): deterministic stubs + in-memory state stay the explicit
default; each real adapter remains opt-in per env var (endpoint-driven
local-kind wiring is preserved regardless of profile).
- production: real adapters are mandatory and the factory FAILS LOUD instead of
silently degrading to a stub —
* HttpCoreEvaluationAdapter requires AGENT_RUNTIME_CORE_ENDPOINT + _CORE_TOKEN
* durable FileMemoryAdapter requires AGENT_RUNTIME_STATE_DIR (also backs the
host-driven FileSchedulerAdapter)
* real OPA policy is enforced (an explicit stub request is refused)
- reasoning engine (Hermes/Swarms/Cowork/routing) wired by AGENT_RUNTIME_ENGINE
where available; unset keeps the deterministic stub in every profile
(GT-385-gated).
Documents the switch in .env.example and adds a focused factory selection-matrix
spec (26 cases): dev ⇒ stubs; production+endpoint ⇒ real adapters;
production+missing endpoint/token/state-dir ⇒ throws; engine selection + errors.
Verification: agent-runtime-api tsc -b clean; jest 59/59 (26 new).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit acf2824026d09aefea457708385617aadad86de0)
…· ADR-0113) Renumbered companion ADR 0112→0113 to avoid collision with the concurrently landed ADR-0112 (RAG embedding/vector-store). First concrete provider behind the GT-533 Quality Signal seam; deterministic Evidence + full provenance. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ress - GT-534 PENDING→DONE: Lighthouse evidence adapter (af97a14), first concrete provider behind the GT-533 seam; deterministic Evidence + provenance, 105/105. Companion ADR renumbered 0112→0113 (0112 taken by the concurrent RAG wave). Closure record added. - GT-526 IN-PROGRESS→DONE: edit-time enforcement cross-agent hook (8fd95eb) — CLI blocks violating edits (exit 2), VendorHookAdapter registry, 967/967. Completes the three READ→CONTROL surfaces. Closure record added. - GT-438 stays IN-PROGRESS: prod profile wires Core-eval/memory/OPA fail-loud (7fe2c71, 26 tests); remaining = real engine (GT-385-gated) + scheduler host loop. - Counter 504→506 done · 15→14 pending · 18→17 in-progress (541 total). Guard green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…r reservation) Formalizes the fix for the ADR-0112 double-allocation between the RAG-maturity session and the gap-closing-waves session. Establishes: (1) reserve-then-push for ADR numbers and GT-IDs via authoritative next-free registers (next ADR 0114, next GT-542), (2) ownership lanes so two sessions never edit the same board rows, (3) a fetch-recompute-push-immediately protocol for the shared Progress counter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📊 Bilingual Coverage ImpactPR Changes
Repository Coverage
To create skeletons: node .harness/scripts/generate-es-skeleton.mjs <file.md>Generated by GitHub Actions |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d944527916
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const content = asString(input.new_string); | ||
| return content === undefined ? null : { filePath, content }; |
There was a problem hiding this comment.
Evaluate full files for Edit/MultiEdit payloads
For Claude Code Edit payloads that replace only an import specifier or other substring, this sends just new_string to evaluateEdit, so extractImports sees no import statement and the gate allows a boundary-crossing change such as changing '../domain/db' to '../infrastructure/db' in src/domain/order.ts. The MultiEdit branch below has the same issue because it concatenates only the replacement fragments; the hook needs to evaluate the resulting file content, or it will miss common Edit/MultiEdit writes that the feature is meant to block.
Useful? React with 👍 / 👎.
| `[agent-runtime] AGENT_RUNTIME_ENGINE_ROUTER is not valid JSON: ${(err as Error).message}`, | ||
| ); | ||
| } | ||
| overrides = { ...overrides, engineRouterConfig: routerConfig }; |
There was a problem hiding this comment.
Include Cowork in routed engine configs
When AGENT_RUNTIME_ENGINE=routing and the router JSON names cowork as the default or a route target, this path delegates to createAgentRuntime, whose built-in RoutingAgentAdapter engine map only contains stub, hermes, and swarms; the service therefore fails at boot for defaultEngine:'cowork' or later when a route selects it. Since this factory now exposes both cowork and routing as supported engine selections, the routed path should either provide a Cowork adapter to the router map or reject cowork in router configs with a clear validation error.
Useful? React with 👍 / 👎.
Aligns
mainwithdevelopafter the RAG-slice merge (8707ab2) leftmainbehind. Carries the gap-closing Wave 2 work + the session-coordination ledger. Runs the required checks that the prior admin-bypass merge to main skipped.Carries (5 commits, main..develop)
af97a14cAGENT_RUNTIME_PROFILE(fail-loud Core-eval/memory/OPA).7fe2c7178fd95eb329d00afbreference/core/control-center/COORDINATION.md(lanes + allocator reservation).d9445279Verified on develop
core-domain 960/960 · agent-runtime 98/98 · infra-providers 105/105 · sdk/cli 967/967 · agent-runtime-api 59/59 · tracking guard green (541 gaps / 488 records).
🤖 Generated with Claude Code