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

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:
dongarandClaude Opus 5.5 committed 2026-10-01 00:17:48 +00:00
1 parent 890708594b
commit 1ad0b2147d
73 files changed
+259 -1786

No files matched your search

+12 -12
View File
@@ -121,7 +121,7 @@ def test_delegation_works_on_its_own_branch(
def test_abort_discards_the_branch_and_its_work(
store: StateStore, ws: Workspace, repo: GitRepo
) -> None:
# A13: abort must leave nothing to resume on top of.
# L9: abort must leave nothing to resume on top of.
client = ScriptedClient(
[
[call("write_file", path="half-done.py", content="oops")],
@@ -138,7 +138,7 @@ def test_abort_discards_the_branch_and_its_work(
def test_stop_discards_the_branch_and_settles_the_intent(
store: StateStore, ws: Workspace, repo: GitRepo
) -> None:
# A4 stop is treated like a failure, not like an outage: the operator
# L2's stop is treated like a failure, not like an outage: the operator
# stopped it for a reason, so nothing is kept for resuming.
cancel = Cancel()
client = ScriptedClient(
@@ -213,7 +213,7 @@ def test_cap_breach_is_not_usable_and_discards_work(
brief="b", branch="d"
)
assert not result.usable # the caller must gate, not resume (A13)
assert not result.usable # the caller must gate, not resume (L9)
assert not (repo.root / "partial.py").exists()
@@ -251,7 +251,7 @@ def test_composite_events_record_the_brief_caps_and_outcome(
assert started.brief == "the brief"
assert started.model == "claude-haiku-4-5"
assert started.caps == {"turns": 7, "tokens": 1234, "wall_clock_s": 42.0}
# A16: this pair is the eval record, so it must carry the outcome.
# L9: this pair is the eval record, so it must carry the outcome.
assert completed.exit_status == "handback"
assert "greet()" in completed.handback
@@ -259,7 +259,7 @@ def test_composite_events_record_the_brief_caps_and_outcome(
def test_hand_back_tool_is_offered_alongside_the_executor_tools() -> None:
names = [t["function"]["name"] for t in DELEGATE_TOOLS]
assert names[-1] == "hand_back"
assert "run_command" in names # full tool access, not a consult (A13)
assert "run_command" in names # full tool access, not a consult (L9)
def test_malformed_handback_is_rejected_and_the_delegation_continues(
@@ -348,7 +348,7 @@ def test_failure_may_be_reported_without_doing_work(
assert len(client.calls) == 1 # believed immediately, not challenged
# --- A3 step 5: the resume rule -----------------------------------------
# --- L8 boot step 5: the resume rule -----------------------------------------
def pending_delegation_intent(store: StateStore, branch: str = "d") -> Any:
@@ -446,7 +446,7 @@ def test_resume_continues_the_same_delegation(
store: StateStore, ws: Workspace, repo: GitRepo
) -> None:
# Interrupt after one turn, then resume: no second delegation_started,
# because A10 defines a session as the delegation, not the process.
# because L7 defines a session as the delegation, not the process.
repo.checkout_new_branch("d")
store.append_event(
DelegationStarted(brief="b", role="delegate", model="m", caps={})
@@ -497,7 +497,7 @@ def test_recover_resumes_a_clean_cut_with_a_notice(
result = build(client, store, ws, repo).recover(notices.append)
assert result is not None and result.usable
# A3: a notice, not a question — a clean cut needs no operator decision.
# L8: a notice, not a question — a clean cut needs no operator decision.
assert notices and "resuming the delegation" in notices[0]
@@ -550,7 +550,7 @@ def test_recover_leaves_an_unclean_cut_for_the_boot_gate(
assert [i.kind for i in store.pending_intents()] == [DELEGATION_INTENT]
# --- the token cap, which A13 calls hard and was decoration -------------
# --- the token cap, which L9 calls hard and was decoration -------------
class MeteredClient(ScriptedClient):
@@ -599,7 +599,7 @@ def test_tokens_spent_are_reported_not_left_at_zero(
completed = next(
e.event for e in store.read_events() if isinstance(e.event, DelegationCompleted)
)
# A16 evaluates cost against outcome, which needs a real number.
# L9 evaluates cost against outcome, which needs a real number.
assert completed.tokens == 2000
@@ -639,7 +639,7 @@ def test_budget_exhaustion_preserves_the_work_for_later(
# The work survives, on its branch.
assert repo.current_branch() == "d"
assert (repo.root / "progress.py").exists()
# And the intent stays pending, which is what A3's resume rule keys on.
# And the intent stays pending, which is what L8's resume rule keys on.
assert [i.kind for i in store.pending_intents()] == [DELEGATION_INTENT]
@@ -647,7 +647,7 @@ def test_an_ordinary_failure_still_discards(
store: StateStore, ws: Workspace, repo: GitRepo
) -> None:
# Only external interruptions are preserved; a delegate that made a mess
# is still cleaned up (A13).
# is still cleaned up (L9).
client = ScriptedClient([[hand_back(succeeded=False, changed="cannot")]])
result = build(client, store, ws, repo).run(brief="b", branch="d")