joycraft 0.5.3 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -86,6 +86,24 @@ One sentence \u2014 what breaks or is missing without this?
86
86
  - [ ] Build passes
87
87
  - [ ] Tests pass
88
88
 
89
+ ## Test Plan
90
+
91
+ | Acceptance Criterion | Test | Type |
92
+ |---------------------|------|------|
93
+ | [Each AC above] | [What to call/assert] | [unit/integration/e2e] |
94
+
95
+ **Execution order:**
96
+ 1. Write all tests above \u2014 they should fail against current/stubbed code
97
+ 2. Run tests to confirm they fail (red)
98
+ 3. Implement until all tests pass (green)
99
+
100
+ **Smoke test:** [Identify the fastest test for iteration feedback]
101
+
102
+ **Before implementing, verify your test harness:**
103
+ 1. Run all tests \u2014 they must FAIL (if they pass, you're testing the wrong thing)
104
+ 2. Each test calls your actual function/endpoint \u2014 not a reimplementation or the underlying library
105
+ 3. Identify your smoke test \u2014 it must run in seconds, not minutes, so you get fast feedback on each change
106
+
89
107
  ## Constraints
90
108
  - MUST: [hard requirement]
91
109
  - MUST NOT: [hard prohibition]
@@ -104,7 +122,7 @@ Strategy, data flow, key decisions. Name one rejected alternative.
104
122
 
105
123
  If \`docs/templates/ATOMIC_SPEC_TEMPLATE.md\` exists, reference it for the full template with additional guidance.
106
124
 
107
- Fill in all sections \u2014 each spec must be self-contained (no "see the brief for context"). Copy relevant constraints from the Feature Brief into each spec. Write acceptance criteria specific to THIS spec, not the whole feature.
125
+ Fill in all sections \u2014 each spec must be self-contained (no "see the brief for context"). Copy relevant constraints from the Feature Brief into each spec. Write acceptance criteria specific to THIS spec, not the whole feature. Every acceptance criterion must have at least one corresponding test in the Test Plan. If the user provided test strategy info from the interview, use it to choose test types and frameworks. Include the test harness verification rules in every Test Plan.
108
126
 
109
127
  ## Step 6: Recommend Execution Strategy
110
128
 
@@ -177,19 +195,21 @@ Accept the default or the user's choice.
177
195
 
178
196
  ### Question 2: GitHub App
179
197
 
180
- > Level 5 needs a GitHub App to provide a separate identity for autofix pushes (this avoids GitHub's anti-recursion protection).
198
+ > Level 5 needs a GitHub App to provide a separate identity for autofix pushes (this avoids GitHub's anti-recursion protection). Creating one takes about 2 minutes:
181
199
  >
182
- > **Option A:** Install the shared Joycraft Autofix app (quickest \u2014 1 click)
183
- > **Option B:** Create your own GitHub App (more control)
200
+ > 1. Go to https://github.com/settings/apps/new
201
+ > 2. Give it a name (e.g., "My Project Autofix")
202
+ > 3. Uncheck "Webhook > Active" (not needed)
203
+ > 4. Under **Repository permissions**, set:
204
+ > - **Contents**: Read & Write
205
+ > - **Pull requests**: Read & Write
206
+ > - **Actions**: Read & Write
207
+ > 5. Click **Create GitHub App**
208
+ > 6. Note the **App ID** from the settings page
209
+ > 7. Scroll to **Private keys** > click **Generate a private key** > save the \`.pem\` file
210
+ > 8. Click **Install App** in the left sidebar > install it on your repo
184
211
  >
185
- > Which do you prefer?
186
-
187
- If Option A: The App ID is \`3180156\`. Note this for later.
188
- If Option B: Guide them to create an app at \`https://github.com/settings/apps/new\` with permissions: Contents (Read & Write), Pull Requests (Read & Write), Actions (Read & Write). They'll need the App ID from the settings page.
189
-
190
- ### Question 3: App ID
191
-
192
- If they chose Option B, ask for their App ID. If Option A, use \`3180156\`.
212
+ > What's your App ID?
193
213
 
194
214
  ## Step 3: Run init-autofix
195
215
 
@@ -205,28 +225,15 @@ Review the output with the user. Confirm files were created.
205
225
 
206
226
  Guide the user step by step:
207
227
 
208
- ### 4a: GitHub App Private Key
228
+ ### 4a: Add Secrets to Main Repo
209
229
 
210
- > If you chose the shared Joycraft Autofix app, you'll need to generate a private key:
211
- > 1. Go to https://github.com/settings/apps/joycraft-autofix
212
- > 2. Scroll to "Private keys" and generate one
213
- > 3. Download the \`.pem\` file
214
- >
215
- > If you created your own app, generate a private key from your app's settings page.
216
-
217
- ### 4b: Add Secrets to Main Repo
230
+ > You should already have the \`.pem\` file from when you created the app in Step 2.
218
231
 
219
232
  > Go to your repo's Settings > Secrets and variables > Actions, and add:
220
233
  > - \`JOYCRAFT_APP_PRIVATE_KEY\` \u2014 paste the contents of your \`.pem\` file
221
234
  > - \`ANTHROPIC_API_KEY\` \u2014 your Anthropic API key
222
235
 
223
- ### 4c: Install the App
224
-
225
- > The GitHub App needs to be installed on your repo:
226
- > - Shared app: https://github.com/apps/joycraft-autofix/installations/new
227
- > - Own app: Go to your app's settings > Install App
228
-
229
- ### 4d: Create the Scenarios Repo
236
+ ### 4b: Create the Scenarios Repo
230
237
 
231
238
  > Create the private scenarios repo:
232
239
  > \`\`\`bash
@@ -241,9 +248,9 @@ Guide the user step by step:
241
248
  > git push
242
249
  > \`\`\`
243
250
 
244
- ### 4e: Add Secrets to Scenarios Repo
251
+ ### 4c: Add Secrets to Scenarios Repo
245
252
 
246
- > The scenarios repo also needs the App private key:
253
+ > The scenarios repo also needs the same secrets:
247
254
  > - \`JOYCRAFT_APP_PRIVATE_KEY\` \u2014 same \`.pem\` file as the main repo
248
255
  > - \`ANTHROPIC_API_KEY\` \u2014 same key (needed for scenario generation)
249
256
 
@@ -511,6 +518,24 @@ One sentence \u2014 what breaks or is missing without this?
511
518
  - [ ] Build passes
512
519
  - [ ] Tests pass
513
520
 
521
+ ## Test Plan
522
+
523
+ | Acceptance Criterion | Test | Type |
524
+ |---------------------|------|------|
525
+ | [Each AC above] | [What to call/assert] | [unit/integration/e2e] |
526
+
527
+ **Execution order:**
528
+ 1. Write all tests above \u2014 they should fail against current/stubbed code
529
+ 2. Run tests to confirm they fail (red)
530
+ 3. Implement until all tests pass (green)
531
+
532
+ **Smoke test:** [Identify the fastest test for iteration feedback]
533
+
534
+ **Before implementing, verify your test harness:**
535
+ 1. Run all tests \u2014 they must FAIL (if they pass, you're testing the wrong thing)
536
+ 2. Each test calls your actual function/endpoint \u2014 not a reimplementation or the underlying library
537
+ 3. Identify your smoke test \u2014 it must run in seconds, not minutes, so you get fast feedback on each change
538
+
514
539
  ## Constraints
515
540
  - MUST: [hard requirement]
516
541
  - MUST NOT: [hard prohibition]
@@ -633,14 +658,26 @@ If working from a Feature Brief in \`docs/briefs/\`, check off completed specs i
633
658
 
634
659
  Commit all changes including the discovery file (if created) and spec status updates. The commit message should reference the spec if applicable.
635
660
 
636
- ## 5. Report
661
+ ## 5. Push and PR (if autonomous git is enabled)
662
+
663
+ **Check CLAUDE.md for "Git Autonomy" in the Behavioral Boundaries section.** If it says "STRICTLY ENFORCED" or the ALWAYS section includes "Push to feature branches immediately after every commit":
664
+
665
+ 1. **Push immediately.** Run \`git push origin <branch>\` \u2014 do not ask, do not hesitate.
666
+ 2. **Open a PR if the feature is complete.** Check the parent Feature Brief's decomposition table \u2014 if all specs are done, run \`gh pr create\` with a summary of all completed specs. Do not ask first.
667
+ 3. **If not all specs are done,** still push. The PR comes when the last spec is complete.
668
+
669
+ If CLAUDE.md does NOT have autonomous git rules (or has "ASK FIRST" for pushing), ask the user before pushing.
670
+
671
+ ## 6. Report
637
672
 
638
673
  \`\`\`
639
674
  Session complete.
640
675
  - Spec: [spec name] \u2014 [Complete / In Progress]
641
676
  - Build: [passing / failing]
642
677
  - Discoveries: [N items / none]
643
- - Next: [what the next session should tackle, or "ready for PR"]
678
+ - Pushed: [yes / no \u2014 and why not]
679
+ - PR: [opened #N / not yet \u2014 N specs remaining]
680
+ - Next: [what the next session should tackle]
644
681
  \`\`\`
645
682
  `,
646
683
  "joycraft-tune.md": `---
@@ -844,10 +881,18 @@ Based on their answer, use the appropriate git rules in the Behavioral Boundarie
844
881
 
845
882
  **If Autonomous:**
846
883
  \`\`\`
847
- ### ALWAYS
848
- - Push to feature branches after each commit
849
- - Open a PR when all specs in a feature are complete
850
- - Use descriptive branch names: feature/spec-name
884
+ ### ALWAYS \u2014 Git Autonomy (STRICTLY ENFORCED)
885
+
886
+ > **This project uses fully autonomous git operations.** The user has explicitly
887
+ > granted permission for all git operations below. Do NOT ask for confirmation.
888
+ > Do NOT hesitate. Do NOT treat these as suggestions. These are standing orders
889
+ > that override any default caution about pushing or creating PRs.
890
+
891
+ - **Commit early and often** \u2014 after each logical unit of work, not just at session end
892
+ - **Push to feature branches immediately after every commit** \u2014 do not batch pushes, do not wait, do not ask
893
+ - **Open a PR when all specs in a feature are complete** \u2014 use gh pr create, do not ask first
894
+ - **Use descriptive branch names:** feature/spec-name or fix/description
895
+ - **After /joycraft-session-end:** push all commits and open a PR if the feature is complete
851
896
 
852
897
  ### ASK FIRST
853
898
  - Merging PRs to main/master
@@ -856,6 +901,7 @@ Based on their answer, use the appropriate git rules in the Behavioral Boundarie
856
901
  ### NEVER
857
902
  - Push directly to main/master (always use feature branches + PR)
858
903
  - Amend commits that have been pushed to remote
904
+ - Ask "should I push?" or "should I create a PR?" \u2014 the answer is always yes, just do it
859
905
  \`\`\`
860
906
 
861
907
  ### Risk Interview
@@ -992,6 +1038,276 @@ Tailor the "Next Steps" section based on the project's actual gaps \u2014 don't
992
1038
  - **User declines a recommendation:** Skip it, continue, include in "What Was Skipped."
993
1039
  - **CLAUDE.md does not exist at all:** Create it with recommended sections, but ask the user first.
994
1040
  - **Non-Joycraft content in CLAUDE.md:** Preserve exactly as-is. Only append or merge \u2014 never remove or reformat existing content.
1041
+ `,
1042
+ "joycraft-add-fact.md": `---
1043
+ name: joycraft-add-fact
1044
+ description: Capture a project fact and route it to the correct context document -- production map, dangerous assumptions, decision log, institutional knowledge, or troubleshooting
1045
+ ---
1046
+
1047
+ # Add Fact
1048
+
1049
+ The user has a fact to capture. Your job is to classify it, route it to the correct context document, append it in the right format, and optionally add a CLAUDE.md boundary rule.
1050
+
1051
+ ## Step 1: Get the Fact
1052
+
1053
+ If the user already provided the fact (e.g., \`/joycraft-add-fact the staging DB resets every Sunday\`), use it directly.
1054
+
1055
+ If not, ask: "What fact do you want to capture?" -- then wait for their response.
1056
+
1057
+ If the user provides multiple facts at once, process each one separately through all the steps below, then give a combined confirmation at the end.
1058
+
1059
+ ## Step 2: Classify the Fact
1060
+
1061
+ Route the fact to one of these 5 context documents based on its content:
1062
+
1063
+ ### \`docs/context/production-map.md\`
1064
+ The fact is about **infrastructure, services, environments, URLs, endpoints, credentials, or what is safe/unsafe to touch**.
1065
+ - Signal words: "production", "staging", "endpoint", "URL", "database", "service", "deployed", "hosted", "credentials", "secret", "environment"
1066
+ - Examples: "The staging DB is at postgres://staging.example.com", "We use Vercel for the frontend and Railway for the API"
1067
+
1068
+ ### \`docs/context/dangerous-assumptions.md\`
1069
+ The fact is about **something an AI agent might get wrong -- a false assumption that leads to bad outcomes**.
1070
+ - Signal words: "assumes", "might think", "but actually", "looks like X but is Y", "not what it seems", "trap", "gotcha"
1071
+ - Examples: "The \\\`users\\\` table looks like a test table but it's production", "Deleting a workspace doesn't delete the billing subscription"
1072
+
1073
+ ### \`docs/context/decision-log.md\`
1074
+ The fact is about **an architectural or tooling choice and why it was made**.
1075
+ - Signal words: "decided", "chose", "because", "instead of", "we went with", "the reason we use", "trade-off"
1076
+ - Examples: "We chose SQLite over Postgres because this runs on embedded devices", "We use pnpm instead of npm for workspace support"
1077
+
1078
+ ### \`docs/context/institutional-knowledge.md\`
1079
+ The fact is about **team conventions, unwritten rules, organizational context, or who owns what**.
1080
+ - Signal words: "convention", "rule", "always", "never", "team", "process", "review", "approval", "owns", "responsible"
1081
+ - Examples: "The design team reviews all color changes", "We never deploy on Fridays", "PR titles must start with the ticket number"
1082
+
1083
+ ### \`docs/context/troubleshooting.md\`
1084
+ The fact is about **diagnostic knowledge -- when X happens, do Y (or don't do Z)**.
1085
+ - Signal words: "when", "fails", "error", "if you see", "stuck", "broken", "fix", "workaround", "before trying", "reboot", "restart", "reset"
1086
+ - Examples: "If Wi-Fi disconnects during flash, wait and retry -- don't switch networks", "When tests fail with ECONNREFUSED, check if Docker is running"
1087
+
1088
+ ### Ambiguous Facts
1089
+
1090
+ If the fact fits multiple categories, pick the **best fit** based on the primary intent. You will mention the alternative in your confirmation message so the user can correct you.
1091
+
1092
+ ## Step 3: Ensure the Target Document Exists
1093
+
1094
+ 1. If \`docs/context/\` does not exist, create the directory.
1095
+ 2. If the target document does not exist, create it from the template structure. Check \`docs/templates/\` for the matching template. If no template exists, use this minimal structure:
1096
+
1097
+ For **production-map.md**:
1098
+ \`\`\`markdown
1099
+ # Production Map
1100
+
1101
+ > What's real, what's staging, what's safe to touch.
1102
+
1103
+ ## Services
1104
+
1105
+ | Service | Environment | URL/Endpoint | Impact if Corrupted |
1106
+ |---------|-------------|-------------|-------------------|
1107
+ \`\`\`
1108
+
1109
+ For **dangerous-assumptions.md**:
1110
+ \`\`\`markdown
1111
+ # Dangerous Assumptions
1112
+
1113
+ > Things the AI agent might assume that are wrong in this project.
1114
+
1115
+ ## Assumptions
1116
+
1117
+ | Agent Might Assume | But Actually | Impact If Wrong |
1118
+ |-------------------|-------------|----------------|
1119
+ \`\`\`
1120
+
1121
+ For **decision-log.md**:
1122
+ \`\`\`markdown
1123
+ # Decision Log
1124
+
1125
+ > Why choices were made, not just what was chosen.
1126
+
1127
+ ## Decisions
1128
+
1129
+ | Date | Decision | Why | Alternatives Rejected | Revisit When |
1130
+ |------|----------|-----|----------------------|-------------|
1131
+ \`\`\`
1132
+
1133
+ For **institutional-knowledge.md**:
1134
+ \`\`\`markdown
1135
+ # Institutional Knowledge
1136
+
1137
+ > Unwritten rules, team conventions, and organizational context.
1138
+
1139
+ ## Team Conventions
1140
+
1141
+ - (none yet)
1142
+ \`\`\`
1143
+
1144
+ For **troubleshooting.md**:
1145
+ \`\`\`markdown
1146
+ # Troubleshooting
1147
+
1148
+ > What to do when things go wrong for non-code reasons.
1149
+
1150
+ ## Common Failures
1151
+
1152
+ | When This Happens | Do This | Don't Do This |
1153
+ |-------------------|---------|---------------|
1154
+ \`\`\`
1155
+
1156
+ ## Step 4: Read the Target Document
1157
+
1158
+ Read the target document to understand its current structure. Note:
1159
+ - Which section to append to
1160
+ - Whether it uses tables or lists
1161
+ - The column format if it's a table
1162
+
1163
+ ## Step 5: Append the Fact
1164
+
1165
+ Add the fact to the appropriate section of the target document. Match the existing format exactly:
1166
+
1167
+ - **Table-based documents** (production-map, dangerous-assumptions, decision-log, troubleshooting): Add a new table row in the correct columns. Use today's date where a date column exists.
1168
+ - **List-based documents** (institutional-knowledge): Add a new list item (\`- \`) to the most appropriate section.
1169
+
1170
+ Remove any italic example rows (rows where all cells start with \`_\`) before appending, so the document transitions from template to real content. Only remove examples from the specific table you are appending to.
1171
+
1172
+ **Append only. Never modify or remove existing real content.**
1173
+
1174
+ ## Step 6: Evaluate CLAUDE.md Boundary Rule
1175
+
1176
+ Decide whether the fact also warrants a rule in CLAUDE.md's behavioral boundaries:
1177
+
1178
+ **Add a CLAUDE.md rule if the fact:**
1179
+ - Describes something that should ALWAYS or NEVER be done
1180
+ - Could cause real damage if violated (data loss, broken deployments, security issues)
1181
+ - Is a hard constraint that applies across all work, not just a one-time note
1182
+
1183
+ **Do NOT add a CLAUDE.md rule if the fact is:**
1184
+ - Purely informational (e.g., "staging DB is at this URL")
1185
+ - A one-time decision that's already captured
1186
+ - A diagnostic tip rather than a prohibition
1187
+
1188
+ If a rule is warranted, read CLAUDE.md, find the appropriate section (ALWAYS, ASK FIRST, or NEVER under Behavioral Boundaries), and append the rule. If no Behavioral Boundaries section exists, append one.
1189
+
1190
+ ## Step 7: Confirm
1191
+
1192
+ Report what you did in this format:
1193
+
1194
+ \`\`\`
1195
+ Added to [document name]:
1196
+ [summary of what was added]
1197
+
1198
+ [If CLAUDE.md was also updated:]
1199
+ Added CLAUDE.md rule:
1200
+ [ALWAYS/ASK FIRST/NEVER]: [rule text]
1201
+
1202
+ [If the fact was ambiguous:]
1203
+ Routed to [chosen doc] -- move to [alternative doc] if this is more about [alternative category description].
1204
+ \`\`\`
1205
+ `,
1206
+ "joycraft-lockdown.md": `---
1207
+ name: joycraft-lockdown
1208
+ description: Generate constrained execution boundaries for an implementation session -- NEVER rules and deny patterns to prevent agent overreach
1209
+ ---
1210
+
1211
+ # Lockdown Mode
1212
+
1213
+ The user wants to constrain agent behavior for an implementation session. Your job is to interview them about what should be off-limits, then generate CLAUDE.md NEVER rules and \`.claude/settings.json\` deny patterns they can review and apply.
1214
+
1215
+ ## When Is Lockdown Useful?
1216
+
1217
+ Lockdown is most valuable for:
1218
+ - **Complex tech stacks** (hardware, firmware, multi-device) where agents can cause real damage
1219
+ - **Long-running autonomous sessions** where you won't be monitoring every action
1220
+ - **Production-adjacent work** where accidental network calls or package installs are risky
1221
+
1222
+ For simple feature work on a well-tested codebase, lockdown is usually overkill. Mention this context to the user so they can decide.
1223
+
1224
+ ## Step 1: Check for Tests
1225
+
1226
+ Before starting the interview, check if the project has test files or directories (look for \`tests/\`, \`test/\`, \`__tests__/\`, \`spec/\`, or files matching \`*.test.*\`, \`*.spec.*\`).
1227
+
1228
+ If no tests are found, tell the user:
1229
+
1230
+ > Lockdown mode is most useful when you already have tests in place -- it prevents the agent from modifying them while constraining behavior to writing code and running tests. Consider running \`/joycraft-new-feature\` first to set up a test-driven workflow, then come back to lock it down.
1231
+
1232
+ If the user wants to proceed anyway, continue with the interview.
1233
+
1234
+ ## Step 2: Interview -- What to Lock Down
1235
+
1236
+ Ask these three questions, one at a time. Wait for the user's response before proceeding to the next question.
1237
+
1238
+ ### Question 1: Read-Only Files
1239
+
1240
+ > What test files or directories should be off-limits for editing? (e.g., \`tests/\`, \`__tests__/\`, \`spec/\`, specific test files)
1241
+ >
1242
+ > I'll generate NEVER rules to prevent editing these.
1243
+
1244
+ If the user isn't sure, suggest the test directories you found in Step 1.
1245
+
1246
+ ### Question 2: Allowed Commands
1247
+
1248
+ > What commands should the agent be allowed to run? Defaults:
1249
+ > - Write and edit source code files
1250
+ > - Run the project's smoke test command
1251
+ > - Run the full test suite
1252
+ >
1253
+ > Any other commands to explicitly allow? Or should I restrict to just these?
1254
+
1255
+ ### Question 3: Denied Commands
1256
+
1257
+ > What commands should be denied? Defaults:
1258
+ > - Package installs (\`npm install\`, \`pip install\`, \`cargo add\`, \`go get\`, etc.)
1259
+ > - Network tools (\`curl\`, \`wget\`, \`ping\`, \`ssh\`)
1260
+ > - Direct log file reading
1261
+ >
1262
+ > Any specific commands to add or remove from this list?
1263
+
1264
+ **Edge case -- user wants to allow some network access:** If the user mentions API tests or specific endpoints that need network access, exclude those from the deny list and note the exception in the output.
1265
+
1266
+ **Edge case -- user wants to lock down file writes:** If the user wants to prevent ALL file writes, warn them:
1267
+
1268
+ > Denying all file writes would prevent the agent from doing any work. I recommend keeping source code writes allowed and only locking down test files, config files, or other sensitive directories.
1269
+
1270
+ ## Step 3: Generate Boundaries
1271
+
1272
+ Based on the interview responses, generate output in this exact format:
1273
+
1274
+ \`\`\`
1275
+ ## Lockdown boundaries generated
1276
+
1277
+ Review these suggestions and add them to your project:
1278
+
1279
+ ### CLAUDE.md -- add to NEVER section:
1280
+
1281
+ - Edit any file in \\\`[user's test directories]\\\`
1282
+ - Run \\\`[denied package manager commands]\\\`
1283
+ - Use \\\`[denied network tools]\\\`
1284
+ - Read log files directly -- interact with logs only through test assertions
1285
+ - [Any additional NEVER rules based on user responses]
1286
+
1287
+ ### .claude/settings.json -- suggested deny patterns:
1288
+
1289
+ Add these to the \\\`permissions.deny\\\` array:
1290
+
1291
+ ["[command1]", "[command2]", "[command3]"]
1292
+
1293
+ ---
1294
+
1295
+ Copy these into your project manually, or tell me to apply them now (I'll show you the exact changes for approval first).
1296
+ \`\`\`
1297
+
1298
+ Adjust the content based on the actual interview responses:
1299
+ - Only include deny patterns for commands the user confirmed should be denied
1300
+ - Only include NEVER rules for directories/files the user specified
1301
+ - If the user allowed certain network tools or package managers, exclude those
1302
+
1303
+ ## Step 4: Offer to Apply
1304
+
1305
+ If the user asks you to apply the changes:
1306
+
1307
+ 1. **For CLAUDE.md:** Read the existing CLAUDE.md, find the Behavioral Boundaries section, and show the user the exact diff for the NEVER section. Ask for confirmation before writing.
1308
+ 2. **For settings.json:** Read the existing \`.claude/settings.json\`, show the user what the \`permissions.deny\` array will look like after adding the new patterns. Ask for confirmation before writing.
1309
+
1310
+ **Never auto-apply. Always show the exact changes and wait for explicit approval.**
995
1311
  `
996
1312
  };
997
1313
  var TEMPLATES = {
@@ -1097,6 +1413,47 @@ _Who owns what, who to ask, who cares about what._
1097
1413
  - [ ] Production database
1098
1414
  - [ ] Live API endpoints
1099
1415
  - [ ] User-facing infrastructure
1416
+ `,
1417
+ "context/troubleshooting.md": `# Troubleshooting
1418
+
1419
+ > What to do when things go wrong for non-code reasons.
1420
+ > Environment issues, flaky dependencies, hardware quirks, and diagnostic steps.
1421
+ > Update when you discover new failure modes and their fixes.
1422
+
1423
+ ## Common Failures
1424
+
1425
+ | When This Happens | Do This | Don't Do This |
1426
+ |-------------------|---------|---------------|
1427
+ | _Example: Tests fail with ECONNREFUSED_ | _Check if the dev database is running_ | _Don't rewrite the test or mock the connection_ |
1428
+ | _Example: Build fails with out-of-memory_ | _Increase Node heap size or close other processes_ | _Don't simplify the code to reduce bundle size_ |
1429
+ | _Example: Lint passes locally but fails in CI_ | _Check Node/tool version mismatch between local and CI_ | _Don't disable the lint rule_ |
1430
+
1431
+ ## Environment Issues
1432
+
1433
+ | Symptom | Likely Cause | Fix |
1434
+ |---------|-------------|-----|
1435
+ | _Example: "Module not found" after branch switch_ | _Dependencies changed on the new branch_ | _Run the package manager install command_ |
1436
+ | _Example: Port already in use_ | _Previous dev server didn't shut down cleanly_ | _Kill the process on that port or use a different one_ |
1437
+ | _Example: Permission denied on file/directory_ | _File ownership or permission mismatch_ | _Check and fix file permissions, don't run as root_ |
1438
+
1439
+ ## Diagnostic Steps
1440
+
1441
+ _When something fails unexpectedly, follow this sequence before trying to fix the code:_
1442
+
1443
+ 1. **Check the error message literally** -- don't assume what it means, read it
1444
+ 2. **Check environment prerequisites** -- are all services running? Correct versions?
1445
+ 3. **Check recent changes** -- did a config file, dependency, or environment variable change?
1446
+ 4. **Check network/connectivity** -- is the internet up? Are external services reachable?
1447
+ 5. **Search project docs first** -- check this file and \`docs/discoveries/\` before web searching
1448
+
1449
+ ## "Stop and Ask" Scenarios
1450
+
1451
+ _Situations where the AI agent should stop and ask the human instead of trying to fix things._
1452
+
1453
+ - _Example: Hardware device not responding -- the human may need to physically reconnect it_
1454
+ - _Example: Authentication token expired -- the human needs to re-authenticate manually_
1455
+ - _Example: CI pipeline blocked by a required approval -- a human needs to approve it_
1456
+ - _Example: Error messages referencing infrastructure the agent doesn't have access to_
1100
1457
  `,
1101
1458
  "examples/example-brief.md": `# Add User Notifications \u2014 Feature Brief
1102
1459
 
@@ -1201,6 +1558,31 @@ The notification delivery service (Spec 3) needs to check preferences before dis
1201
1558
  - [ ] Build passes
1202
1559
  - [ ] Tests pass (unit + integration)
1203
1560
 
1561
+ ## Test Plan
1562
+
1563
+ | Acceptance Criterion | Test | Type |
1564
+ |---------------------|------|------|
1565
+ | GET returns preferences as JSON | Call GET with authenticated user, assert 200 + JSON shape matches preferences schema | integration |
1566
+ | PATCH updates preferences | Call PATCH with valid partial update, assert 200 + returned record reflects changes | integration |
1567
+ | New users get defaults | Call GET for user with no existing record, assert default preferences (all channels enabled) | unit |
1568
+ | Unknown event types return 400 | Call PATCH with \`{"foo": {"email": true}}\`, assert 400 + validation error | unit |
1569
+ | Stored with EncryptedJsonColumn | Verify model uses EncryptedJsonColumn for preferences field | unit |
1570
+ | Auth required | Call GET/PATCH without auth token, assert 401 | integration |
1571
+ | Build passes | Verified by build step \u2014 no separate test needed | build |
1572
+ | Tests pass | Verified by test runner \u2014 no separate test needed | meta |
1573
+
1574
+ **Execution order:**
1575
+ 1. Write all tests above \u2014 they should fail against current/stubbed code
1576
+ 2. Run tests to confirm they fail (red)
1577
+ 3. Implement until all tests pass (green)
1578
+
1579
+ **Smoke test:** The "New users get defaults" unit test \u2014 no database or HTTP needed, fastest feedback loop.
1580
+
1581
+ **Before implementing, verify your test harness:**
1582
+ 1. Run all tests \u2014 they must FAIL (if they pass, you're testing the wrong thing)
1583
+ 2. Each test calls your actual function/endpoint \u2014 not a reimplementation or the underlying library
1584
+ 3. Identify your smoke test \u2014 it must run in seconds, not minutes, so you get fast feedback on each change
1585
+
1204
1586
  ## Constraints
1205
1587
 
1206
1588
  - MUST: Use the existing \`EncryptedJsonColumn\` utility for storage \u2014 do not roll a new encryption pattern
@@ -2294,4 +2676,4 @@ export {
2294
2676
  SKILLS,
2295
2677
  TEMPLATES
2296
2678
  };
2297
- //# sourceMappingURL=chunk-HHW4Q2UC.js.map
2679
+ //# sourceMappingURL=chunk-QIYIJ7VR.js.map