From hitl
Design a new system from scratch starting from a PRD. Produces domain decomposition, system manifest, HLDs, ADRs, LLDs, and an initial delivery plan — demoable slices sequenced by dependency, each with a decision packet ready to hand to a developer. Run once at project inception.
How this skill is triggered — by the user, by Claude, or both
Slash command
/hitl:architect-design-system [path to PRD][path to PRD]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Input:** $ARGUMENTS (path to PRD, or description of where to find it)
Input: $ARGUMENTS (path to PRD, or description of where to find it)
Refusal rule: If no PRD path or content is provided, stop and say: "A PRD is required to start system design. Point me to docs/01-product/prd.md or provide the PRD content directly."
Before doing anything else, check .hitl/design-system.yaml:
[ -f .hitl/design-system.yaml ] && grep "^status:" .hitl/design-system.yaml || echo "status: not-found"
Route based on the current status:
| Status | Action |
|---|---|
| File not found | Initialize .hitl/design-system.yaml with status: initializing, then proceed from Phase 1 |
initializing | Proceed from Phase 1 |
awaiting-requirements | Output the gate-pending message and STOP |
requirements-confirmed | Skip to Phase 2 (Domain Decomposition) |
awaiting-domains | Output the gate-pending message and STOP |
domains-confirmed | Skip to Phase 3 (System Manifest) |
awaiting-manifest | Output the gate-pending message and STOP |
manifest-confirmed | Skip to Phase 5 (HLDs) |
awaiting-hld-approval | Output the gate-pending message and STOP |
hld-approved | Skip to Phase 6 (LLDs) |
awaiting-lld-approval | Output the gate-pending message and STOP |
lld-approved | Skip to Phase 8 (Delivery Plan) |
awaiting-delivery-plan | Output the gate-pending message and STOP |
complete | Output: "System design is complete. Decision packets are ready — assign them to developers to begin /hitl:dev-tdd." and STOP |
blocked | Output the blocked message and STOP |
Gate-pending message (for any awaiting-* status):
Gate pending — waiting for TA approval.
Status: [current status]
The TA must run /hitl:ta-approve to review the current artifact and advance this gate.
Once approved, re-run this command to continue to the next phase.
Blocked message (for blocked status):
This system design is blocked — a gate was rejected by the TA.
Gate: [blocker.gate]
Finding: [blocker.finding]
Address the finding above, then re-run this command. The skill will resume
at the rejected phase so you can rework the artifact.
For blocked status: after showing the blocked message, ask: "Are you ready to rework the [blocker.gate] artifact? Say 'yes' to resume." On confirmation, clear the blocked status and route to the appropriate phase.
.hitl/design-system.yaml initial content (written when file not found):
status: initializing
prd: "[path from $ARGUMENTS]"
Ensure the .hitl/ directory exists: mkdir -p .hitl
Read the document at the path in $ARGUMENTS. If none given, check docs/01-product/prd.md.
Extract and summarize:
| Category | Extracted content |
|---|---|
| System name and purpose | |
| User personas and their primary goals | |
| Core use cases (the 3–5 workflows that matter most) | |
| Functional requirements (must-have vs nice-to-have) | |
| Non-functional requirements (performance, scale, availability, security, compliance) | |
| External integrations (systems this will call or be called by) | |
| Tech stack constraints (anything pre-decided by the organization) | |
| Explicit out-of-scope items | |
| Open questions |
Do not proceed past this step with any unanswered item. Missing NFRs at design time become architecture mistakes at build time.
Run through the full NFR checklist in ${CLAUDE_PLUGIN_ROOT}/shared/challenge-stance.md (Minimum NFR Checklist section). For each NFR that is absent or vague in the PRD, ask the architect or PM now.
One rule for unresolvable NFRs: Ask first. If the answer cannot be obtained (early-stage project, no stakeholder available), make a stated assumption with a specific number and record it as a design risk in the gate below — do not leave it unnamed. "We don't know yet" embedded silently in an architecture is far more dangerous than an explicit assumption the team can challenge and update.
Present the extracted summary and gaps.
Update .hitl/design-system.yaml: set status: awaiting-requirements.
Output:
Gate 1 reached — status set to 'awaiting-requirements'.
The TA must run /hitl:ta-approve to confirm requirements before domain decomposition begins.
Re-run /hitl:architect-design-system after TA approval to continue.
STOP. Do not propose a domain breakdown. This session ends here.
This is the most consequential decision in the session. Domain boundary errors cascade through every subsequent artifact. Take the time to get this right.
From the PRD use cases and functional requirements, identify candidate domains using these heuristics:
For each candidate domain, specify:
Domain: <name>
Purpose: <one sentence>
Owns: <what data/state this domain is the authority for>
Key responsibilities: <3-5 bullet points from the PRD>
Does NOT own: <explicit exclusions to prevent creep>
For each pair of domains that must exchange data:
Draw the interaction matrix:
domain_a → domain_b: [what crosses, why, sync/async]
Flag any circular dependencies — they indicate a boundary is in the wrong place.
Before presenting to the architect, challenge it yourself:
Present the proposed domains and interaction map.
Update .hitl/design-system.yaml: set status: awaiting-domains.
Output:
Gate 2 reached — status set to 'awaiting-domains'.
Domain boundaries are the hardest decision to change later.
The TA must run /hitl:ta-approve to confirm the domain decomposition before manifest generation begins.
Re-run /hitl:architect-design-system after TA approval to continue.
STOP. Do not generate the system manifest. This session ends here.
Generate docs/system-manifest.yaml from the confirmed domain breakdown. Follow the schema in ${CLAUDE_PLUGIN_ROOT}/shared/templates/system-manifest.schema.yaml.
For a greenfield system, apply these rules per domain:
files and tests: empty arrays — no code exists yetlld: "pending" — updated in Phase 6facade_apis, boundary_entities, and events_* fields: propose from PRD use cases and mark every value DRAFT — architect to verify — these are intended contracts, not ground truthdepends_on: from the interaction matrix (Phase 2b)conventions: empty array — filled in after Phase 4 ADRs resolveCross-cutting section: propose conventions from tech stack decisions (if known), NFRs, and any organization-wide standards in the PRD. Mark all as DRAFT.
Interaction matrix: populate from Phase 2b.
Important: Every human-authored field (facade_apis, boundary_entities, events_*) must be marked DRAFT — architect to verify. These are proposals from the PRD, not ground truth. The architect fills in the real values as the first implementations run.
Update .hitl/design-system.yaml: set status: awaiting-manifest.
Output:
Gate 3 reached — status set to 'awaiting-manifest'.
System manifest and foundational ADRs are ready for TA review.
The TA must run /hitl:ta-approve to confirm before HLD generation begins.
Re-run /hitl:architect-design-system after TA approval to continue.
STOP. Do not generate ADRs or HLDs yet. This session ends here.
From the PRD, the confirmed domains, and any tech stack constraints already known, identify every major architectural decision that must be made before the first line of code:
| Decision area | Options | Must decide now? |
|---|---|---|
| Primary language and framework | Yes — affects conventions, LLDs | |
| Data storage (type and product) | Yes — affects domain schemas | |
| Authentication and authorization approach | Yes — cross-cutting, affects every domain | |
| API style (REST / GraphQL / gRPC / events) | Yes — affects facade API shapes | |
| Deployment model (monolith / services / serverless) | Yes — affects domain boundaries | |
| Observability stack (logging, tracing, metrics) | Yes — affects cross-cutting conventions | |
| Data consistency model (sync / eventual) | Yes if multi-domain writes exist |
Ask the architect: "Which of these are already decided by your organization? Which are open decisions that we should work through now?"
For each decision (decided or open), create docs/02-design/technical/adrs/<decision-slug>.md using ${CLAUDE_PLUGIN_ROOT}/shared/templates/adr-template.md.
For decisions already made: pre-fill Status: Accepted, Decision section, ask architect to fill in the Rationale (the why — what alternatives were considered and why this won).
For open decisions: fill Status: Proposed, list the options and their tradeoffs, leave Decision blank. STOP on each open ADR and ask the architect to decide before continuing. Architecture cannot proceed with unresolved ADRs on the list above.
Update docs/02-design/technical/adrs/README.md with all new ADRs.
Confirm with the architect: "Are all foundational ADRs accurate before I generate the HLDs? Say 'yes' to continue."
On confirmation, update .hitl/design-system.yaml: set status: manifest-confirmed. Then continue to Phase 5 in the same session.
Generate the following HLDs using ${CLAUDE_PLUGIN_ROOT}/shared/templates/hld-template.md. Each must read from the confirmed manifest and ADRs — not from memory or general reasoning.
Always generate:
System architecture (docs/02-design/technical/hld/system-architecture.md)
graph LR or graph TDData architecture (docs/02-design/technical/hld/data-architecture.md)
Security architecture (docs/02-design/technical/hld/security-architecture.md)
Generate if applicable:
API architecture (docs/02-design/technical/hld/api-architecture.md) — if the system has an external-facing API
Observability architecture (docs/02-design/technical/hld/observability-architecture.md) — if NFRs specify SLA, availability, or incident response requirements
Update docs/02-design/technical/hld/index.md after all HLDs.
After all HLDs are written, update .hitl/design-system.yaml: set status: awaiting-hld-approval.
Output:
Gate 4 reached — status set to 'awaiting-hld-approval'.
All system HLDs are ready for TA review:
[list each HLD path]
The TA must run /hitl:ta-approve to review the HLDs before LLD generation begins.
Re-run /hitl:architect-design-system after TA approval to continue.
STOP. Do not generate LLDs. This session ends here.
For each domain in the confirmed manifest, generate a LLD at docs/02-design/technical/lld/<domain>/<domain>.md using ${CLAUDE_PLUGIN_ROOT}/shared/templates/lld-component-template.md.
For each LLD:
facade_apis and satisfy the use cases from Phase 1 that this domain ownsAfter each LLD, update:
docs/02-design/technical/lld/index.mdlld field in docs/system-manifest.yamlAfter all domain LLDs, generate docs/02-design/technical/lld/packages.md — a Mermaid graph TD showing the domain dependency structure using the confirmed interaction matrix.
After all LLDs are written, update .hitl/design-system.yaml: set status: awaiting-lld-approval.
Output:
Gate 5 reached — status set to 'awaiting-lld-approval'.
All domain LLDs are ready for TA review:
[list each LLD path]
The TA must run /hitl:ta-approve to review the LLDs before the delivery plan is assembled.
Re-run /hitl:architect-design-system after TA approval to continue.
STOP. Do not begin the HITL process bootstrap or delivery plan. This session ends here.
Follow the instructions in Phase R5 of the generate-docs skill exactly. This sets up the process infrastructure:
CLAUDE.md from ${CLAUDE_PLUGIN_ROOT}/shared/templates/CLAUDE.md.template — inline the cross-cutting conventions from the ADRs and manifestconvention-checks.yaml — create checks from the conventions established in Phase 4 ADRs/architect/design-feature, /hitl:dev-tdd, /hitl:dev-generate-docs, etc. are available.github/workflows/.github/ISSUE_TEMPLATE/technical-change.md from ${CLAUDE_PLUGIN_ROOT}/shared/templates/issue-template.mdshared/graphify-setup.md for full instructions):
uv tool install graphifyy # install once per machine
graphify claude install # register /graphify skill with Claude Code
graphify . # build initial graph → graphify-out/graph.json
graphify hook install # auto-rebuild on every git commit
Commit graphify-out/ (excluding manifest.json and cost.json) so teammates get the graph on git pull. The PostToolUse hook in this project also rebuilds incrementally after doc writes during a session.docs/README.md — table of contents linking all HLDs, LLDs, ADRs, and the manifestThe design is complete. Now translate it into an ordered set of work packets — one per slice — that developers can pick up and execute independently using the 31-step workflow.
For each domain in the approved manifest, propose the minimum set of implementation slices that builds the domain's foundational capability. A slice is a unit of work one developer can complete in 2–5 days that produces something observable.
For each proposed slice:
Slice: <domain>-<N> (e.g. billing-1)
Domain: <domain name> — one domain only
Delivers: <what gets built in this slice>
Demo check: What does the PM see at the end of this slice?
Valid: user-visible feature or measurable outcome (record counts, latency, error rate)
Invalid: "nothing visible yet" → extend or merge with an adjacent slice
Dependencies: which other slices must complete first (from interaction matrix)
Rule: If a slice cannot answer the demo check with something concrete, it is too narrow. Extend it forward to the next observable boundary or merge it with the slice that completes the visible outcome.
Order all slices from all domains into a delivery sequence:
Present as a table:
| Order | Slice ID | Domain | Delivers | Demo check | Parallel with |
|---|---|---|---|---|---|
| 1 | domain-a-1 | domain-b-1 | |||
| 1 | domain-b-1 | domain-a-1 | |||
| 2 | domain-c-1 | — |
Update .hitl/design-system.yaml: set status: awaiting-delivery-plan.
Output:
Gate 6 reached — status set to 'awaiting-delivery-plan'.
Delivery plan is ready for TA review: [N] slices across [M] domains.
The TA must run /hitl:ta-approve to confirm the delivery plan before decision packets are generated.
Re-run /hitl:architect-design-system after TA approval to continue.
STOP. Do not generate decision packets. This session ends here.
For each confirmed slice, create a GitHub issue (or use the next available issue number) and create docs/decisions/issue-<N>-slice-<M>.yaml (or docs/decisions/issue-<N>.yaml for single-slice domains). Create the docs/decisions/ directory first if it does not exist.
Use exactly the schema below — do not add, remove, or rename fields. For a greenfield system, apply the defaults shown unless the slice warrants otherwise:
# docs/decisions/issue-<N>.yaml (or issue-<N>-slice-<M>.yaml for multi-slice)
issue: <N> # GitHub issue number for this slice
slice: null # slice number M, or null if one slice per domain
title: "<domain> — initial implementation"
change_type: feature
risk_level: low # raise to medium/high if cross-domain or high-traffic
domains:
- <domain-name> # exactly one domain per packet
source_docs:
prd: "<path>#<requirement-ref>"
hld:
- "<path>" # relevant HLD from Phase 5
lld:
- "<path>" # domain LLD from Phase 6
adr:
- "<path>" # ADRs governing this slice (empty list if none)
tests:
plan: "<key scenarios from facade APIs in the LLD>"
new_tests: [] # developer fills in during /hitl:dev-tdd
registry_updated: false
incidents:
checked: true
relevant: null # null for new systems — no incident history
rollout:
risk: low
strategy: "Direct deploy — new system, no existing traffic"
go_no_go: "<observable criterion from demo check in 8a>"
roi:
required: false # set true if slice takes > 1 day
estimate: null
impact_brief:
pm_mental_model: "<demo check from 8a in one sentence>"
risk_assessment: "<main risk for this slice>"
approvals:
architecture: pending # architect sets to approved after review
The pm_mental_model line is the demo check from 8a in one sentence — it is the handoff signal to the PM that this slice is complete.
After all decision packets are written, update .hitl/design-system.yaml: set status: complete.
Present a completion summary:
┌─────────────────────────────────────────────────────┐
│ SYSTEM DESIGN COMPLETE — [System Name] │
├─────────────────────────────────────────────────────┤
│ Domains: N | HLDs: N | LLDs: N | ADRs: N │
├─────────────────────────────────────────────────────┤
│ ARTIFACTS │
│ System manifest: docs/system-manifest.yaml │
│ HLDs: docs/02-design/technical/hld/ │
│ LLDs: docs/02-design/technical/lld/ │
│ ADRs: docs/02-design/technical/adrs/ │
│ CLAUDE.md: repo root │
│ Convention checks: convention-checks.yaml │
│ CI: .github/workflows/ │
│ Graphify: [installed / not required] │
├─────────────────────────────────────────────────────┤
│ NEEDS ARCHITECT ATTENTION BEFORE FIRST FEATURE │
│ • Facade API blurbs (DRAFT): N fields │
│ • Boundary entity shapes (DRAFT): N fields │
│ • ADR rationale sections: N docs │
│ • LLD method signatures (DRAFT): N domains │
├─────────────────────────────────────────────────────┤
│ DELIVERY PLAN │
│ Slices: N | Parallel tracks: N | Packets: N │
├─────────────────────────────────────────────────────┤
│ NEXT STEPS │
│ 1. Fill in DRAFT fields in manifest and ADRs │
│ 2. Assign decision packets to developers │
│ — each developer receives one packet and runs │
│ the standard 31-step workflow from it │
│ 3. Run /hitl:dev-generate-docs reverse-engineer after the │
│ first sprint to reconcile design vs. built │
└─────────────────────────────────────────────────────┘
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub pappar/hitl-claude-plugin --plugin hitl