Retire the old build spec, and point every reference at the architecture (M0.1)
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m22s
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m22s
Development Plan M0.1. Every section reference in code, tests, specs/, the example config, the tuning guide, and the CLAUDE.md and README files now cites docs/Architecture.md (P, L, D, O, X, Q) instead of the old spec's A-H, and docs/Architecture-Build-Spec.md is deleted (git keeps it). The plan's old-to-new table goes with it. Mostly mechanical, with a per-site choice where one old section split: A4 became L2 where it meant stop/abandon/the loop and L3 where it meant approvals; A10 became L6 in the context-budget code and L7 elsewhere; B2 became D4 for outbound Gitea and publishing and D5 for review intake; 'A3 step N' became the matching step of L8's boot sequence. Comments describing behaviour the architecture drops (planning always escalating, thresholds tuned at an old build step) now describe the current code and point at the Development Plan. docs/Architecture.md gains one line the rewrite missed: intake outages delay but never fail work (old B2), now in L5, where the poller and Matrix code cite it. Comments and docs only; no behaviour change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
1 parent
890708594b
commit
1ad0b2147d
73 files changed
+259
-1786
No files matched your search
@@ -1,5 +1,5 @@
|
||||
"""Integration: state written before an abrupt process death must be intact
|
||||
and the in-flight intent visible on the next boot (spec A2/A3)."""
|
||||
and the in-flight intent visible on the next boot (architecture L8)."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"""A real consult over the normalized route (A14).
|
||||
"""A real consult over the normalized route (L9).
|
||||
|
||||
The point is the prompt-level contract: a live model must produce something
|
||||
that parses against our local schema, since no API-level enforcement exists.
|
||||
@@ -41,7 +41,7 @@ def test_live_consult_parses_against_the_local_schema(desk) -> None:
|
||||
|
||||
assert answer.confidence in {"high", "medium", "low"}
|
||||
assert len(answer.answer) > 20
|
||||
# The consult is captured for A16 without any extra bookkeeping.
|
||||
# The consult is captured for L9 without any extra bookkeeping.
|
||||
[record] = collect(store)
|
||||
assert record.role == "consultant"
|
||||
assert record.exit_status == "answered"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Integration: a restart mid-gate resumes the open gate with its revision
|
||||
history intact; unresolved intents gate the whole boot to AWAIT_INPUT
|
||||
(spec A2/A3/A4 together)."""
|
||||
(architecture L8 and L3 together)."""
|
||||
|
||||
import io
|
||||
from pathlib import Path
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Live Gitea round trip against the sandbox repo: push a branch, open a PR,
|
||||
comment, and prove the A3 reconciler reads external truth correctly.
|
||||
comment, and prove the L8 reconciler reads external truth correctly.
|
||||
|
||||
Cleans up after itself (closes the PR, deletes the branch) so repeated runs
|
||||
do not silt up the sandbox.
|
||||
@@ -74,7 +74,7 @@ def test_push_open_pr_and_reconcile(
|
||||
# Now the same reconciler must see the effect and refuse to repeat it.
|
||||
assert reconcile(intent_for(branch)) is True
|
||||
|
||||
# A4 is only real if the server enforces it. The agent's own token
|
||||
# D4 is only real if the server enforces it. The agent's own token
|
||||
# must not be able to merge the PR it just opened, and must not be
|
||||
# able to push to the protected default branch at all.
|
||||
merged = client._http.post(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"""Capability matrix across models (spec Part H, A15).
|
||||
"""Capability matrix across models (architecture L9, Q).
|
||||
|
||||
Part H says the thresholds that depend on local capability — A12's failure
|
||||
count, A14's consult budget, A15's manifest size — must be tuned "at
|
||||
build-order step 5 on the real hardware". This is the measurement that makes
|
||||
that possible, rather than reasoning about model strength from reputation.
|
||||
The thresholds that depend on local capability (L9: the failure count, the
|
||||
consult budget, the manifest size) are tuned on the real hardware. This is the
|
||||
measurement that makes that possible, rather than reasoning about model
|
||||
strength from reputation.
|
||||
|
||||
What it measures is the thing that actually breaks: whether a model can hold
|
||||
the tool-call contract our loops depend on. llama3.2 could not — it returned
|
||||
@@ -102,7 +102,7 @@ def test_model_answers_at_all(model: str, catalog: ModelCatalog, routes) -> None
|
||||
def test_model_holds_the_planner_contract(
|
||||
model: str, catalog: ModelCatalog, routes
|
||||
) -> None:
|
||||
"""A4's gating is structural at the tool layer: a model that answers in
|
||||
"""L3's approvals are structural at the tool layer: a model that answers in
|
||||
prose cannot be gated, because there is no plan to approve."""
|
||||
normalized, passthrough = routes
|
||||
client = select_client(model, normalized, passthrough, catalog)
|
||||
@@ -161,7 +161,7 @@ def test_model_round_trips_a_tool_result(
|
||||
def test_model_holds_the_prompt_level_json_contract(
|
||||
model: str, catalog: ModelCatalog, routes
|
||||
) -> None:
|
||||
"""A14 contracts structured output at the prompt level because vendors
|
||||
"""L9 contracts structured output at the prompt level because vendors
|
||||
differ on JSON enforcement. This measures whether that holds per model."""
|
||||
normalized, passthrough = routes
|
||||
client = select_client(model, normalized, passthrough, catalog)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Live Anthropic passthrough: the vendor-native route delegations will use.
|
||||
|
||||
Proves the renderer's body is accepted as-is, that a tool call round-trips
|
||||
through the canonical log, and — per A5 — that prompt caching survives the
|
||||
through the canonical log, and — per L9 — that prompt caching survives the
|
||||
passthrough rather than being flattened by the proxy.
|
||||
"""
|
||||
|
||||
@@ -75,7 +75,7 @@ def test_passthrough_round_trips_a_tool_call(
|
||||
def test_prompt_caching_survives_the_passthrough(
|
||||
live_config: AgentConfig, live_model: str
|
||||
) -> None:
|
||||
# A5 asks for this to be verified rather than assumed: a proxy that
|
||||
# L9 asks for this to be verified rather than assumed: a proxy that
|
||||
# flattened the request would silently drop cache control and turn a
|
||||
# cost optimisation into a per-call expense.
|
||||
base = live_config.llm_base_url.rstrip("/")
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"""Live planning turn: a real model must answer with a submit_plan or
|
||||
ask_human tool call, not prose.
|
||||
|
||||
Plans with the test config's planner role. Planning escalates to a frontier
|
||||
model unconditionally (A12), and small local models do not hold the tool-call
|
||||
Plans with the test config's planner role. The planner role is a frontier
|
||||
model today (Development Plan §2), and small local models do not hold the tool-call
|
||||
contract reliably, so that role must be one that does.
|
||||
"""
|
||||
|
||||
@@ -43,5 +43,5 @@ def test_live_planning_turn_returns_a_tool_action(
|
||||
assert isinstance(action, SubmitPlan | AskHuman)
|
||||
text = action.content if isinstance(action, SubmitPlan) else action.question
|
||||
assert text.strip(), "tool call carried empty content"
|
||||
# The turn must be durable regardless of what the model said (A2/A10).
|
||||
# The turn must be durable regardless of what the model said (L8/L7).
|
||||
assert len(store.read_events()) > 1
|
||||
Reference in new issue
Block a user