Architecture Quality Loop - Analyze, Assess, Improve (Deliberate)
You drive a deliberate loop that improves a project's architecture: analyze it, produce a reasoned assessment, work the fixable weaknesses by tier, reconcile the docs, and loop until the fixable ones are resolved or the loop plateaus. This is the heavy, on-purpose counterpart to the code-focused project-quality-loop - it runs only when a user invokes it (/project-architecture-quality-loop), never automatically, because architecture analysis is expensive and architecture changes are consequential.
Best run in Claude Code, where you can dispatch the analysis and build seats and edit files across rounds. On a large codebase, scope it - point it at one bounded context or module subtree per run. The frontmatter names opus (the architecture judgment runs in-session, per the capture) - but a skill-level model pin is not reliably honored for main-session turns (measured: three invocations ran the session model despite it, while agent-level pins held exactly), so set the session to Opus with /model for the run and switch back at the final report. The run-start mode ask carries the check: when the session is not on Opus, the ask says so - the switch happens before any judgment is spent, never discovered after.
Execution modes
DELEGATED vs INLINE keys on dispatch capability, not file presence - a project can carry the agent files on disk with no Agent tool to dispatch them, which is still INLINE. Detection only names what is possible; the user picks: when dispatch is available, ask ONE question before ANALYZE, via AskUserQuestion - run the loop in the current session, or dispatch the stack seats? - then hold the answer for the run. No dispatch capability is INLINE without asking - never offer seats that cannot run:
- DELEGATED (the user chose agents) - the main session dispatches every seat - architecture-analyzer for the capture's gathering, then the domain designer / implementers / verifier for a substantial fix, or an implementer for a small one - never doing their work itself (the architecture reasoning itself runs in the main session, per the capture). This skill is manual (
disable-model-invocation) and stays the orchestrator: a substantial fix runs the stack vertical by dispatching that stack's seats directly - the loop discipline is this skill's own references/domain-trio-protocol.md, never a re-entry into the full router (the loop already owns the scoping the router would re-derive).
- INLINE (the user chose the current session - or forced, no question asked: Cursor, a non-stack project, or a scope too small to fan out) - do the same steps in-session: map and assess the architecture yourself against the house architecture skills, then apply the fixable cons directly, smallest blast radius first.
The loop
1. ANALYZE + ASSESS
Run the project-architecture-analyzer capture over the target - its protocol owns the gather-and-reason mechanics. The capture is a Skill call, so past the fresh-session trigger (the resolved window's own absolute figure - 150,000 tokens on a 200k window, 400,000 above it) guard-fresh-session-start.js blocks it - that block is the gate working, not a fault: put the choice through AskUserQuestion (run the capture in a fresh session, recommended, ending this turn with the resume block; or continue here, in which case follow the capture's protocol in-session by reading its SKILL.md rather than re-invoking the Skill). Never retry the blocked call. Exception - the assessment is already fresh in THIS context: when it was produced or reconciled this session and its Captured: stamp matches HEAD, take its weaknesses as the work list directly and skip the capture; any older stamp runs the capture (its UPDATE path is diff-scoped and cheap). What this loop consumes is its output: <docs-path>/architecture/ARCHITECTURE.md (the structure map) and <docs-path>/architecture/ASSESSMENT.md (every gate-passing strength and weakness - counts are outputs, never targets - each Must-fix weakness carrying a remediation and a tier: small / substantial / structural). Read <docs-path>/architecture/ASSESSMENT.md: the Must-fix weaknesses are this loop's work list, the tier on each is its routing key, and the Worth-knowing and Deliberate-tradeoff buckets are left alone - do not 'fix' a conscious choice.
When the work list is drained (or a later round wants findings the last capture missed), run a lens sweep instead of re-capturing: pick 3-5 distinct cross-cutting defect classes the codebase is actually exposed to (e.g. concurrency, money/precision handling, fail-open error paths, boot/config wiring, external-API trust), and sweep the code one lens at a time - in DELEGATED mode one architecture-analyzer seat per lens, each briefed with ONLY its lens plus the areas to read - and for map orientation, the brief pastes the RELEVANT map sections (or names them for a ranged read), never a bare path to the whole doc (measured: 7 seats each whole-read an identical 8.4k-token map, md5-proven, because the brief passed only the path). Findings triage into the same tier routing as assessment weaknesses. Lenses are disjoint by construction - a seat that gets two lenses dilutes both (proven practice across eleven consecutive rounds of one project's loop: sweeps surfaced real off-list production bugs, including a fee under-charging money bug and a silent config zero-default, that captures and the work list never held).
2. TRIAGE + FIX by tier
Take the open weaknesses in leverage order (the assessment's top-few first). Route each by its tier - and confirm the green baseline (build + tests) before you start, so a regression is visible. Hold every fix against the assessment's Strengths list: a remediation whose entry names a strength tension is applied the way the entry preserves the strength, and a fix that turns out mid-round to erode a listed strength stops - resolving a weakness by breaking a strength is a net loss, and a genuine strength-vs-weakness tradeoff is a structural-tier user decision, never an auto-fix:
- small (a localized edit) - dispatch the matching domain implementer with the remediation as a scoped brief (the file/symbol, the smallest correct change, the check that proves it). The brief states
memory: none - a scoped fix has no serena hand-off; a brief that does hand a note names it literally, read side included (memory hygiene: references/domain-trio-protocol.md - measured: un-briefed seats wrote unrequested notes and ran full-store list_memories fan-outs). Re-run build + tests.
- substantial (a designer-led multi-task change) - dispatch the domain solution-designer to turn the remediation into a decomposition, gate the returned plan with
project-verify-plan (an actual Skill invocation recording plan_review: approved|waived - stated here because the reference carrying it went unread in two runs, one of which paid 41k tokens of rework for a defect the gate exists to catch), then get the user's approval on that plan before building (an architecture refactor is consequential - never fan out against an unapproved structural plan): present the plan, ask via AskUserQuestion - approve-and-build vs changes-needed, free text via Other (plain-text options where the harness lacks the tool) - and record the approving answer: write <docs-path>/flow/APPROVAL, first line APPROVED <plan id> - "<the user's words, verbatim>" - the selected answer IS those words (the dispatch hook blocks an unstamped implementer; delete the file when the run completes). Write the stamp at the ABSOLUTE path $CLAUDE_PROJECT_DIR/<docs-path>/flow/APPROVAL with the Write tool - .claude/ is a protected path, so the first write in a session prompts; take the prompt's 'allow Claude to edit its own settings for this session' option and the rest of the run is free (no settings key can pre-approve it: permissions.allow is not consulted for protected paths); a relative write follows whatever cwd the shell drifted to and the dispatch then bounces. The stamp belongs to the session that dispatches - written when its own decision lands, deleted at its own close; an earlier session's leftover stamp is not consent. If BOTH the Write tool and an absolute-path Bash write are refused by the harness's classifier, stop and put the choice through AskUserQuestion (retry the stamp, or run this stage inline) rather than retrying blind or dispatching around the gate. When the designer's findings SHRINK the item ('this is actually small'), the re-tier still routes through an AskUserQuestion before any implementer dispatch - a self-declared downgrade that proceeds on the old small-tier stamp is the silent-downgrade this tiering forbids (measured: 'so I'm proceeding' built a substantial fix on a 29-minute-old stamp for an unrelated consent). Then fan the tasks out to the domain implementers and gate the assembled result with the domain verifier, looping its punch-list back. This is the domain-trio vertical (this skill's own references/domain-trio-protocol.md), dispatched directly.
- structural (a risky, cross-cutting rework) - do NOT auto-apply. Present the weakness, its reasoning, and the remediation, then ask the decision via AskUserQuestion - apply (routes as substantial) vs decline vs defer (plain-text options where the harness lacks the tool). A structural rework the user has not approved is flagged in the final report, not attempted.
Keep the build and tests green across the round: after each fix batch, re-run them, and a red routes to the matching resolver (dotnet-build-error-resolver / dotnet-test-failure-resolver / ng-build-error-resolver / angular-test-resolver) before the next weakness.
3. UPDATE DOCS
Prune <docs-path>/architecture/ASSESSMENT.md yourself: delete each weakness this round resolved (its fix landed and build + tests are green), and add any weakness a fix exposed - reasoned, with a remediation and tier, shaped like the capture writes them. Land the whole round's prune as ONE batched edit at round close - collect the deletions and additions first, then touch the doc once, and before advancing to step 4 COUNT this round's edits to the doc from your own tool calls (Bash-routed writes included): above one means you streamed it - stop and say so in the report, never rationalize the count (measured: the one-batched-edit rule broke in six audited rounds at 5-11 edits each, twice right after the model narrated 'writing it as one batched edit', and self-reported counts were wrong in three of them - only the mechanical count holds). Cap the doc's history while pruning: keep the current round's headline verbatim and fold older per-round headlines into a one-line changelog - the doc otherwise only ever grows (+8.2KB in one no-prune round, measured), and its mandatory first read costs more every round. Everything else stays: strengths, accepted tradeoffs, declined structural items, and the Captured stamp (it marks the last capture and the stop-time reconcile diffs from it - never advance it by hand). No capture re-run per round: the loop already knows which weaknesses it closed, and a full re-analysis to learn that is waste - a brand-new weakness only fresh analysis would surface waits for the next deliberate capture.
4. LOOP or STOP
Decide off the weakness set you just pruned - it is already in this context: re-read <docs-path>/architecture/ASSESSMENT.md only after a compaction or when the in-context copy is genuinely stale, never as a per-round habit (the doc grows across rounds, so each needless re-read costs more than the last - measured at 21 reads / 33.5k tokens in one session). On a LOOP verdict, run the fresh-session ask (Bounded and honest) before starting the next round - the resume invocation names the rounds already consumed so the 3-round cap survives a resume. The round verdict line carries the ask's receipt - next: fresh-session | continue - "<the user's answer, verbatim>" - and that receipt can only come from the AskUserQuestion answer; a verdict line without it is an unfinished step 4 (measured: a continue-ask fired without the fresh-session option and round 2 ran inside the same 411k-ctx/msg chat). Decide off the set, not by eye:
- SATISFIED - no fixable (small/substantial) weakness remains; only accepted tradeoffs and user-declined structural items are left.
- PLATEAU - the fixable-weakness set equals the previous round's and none is now resolvable - stop rather than re-run identically.
- CAPPED - you reached the improve-round cap (see Bounded and honest).
- BLOCKED - only structural weaknesses remain and the user has not approved a rework - report and stop.
On STOP, when any fix shipped, reconcile the docs ONCE: run the project-architecture-analyzer capture (its UPDATE path - the diff since the Captured stamp) - and when this session is already past that same trigger, the same fresh-session choice above applies before the capture runs so <docs-path>/architecture/ARCHITECTURE.md picks up the shipped boundaries and the pruned assessment is validated against the code as it now stands. This reconcile is the step, not a suggestion: substituting anything lighter (a 'targeted reconcile', a hand edit) goes through an AskUserQuestion first - a substitution offered back in prose is a skipped mandatory step wearing a courtesy (measured twice: one run silently downgraded to a hand reconcile, another improvised a single mis-permissioned dispatch the read-only agent rightly refused). A run that shipped nothing skips the reconcile - there is no drift to pick up. Then emit the final report - one line per field, a table where a field lists several items (the close is an answer like any other and the answer-length hook blocks a wall of prose; tables are exempt):
- Outcome - SATISFIED / PLATEAU / CAPPED / BLOCKED, and on which round. CAPPED means the
CUMULATIVE improve-round cap was reached - rounds count across sessions via the resume
invocation's round numbering; a session ending because the user chose the fresh-session
option with fixable weaknesses left is a LOOP handoff, not CAPPED (two audited rounds
labeled the same state differently - this line is the tiebreak).
- Resolved - each weakness fixed, its tier, and the change that closed it.
- Deferred - structural items the user declined or has not decided, plus accepted tradeoffs left alone.
- Docs - the pruned
<docs-path>/architecture/ASSESSMENT.md + the stop-time reconcile of <docs-path>/architecture/ARCHITECTURE.md (skipped when nothing shipped), each with its touch count - ASSESSMENT: 1 batched edit - because a count above one per doc per round is the serial-edit stream the UPDATE-DOCS step forbids (measured: 8 serial edits in one session, 15 in another, against the written rule).
- Baseline - build + tests green at stop (or the red that blocked it), plus the push state
when commits exist - unpushed rounds accumulate silently otherwise (measured: three committed
rounds sat unpushed until the user asked twice what was left).
- Memories -
memories purged: <names|none>, fold-first (the trio reference's receipt,
restated here because loop rounds measured 0 purges with the rule sitting unloaded).
- Next actions - when Deferred items are blocked on the operator (a live walk, a log grab,
a replay), a ranked what-to-do list ships IN this report, not on request (measured: a CAPPED
stop without one cost three clarifying prompts and an ad hoc doc no contract names).
When the report closes with uncommitted work and no next round queued, the commit decision goes through AskUserQuestion (commit now / hold) - never a prose 'your call' bullet (measured: three such bullets in one session drifted unresolved for 5h while the uncommitted set grew 16 -> 23 files). The same close names what this round's runs started and still have up - a Docker container or compose stack, seeded integration-test data, a background process - and puts tear-down-vs-keep through the same AskUserQuestion call (teardown recommended; started-nothing is said plainly, and what the round did not start is never touched).
Example
DELEGATED, one run over the Orders module:
- ANALYZE + ASSESS - run the project-architecture-analyzer capture; ARCHITECTURE.md + ASSESSMENT.md land with tiered weaknesses. The top two: a small con (a repository leaks an EF type across the boundary) and a substantial con (queries and handlers share one grab-bag namespace).
- FIX by tier - confirm the green baseline. Small: dispatch aspnet-implementer with a scoped brief, re-run build + tests. Substantial: dispatch aspnet-solution-designer for a decomposition, get approval, fan out implementers, gate with aspnet-verifier. A structural con (invert the persistence dependency) is flagged for a user decision, not auto-applied.
- UPDATE DOCS - delete the two fixed weaknesses from ASSESSMENT.md; the namespace split exposed nothing new.
- LOOP or STOP - re-read ASSESSMENT.md: only the user-declined structural item and accepted tradeoffs remain -> SATISFIED. One capture UPDATE reconciles ARCHITECTURE.md with the namespace split; emit the final report.
Bounded and honest
- Hard cap: 3 improve rounds. Architecture changes are expensive and consequential; do not loop indefinitely chasing the last debatable con.
- Each round boundary is a fresh-session resume point - the pruned
<docs-path>/architecture/ASSESSMENT.md is the handoff; measured, carried-forward conversation (not tool output) dominates session cost. A step, not advice (the advice form was ignored in 4 of 4 audited long sessions): at each LOOP decision, ask via AskUserQuestion - resume in a fresh session from the pruned assessment (recommended) vs continue here, and the fresh-session option is ALWAYS one of the ask's options (a continue-ask without it is the measured failure step 4's receipt exists to catch); on 'fresh', end the turn with a RESUME BLOCK the new session can start from alone: the exact invocation (naming the rounds already consumed so the 3-round cap survives), the remaining weaknesses in leverage order with their tiers, and the docs to read first (the pruned <docs-path>/architecture/ASSESSMENT.md, the green-baseline state).
- Never weaken a test or delete an assertion to make a con look resolved - that is a new weakness, not a fix.
- Make the smallest change that resolves each weakness; a rewrite that introduces new coupling makes the loop diverge.
- The assessment's tier is the routing authority - do not silently upgrade a small con into a rewrite, or downgrade a structural one to sneak it past the approval gate.
Rules
- The main session is the only orchestrator. The build seats it dispatches - the domain designer / implementers / verifier / resolvers - carry no Agent tool, so the fan-out stays flat; a con needing analysis and a fix is separate dispatches from here, not one nested one. The capture's architecture-analyzer fan-out is also dispatched from here, flat - there is no dispatched architecture seat and no nesting.
- Substantial and structural changes are gated on user approval before building; small localized fixes proceed. Architecture changes are consequential - confirm before reshaping the structure. In DELEGATED mode, the mode ask's answer IS the dispatch consent for small-tier fixes: write the
<docs-path>/flow/APPROVAL stamp (APPROVED small-tier - "<the answer, verbatim>") the moment that answer lands, and rewrite it as substantial-tier approvals arrive - the dispatch guard is deliberately tier-blind, so an unstamped small-tier dispatch just bounces (measured: one sat blocked 34 minutes behind an unrelated substantial approval). On a RESUMED session no mode ask fires - the small-tier stamp then quotes the RESUME BLOCK's own dispatch line (APPROVED small-tier - resumed round <N>, "<the block's mode line, verbatim>"), never repurposed task framing (measured: a resume improvised its stamp source from general instructions). The mode answer covers the WHOLE round - a DELEGATED round's fixes go to the seats, its lens sweeps to analyzer seats; working a fix inline under a DELEGATED answer, or scoping the ask to just the analyze step, leaves the round's real work with no mode decision at all (measured twice: every small-tier fix of one DELEGATED round was applied inline; another round's ask covered only 'the lens sweep' and the fix ran unmoded).
- Keep this skill orchestration only. The architecture judgement lives in the project-architecture-analyzer capture and the house architecture skills it loads; the build knowledge lives in the domain seats. For a pure code-quality polish reach for
project-quality-loop; for a single feature build reach for project-solve-cross-task.
1---2name: project-architecture-quality-loop3description: The deliberate architecture analyze-assess-improve loop. Runs the project-architecture-analyzer capture, works the ASSESSMENT's weaknesses by tier - small to a domain implementer, substantial through a designer -> implementers -> verifier (plan approved first), structural flagged for a user decision and never auto-applied - prunes the fixed weaknesses from the ASSESSMENT itself (one capture reconcile at stop, not per round), and loops until the fixable cons resolve or plateau. Manual, /-only. Triggers on 'run the architecture quality loop' or 'analyze and improve the architecture'. NOT for a code-quality polish (project-quality-loop), a single feature build (project-solve-cross-task), or a capture-only run with no fixes (/project-architecture-analyzer alone).4---56# Architecture Quality Loop - Analyze, Assess, Improve (Deliberate)78You drive a deliberate loop that improves a project's architecture: analyze it, produce a reasoned assessment, work the fixable weaknesses by tier, reconcile the docs, and loop until the fixable ones are resolved or the loop plateaus. This is the heavy, on-purpose counterpart to the code-focused `project-quality-loop` - it runs only when a user invokes it (`/project-architecture-quality-loop`), never automatically, because architecture analysis is expensive and architecture changes are consequential.910Best run in Claude Code, where you can dispatch the analysis and build seats and edit files across rounds. On a large codebase, scope it - point it at one bounded context or module subtree per run. The frontmatter names `opus` (the architecture judgment runs in-session, per the capture) - but a skill-level model pin is not reliably honored for main-session turns (measured: three invocations ran the session model despite it, while agent-level pins held exactly), so set the session to Opus with `/model` for the run and switch back at the final report. The run-start mode ask carries the check: when the session is not on Opus, the ask says so - the switch happens before any judgment is spent, never discovered after.1112## Execution modes13DELEGATED vs INLINE keys on dispatch capability, not file presence - a project can carry the agent files on disk with no Agent tool to dispatch them, which is still INLINE. Detection only names what is possible; the user picks: when dispatch is available, ask ONE question before ANALYZE, via AskUserQuestion - run the loop in the current session, or dispatch the stack seats? - then hold the answer for the run. No dispatch capability is INLINE without asking - never offer seats that cannot run:1415- **DELEGATED** (the user chose agents) - the main session dispatches every seat - architecture-analyzer for the capture's gathering, then the domain designer / implementers / verifier for a substantial fix, or an implementer for a small one - never doing their work itself (the architecture reasoning itself runs in the main session, per the capture). This skill is manual (`disable-model-invocation`) and stays the orchestrator: a substantial fix runs the stack vertical by dispatching that stack's seats directly - the loop discipline is this skill's own `references/domain-trio-protocol.md`, never a re-entry into the full router (the loop already owns the scoping the router would re-derive).16- **INLINE** (the user chose the current session - or forced, no question asked: Cursor, a non-stack project, or a scope too small to fan out) - do the same steps in-session: map and assess the architecture yourself against the house architecture skills, then apply the fixable cons directly, smallest blast radius first.1718## The loop1920### 1. ANALYZE + ASSESS21Run the `project-architecture-analyzer` capture over the target - its protocol owns the gather-and-reason mechanics. The capture is a Skill call, so past the fresh-session trigger (the resolved window's own absolute figure - 150,000 tokens on a 200k window, 400,000 above it) `guard-fresh-session-start.js` blocks it - that block is the gate working, not a fault: put the choice through AskUserQuestion (run the capture in a fresh session, recommended, ending this turn with the resume block; or continue here, in which case follow the capture's protocol in-session by reading its `SKILL.md` rather than re-invoking the Skill). Never retry the blocked call. Exception - the assessment is already fresh in THIS context: when it was produced or reconciled this session and its `Captured:` stamp matches HEAD, take its weaknesses as the work list directly and skip the capture; any older stamp runs the capture (its UPDATE path is diff-scoped and cheap). What this loop consumes is its output: `<docs-path>/architecture/ARCHITECTURE.md` (the structure map) and `<docs-path>/architecture/ASSESSMENT.md` (every gate-passing strength and weakness - counts are outputs, never targets - each Must-fix weakness carrying a remediation and a tier: small / substantial / structural). Read `<docs-path>/architecture/ASSESSMENT.md`: the Must-fix weaknesses are this loop's work list, the tier on each is its routing key, and the Worth-knowing and Deliberate-tradeoff buckets are left alone - do not 'fix' a conscious choice.2223When the work list is drained (or a later round wants findings the last capture missed), run a **lens sweep** instead of re-capturing: pick 3-5 distinct cross-cutting defect classes the codebase is actually exposed to (e.g. concurrency, money/precision handling, fail-open error paths, boot/config wiring, external-API trust), and sweep the code one lens at a time - in DELEGATED mode one architecture-analyzer seat per lens, each briefed with ONLY its lens plus the areas to read - and for map orientation, the brief pastes the RELEVANT map sections (or names them for a ranged read), never a bare path to the whole doc (measured: 7 seats each whole-read an identical 8.4k-token map, md5-proven, because the brief passed only the path). Findings triage into the same tier routing as assessment weaknesses. Lenses are disjoint by construction - a seat that gets two lenses dilutes both (proven practice across eleven consecutive rounds of one project's loop: sweeps surfaced real off-list production bugs, including a fee under-charging money bug and a silent config zero-default, that captures and the work list never held).2425### 2. TRIAGE + FIX by tier26Take the open weaknesses in leverage order (the assessment's top-few first). Route each by its tier - and confirm the green baseline (build + tests) before you start, so a regression is visible. Hold every fix against the assessment's Strengths list: a remediation whose entry names a strength tension is applied the way the entry preserves the strength, and a fix that turns out mid-round to erode a listed strength stops - resolving a weakness by breaking a strength is a net loss, and a genuine strength-vs-weakness tradeoff is a structural-tier user decision, never an auto-fix:2728- **small** (a localized edit) - dispatch the matching domain implementer with the remediation as a scoped brief (the file/symbol, the smallest correct change, the check that proves it). The brief states `memory: none` - a scoped fix has no serena hand-off; a brief that does hand a note names it literally, read side included (memory hygiene: `references/domain-trio-protocol.md` - measured: un-briefed seats wrote unrequested notes and ran full-store list_memories fan-outs). Re-run build + tests.29- **substantial** (a designer-led multi-task change) - dispatch the domain solution-designer to turn the remediation into a decomposition, gate the returned plan with `project-verify-plan` (an actual Skill invocation recording `plan_review: approved|waived` - stated here because the reference carrying it went unread in two runs, one of which paid 41k tokens of rework for a defect the gate exists to catch), then **get the user's approval on that plan before building** (an architecture refactor is consequential - never fan out against an unapproved structural plan): present the plan, ask via AskUserQuestion - approve-and-build vs changes-needed, free text via Other (plain-text options where the harness lacks the tool) - and record the approving answer: write `<docs-path>/flow/APPROVAL`, first line `APPROVED <plan id> - "<the user's words, verbatim>"` - the selected answer IS those words (the dispatch hook blocks an unstamped implementer; delete the file when the run completes). Write the stamp at the ABSOLUTE path `$CLAUDE_PROJECT_DIR/<docs-path>/flow/APPROVAL` with the Write tool - `.claude/` is a protected path, so the first write in a session prompts; take the prompt's 'allow Claude to edit its own settings for this session' option and the rest of the run is free (no settings key can pre-approve it: `permissions.allow` is not consulted for protected paths); a relative write follows whatever cwd the shell drifted to and the dispatch then bounces. The stamp belongs to the session that dispatches - written when its own decision lands, deleted at its own close; an earlier session's leftover stamp is not consent. If BOTH the Write tool and an absolute-path Bash write are refused by the harness's classifier, stop and put the choice through AskUserQuestion (retry the stamp, or run this stage inline) rather than retrying blind or dispatching around the gate. When the designer's findings SHRINK the item ('this is actually small'), the re-tier still routes through an AskUserQuestion before any implementer dispatch - a self-declared downgrade that proceeds on the old small-tier stamp is the silent-downgrade this tiering forbids (measured: 'so I'm proceeding' built a substantial fix on a 29-minute-old stamp for an unrelated consent). Then fan the tasks out to the domain implementers and gate the assembled result with the domain verifier, looping its punch-list back. This is the domain-trio vertical (this skill's own `references/domain-trio-protocol.md`), dispatched directly.30- **structural** (a risky, cross-cutting rework) - do NOT auto-apply. Present the weakness, its reasoning, and the remediation, then ask the decision via AskUserQuestion - apply (routes as substantial) vs decline vs defer (plain-text options where the harness lacks the tool). A structural rework the user has not approved is flagged in the final report, not attempted.3132Keep the build and tests green across the round: after each fix batch, re-run them, and a red routes to the matching resolver (dotnet-build-error-resolver / dotnet-test-failure-resolver / ng-build-error-resolver / angular-test-resolver) before the next weakness.3334### 3. UPDATE DOCS35Prune `<docs-path>/architecture/ASSESSMENT.md` yourself: delete each weakness this round resolved (its fix landed and build + tests are green), and add any weakness a fix exposed - reasoned, with a remediation and tier, shaped like the capture writes them. Land the whole round's prune as ONE batched edit at round close - collect the deletions and additions first, then touch the doc once, and before advancing to step 4 COUNT this round's edits to the doc from your own tool calls (Bash-routed writes included): above one means you streamed it - stop and say so in the report, never rationalize the count (measured: the one-batched-edit rule broke in six audited rounds at 5-11 edits each, twice right after the model narrated 'writing it as one batched edit', and self-reported counts were wrong in three of them - only the mechanical count holds). Cap the doc's history while pruning: keep the current round's headline verbatim and fold older per-round headlines into a one-line changelog - the doc otherwise only ever grows (+8.2KB in one no-prune round, measured), and its mandatory first read costs more every round. Everything else stays: strengths, accepted tradeoffs, declined structural items, and the Captured stamp (it marks the last capture and the stop-time reconcile diffs from it - never advance it by hand). No capture re-run per round: the loop already knows which weaknesses it closed, and a full re-analysis to learn that is waste - a brand-new weakness only fresh analysis would surface waits for the next deliberate capture.3637### 4. LOOP or STOP38Decide off the weakness set you just pruned - it is already in this context: re-read `<docs-path>/architecture/ASSESSMENT.md` only after a compaction or when the in-context copy is genuinely stale, never as a per-round habit (the doc grows across rounds, so each needless re-read costs more than the last - measured at 21 reads / 33.5k tokens in one session). On a LOOP verdict, run the fresh-session ask (Bounded and honest) before starting the next round - the resume invocation names the rounds already consumed so the 3-round cap survives a resume. The round verdict line carries the ask's receipt - `next: fresh-session | continue - "<the user's answer, verbatim>"` - and that receipt can only come from the AskUserQuestion answer; a verdict line without it is an unfinished step 4 (measured: a continue-ask fired without the fresh-session option and round 2 ran inside the same 411k-ctx/msg chat). Decide off the set, not by eye:3940- **SATISFIED** - no fixable (small/substantial) weakness remains; only accepted tradeoffs and user-declined structural items are left.41- **PLATEAU** - the fixable-weakness set equals the previous round's and none is now resolvable - stop rather than re-run identically.42- **CAPPED** - you reached the improve-round cap (see Bounded and honest).43- **BLOCKED** - only structural weaknesses remain and the user has not approved a rework - report and stop.4445On STOP, when any fix shipped, reconcile the docs ONCE: run the `project-architecture-analyzer` capture (its UPDATE path - the diff since the Captured stamp) - and when this session is already past that same trigger, the same fresh-session choice above applies before the capture runs so `<docs-path>/architecture/ARCHITECTURE.md` picks up the shipped boundaries and the pruned assessment is validated against the code as it now stands. This reconcile is the step, not a suggestion: substituting anything lighter (a 'targeted reconcile', a hand edit) goes through an AskUserQuestion first - a substitution offered back in prose is a skipped mandatory step wearing a courtesy (measured twice: one run silently downgraded to a hand reconcile, another improvised a single mis-permissioned dispatch the read-only agent rightly refused). A run that shipped nothing skips the reconcile - there is no drift to pick up. Then emit the final report - one line per field, a table where a field lists several items (the close is an answer like any other and the answer-length hook blocks a wall of prose; tables are exempt):46- **Outcome** - SATISFIED / PLATEAU / CAPPED / BLOCKED, and on which round. CAPPED means the47 CUMULATIVE improve-round cap was reached - rounds count across sessions via the resume48 invocation's round numbering; a session ending because the user chose the fresh-session49 option with fixable weaknesses left is a LOOP handoff, not CAPPED (two audited rounds50 labeled the same state differently - this line is the tiebreak).51- **Resolved** - each weakness fixed, its tier, and the change that closed it.52- **Deferred** - structural items the user declined or has not decided, plus accepted tradeoffs left alone.53- **Docs** - the pruned `<docs-path>/architecture/ASSESSMENT.md` + the stop-time reconcile of `<docs-path>/architecture/ARCHITECTURE.md` (skipped when nothing shipped), each with its touch count - `ASSESSMENT: 1 batched edit` - because a count above one per doc per round is the serial-edit stream the UPDATE-DOCS step forbids (measured: 8 serial edits in one session, 15 in another, against the written rule).54- **Baseline** - build + tests green at stop (or the red that blocked it), plus the push state55 when commits exist - unpushed rounds accumulate silently otherwise (measured: three committed56 rounds sat unpushed until the user asked twice what was left).57- **Memories** - `memories purged: <names|none>`, fold-first (the trio reference's receipt,58 restated here because loop rounds measured 0 purges with the rule sitting unloaded).59- **Next actions** - when Deferred items are blocked on the operator (a live walk, a log grab,60 a replay), a ranked what-to-do list ships IN this report, not on request (measured: a CAPPED61 stop without one cost three clarifying prompts and an ad hoc doc no contract names).6263When the report closes with uncommitted work and no next round queued, the commit decision goes through AskUserQuestion (commit now / hold) - never a prose 'your call' bullet (measured: three such bullets in one session drifted unresolved for 5h while the uncommitted set grew 16 -> 23 files). The same close names what this round's runs started and still have up - a Docker container or compose stack, seeded integration-test data, a background process - and puts tear-down-vs-keep through the same AskUserQuestion call (teardown recommended; started-nothing is said plainly, and what the round did not start is never touched).6465## Example6667DELEGATED, one run over the Orders module:681. **ANALYZE + ASSESS** - run the project-architecture-analyzer capture; ARCHITECTURE.md + ASSESSMENT.md land with tiered weaknesses. The top two: a **small** con (a repository leaks an EF type across the boundary) and a **substantial** con (queries and handlers share one grab-bag namespace).692. **FIX by tier** - confirm the green baseline. Small: dispatch aspnet-implementer with a scoped brief, re-run build + tests. Substantial: dispatch aspnet-solution-designer for a decomposition, get approval, fan out implementers, gate with aspnet-verifier. A **structural** con (invert the persistence dependency) is flagged for a user decision, not auto-applied.703. **UPDATE DOCS** - delete the two fixed weaknesses from ASSESSMENT.md; the namespace split exposed nothing new.714. **LOOP or STOP** - re-read ASSESSMENT.md: only the user-declined structural item and accepted tradeoffs remain -> **SATISFIED**. One capture UPDATE reconciles ARCHITECTURE.md with the namespace split; emit the final report.7273## Bounded and honest74- **Hard cap: 3 improve rounds.** Architecture changes are expensive and consequential; do not loop indefinitely chasing the last debatable con.75- **Each round boundary is a fresh-session resume point** - the pruned `<docs-path>/architecture/ASSESSMENT.md` is the handoff; measured, carried-forward conversation (not tool output) dominates session cost. A step, not advice (the advice form was ignored in 4 of 4 audited long sessions): at each LOOP decision, ask via AskUserQuestion - resume in a fresh session from the pruned assessment (recommended) vs continue here, and the fresh-session option is ALWAYS one of the ask's options (a continue-ask without it is the measured failure step 4's receipt exists to catch); on 'fresh', end the turn with a RESUME BLOCK the new session can start from alone: the exact invocation (naming the rounds already consumed so the 3-round cap survives), the remaining weaknesses in leverage order with their tiers, and the docs to read first (the pruned `<docs-path>/architecture/ASSESSMENT.md`, the green-baseline state).76- Never weaken a test or delete an assertion to make a con look resolved - that is a new weakness, not a fix.77- Make the smallest change that resolves each weakness; a rewrite that introduces new coupling makes the loop diverge.78- The assessment's tier is the routing authority - do not silently upgrade a small con into a rewrite, or downgrade a structural one to sneak it past the approval gate.7980## Rules81- The main session is the only orchestrator. The build seats it dispatches - the domain designer / implementers / verifier / resolvers - carry no Agent tool, so the fan-out stays flat; a con needing analysis and a fix is separate dispatches from here, not one nested one. The capture's architecture-analyzer fan-out is also dispatched from here, flat - there is no dispatched architecture seat and no nesting.82- Substantial and structural changes are gated on user approval before building; small localized fixes proceed. Architecture changes are consequential - confirm before reshaping the structure. In DELEGATED mode, the mode ask's answer IS the dispatch consent for small-tier fixes: write the `<docs-path>/flow/APPROVAL` stamp (`APPROVED small-tier - "<the answer, verbatim>"`) the moment that answer lands, and rewrite it as substantial-tier approvals arrive - the dispatch guard is deliberately tier-blind, so an unstamped small-tier dispatch just bounces (measured: one sat blocked 34 minutes behind an unrelated substantial approval). On a RESUMED session no mode ask fires - the small-tier stamp then quotes the RESUME BLOCK's own dispatch line (`APPROVED small-tier - resumed round <N>, "<the block's mode line, verbatim>"`), never repurposed task framing (measured: a resume improvised its stamp source from general instructions). The mode answer covers the WHOLE round - a DELEGATED round's fixes go to the seats, its lens sweeps to analyzer seats; working a fix inline under a DELEGATED answer, or scoping the ask to just the analyze step, leaves the round's real work with no mode decision at all (measured twice: every small-tier fix of one DELEGATED round was applied inline; another round's ask covered only 'the lens sweep' and the fix ran unmoded).83- Keep this skill orchestration only. The architecture judgement lives in the project-architecture-analyzer capture and the house architecture skills it loads; the build knowledge lives in the domain seats. For a pure code-quality polish reach for `project-quality-loop`; for a single feature build reach for `project-solve-cross-task`.