tracerkit 1.12.0 → 1.13.1

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.
package/README.md CHANGED
@@ -94,14 +94,14 @@ See [Examples](docs/examples.md) for full walkthroughs.
94
94
  <details>
95
95
  <summary>GitHub Issues as storage backend</summary>
96
96
 
97
- Same skills, same workflow. Artifacts live in GitHub Issues instead of local files:
97
+ Same skills, same workflow. Storage is configured per-project:
98
98
 
99
99
  ```bash
100
- tracerkit init --storage github # first install
100
+ tracerkit config storage github # set current project to use GitHub
101
101
  tracerkit config github.repo org/repo # set target repo
102
102
  ```
103
103
 
104
- PRDs and plans become GitHub Issues with `tk:prd` and `tk:plan` labels. On `/tk:check` pass, issues are closed instead of archived locally. See [Configuration](docs/configuration.md) for details.
104
+ PRDs and plans become GitHub Issues with `tk:prd` and `tk:plan` labels. On `/tk:check` pass, issues are closed instead of archived locally. Each project can use a different backend; local is the default. See [Configuration](docs/configuration.md) for details.
105
105
 
106
106
  </details>
107
107
 
@@ -140,7 +140,7 @@ Without arguments, shows a feature dashboard with status and progress before ask
140
140
  | Document | Description |
141
141
  | ------------------------------------------------ | -------------------------------------------------- |
142
142
  | [Examples](docs/examples.md) | Walk through end-to-end usage scenarios |
143
- | [CLI Reference](docs/cli-reference.md) | Lifecycle commands: init, update, uninstall |
143
+ | [CLI Reference](docs/cli-reference.md) | Commands: init, update, config, uninstall |
144
144
  | [Configuration](docs/configuration.md) | Storage backends, GitHub options, custom paths |
145
145
  | [Metadata Lifecycle](docs/metadata-lifecycle.md) | Understand YAML frontmatter states and transitions |
146
146
  | [Comparison](docs/comparison.md) | Compare TracerKit to Spec Kit, Kiro, and OpenSpec |
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, r as c, t as l } from "./uninstall-BkaWoWd0.js";
2
+ import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, r as c, t as l } from "./uninstall-9tiXr-15.js";
3
3
  import { existsSync as u, readFileSync as d, statSync as f } from "node:fs";
4
4
  import { dirname as p, join as m, resolve as h } from "node:path";
5
5
  import { fileURLToPath as g } from "node:url";
@@ -54,11 +54,11 @@ var { version: T } = JSON.parse(d(h(p(g(import.meta.url)), "..", "package.json")
54
54
  "",
55
55
  "Options:",
56
56
  " --force Overwrite modified files during update",
57
- " --storage <type> Set storage (local, github) during init",
58
57
  " --help, -h Show this help message",
59
58
  " --version, -v Print version",
60
59
  "",
61
- "All commands default to the home directory when no path is given."
60
+ "init/update/uninstall default to the home directory when no path is given.",
61
+ "config defaults to the current working directory."
62
62
  ];
63
63
  function O(e) {
64
64
  if (!e) return !1;
@@ -78,17 +78,14 @@ function A(e) {
78
78
  let n = e[0], r = e.slice(1);
79
79
  if (s.includes(n)) return [`"${n}" has been removed — skills handle this now.`, "Run `tracerkit update` to get the latest skills."];
80
80
  switch (n) {
81
- case "init": {
82
- let e = r.indexOf(t.storage), n = e >= 0 ? r[e + 1] : void 0;
83
- return o(k(e >= 0 ? r.filter((t, n) => n !== e && n !== e + 1) : r), { storage: n });
84
- }
81
+ case "init": return o(k(r));
85
82
  case "update": {
86
83
  let e = r.includes(t.force), n = c(k(r.filter((e) => e !== t.force)), { force: e });
87
84
  return n.push("", "Updated to the latest TracerKit."), n.push("If using Claude Code, restart your session to load changes."), n;
88
85
  }
89
86
  case "config": {
90
- let e = O(r[0]) ? h(r[0]) : _();
91
- return v(e, e === _() ? r : r.slice(1));
87
+ let e = O(r[0]);
88
+ return v(e ? h(r[0]) : process.cwd(), e ? r.slice(1) : r);
92
89
  }
93
90
  case "uninstall": return l(k(r));
94
91
  default: return D;
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as e, l as t, n, r, s as i, t as a } from "./uninstall-BkaWoWd0.js";
1
+ import { a as e, l as t, n, r, s as i, t as a } from "./uninstall-9tiXr-15.js";
2
2
  export { e as COMMANDS, i as DEPRECATED_SKILLS, t as SKILL_NAMES, n as init, a as uninstall, r as update };
@@ -3,20 +3,20 @@ import { dirname as o, join as s } from "node:path";
3
3
  import { createHash as c } from "node:crypto";
4
4
  import { fileURLToPath as l } from "node:url";
5
5
  //#region src/config.ts
6
- var u = "local", d = "github", f = [u, d], p = {
6
+ var u = "local", d = [u, "github"], f = {
7
7
  prds: ".tracerkit/prds",
8
8
  plans: ".tracerkit/plans",
9
9
  archives: ".tracerkit/archives"
10
- }, m = { labels: {
10
+ }, p = { labels: {
11
11
  prd: "tk:prd",
12
12
  plan: "tk:plan"
13
13
  } };
14
- function h(t) {
14
+ function m(t) {
15
15
  let r = s(t, ".tracerkit", "config.json");
16
16
  if (!e(r)) return {
17
17
  storage: u,
18
- paths: { ...p },
19
- github: { ...m }
18
+ paths: { ...f },
19
+ github: { ...p }
20
20
  };
21
21
  let i;
22
22
  try {
@@ -25,33 +25,33 @@ function h(t) {
25
25
  throw Error("Invalid .tracerkit/config.json — expected valid JSON");
26
26
  }
27
27
  return {
28
- storage: g(i.storage),
29
- paths: _(i.paths),
30
- github: v(i.github)
28
+ storage: h(i.storage),
29
+ paths: g(i.paths),
30
+ github: _(i.github)
31
31
  };
32
32
  }
33
- function g(e) {
34
- return typeof e == "string" && f.includes(e) ? e : u;
33
+ function h(e) {
34
+ return typeof e == "string" && d.includes(e) ? e : u;
35
35
  }
36
- function _(e) {
37
- let t = x(e) ? e : {};
36
+ function g(e) {
37
+ let t = b(e) ? e : {};
38
38
  return {
39
- prds: typeof t.prds == "string" ? t.prds : p.prds,
40
- plans: typeof t.plans == "string" ? t.plans : p.plans,
41
- archives: typeof t.archives == "string" ? t.archives : p.archives
39
+ prds: typeof t.prds == "string" ? t.prds : f.prds,
40
+ plans: typeof t.plans == "string" ? t.plans : f.plans,
41
+ archives: typeof t.archives == "string" ? t.archives : f.archives
42
42
  };
43
43
  }
44
- function v(e) {
45
- let t = x(e) ? e : {}, n = x(t.labels) ? t.labels : {};
44
+ function _(e) {
45
+ let t = b(e) ? e : {}, n = b(t.labels) ? t.labels : {};
46
46
  return {
47
47
  ...typeof t.repo == "string" ? { repo: t.repo } : {},
48
48
  labels: {
49
- prd: typeof n.prd == "string" ? n.prd : m.labels.prd,
50
- plan: typeof n.plan == "string" ? n.plan : m.labels.plan
49
+ prd: typeof n.prd == "string" ? n.prd : p.labels.prd,
50
+ plan: typeof n.plan == "string" ? n.plan : p.labels.plan
51
51
  }
52
52
  };
53
53
  }
54
- function y(r, i) {
54
+ function v(r, i) {
55
55
  let c = s(r, ".tracerkit", "config.json");
56
56
  t(o(c), { recursive: !0 });
57
57
  let l = {};
@@ -60,32 +60,31 @@ function y(r, i) {
60
60
  } catch {
61
61
  l = {};
62
62
  }
63
- let u = b(l, i);
63
+ let u = y(l, i);
64
64
  a(c, JSON.stringify(u, null, 2) + "\n");
65
65
  }
66
- function b(e, t) {
66
+ function y(e, t) {
67
67
  let n = { ...e };
68
- for (let e of Object.keys(t)) x(n[e]) && x(t[e]) ? n[e] = b(n[e], t[e]) : n[e] = t[e];
68
+ for (let e of Object.keys(t)) b(n[e]) && b(t[e]) ? n[e] = y(n[e], t[e]) : n[e] = t[e];
69
69
  return n;
70
70
  }
71
- function x(e) {
71
+ function b(e) {
72
72
  return typeof e == "object" && !!e && !Array.isArray(e);
73
73
  }
74
- var S = [
74
+ var x = [
75
75
  "tk:brief",
76
76
  "tk:prd",
77
77
  "tk:plan",
78
78
  "tk:check"
79
- ], C = ["tk:verify"], w = {
79
+ ], S = ["tk:verify"], C = {
80
80
  force: "--force",
81
81
  help: "--help",
82
- storage: "--storage",
83
82
  version: "--version"
84
- }, T = [
83
+ }, w = [
85
84
  "brief",
86
85
  "progress",
87
86
  "archive"
88
- ], E = [
87
+ ], T = [
89
88
  {
90
89
  name: "init",
91
90
  args: "[path]",
@@ -106,46 +105,44 @@ var S = [
106
105
  args: "[path]",
107
106
  desc: "Remove TracerKit skill directories, keep .tracerkit/ artifacts"
108
107
  }
109
- ], D = s(o(l(import.meta.url)), "..", "skills");
110
- function O(e, t = "") {
108
+ ], E = s(o(l(import.meta.url)), "..", "skills");
109
+ function D(e, t = "") {
111
110
  let n = r(e, { withFileTypes: !0 }), i = [];
112
111
  for (let r of n) {
113
112
  let n = t ? `${t}/${r.name}` : r.name;
114
- r.isDirectory() ? i.push(...O(s(e, r.name), n)) : i.push(n);
113
+ r.isDirectory() ? i.push(...D(s(e, r.name), n)) : i.push(n);
115
114
  }
116
115
  return i.sort();
117
116
  }
118
- function k(e) {
117
+ function O(e) {
119
118
  return `.claude/skills/tk:${e}`;
120
119
  }
121
- function A(e) {
120
+ function k(e) {
122
121
  return e.slice(18);
123
122
  }
124
- function j(e, t) {
123
+ function A(e, t) {
125
124
  let n = e;
126
- t.paths.prds !== p.prds && (n = n.replaceAll(p.prds, t.paths.prds)), t.paths.plans !== p.plans && (n = n.replaceAll(p.plans, t.paths.plans)), t.paths.archives !== p.archives && (n = n.replaceAll(p.archives, t.paths.archives));
127
- let r = t.storage ?? "local", i = r === "local" ? d : u;
128
- return n = n.replace(RegExp(`<!-- if:${i} -->[^\\S\\n]*\\n[\\s\\S]*?<!-- end:${i} -->[^\\S\\n]*\\n?`, "g"), ""), n = n.replace(RegExp(`<!-- if:${r} -->[^\\S\\n]*\\n`, "g"), ""), n = n.replace(RegExp(`<!-- end:${r} -->[^\\S\\n]*\\n?`, "g"), ""), t.github?.repo && (n = n.replaceAll("{{github.repo}}", t.github.repo)), t.github?.labels?.prd && (n = n.replaceAll("{{github.labels.prd}}", t.github.labels.prd)), t.github?.labels?.plan && (n = n.replaceAll("{{github.labels.plan}}", t.github.labels.plan)), n;
125
+ return t.paths.prds !== f.prds && (n = n.replaceAll(f.prds, t.paths.prds)), t.paths.plans !== f.plans && (n = n.replaceAll(f.plans, t.paths.plans)), t.paths.archives !== f.archives && (n = n.replaceAll(f.archives, t.paths.archives)), t.github?.repo && (n = n.replaceAll("{{github.repo}}", t.github.repo)), t.github?.labels?.prd && (n = n.replaceAll("{{github.labels.prd}}", t.github.labels.prd)), t.github?.labels?.plan && (n = n.replaceAll("{{github.labels.plan}}", t.github.labels.plan)), n;
129
126
  }
130
- function M(e, r, i) {
131
- let c = i ?? O(D).map(k);
127
+ function j(e, r, i) {
128
+ let c = i ?? D(E).map(O);
132
129
  for (let i of c) {
133
- let c = s(D, A(i)), l = s(e, i);
134
- t(o(l), { recursive: !0 }), a(l, j(n(c, "utf8"), r));
130
+ let c = s(E, k(i)), l = s(e, i);
131
+ t(o(l), { recursive: !0 }), a(l, A(n(c, "utf8"), r));
135
132
  }
136
133
  return { copied: c };
137
134
  }
138
- function N(e) {
135
+ function M(e) {
139
136
  return c("sha256").update(e).digest("hex");
140
137
  }
141
- function P(t, r) {
142
- let i = O(D).map(k), a = [], o = [], c = [];
138
+ function N(t, r) {
139
+ let i = D(E).map(O), a = [], o = [], c = [];
143
140
  for (let l of i) {
144
141
  let i = s(t, l);
145
142
  if (!e(i)) c.push(l);
146
143
  else {
147
- let e = j(n(s(D, A(l)), "utf8"), r);
148
- N(Buffer.from(e)) === N(n(i)) ? a.push(l) : o.push(l);
144
+ let e = A(n(s(E, k(l)), "utf8"), r);
145
+ M(Buffer.from(e)) === M(n(i)) ? a.push(l) : o.push(l);
149
146
  }
150
147
  }
151
148
  return {
@@ -156,10 +153,10 @@ function P(t, r) {
156
153
  }
157
154
  //#endregion
158
155
  //#region src/commands/update.ts
159
- function F(t, n) {
160
- if (!S.some((n) => e(s(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — run `tracerkit init` first");
161
- let r = h(t), { unchanged: a, modified: o, missing: c } = P(t, r), l = [];
162
- for (let n of C) {
156
+ function P(t, n) {
157
+ if (!x.some((n) => e(s(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — run `tracerkit init` first");
158
+ let r = m(t), { unchanged: a, modified: o, missing: c } = N(t, r), l = [];
159
+ for (let n of S) {
163
160
  let r = s(t, ".claude", "skills", n);
164
161
  e(r) && (i(r, {
165
162
  recursive: !0,
@@ -172,7 +169,7 @@ function F(t, n) {
172
169
  ...u ? o : []
173
170
  ];
174
171
  if (d.length > 0) {
175
- M(t, r, d);
172
+ j(t, r, d);
176
173
  for (let e of a) l.push(`✓ ${e}`);
177
174
  for (let e of c) l.push(`✓ ${e} (added)`);
178
175
  if (u) for (let e of o) l.push(`✓ ${e} (replaced)`);
@@ -185,18 +182,17 @@ function F(t, n) {
185
182
  }
186
183
  //#endregion
187
184
  //#region src/commands/init.ts
188
- function I(t, n) {
189
- let r = h(t), i = n?.storage && n.storage !== r.storage;
190
- if (i && y(t, { storage: n.storage }), S.some((n) => e(s(t, ".claude", "skills", n)))) return F(t, { force: !!i });
191
- let { copied: a } = M(t, h(t));
192
- return a.map((e) => `✓ ${e}`);
185
+ function F(t) {
186
+ if (x.some((n) => e(s(t, ".claude", "skills", n)))) return P(t, { force: !1 });
187
+ let { copied: n } = j(t, m(t));
188
+ return n.map((e) => `✓ ${e}`);
193
189
  }
194
190
  //#endregion
195
191
  //#region src/commands/uninstall.ts
196
- function L(t) {
197
- if (!S.some((n) => e(s(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — nothing to uninstall");
192
+ function I(t) {
193
+ if (!x.some((n) => e(s(t, ".claude", "skills", n)))) throw Error("TracerKit not initialized — nothing to uninstall");
198
194
  let n = [];
199
- for (let r of S) {
195
+ for (let r of x) {
200
196
  let a = s(t, ".claude", "skills", r);
201
197
  e(a) && (i(a, {
202
198
  recursive: !0,
@@ -206,4 +202,4 @@ function L(t) {
206
202
  return n;
207
203
  }
208
204
  //#endregion
209
- export { E as a, w as c, h as d, y as f, M as i, S as l, I as n, T as o, F as r, C as s, L as t, u };
205
+ export { T as a, C as c, m as d, v as f, j as i, x as l, F as n, w as o, P as r, S as s, I as t, u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tracerkit",
3
- "version": "1.12.0",
3
+ "version": "1.13.1",
4
4
  "description": "Spec-driven workflow for Claude Code: replace ad-hoc prompts with PRD → plan → verify.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -2,9 +2,11 @@
2
2
  description: Session briefing — shows active features, progress, and suggested focus. Use at the start of a session to orient.
3
3
  ---
4
4
 
5
+ **Config**: read `.tracerkit/config.json` (default: `local`). Follow matching `<!-- if:local/github -->` blocks. GitHub: use `github.repo` from config or git remote.
6
+
5
7
  # Session Briefing
6
8
 
7
- Get a quick overview of all active features, their progress, and what to focus on next.
9
+ Overview of active features, progress, and suggested focus.
8
10
 
9
11
  ## Pre-loaded context
10
12
 
@@ -18,23 +20,16 @@ Get a quick overview of all active features, their progress, and what to focus o
18
20
 
19
21
  ## Algorithm
20
22
 
21
- Follow these steps exactly to build the briefing table:
22
-
23
23
  ### 1. Discover features
24
24
 
25
25
  <!-- if:local -->
26
26
 
27
- For each `.md` file in `.tracerkit/prds/`:
27
+ For each `.md` file in `.tracerkit/prds/`: parse frontmatter, extract `status` and `created`. Skip `status: done`. Slug = filename without `.md`.
28
28
 
29
- 1. Read the file
30
- 2. Parse YAML frontmatter (the block between `---` fences at the top)
31
- 3. Extract `status` and `created` fields
32
- 4. Skip files where `status: done`
33
- 5. The slug is the filename without `.md`
34
29
  <!-- end:local -->
35
30
  <!-- if:github -->
36
31
 
37
- List open GitHub Issues with label `{{github.labels.prd}}`:
32
+ List open GitHub Issues with label `{{github.labels.prd}}`:
38
33
 
39
34
  6. For each issue, parse the `<!-- tk:metadata -->` comment in the body
40
35
  7. Extract `status` and `created` fields from the metadata
@@ -47,38 +42,22 @@ For each `.md` file in `.tracerkit/prds/`:
47
42
 
48
43
  <!-- if:local -->
49
44
 
50
- For each slug, check if `.tracerkit/plans/<slug>.md` exists. If it does:
51
-
52
- 1. Read the plan file
53
- 2. Find every `## Phase N` heading (regex: `^## Phase \d+`)
54
- 3. Within each phase section (until the next `## ` heading), count:
55
- - Checked items: lines matching `^- \[x\] ` (case-insensitive)
56
- - Unchecked items: lines matching `^- \[ \] `
57
- 4. Sum checked and total across all phases → `checked/total`
58
- 5. Find the first unchecked item (`^- \[ \] (.+)`) in the entire plan — that's the "Next" value. Strip any trailing `[tag]` markers.
45
+ For each slug with a plan at `.tracerkit/plans/<slug>.md`:
59
46
 
60
- If no plan exists, progress is `—` and next is `—`.
47
+ Count `- [x]` and `- [ ]` lines under each `## Phase N` heading. Sum → `checked/total`. First unchecked item → "Next" (strip trailing `[tag]`). No plan → `—`.
61
48
 
62
49
  <!-- end:local -->
63
50
  <!-- if:github -->
64
51
 
65
- For each slug, search for a GitHub Issue with label `{{github.labels.plan}}` and title matching `[{{github.labels.plan}}] <slug>:`. If found:
52
+ For each slug, find plan issue with label `{{github.labels.plan}}` and matching title. If found:
66
53
 
67
- 1. Read the plan issue body
68
- 2. Find every `## Phase N` heading (regex: `^## Phase \d+`)
69
- 3. Within each phase section (until the next `## ` heading), count:
70
- - Checked items: lines matching `^- \[x\] ` (case-insensitive)
71
- - Unchecked items: lines matching `^- \[ \] `
72
- 4. Sum checked and total across all phases → `checked/total`
73
- 5. Find the first unchecked item (`^- \[ \] (.+)`) in the entire plan — that's the "Next" value. Strip any trailing `[tag]` markers.
74
-
75
- If no plan issue exists, progress is `—` and next is `—`.
54
+ Count `- [x]` and `- [ ]` lines under each `## Phase N` heading. Sum `checked/total`. First unchecked item → "Next" (strip trailing `[tag]`). No plan `—`.
76
55
 
77
56
  <!-- end:github -->
78
57
 
79
58
  ### 3. Build the table
80
59
 
81
- Sort features by `created` date ascending (no-date entries last). Calculate age from `created`:
60
+ Sort by `created` ascending (no-date last). Age from `created`:
82
61
 
83
62
  - < 7 days → `Nd` (e.g. `3d`)
84
63
  - < 30 days → `Nw` (e.g. `2w`)
@@ -110,14 +89,13 @@ Append below the table:
110
89
 
111
90
  ### 5. Offer next steps
112
91
 
113
- Ask the user what they'd like to do:
114
-
115
92
  <!-- if:local -->
116
93
 
117
- - Continue the focused feature (read its plan at `.tracerkit/plans/<slug>.md`)
118
- <!-- end:local -->
119
- <!-- if:github -->
120
- - Continue the focused feature (read its plan issue)
94
+ Options: continue focused feature (read plan at `.tracerkit/plans/<slug>.md`), `/tk:prd` for new feature, `/tk:check <slug>` for progress.
95
+
96
+ <!-- end:local -->
97
+ <!-- if:github -->
98
+
99
+ Options: continue focused feature (read plan issue), `/tk:prd` for new feature, `/tk:check <slug>` for progress.
100
+
121
101
  <!-- end:github -->
122
- - Start a new feature with `/tk:prd`
123
- - Check progress on a feature with `/tk:check <slug>`
@@ -3,6 +3,8 @@ description: Verify implementation against plan. Shows progress, finds blockers,
3
3
  argument-hint: '[slug]'
4
4
  ---
5
5
 
6
+ **Config**: read `.tracerkit/config.json` (default: `local`). Follow matching `<!-- if:local/github -->` blocks. GitHub: use `github.repo` from config or git remote.
7
+
6
8
  # Check Implementation
7
9
 
8
10
  Check implementation against a plan. Update checks, stamp findings, transition status, and archive when done.
@@ -48,18 +50,11 @@ For each `.md` file in `.tracerkit/prds/`:
48
50
  6. If plan issue exists, count progress from checkboxes in its body (see Progress Algorithm below). Show `—` if no plan.
49
51
  <!-- end:github -->
50
52
 
51
- After the table, ask which feature to verify.
53
+ Ask which feature to verify.
52
54
 
53
55
  ## Progress Algorithm
54
56
 
55
- To count progress for a plan file:
56
-
57
- 1. Find every `## Phase N` heading (regex: `^## Phase \d+`)
58
- 2. Within each phase section (until the next `## ` heading), count:
59
- - Checked: lines matching `^- \[x\] ` (case-insensitive)
60
- - Unchecked: lines matching `^- \[ \] `
61
- 3. Per-phase output: ` Phase N — title: checked/total`
62
- 4. Sum across all phases → `Total: checked/total`
57
+ Count `- [x]` and `- [ ]` lines under each `## Phase N` heading. Per-phase: `Phase N — title: checked/total`. Sum → `Total: checked/total`.
63
58
 
64
59
  ## Workflow
65
60
 
@@ -67,12 +62,12 @@ To count progress for a plan file:
67
62
 
68
63
  <!-- if:local -->
69
64
 
70
- Read `.tracerkit/plans/<slug>.md`. If it does not exist, list available plans and ask.
65
+ Read `.tracerkit/plans/<slug>.md`. If missing, list plans and ask.
71
66
 
72
67
  <!-- end:local -->
73
68
  <!-- if:github -->
74
69
 
75
- Find the plan issue: search for an open GitHub Issue with label `{{github.labels.plan}}` and title matching `[{{github.labels.plan}}] <slug>:`. Read its body. If not found, list available plan issues and ask.
70
+ Find plan issue: open issue with label `{{github.labels.plan}}`, title matching `[{{github.labels.plan}}] <slug>:`. If missing, list plans and ask.
76
71
 
77
72
  <!-- end:github -->
78
73
 
@@ -80,18 +75,18 @@ Find the plan issue: search for an open GitHub Issue with label `{{github.labels
80
75
 
81
76
  <!-- if:local -->
82
77
 
83
- Read the source PRD referenced in the plan header (`> Source PRD: ...`).
78
+ Read source PRD referenced in plan header (`> Source PRD: ...`).
84
79
 
85
80
  <!-- end:local -->
86
81
  <!-- if:github -->
87
82
 
88
- Read the source PRD issue referenced in the plan body (`> Source PRD: #<number>`).
83
+ Read source PRD issue referenced in plan body (`> Source PRD: #<number>`).
89
84
 
90
85
  <!-- end:github -->
91
86
 
92
87
  ### 3. Fast-path: check if implementation exists
93
88
 
94
- Before launching a subagent, check whether the primary module file(s) from Phase 1 exist. If none exist, skip the subagent entirely and report `0/N — not yet started`. List Phase 1's "Done when" items as next steps and jump to Step 5.
89
+ If primary module file(s) from Phase 1 don't exist, skip subagent report `0/N — not yet started`, list Phase 1 done-when items, jump to Step 5.
95
90
 
96
91
  ### 3b. Launch read-only review
97
92
 
@@ -132,7 +127,7 @@ Based on checks and findings, decide the status transition:
132
127
 
133
128
  ### 5. Report to user
134
129
 
135
- Count progress per phase using the Progress Algorithm above, then print the verdict report:
130
+ Count progress per phase (Progress Algorithm), then print:
136
131
 
137
132
  ```markdown
138
133
  ## Verification: <slug>
@@ -186,35 +181,19 @@ If all checks pass and zero BLOCKERS:
186
181
 
187
182
  <!-- if:local -->
188
183
 
189
- Perform these steps in order:
190
-
191
- 1. Create directory `.tracerkit/archives/<slug>/`
192
- 2. If `.tracerkit/prds/<slug>.md` exists:
193
- - Read the PRD file
194
- - In the YAML frontmatter (between `---` fences), find the `status:` line and replace its value with `done`. If no `status:` line exists, add `status: done` as a new line inside the frontmatter block.
195
- - Add a `completed: <current UTC ISO 8601 timestamp>` line inside the frontmatter block (e.g. `completed: 2025-06-15T14:30:00Z`)
196
- - Write the updated content to `.tracerkit/archives/<slug>/prd.md`
197
- 3. Read `.tracerkit/plans/<slug>.md`
198
- - Append to the end: `\n## Archived\n\nArchived on YYYY-MM-DD.\n`
199
- - Write the result to `.tracerkit/archives/<slug>/plan.md`
200
- 4. Delete `.tracerkit/prds/<slug>.md` (if it exists)
201
- 5. Delete `.tracerkit/plans/<slug>.md`
184
+ Archive to `.tracerkit/archives/<slug>/`:
202
185
 
203
- Tell the user: archived to `.tracerkit/archives/<slug>/`, one-line summary of the feature.
186
+ 1. Copy PRD `prd.md` (set `status: done`, add `completed` timestamp in frontmatter)
187
+ 2. Copy plan → `plan.md` (append `## Archived` with date)
188
+ 3. Delete originals
204
189
 
205
190
  <!-- end:local -->
206
191
  <!-- if:github -->
207
192
 
208
- Perform these steps in order:
209
-
210
- 1. Update the PRD issue:
211
- - Add `tk:done` label, remove `tk:in-progress` label
212
- - Update the `<!-- tk:metadata -->` comment: set `status: done`, add `completed: <current UTC ISO 8601 timestamp>`
213
- 2. Close the PRD issue with reason `completed`
214
- 3. Close the plan issue with reason `completed`
215
- 4. If there is a current PR associated with this work, reference it in a closing comment on the PRD issue
216
-
217
- Tell the user: issues closed (include issue numbers), one-line summary of the feature.
193
+ 1. PRD issue: add `tk:done`, remove `tk:in-progress`, set metadata `status: done` + `completed` timestamp
194
+ 2. Close PRD issue (reason: `completed`)
195
+ 3. Close plan issue (reason: `completed`)
196
+ 4. If current PR exists, reference it in closing comment on PRD issue
218
197
 
219
198
  <!-- end:github -->
220
199
 
@@ -232,15 +211,3 @@ List the blockers to fix, then re-run `/tk:check <slug>`.
232
211
  - The only file writes this skill makes are: checkboxes + verdict block in the plan, and the archive steps on `done`
233
212
  - Never modify implementation code — only observe and report
234
213
  - If the PRD file is missing but all checks pass, warn and proceed — archive the plan only (skip PRD steps in archive)
235
-
236
- ## Error Handling
237
-
238
- - Plan not found — list available plans and ask
239
- - PRD referenced in plan not found — warn and continue with plan checks only
240
- <!-- if:local -->
241
- - `.tracerkit/plans/` missing — tell user to run `/tk:plan` first
242
- - `.tracerkit/archives/<slug>/` already exists — warn and ask whether to remove it first
243
- <!-- end:local -->
244
- <!-- if:github -->
245
- - Issue update fails — report the error and suggest checking `gh auth status`
246
- <!-- end:github -->
@@ -1,8 +1,10 @@
1
1
  ---
2
- description: Turn a PRD into a multi-phase implementation plan using tracer-bullet vertical slices, saved to .tracerkit/plans/. Use after /tk:prd.
2
+ description: Turn a PRD into a multi-phase implementation plan using tracer-bullet vertical slices. Use after /tk:prd.
3
3
  argument-hint: '[slug]'
4
4
  ---
5
5
 
6
+ **Config**: read `.tracerkit/config.json` (default: `local`). Follow matching `<!-- if:local/github -->` blocks. GitHub: use `github.repo` from config or git remote.
7
+
6
8
  # PRD to Plan
7
9
 
8
10
  Break a PRD into phased vertical slices (tracer bullets).
@@ -32,7 +34,7 @@ Output: a GitHub Issue with label `{{github.labels.plan}}`.
32
34
 
33
35
  The argument (if provided) is: $ARGUMENTS
34
36
 
35
- Use the argument as `<slug>` if given. If no argument is provided, list available PRDs and ask which one to plan.
37
+ Use argument as `<slug>`. If empty, list available PRDs and ask.
36
38
 
37
39
  ## Workflow
38
40
 
@@ -40,16 +42,12 @@ Use the argument as `<slug>` if given. If no argument is provided, list availabl
40
42
 
41
43
  <!-- if:local -->
42
44
 
43
- Read `.tracerkit/prds/<slug>.md`. If it does not exist, list available PRDs and ask.
44
-
45
- If `.tracerkit/plans/<slug>.md` already exists, tell the user and ask whether to overwrite or pick a new name.
45
+ Read `.tracerkit/prds/<slug>.md`. If missing, list PRDs and ask. If `.tracerkit/plans/<slug>.md` exists, ask: overwrite or new name?
46
46
 
47
47
  <!-- end:local -->
48
48
  <!-- if:github -->
49
49
 
50
- Find the PRD issue: search for an open GitHub Issue with label `{{github.labels.prd}}` and title matching `[{{github.labels.prd}}] <slug>:`. Read its body. If not found, list available PRD issues and ask.
51
-
52
- Search for an existing plan issue with label `{{github.labels.plan}}` and title matching `[{{github.labels.plan}}] <slug>:`. If found, tell the user and ask whether to update it or pick a new name.
50
+ Find PRD issue: open issue with label `{{github.labels.prd}}`, title matching `[{{github.labels.prd}}] <slug>:`. If missing, list PRDs and ask. If plan issue with label `{{github.labels.plan}}` and matching title exists, ask: update or new name?
53
51
 
54
52
  <!-- end:github -->
55
53
 
@@ -57,9 +55,7 @@ Search for an existing plan issue with label `{{github.labels.plan}}` and title
57
55
 
58
56
  <!-- if:local -->
59
57
 
60
- Update the YAML frontmatter in `.tracerkit/prds/<slug>.md` to `status: in_progress`. Change only the `status` field — do not touch any other frontmatter fields or the markdown content below the closing `---`.
61
-
62
- If the PRD has no frontmatter, skip this step silently.
58
+ Set `status: in_progress` in `.tracerkit/prds/<slug>.md` frontmatter. Change only `status`.
63
59
 
64
60
  <!-- end:local -->
65
61
  <!-- if:github -->
@@ -72,9 +68,9 @@ Update the PRD issue:
72
68
 
73
69
  ### 2. Explore the codebase
74
70
 
75
- Understand current architecture, existing patterns, and integration points. If you already have codebase context from a prior step in this conversation (e.g., you just ran `/tk:prd`), skip the exploration and note which context you're reusing.
71
+ Map architecture, patterns, integration points. Skip if codebase context exists from prior step.
76
72
 
77
- **Research protocol**: codebase first, then project docs. If you cannot verify a technical claim from these sources, flag it as uncertain never fabricate.
73
+ **Research protocol**: codebase first, then docs. Unverifiable claims flag as uncertain, never fabricate.
78
74
 
79
75
  ### 3. Identify durable architectural decisions
80
76
 
@@ -88,7 +84,7 @@ Before slicing, extract decisions that hold across all phases:
88
84
 
89
85
  ### 4. Draft vertical slices
90
86
 
91
- Each phase is a thin **tracer bullet** — a narrow but complete path through every integration layer (schema, service, API, UI, tests). A completed phase is demoable on its own.
87
+ Each phase: thin vertical slice through all layers (schema service API UI tests). Demoable alone.
92
88
 
93
89
  **Deriving tasks from the PRD:**
94
90
 
@@ -106,9 +102,9 @@ Each phase is a thin **tracer bullet** — a narrow but complete path through ev
106
102
 
107
103
  **Phase naming:** use a goal phrase answering "what can we demo when this is done?" (e.g., "Phase 1 — Revenue visible end-to-end"), not a layer name.
108
104
 
109
- **Done when:** write as a checkbox list of atomic, verifiable conditions not prose. Each item must pass this test: _"Can an agent verify this by reading files, running a command, or checking a test result — with no subjective judgment?"_ Bad: "API is clean". Good: "`GET /api/revenue` returns `{ total: number }`". The agent marks `[x]` during implementation to track progress.
105
+ **Done when:** checkbox list of atomic, verifiable conditions (not prose). Test: "Can an agent verify by reading files, running a command, or checking a test?" Agent marks `[x]` during implementation.
110
106
 
111
- **When to use layer-by-layer instead:** If the PRD has complex schema changes that all modules depend on and no single user story can stand alone without the full schema, build the data foundation first, then slice the rest vertically.
107
+ **Layer-by-layer exception:** if complex schema changes underpin all modules and no story stands alone, build data foundation first, then slice vertically.
112
108
 
113
109
  **Phase count thresholds:**
114
110
 
@@ -126,19 +122,13 @@ Assign an agent tag to tasks where appropriate:
126
122
 
127
123
  ### 5. Quiz the user
128
124
 
129
- Present the breakdown. For each phase show:
130
-
131
- - **Title**: short goal phrase
132
- - **User stories covered**: which PRD stories this addresses
133
- - **Done when**: the testable condition
134
-
135
- Ask: Does the granularity feel right? Should any phases merge or split? Iterate until approved.
125
+ Present breakdown (title, user stories covered, done-when per phase). Ask: granularity right? Merge or split? Iterate until approved.
136
126
 
137
127
  ### 6. Save plan
138
128
 
139
129
  <!-- if:local -->
140
130
 
141
- Save to `.tracerkit/plans/<slug>.md` (create `.tracerkit/plans/` if missing).
131
+ Save to `.tracerkit/plans/<slug>.md` (create dir if missing).
142
132
 
143
133
  ```markdown
144
134
  # Plan: <Feature Name>
@@ -149,16 +139,9 @@ Save to `.tracerkit/plans/<slug>.md` (create `.tracerkit/plans/` if missing).
149
139
  <!-- end:local -->
150
140
  <!-- if:github -->
151
141
 
152
- Ensure the following labels exist (create if missing):
142
+ Ensure labels exist: `{{github.labels.plan}}`, `tk:in-progress` (create if missing).
153
143
 
154
- - `{{github.labels.plan}}` TracerKit implementation plan
155
- - `tk:in-progress` — Plan generated, implementation underway
156
-
157
- Create a GitHub Issue with:
158
-
159
- - **Title**: `[{{github.labels.plan}}] <slug>: Plan: <Feature Title>`
160
- - **Labels**: `{{github.labels.plan}}`, `tk:in-progress`
161
- - **Body**: the plan content below, with a source PRD reference by issue number
144
+ Create GitHub Issue — title: `[{{github.labels.plan}}] <slug>: Plan: <Feature Title>`, labels: `{{github.labels.plan}}`, `tk:in-progress`.
162
145
 
163
146
  ```markdown
164
147
  <!-- tk:metadata
@@ -210,16 +193,7 @@ Carried forward from PRD verbatim.
210
193
  Gaps found in the PRD needing resolution. Blank if none.
211
194
  ```
212
195
 
213
- <!-- if:local -->
214
-
215
- Print saved path and one line per phase: `Phase N — <title> (<condition summary>)`. Then ask: "Run `/tk:check <slug>` when ready?"
216
-
217
- <!-- end:local -->
218
- <!-- if:github -->
219
-
220
- Print issue number/URL and one line per phase: `Phase N — <title> (<condition summary>)`. Then ask: "Run `/tk:check <slug>` when ready?"
221
-
222
- <!-- end:github -->
196
+ Print one line per phase: `Phase N — <title> (<condition summary>)`. Then ask: "Run `/tk:check <slug>` when ready?"
223
197
 
224
198
  ## Rules
225
199
 
@@ -234,14 +208,3 @@ Print issue number/URL and one line per phase: `Phase N — <title> (<condition
234
208
  - Never modify the source PRD content — only update metadata and labels
235
209
  <!-- end:github -->
236
210
  - Carry PRD's Out of Scope forward verbatim
237
-
238
- ## Error Handling
239
-
240
- - PRD not found — list available PRDs and ask
241
- - PRD missing sections — note gaps inline and continue
242
- <!-- if:local -->
243
- - `.tracerkit/plans/` missing — create it
244
- <!-- end:local -->
245
- <!-- if:github -->
246
- - Issue creation fails — report the error and suggest checking `gh auth status`
247
- <!-- end:github -->
@@ -1,11 +1,13 @@
1
1
  ---
2
- description: Create a PRD through user interview, codebase exploration, and module design, saved to .tracerkit/prds/. Use when starting a new feature or change.
2
+ description: Create a PRD through user interview, codebase exploration, and module design. Use when starting a new feature or change.
3
3
  argument-hint: <idea>
4
4
  ---
5
5
 
6
+ **Config**: read `.tracerkit/config.json` (default: `local`). Follow matching `<!-- if:local/github -->` blocks. GitHub: use `github.repo` from config or git remote.
7
+
6
8
  # PRD Writing
7
9
 
8
- Skip steps already satisfied. If user provided a description via arguments, skip to Step 2.
10
+ Skip satisfied steps. If argument provided, skip to Step 2.
9
11
 
10
12
  ## Pre-loaded context
11
13
 
@@ -21,9 +23,7 @@ Skip steps already satisfied. If user provided a description via arguments, skip
21
23
 
22
24
  The argument is: $ARGUMENTS
23
25
 
24
- If the argument is empty, go straight to Step 1 (gather problem description). After gathering the idea, derive the slug from the idea.
25
-
26
- If the argument is provided, derive a slug using this exact algorithm:
26
+ If empty, go to Step 1; derive slug after gathering the idea. If provided, derive slug:
27
27
 
28
28
  1. Take only the text before the first `—` or `–` (if present)
29
29
  2. Lowercase the text
@@ -33,16 +33,12 @@ If the argument is provided, derive a slug using this exact algorithm:
33
33
 
34
34
  <!-- if:local -->
35
35
 
36
- The output file is `.tracerkit/prds/<slug>.md`.
37
-
38
- If `.tracerkit/prds/<slug>.md` already exists, tell the user and ask whether to overwrite or pick a new name.
36
+ Output: `.tracerkit/prds/<slug>.md`. If exists, ask: overwrite or new name?
39
37
 
40
38
  <!-- end:local -->
41
39
  <!-- if:github -->
42
40
 
43
- The output is a GitHub Issue with label `{{github.labels.prd}}` and title `[{{github.labels.prd}}] <slug>: <Feature Title>`.
44
-
45
- Search for an existing open issue with title matching `[{{github.labels.prd}}] <slug>:`. If found, tell the user and ask whether to update it or pick a new slug.
41
+ Output: GitHub Issue with label `{{github.labels.prd}}`, title `[{{github.labels.prd}}] <slug>: <Feature Title>`. If matching issue exists, ask: update or new slug?
46
42
 
47
43
  <!-- end:github -->
48
44
 
@@ -54,180 +50,86 @@ Ask the user for a detailed description of the problem and any solution ideas.
54
50
 
55
51
  ### 2. Explore codebase
56
52
 
57
- Verify assertions and map current state: data models, services, API routes, frontend structure, and test patterns. Note what exists vs. what must be built.
53
+ Map current state: data models, services, API routes, frontend, tests. Note exists vs. must build.
58
54
 
59
- **Research protocol**: codebase first, then project docs. If you cannot verify a technical claim from these sources, flag it as uncertain never fabricate.
55
+ **Research protocol**: codebase first, then docs. Unverifiable claims flag as uncertain, never fabricate.
60
56
 
61
57
  ### 3. Interview
62
58
 
63
- Interview relentlessly, one question at a time. Lead with your recommended answer; let the user confirm or correct. If a question can be answered by exploring code, explore instead of asking. For terse answers, offer concrete options (A/B/C).
59
+ One question at a time. Lead with your recommended answer. Explore code instead of asking when possible. Offer A/B/C for terse answers.
64
60
 
65
- Walk these branches. **Skip rule**: skip a branch when the project type makes it irrelevant (e.g., skip Display/Access/Navigation for CLIs and libraries) AND the user's idea does not mention it.
61
+ | Branch | Key questions | Skip when |
62
+ | ---------------- | --------------------------------------- | -------------------------------- |
63
+ | Scope & Surface | Where? New page or integrated? Roles? | CLI/library, no new entry points |
64
+ | Data & Concepts | Definitions, existing vs missing data | Never skip |
65
+ | Behavior | Interaction patterns, filtering, search | No user-facing behavior |
66
+ | Display | Numbers, tables, charts, exports | No UI |
67
+ | Access & Privacy | Who sees what? Sensitive data? | Single-user, no auth |
68
+ | Boundaries | Out of scope, deferred features | Never skip |
69
+ | Integration | Schema, services, external deps | Self-contained change |
66
70
 
67
- - **Scope & Surface** — Where does this live? New page/view or integrated? Which user roles? _Skip if_: single-surface project (CLI, library) with no new entry points.
68
- - **Data & Concepts** — Precise definitions for each new concept. What data exists, what's missing? _Never skip_ — every feature has data.
69
- - **Behavior & Interaction** — How does the user interact? Sorting, filtering, search, time ranges? _Skip if_: feature is purely internal/backend with no user-facing behavior change.
70
- - **Display & Output** — Numbers, tables, charts, forms? Exportable? URL-driven state? _Skip if_: no UI or formatted output involved.
71
- - **Access & Privacy** — Who sees what? Role-based restrictions? Sensitive data concerns? _Skip if_: single-user project with no auth layer.
72
- - **Boundaries** — What is explicitly out of scope? Adjacent features to defer? _Never skip_ — scope control prevents creep.
73
- - **Integration** — Schema changes? New or extended services? External dependencies? _Skip if_: self-contained change touching no external systems or storage.
71
+ ### 3b. Gray areas
74
72
 
75
- ### 3b. Gray area checkpoint
76
-
77
- Before continuing, scan the interview for gray areas. Something is a gray area if any of these are true:
78
-
79
- - **Vague answer**: user said "maybe", "probably", "I think", or gave a one-word answer to a multi-part question
80
- - **Contradiction**: two answers conflict (e.g., "no auth needed" but "only admins can access")
81
- - **Unstated assumption**: you filled in a detail the user never confirmed
82
- - **Ambiguous scope**: a feature boundary is unclear (could be in or out of scope)
83
-
84
- Present as a numbered list:
85
-
86
- ```
87
- Gray areas found:
88
- 1. <ambiguity> — assumed <X>, confirm?
89
- 2. <ambiguity> — two options: A or B
90
- ```
91
-
92
- If the list is empty, say "No gray areas found" and move on. Otherwise, resolve each item with the user before proceeding.
73
+ Surface ambiguities, contradictions, unstated assumptions. Present numbered list. Resolve all before continuing.
93
74
 
94
75
  ### 4. Design modules
95
76
 
96
- Sketch major modules to build or modify. Favor **deep modules** — a simple interface (13 entry points) hiding a large implementation that rarely changes, over shallow modules where the interface is nearly as complex as the implementation.
77
+ Sketch modules. Favor **deep modules** — simple interface (1-3 entry points) hiding large implementation over shallow modules where interface implementation.
97
78
 
98
- Signals of shallow design: many small functions with 1:1 query mapping, callers compose multiple calls, adding a feature requires changing the interface.
79
+ Shallow signals: many small 1:1 functions, callers compose multiple calls, feature changes require interface changes.
99
80
 
100
- Present modules to user. Confirm which need tests.
81
+ Present modules. Confirm which need tests.
101
82
 
102
83
  ### 5. Write PRD
103
84
 
104
85
  <!-- if:local -->
105
86
 
106
- Save to `.tracerkit/prds/<slug>.md` (create `.tracerkit/prds/` if missing).
87
+ Save to `.tracerkit/prds/<slug>.md` (create dir if missing).
107
88
 
108
89
  ```markdown
109
90
  ---
110
- created: <current UTC timestamp, ISO 8601, e.g. 2025-06-15T14:30:00Z>
91
+ created: <UTC ISO 8601>
111
92
  status: created
112
93
  ---
113
94
 
114
95
  # Feature Name
115
-
116
- ...
117
96
  ```
118
97
 
119
98
  <!-- end:local -->
120
99
  <!-- if:github -->
121
100
 
122
- Ensure the following labels exist in the repository (create them if missing):
101
+ Ensure labels exist: `{{github.labels.prd}}`, `tk:created` (create if missing).
123
102
 
124
- - `{{github.labels.prd}}` TracerKit PRD
125
- - `tk:created` — PRD written, no plan yet
126
-
127
- Create a GitHub Issue with:
128
-
129
- - **Title**: `[{{github.labels.prd}}] <slug>: <Feature Title>`
130
- - **Labels**: `{{github.labels.prd}}`, `tk:created`
131
- - **Body**: the PRD content below, with metadata in an HTML comment
103
+ Create GitHub Issue — title: `[{{github.labels.prd}}] <slug>: <Feature Title>`, labels: `{{github.labels.prd}}`, `tk:created`.
132
104
 
133
105
  ```markdown
134
106
  <!-- tk:metadata
135
- created: <current UTC timestamp, ISO 8601>
107
+ created: <UTC ISO 8601>
136
108
  status: created
137
109
  -->
138
110
 
139
111
  # Feature Name
140
-
141
- ...
142
112
  ```
143
113
 
144
114
  <!-- end:github -->
145
115
 
146
- Use this structure for the PRD body (same for both local file and issue body):
116
+ PRD body structure (same for local file and issue body). Omit empty sections. No file paths or code snippets.
147
117
 
118
+ ```
148
119
  ## Problem Statement
149
-
150
- The problem from the user's perspective. Focus on pain and impact.
151
-
152
- ## Current State
153
-
154
- What exists today that this feature changes or builds on. Skip for greenfield.
155
-
156
- - Relevant modules, services, or UI surfaces already in place
157
- - Current behavior the user experiences
158
- - Known limitations or workarounds
159
-
160
- ## Solution
161
-
162
- The solution from the user's perspective. Describe the experience, not the architecture.
163
-
164
- ## User Stories
165
-
166
- Long numbered list. Cover happy path, edge cases, error states.
167
-
168
- 1. As a <actor>, I want <feature>, so that <benefit>
169
-
120
+ ## Current State (skip if greenfield)
121
+ ## Solution (user experience, not architecture)
122
+ ## User Stories (numbered, cover happy + edge + error)
170
123
  ## Implementation Decisions
171
-
172
- ### New Modules
173
-
174
- - Module name, purpose, and public interface (function signatures with param types)
175
- - Why each module exists as a separate unit
176
-
177
- ### Architectural Decisions
178
-
179
- - Key definitions (precise meaning of domain terms)
180
- - Data flow from storage to display
181
- - State management approach
182
-
124
+ ### New Modules (name, purpose, interface signatures)
125
+ ### Architectural Decisions (definitions, data flow, state)
183
126
  ### Schema Changes
184
-
185
- - New tables/columns needed, or "None required"
186
-
187
127
  ### API Contracts
188
-
189
- - New routes, request/response shapes
190
-
191
128
  ### Navigation
192
-
193
- - Where the feature is accessed, new routes added
194
-
195
- Do NOT include file paths or code snippets — they go stale.
196
-
197
- Omit any section whose content would be "None required" — only include sections with actual content.
198
-
199
- ## Testing Decisions
200
-
201
- - What makes a good test (behavior, not implementation)
202
- - Which modules need tests
203
- - Key test cases (empty state, boundaries, isolation)
204
- - Prior art: similar test patterns in the codebase
205
-
206
- ## Out of Scope
207
-
208
- Explicit list. Be specific — vague exclusions invite scope creep.
129
+ ## Testing Decisions (behavior tests, key cases, prior art)
130
+ ## Out of Scope (be specific)
131
+ ```
209
132
 
210
133
  ---
211
134
 
212
- <!-- if:local -->
213
-
214
- Tell the user: file created, one-line summary. Then ask: "Run `/tk:plan <slug>` next?"
215
-
216
- <!-- end:local -->
217
- <!-- if:github -->
218
-
219
- Tell the user: issue created (include issue number and URL), one-line summary. Then ask: "Run `/tk:plan <slug>` next?"
220
-
221
- <!-- end:github -->
222
-
223
- ## Error Handling
224
-
225
- <!-- if:local -->
226
-
227
- - `.tracerkit/prds/` missing — create it
228
- <!-- end:local -->
229
- <!-- if:github -->
230
- - Labels missing — create them before creating the issue
231
- - Issue creation fails — report the error and suggest checking `gh auth status`
232
- <!-- end:github -->
233
- - Scope larger than expected — surface and re-scope with user before continuing
135
+ Then ask: "Run `/tk:plan <slug>` next?"