From mattpocock-skills
Use before hard-to-reverse architecture decisions: database or schema changes, tenancy/auth models, service decomposition, module boundaries, public API contracts, core framework/state choices, infrastructure dependencies, queues/retries/storage/deployment topology, or repeated workarounds that suggest the current architecture is becoming a dead end. Convene independent proposals, challenge assumptions, verify evidence, and record an ADR with guardrails, lock level, migration path, and reopen conditions.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mattpocock-skills:architecture-councilThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Before code crosses a lock-in seam, run a **Council**. The job is not to make the requested feature work on the current architecture at any cost; it is to decide whether the architecture remains fit before implementation continues.
agents/openai.yamlexamples/modular-monolith.mdexamples/queue-selection.mdprompts/challenger.mdprompts/judge.mdprompts/lead.mdprompts/proposer.mdprompts/verifier.mdrubrics/database.yamlrubrics/default.yamlrubrics/infrastructure.yamlrubrics/module-boundary.yamltemplates/adr.mdtemplates/case.yamltemplates/decision-locks.yamltemplates/verdict.yamlBefore code crosses a lock-in seam, run a Council. The job is not to make the requested feature work on the current architecture at any cost; it is to decide whether the architecture remains fit before implementation continues.
Prefer boring, standard, reversible solutions. A novel architecture only wins when the evidence and operational justification beat the boring path.
Run this gate whenever planning or implementation touches structure. If no trigger applies and the score is below 6, do not run the full Council; continue with the normal skill and mention the low score only if it matters.
Run the Council when the change has any of these signs:
Score the decision before you decide the process:
Irreversibility: 0-3
Blast radius: 0-3
Operational impact: 0-3
Data migration risk: 0-3
Novelty: 0-2
A total of 6 or more triggers a full Council. A database choice, tenancy model, auth architecture, service decomposition, public contract, event schema, or deployment topology also triggers a full Council even if the score is lower.
Keep UI cooking out of the Council unless it changes structure:
autonomy_zones:
frontend_visual:
autonomy: high
council_required: false
examples:
- layout
- component styling
- Tailwind classes
- animation
- dashboard polish
frontend_architecture:
autonomy: medium
council_required_when:
- introduce_global_state
- introduce_new_rendering_model
- change_api_contract
- create_design_system_contract
- move_business_logic_to_frontend
backend_domain:
autonomy: low
data_architecture:
autonomy: very_low
Before framing the case, read:
CONTEXT.md, if it exists, for domain vocabulary;ARCHITECTURE.md for owner map, routing, public contracts, and allowed dependencies;RUNTIME_CONSTITUTION.md for runtime invariants the decision may create, strengthen, or violate;PROCESS_AND_PROOF_POLICY.md for evidence required to accept and later implement the decision;docs/adr/, docs/architecture/adr/, or src/<context>/docs/adr/);docs/architecture/decision-locks.yaml or equivalent);If there is no ADR convention yet, default to docs/adr/ so the rest of these engineering skills can find the decision. If the target repo already uses docs/architecture/adr/, follow that local convention.
Use .scratch/architecture-council/<decision-slug>/ for intermediate artifacts. Do not edit production code while the decision is unresolved.
Act as Lead. Rewrite the decision as a case file using templates/case.yaml. Include constraints, non-goals, existing locks, the risk score, and the exact question being decided.
Do not propose a solution in Round 0. If the framing has a blocking ambiguity, ask the user before launching proposers. Otherwise state assumptions explicitly and continue.
Launch 3 detached proposer agents by default when the harness supports subagents; use 2-4 only when the case genuinely calls for fewer or more. If the harness does not support subagents, write separate proposal briefs serially and do not let later briefs read earlier ones until Round 2.
Each proposer uses prompts/proposer.md and must output:
Detached means detached: Round 1 agents do not read each other's answers.
Run the Challenger with prompts/challenger.md. The Challenger attacks the proposals rather than adding new ones, unless all proposals miss an obvious boring option.
Every proposer gets one reply to the challenge. Do not allow infinite debate.
Run the Verifier with prompts/verifier.md. The Verifier checks load-bearing claims against code, tests, dependency evidence, official docs, and small spikes only when a spike answers a disputed claim.
Classify every important claim as:
Verified
Likely
Unverified
Contradicted
The Verifier does not vote by taste. It reports evidence and uncertainty.
Score each option with the relevant rubric from rubrics/. Use rubrics/default.yaml unless the decision is mainly database, module-boundary, or infrastructure.
Vote is signal, not authority. A majority can be wrong if the evidence contradicts it or if the boring option has lower lock-in.
Act as Lead Judge with prompts/judge.md. Read the proposals, challenge, replies, verification, and scores before deciding.
The verdict uses templates/verdict.yaml and must include:
soft, guarded, or locked;ARCHITECTURE.md, RUNTIME_CONSTITUTION.md, and PROCESS_AND_PROOF_POLICY.md.If the Council was auto-triggered inside another task, or if the verdict touches a locked item, contradicts an ADR, changes data, or adds infrastructure, present the verdict and ask the user for approval before writing non-scratch files or proceeding to implementation.
An accepted or deliberately rejected architecture decision needs a durable record. Use templates/adr.md. Number the ADR after the existing local convention.
The ADR must preserve reasoning, not just the conclusion:
Update or create docs/architecture/decision-locks.yaml using templates/decision-locks.yaml unless the repo already has an equivalent registry.
Then sync the root control docs when the verdict changes them:
ARCHITECTURE.md — module ownership, routing, allowed dependencies, public contracts, implementation-internal areas, code placement rules.RUNTIME_CONSTITUTION.md — new or changed runtime invariants and the proof each invariant expects when touched.PROCESS_AND_PROOF_POLICY.md — new proof requirements introduced by the architecture decision.If the verdict is pending user approval, write proposed updates only under .scratch/architecture-council/<decision-slug>/ and do not edit the root control docs yet.
Lock levels:
soft — easy to change: naming, folder structure, visual UI conventions. Agent may change and note why.guarded — broad but reversible: module boundaries, API pattern, caching, queue usage, state management. Changing it requires a reduced Council.locked — expensive migration: database, tenancy, service decomposition, public contract, auth architecture, event schema, deployment topology. Changing it requires a full Council and migration plan.Agents must read decision locks before planning structural work. They must not silently violate a guarded or locked decision.
Run a health-check Council when the user asks for an architecture review or when you detect these smells:
Start by asking: is this an implementation problem, or an architecture problem? Then apply the quick gate. If risk is high, run the full Council; if risk is medium and the affected lock is guarded, run a reduced Council with one proposer, one challenger, one verifier, and a verdict.
The Council is complete only when:
npx claudepluginhub eszxcvfd/skills --plugin mattpocock-skillsCreates, edits, and verifies skills using a test-driven development approach with pressure scenarios and subagents.