| name | dev-task-memory |
| description | 5-layer persistent memory for in-progress dev tasks â survives context compression, /new, gateway restart. State file + git checkpoints + external memory + cross-session search. |
| trigger | context compression / /new / gateway restart / '繌çºä¹åçä»»å' / 'where were we' / 'save state' / 'checkpoint task' / subagent åå°äžå stop å
WIP / **multi-phase dev task (>30 min, e.g. security review â fix-batch sprint)** |
| version | 2 |
| category | devops |
Dev Task Memory
解決 David 2026-06-06 hang fix å
延䌞åé¡ïŒcontext èçå®ä¹åŸ, dev task 黿š£å奜被éºå¿ã
5-layer architecture ç¢ºä¿ task å
decisionsãcurrent stateãnext steps å
šéš persist åº file system,
åé LLM memory (æè¢« compression æž
), éœåé user èšäœ (äžå¯é )ã
5 å Layer
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Layer 1: TRIGGER (決å®å¹Ÿæ save) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â ⢠çŽ
ç· 21-22 (long task, > 50 turns) â
â ⢠auto-compression event (gateway/run.py hook) â
â ⢠gateway restart â
â ⢠/new slash command â
â ⢠User explicit "save state" / "checkpoint" â
â ⢠**Subagent åå°äžå stop å
WIP** (æ° trigger â 2026-06-06)â
â â working tree æ untracked / modified files, è·äœçš â
â `references/subagent-wip-pickup-recipe.md` å
6-step â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Layer 2: STATE FILE (Single Source of Truth) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â ~/www/<project>/docs/_meta/dev-task-state.md: â
â - Goal, Decisions (with WHY), Current state, Next steps, â
â Risks, Insights, Session lineage, References â
â - Gitignored via .gitignore snippet â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Layer 3: GIT-TRACKED (å¯å¯©èš + å¯ rollback) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â ⢠enable checkpoints: true (Hermes built-in) â
â ⢠/rollback N for file rollback â
â ⢠git commit footer å
å« state summary â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Layer 4: EXTERNAL MEMORY (cross-session fact recall) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â ⢠holographic (local, no API key) or mem0/honcho (API) â
â ⢠Sync facts (decisions, insights, risks) èœ external store â
â ⢠Cross-session: ãä¹åäœ è©±çš X é»è§£?ã峿 recall â
â ⢠ç¶å external provider, fallback èœ â
â ~/.hermes/memories/dev-task-facts.jsonl â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Layer 5: CROSS-SESSION SEARCH (session_search FTS5) â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ€
â â¢ éæ° session èªå search "what was I working on" â
â ⢠泚å
¥ top-3 relevant past sessions â
â â¢ çš hermes sessions list æŸ candidate sessions â
â ⢠åéèŠ manual session ID èšæ¶ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
ð§ å·¥å
·è
³æ¬
| Script | çšé | è§žçŒææ© |
|---|
scripts/save_state.py | Save ç¶å dev task state èœ docs/_meta/dev-task-state.md | Layer 1 trigger fires 䜢 |
scripts/load_state.py | Read state file + 泚å
¥ context (for resume) | New session / /new / after-compression / after-restart |
scripts/sync_external.py | Extract facts â push to external memory (or local fallback) | æ¯æ¬¡ save_state å®ä¹åŸ fire |
ð æ¯æŽ References
| File | è§žçŒææ© |
|---|
references/subagent-wip-pickup-recipe.md | Resume äžå subagent åå°äžåååå
task â working tree æ uncommitted WIP, è·äœ 6-step recipe: snapshot â commit history â read untracked â audit side effects â finish â verify-before-declaring-doneãæ¶µè duplicate gitignore entriesãbatch-fix å
anti-patternãrevert detection çã |
references/recovery-template-limitation.md | Day 11 lesson (2026-06-09): recovery.sh + save_state.py å
generic template æ°žé å fill çæ£ state(Decisions / Files / Next Steps / Risks section å
šéšä¿ placeholder)ãResume ä¹åäžå®èŠæå overwrite dev-task-state.md,fill çæ£ stateãWorkaround recipe + root cause analysis + future fix blueprint å
šéšåºå
¥é¢ã |
references/working-tree-wip-detection.md | Day 11 lesson (2026-06-09): Agent å David å
±çš worktree å
æå,David å
WIP(modified + untracked) åå¯ä»¥å
¥ agent å
commitãSelective git add <files> recipe + 3 æ¢æ°çŽ
ç·(34-36)+ Day 11 Phase 1 å
case study(crm-system 5M + 3?? WIP detection)ã |
references/plan-execution-deviation-protocol.md | Day 14.7 lesson (2026-06-07): Plan JSON å
§éšççŸå
èç â æ primary intent åæ literal textã3 èåé€çŽé(code comment + commit + report)ãanti-pattern(çšæ¶äžåç
§ shipãéé rewrite plan)ãStep 6 /settings æ¡äŸå worked exampleã |
templates/handoff-doc-scaffold.md | Day 14 lesson (2026-06-07): Human-readable handoff doc å
scaffold,çšæŒ /new / æ¶å·¥ / ãä¹åŸå¢ãtrigger å°é£,Agent 寫äžä»œ David + fresh session agent å
©ééœè®åŸé å
commit-able doc(å state file äºè£)ãSection structure èŠ Â§5 å
recipeã |
ð æšæºäœ¿çšæµçš
1) éæ° dev task (Plan â Build éå§)
cd ~/www/crm-system
python3 ~/.hermes/profiles/developer/skills/dev-task-memory/scripts/save_state.py \
--project crm-system \
--goal "å¯Šäœ Companies 線茯é å è¯ç¹«äºº sub-row" \
--trigger "task-start"
Agent æ¶å° trigger æè©²:
- ç«å³ call
save_state.py
- Fill in
docs/_meta/dev-task-state.md å
DecisionsãNext StepsãInsights section
- Call
sync_external.py push facts èœ external memory
2) Long task äžæ®µ (æ¯ 30 min ææ¯ 10 å tool calls)
Agent èªå trigger:
python3 scripts/save_state.py --project crm-system --trigger "auto-mid-task"
python3 scripts/sync_external.py --project crm-system
å¢å確ä¿å°±ç® hang / compression / restart, state éœåæ lostã
3) Context å£çž® / Hang fix / /new / Restart åŸæ¢åŸ©
User send "繌çº" / "resume" / "where were we":
python3 scripts/load_state.py --project crm-system --search-sessions
Agent æ¶å° output åŸ:
- Read state file content
- Inject å
¥ conversation context
- Resume è·äœ "Next 3-5 Steps" 繌çºå
3b) Subagent WIP Pickup (æ° â 2026-06-06)
Working tree æ untracked + modified files ç±åäžå subagent çäœ, åä¿ from compressionã
å奜 call load_state.py (å state file, åŸæª start), å奜 re-delegate (浪費 70-90% å
WIP)ã
è· references/subagent-wip-pickup-recipe.md å
6-step recipe:
git status + git diff --stat snapshot working tree
git log --oneline -10 check partial progress
- Read untracked / modified files in full
- Audit side effects (
.gitignore duplicates, package.json, etc.)
- Finish from actual pickup point
git log --oneline origin/main..HEAD empty + clean working tree çºæ¢
4) ä»»å宿
åªé€ state file (task done, no need to resume):
rm ~/www/<project>/docs/_meta/dev-task-state.md
æè
archive èœ docs/retros/YYYY-MM-DD-<task-name>.mdã
5) Human-Readable Handoff Doc (Day 14 lesson â 2026-06-07)
When: User 話ãä¹åŸå¢ã/ãæäŒæ¯äžã/ãäœ stop åŠã/ã/new åŠã,Agent ç¥éäžäžå session
æä¿ David èªå·±(æè
fresh agent)è®,éèŠäžä»œ 人é¡å¯è® + å¯ commit + å¯ grep å
æä»¶ã
åå¯ä»¥åªé state file:
dev-task-state.md ä¿ gitignored (çŽ
ç· 28) â äžäžå session å
fresh agent åç¥æå¢å file
- å
§å®¹ä¿ machine-optimized,David è®èµ·äžååé
- å commit å
話,different branch / different machine å
agent æåå°
Handoff doc å
ç¹æ§(å state file å°æ¯):
| ç¹æ§ | docs/_meta/dev-task-state.md (state) | docs/retros/YYYY-MM-DD-<task>-handoff.md (handoff) |
|---|
| Gitignored | â
çŽ
ç· 28 | â æ£åžž commit(å¯ä»¥ PR äžéœ) |
| Reader | Machine + Agent | David + æ° session agent + reviewer |
| Format | Structured (Goal/Decisions/Next Steps) | Narrative + TL;DR + resume block |
| Content | Decisions with WHY, current step | Decisions, uncommitted WIP (App.tsx diff!), key env vars, first-3-commands |
| Lifetime | ä»»åæé | ä»»åçµæåŸ audit trail(æ°žé ä¿ç) |
| Use case | load_state.py resume | /new åŸæå read |
Recipe(2026-06-07 crm-system handoff 詊é work):
cd ~/www/<project>
git log --oneline -8 <branch>
git status --short
git diff --stat <base>..<branch> | tail -5
python3 scripts/save_state.py --project <name> --goal "..." --trigger task-start
python3 scripts/sync_external.py --project <name>
ls -la docs/_meta/dev-task-state.md docs/retros/<date>-<task>-handoff.md
Critical sections that MUST be in handoff doc(David 詊é miss å
):
- Uncommitted WIP â
git diff çµæ(çŽ
ç· 30 å recovery åç)
- David å
untracked files â æ°žé åå¯ä»¥ãæž
çã,å¿
é list åºå
- Key env vars / 32-char gate â äŸåŠ
JWT_SECRET 32-char hard-fail,æ° session èŠ re-export
- Latent bugs fix å
caveat â äŸåŠ seed Role/RolePermission åº prod åååš,æ° endpoint æ 403
- First 3 commands â
cd + load_state.py + start dev
- Routing / runtime invariants (æ° â 2026-06-07 lesson) â ç¶ step commit å
å«
order-dependent routing(sibling route conflict å°é¡)äœ smoke test çå° ship step,å¿
é åº handoff doc éçšç« sub-section,寫äœãè²çš±å
è¡çº + é» verifyããTS pass â
runtime passã詳èŠ
react-router-sibling-route-conflict skillã
Pitfall: åå¥œå° handoff doc å¯«å° docs/_meta/,æè¢« gitignore + å€±å» audit trail å
purposeã
Pitfall: å奜 overwrite å·²ç¶æå
docs/retros/YYYY-MM-DD-<task>.md retro file â handoff ä¿
äžæ· å
trail,retro ä¿ å®æ å
trail,å
©è
timing + content ååã
ð å Hermes å
§å»ºåèœå
æŽå
| Hermes feature | dev-task-memory çšæ³ |
|---|
hermes --resume <id> / -c "<name>" | state file å
Session Lineage section å¯«äœ resume command |
hermes checkpoints (filesystem) | Layer 3 èªå enable, åéèŠé¡å€ config |
hermes memory status | Layer 4 æ¥ active provider |
session_search (FTS5) | Layer 5 load_state.py --search-sessions çšäœ¢ |
/rollback N | Layer 3 file rollback é
state file restore |
â ïž çŽ
ç· (è· SOUL.md çŽ
ç· 24-28 å°éœ)
- çŽ
ç· 24:æ¯æ¬¡ long task éå§å¿
é
save_state.py, åå¯ä»¥ rely on LLM memory
- çŽ
ç· 25:æ¯ 30 åéæ 10 å tool calls å¿
é re-save (Layer 1 èªå trigger)
- çŽ
ç· 26:Decision å¿
é æ WHY â åå¯ä»¥æ·šå¯« "Use Hono", èŠå¯« "Use Hono 4x 现, edge å±çš"
- çŽ
ç· 27:Resume æå¿
é å
load_state.py, åå¯ä»¥åèšèªå·±èšåŸ
- çŽ
ç· 28:State file åå¯ä»¥ commit èœ git â
docs/_meta/* å¿
é åº .gitignore
- çŽ
ç· 33:Resume ä¹åå¿
check
dev-task-state.md åä¿ generic template(Day 11 lesson)ã
Generic template å
signals:æ <Decision 1> / <Risk 1> / **åŸ
填寫** / å
šéš file
éœä¿ M (now) åç寊 file pathãHit ä»»äœäžå â æå overwrite çæ£ state å
resumeã
è©³èŠ references/recovery-template-limitation.md å
workaround recipeã
- çŽ
ç· 34:Sibling subagent äžŠè¡ edit åäž file æå¿
check éæ¹æåŸ diff å overlap(Day 14.7 lesson)ã
Patch tool / write_file æå° warning "modified by sibling subagent" / "last read with
offset/limit pagination" â åå¥œç²æ¹ãRecipe: (1)
git diff <file> ç sibling æ¹åéæ®µ;
(2) èªå·±å
patch åæ®µå sibling å
patch åæ®µåå¯ä»¥éç; (3) åŠéç(regex region æ
å
±å functions / interfaces),æå merge å
©éå
æ¹å,å奜 git add + commit çŽæ¥æ;
(4) Commit message 寫äœãconflict-free with sibling X å
Y æ¹åãã詳èŠ
references/sibling-subagent-concurrent-edit-recipe.md(åŸ
建)ã
- çŽ
ç· 35:Tying two patches to the same commit when they're in different
sub-trees is safe; the dangerous case is two patches both touching the
same function body or interface declaration. Quick test before committing
sibling-collision files:
git diff <file> | grep -E "^[+-]" | sort | uniq -c | sort -rn | head -20 â any line that appears as both + and - is a true
merge conflict, not just proximity.
ð ïž èšå® (.gitignore snippet)
æ¯å project å
.gitignore å :
# dev-task-memory â runtime state, not source
docs/_meta/
dev-task-state.md
𧪠é©èæä»€
python3 scripts/save_state.py --project crm-system --goal "Test" --trigger "manual"
python3 scripts/sync_external.py --project crm-system
python3 scripts/sync_external.py --read --project crm-system
python3 scripts/sync_external.py --search "Prisma"
python3 scripts/load_state.py --project crm-system --search-sessions
ð é
åå
¶ä» skills
context-summarizer (existing): èªåæ¯ 30 åéå£ contextãdev-task-memory è£äœ¢å
çŒºé» â å£åä¹åŸ decisions åæ lost
regression-guard (existing): é²è bug ç¿»çŒãstate file å
Risks section é
RG-XXX
auto-doc-gen (existing): èªåçæ API docãstate file å
Decisions é
doc rationale
ð å·²ç¥éå¶
-
save_state.py å
"extract decisions from session" èå®¶ä¿ stub â TODO: integrate with hermes_state.py è®çæ£ session DB
-
External memory provider (mem0/honcho) API call ä»²æª implement â èå®¶ fallback èœ local jsonl
-
Holographic provider éç¶ä¿ local-only äœéèŠ config, é»èªæªåçš â å¯ä»¥ä¹åŸ setup
-
State file åæ auto-update â å¿
é 人æ call save_state.py
(å°äŸå¯ä»¥å background curator èªå trigger)
-
memory tool round-trip drift guard (2026-06-19 lesson) â Hermes å
memory(action='add') æ refuse write ç¶ ~/.hermes/profiles/developer/memories/MEMORY.md æ manual edit / shell append / patch tool å
content åå¯ä»¥ round-trip through memory() callãDetection: error message æ "MEMORY.md.bak." + "Resolve the drift first â either rewrite the file as a clean §-delimited list of entries, or move the extra content out"ãResolution recipe:
cat ~/.hermes/profiles/developer/memories/MEMORY.md.bak.<timestamp> æ backup
- Manual integrate missing entries into clean §-delimited list (one at a time via
memory(action='add', content='...'))
- Remove or rewrite original MEMORY.md to clean state
- Retry
memory(action='add')
åå¯ä»¥ force overwrite â guard å
ååšä¿é²æ¢ silent data loss (Hermes issue #26045)ãåå¯ä»¥ retry 5 次(浪費 token + æåäžå error)ãLesson codification: åŠæå lesson å¿
é persist äœ memory tool æçµ,fallback èœ skill(SKILL.md body)æè
è¬ç David ç¥èŠäººæ syncã
ð Plan Z â Mid-Handoff Single-Step Commit Cycle (2026-06-07)
Trigger: User has multi-step work (â¥5 steps) remaining, session has hit çŽ
ç· 22 (>50 turns)
or çŽ
ç· 19 (tool-call noise from earlier hang). 3 paths to offer, ordered by safety:
| Path | Description | Hang risk | /new cycles | Total wall time |
|---|
| X (Inline all) | Do every step in this session, accept hang | High (â¥1 hang mid-run) | 0 (until forced) | 4-5 hr + 1 unplanned handoff |
| Y (Inline half) | Do first N/2 steps, then /new handoff | Medium | 1 planned | 4-5 hr, 1 clean checkpoint |
| Z (1-step cycles) | Do exactly 1 step + commit + handoff + /new, repeat | ~Zero per cycle | 1 per step | 4-5 hr, multiple clean checkpoints |
User pick pattern observed: David, when offered Z, replied "Z" within 1 turn. The deciding
factor was proven hang history that session (仿 6 é» 3 å°æ hang, 47-78 API calls stuck).
When user has been burned by hang already, they prefer many small clean cycles over inline sprint.
Plan Z execution recipe (tested on crm-system 2026-06-07 Step 5):
- Scope the next single step only â read handoff doc, pick the smallest step with concrete
file paths (e.g. "Step 5: routes + API client", not "Step 5-8: all frontend").
- Execute in â€20 tool calls â hard budget. If you cross it, stop and handoff what you have.
- Verify locally â
tsc --noEmit, git status --short, type check. Defer browser/E2E
smoke to the final ship step (Step 12 of the original plan).
- Commit + push â single commit, descriptive footer pointing to next step.
- Update handoff doc + state file â re-stamp the "What's Done" section with the new commit,
mark the step as done in the "What's NOT Done" table.
- Emit "ð progress" + explicit
/new recommendation â let user run /new themselves.
Don't auto-/new (user has the shortcut key).
- Tool-call budget enforcement: if a step needs >20 calls, split it across 2 cycles BEFORE
starting, not mid-cycle.
Pitfall â routing conflict undetected (saw in 2026-06-07 crm-system Step 5): When adding
sub-routes that share a prefix with a legacy top-level route (e.g. /settings/* + /settings),
react-router v6 picks most-specific match but the build-time types don't catch this â you
need browser smoke. Plan Z defers that to Step 12, so document the routing invariant in the
handoff doc explicitly so the smoke step knows what to verify.
Pitfall â TS-only verification is not enough: tsc --noEmit passes for valid route trees
that silently shadow each other at runtime. Treat the routing invariant claim in the handoff
doc as a prediction to be tested, not a guarantee.
Why Z beats the çŽ
ç· 21 fallback (delegate_task to subagent): Z keeps the work in the
main session lineage (so cross-session search, state file, retro doc all stay coherent). Subagent
isolation (çŽ
ç· 21) is better when you need to escape the main session context budget; Z is
better when the work is progressing fine and you just need a clean checkpoint.
When NOT to use Z: trivial 1-shot tasks (just do it inline), tasks with hard external
dependencies that won't survive a /new (e.g. holding an SSH tunnel), or tasks where the user
explicitly says "do it all in one go".
ðŽ åäŸ â 2026-06-07 crm-system code review + P0 fix sprint æŒ call save_state.py
æ
å¢:David åæåãCRM code review (A+B+C) â é P0 security fix sprintã,ææŽå 12-todo list + 7 commits + evidence report,å
šçšå call save_state.pyãæçµå data loss(å
šéš commit èœ git),äœäžéæ 2 åé«é¢šéª moment:
- æ¹ auth.ts register endpoint å
æåç¬¬äžæ¬¡å¯«é¯å
_actorId å°å hack(routes åæè©² pass å
§éš data via body)ãåŠææ state file çŽéãauth.ts P0-1: requirePermission('user:create') å°åºŠ getUserIdFromRequest å
helper æè©²é»çšã,ç¬¬äºæ¬¡ patch å°±åæèµ°æªè·¯ã
- Bun
--env-file åº smoke test æ shadowing â 2-3 次 attempts 浪費ãState file å
Insights section 寫äœãBun å
env-file å floor, åå¯ä»¥ shell overrideãå°±åéèŠå re-discoverã
Lesson:ä»»äœ > 30 min å
multi-phase dev task å¿
é åº Layer 1 trigger å°åºŠ fireãå³ä¿:
- çšæ¶è©±ãå A + B + Cãâ å³å»
save_state.py --goal "A + B + C" --trigger task-start
- äžæ®µæ¯ 30 min / æ¯ 10 tool calls â
save_state.py --trigger auto-mid-task + sync_external.py
- Sprint end â 寫
docs/retros/YYYY-MM-DD-<task>.md åŸ,rm docs/_meta/dev-task-state.md(task å®äº)
Skip å
åŸæ:compression / /new ä¹åŸèŠ re-discover åäžå Bun env shadowing pitfallãæè
é寫åäžå _actorId hack,çæŒ burn 5-10 min å
tool callsã
æ°å¢çŽ
ç· 37:multi-phase dev task (>30 min, 3+ todos) å¿
é task-start å³ call save_state.pyãåçŽ
ç· 24 å°éœ(ä»»äœ long task éå§å¿
é save),äœ spec åºå:åæ·šæ¢ãlongã,èŠãmulti-phaseã â å³ todo list ææç¢º phase boundary(Think/Plan/Build/Review/Test/Ship)å
taskã
ðŽ åäŸ 2 â 2026-06-07 crm-system Day 14.7 Plan â Build éæž¡ wire-shape drift (Step 5 â Step 7)
æ
å¢:Day 14.7 System Settings refactor + Tax Rate feature å
multi-phase plan(Steps 5-12,æ Plan doc + 3 å options å
ADR)ãStep 5(commit eb1581f)寫 frontend settingsApi.getTax/putTax wrapper å
æå,çŽæ¥è· Plan JSON doc å
wording çš defaultTaxRate å wire field nameãäœ plan doc å backend actual route handler(apps/api/src/routes/settings.ts)å忥 â backend çš rate å field name(GET response + PUT body å
©ééœä¿)ãPUT runtime äžå® 400 Zod validation error,çšæ¶é¶å¯Šæ© catch åå°ã
æ ¹å :
- Plan doc å
description field 寫ãDefault tax rate (%)ã,field name æå plan éæ®µåå°±åœå defaultTaxRate(亊åç readable)
- Backend dev çŽæ¥ implement
prisma.systemConfig.upsert({ data: { value: rate } }),response çš rate çå(亊åç)
- Plan éæ®µå人 grep backend source code verify actual wire shape
- Frontend wrapper commit å°é£å e2e é(æåº commit message 寫ãsmoke test deferred to Step 12ã,çŽ
ç· â çŽ
ç· 12/16 è¬ P0 US å¿
é Unit+Integration+E2E äžå±€,äœå¢åç®ãwire format bugãåä¿ US)
第 7 æ¥å
catch å çº Step 7 寫寊é settings-tax.tsx å
wire call å°é£,grep backend route handler ç¢ºèª actual wire shape,çŒçŸ defaultTaxRate æ ¹æ¬åååšæŒ backend responseãCommit bd1d107 fix å TaxConfig interface + putTax payloadã
Lesson + æ°å¢çŽ
ç· 38:Plan â Build éæž¡æ wire-shape verification(é©çšæŒææ plan-then-build multi-step task,å°€å
¶æ¶å backend â frontend contract):
- Step N wrapper commit ä¹å,grep backend actual handler ç¢ºèª wire field name + shape(record åº Insights section å
state file)
- Plan doc å
description / è®éåä¿ äººè©± åœå,backend å
field name ä¿ code åœå,åå¯ä»¥åèš 1:1
- Plan doc æãOptions A/B/C 決å®ãäœåèš wire shape å
section â èªå·±å ,åº Plan stage commit å°é£ grep äžæ¬¡ backend
- Build stage 寫 wrapper å°é£,è· backend source åè· plan doc(çŽ
ç·:ãæåŸç«¯ source code çºæçµäŸæžã)
Prevention recipe(references/wire-shape-verification-recipe.md æè©³çް case study):
- Plan stage å¯«å® doc â
git grep backend route / zod schema â å°éœ wire field name
- Plan doc éäžå "Wire shape (verified against backend)" section èšäœ
GET /x â { fieldA, fieldB } / PUT /x body â { fieldA }
- Build stage wrapper commit ä¹åå grep äžæ¬¡(backend å¯èœ plan stage ä¹åŸæ¹å)
- ç¬¬äžæ¬¡å¯Šé wire call å
commit(å
žåä¿ã寊äœç¬¬äžå page å°å stepã),commit ä¹å 5-min smoke(å°±ç®å full E2E éœèŠ curl äžæ¬¡ GET 200 ç¢ºèª field name)
åäŸæè:Step 5 wrapper å¯«é¯ â Step 7 catch â commit bd1d107 fix 浪費 1 commit boundary äœå runtime disaster(å çº spec 寫ãStep 12 smoke test å
é©ã,æªå° user)ãåŠæ David Day 14 éåæ° tab çŽæ¥ trigger putTax å°±æ 400 â äœ Plan ç¯åå expose settings UI until Step 7,æä»¥é¶ user-facing impactãPrevention å
ROI åä¿ãçœé£é¿å
ã,ä¿ãæ·š commit boundaryã+ãplan doc å
wire-shape section å°æ¥åŸ audit æçšãã
ð Reusable sub-route + tab navigation recipe(Day 14.7 Step 6-8 å°è)
ç¶ plan æåãoption A â äžå URL åæãå
Tabs pattern(å°æåžžèŠå
admin â settings â sub-tab éæ§),templates/shadcn-tabs-wrapper.tsx ä¿ known-good starterãåžžèŠé·é±:
- Radix
<Tabs> controlled mode é
NavLink â warningãæ¯å <TabsTrigger> å¿
é æå°æ value å active trigger é
å°;çŽæ¥ NavLink å
¥ <TabsList> æ trigger Radix warning "missing trigger"ãPick B:TabsTrigger + onClick={() => navigate('/settings/' + value)} å€±å» middle-click open-in-new-tab,äœé¿ warningã
- Layout å
page ä¹åŸ double-headerãPage æ¬èº« render èªå·±å
h1 + èªè£œ button-tab strip â Layout å render â èŠèŠºååŸãStep 6 æŽ layout å°é£é ææž
page å
§éš chrome(寫å Step 8 extract å
plan)ã
- Legacy route URL ä¿çã
<Route path="/old"><Navigate to="/new" replace /></Route> å backward-compat 5-10 å redirect äžæ¬¡éå ,bookmark/email link åææ»ã
- Query-string é å¡« filter å°å² pageãäŸåŠ audit page æ¥å
?action=SYSTEM_CONFIG_UPDATED åŸ settings è·³éäŸå³ filtered â å
¥ page å°é£ useSearchParams() æ initial state,1-2 è¡ codeã
å®æŽ 7-step walkthrough + å°æ crm-system commit hash å°ç
§ åº references/wire-shape-verification-recipe.md å
"Sub-route tab navigation" sectionã
ð E2E test result (2026-06-06)
- Save: 2715 bytes 寫å
¥
~/www/crm-system/docs/_meta/dev-task-state.md
- Edit: 2 decisions + 1 insight injected
- Sync: 4 facts â
~/.hermes/memories/dev-task-facts.jsonl
- Read: 4 facts loaded back â
- Search: "Prisma" â 1 hit â
- Load: state file full render â
Subagent WIP Pickup test (2026-06-06)
- å
¥å£: User send "çŸåšç¹Œçºå" +
git status show 1 untracked + 2 modified
- Recipe: 6 steps, ~15 min total
- çµæ: 1 commit (
7dc56d0), push æå, git log --oneline origin/main..HEAD empty
- ç¯ç vs re-delegate: ~15 min (WIP 95% correct, æ·šä¿ consumer page wiring 猺)
- æ°å¢ lessons: audit
.gitignore for subagent duplicates, batch-fix noise åºçšç« commit