@codyswann/lisa 2.215.0 β†’ 2.217.0

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.
Files changed (123) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa/.codex-plugin/skills/lisa-confluence-to-tracker/SKILL.md +78 -3
  5. package/plugins/lisa/.codex-plugin/skills/lisa-github-to-tracker/SKILL.md +81 -4
  6. package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +31 -0
  7. package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +16 -0
  8. package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +32 -0
  9. package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +16 -0
  10. package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +82 -4
  11. package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +31 -0
  12. package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +16 -0
  13. package/plugins/lisa/.codex-plugin/skills/lisa-notion-to-tracker/SKILL.md +78 -2
  14. package/plugins/lisa/.codex-plugin/skills/lisa-prd-backlink/SKILL.md +12 -3
  15. package/plugins/lisa/.codex-plugin/skills/lisa-prd-ticket-coverage/SKILL.md +17 -0
  16. package/plugins/lisa/skills/lisa-confluence-to-tracker/SKILL.md +78 -3
  17. package/plugins/lisa/skills/lisa-github-to-tracker/SKILL.md +81 -4
  18. package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +31 -0
  19. package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +16 -0
  20. package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +32 -0
  21. package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +16 -0
  22. package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +82 -4
  23. package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +31 -0
  24. package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +16 -0
  25. package/plugins/lisa/skills/lisa-notion-to-tracker/SKILL.md +78 -2
  26. package/plugins/lisa/skills/lisa-prd-backlink/SKILL.md +12 -3
  27. package/plugins/lisa/skills/lisa-prd-ticket-coverage/SKILL.md +17 -0
  28. package/plugins/lisa-agy/plugin.json +1 -1
  29. package/plugins/lisa-agy/skills/lisa-confluence-to-tracker/SKILL.md +78 -3
  30. package/plugins/lisa-agy/skills/lisa-github-to-tracker/SKILL.md +81 -4
  31. package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +31 -0
  32. package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +16 -0
  33. package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +32 -0
  34. package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +16 -0
  35. package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +82 -4
  36. package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +31 -0
  37. package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +16 -0
  38. package/plugins/lisa-agy/skills/lisa-notion-to-tracker/SKILL.md +78 -2
  39. package/plugins/lisa-agy/skills/lisa-prd-backlink/SKILL.md +12 -3
  40. package/plugins/lisa-agy/skills/lisa-prd-ticket-coverage/SKILL.md +17 -0
  41. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  43. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  44. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-copilot/skills/lisa-confluence-to-tracker/SKILL.md +78 -3
  48. package/plugins/lisa-copilot/skills/lisa-github-to-tracker/SKILL.md +81 -4
  49. package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +31 -0
  50. package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +16 -0
  51. package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +32 -0
  52. package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +16 -0
  53. package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +82 -4
  54. package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +31 -0
  55. package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +16 -0
  56. package/plugins/lisa-copilot/skills/lisa-notion-to-tracker/SKILL.md +78 -2
  57. package/plugins/lisa-copilot/skills/lisa-prd-backlink/SKILL.md +12 -3
  58. package/plugins/lisa-copilot/skills/lisa-prd-ticket-coverage/SKILL.md +17 -0
  59. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-cursor/skills/lisa-confluence-to-tracker/SKILL.md +78 -3
  61. package/plugins/lisa-cursor/skills/lisa-github-to-tracker/SKILL.md +81 -4
  62. package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +31 -0
  63. package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +16 -0
  64. package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +32 -0
  65. package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +16 -0
  66. package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +82 -4
  67. package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +31 -0
  68. package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +16 -0
  69. package/plugins/lisa-cursor/skills/lisa-notion-to-tracker/SKILL.md +78 -2
  70. package/plugins/lisa-cursor/skills/lisa-prd-backlink/SKILL.md +12 -3
  71. package/plugins/lisa-cursor/skills/lisa-prd-ticket-coverage/SKILL.md +17 -0
  72. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  74. package/plugins/lisa-expo-agy/plugin.json +1 -1
  75. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  79. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  80. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  84. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  85. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  89. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  90. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  94. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  95. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  99. package/plugins/lisa-rails-agy/plugin.json +1 -1
  100. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  101. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  104. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  105. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  106. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  109. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  110. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  111. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  112. package/plugins/src/base/skills/lisa-confluence-to-tracker/SKILL.md +78 -3
  113. package/plugins/src/base/skills/lisa-github-to-tracker/SKILL.md +81 -4
  114. package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +31 -0
  115. package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +16 -0
  116. package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +32 -0
  117. package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +16 -0
  118. package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +82 -4
  119. package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +31 -0
  120. package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +16 -0
  121. package/plugins/src/base/skills/lisa-notion-to-tracker/SKILL.md +78 -2
  122. package/plugins/src/base/skills/lisa-prd-backlink/SKILL.md +12 -3
  123. package/plugins/src/base/skills/lisa-prd-ticket-coverage/SKILL.md +17 -0
@@ -27,21 +27,29 @@ This skill supports two modes, controlled by a `dry_run` flag in `$ARGUMENTS`:
27
27
  - **`dry_run: false`** (default β€” full mode): run all phases, write tickets via `lisa-tracker-write`, run the preservation gate, report.
28
28
  - **`dry_run: true`** (planning + validation only β€” no writes): run Phases 1, 1.5, 1.6, 2, 3, 4 to plan the hierarchy and draft each ticket spec, then call `lisa-tracker-validate` (with `--spec-only`) on every drafted ticket. Aggregate the per-ticket validator reports into a single dry-run report. **Skip Phase 5 (sub-task creation), Phase 5.5 (preservation gate), and Phase 6 (results report)** β€” none of those make sense without writes. Return the dry-run report so the caller (e.g. `lisa-linear-prd-intake`) can decide whether to proceed.
29
29
 
30
- Dry-run output format is identical to `lisa-notion-to-tracker`'s and `lisa-confluence-to-tracker`'s. Reuse the same fields, including `prd_anchor` and `prd_section`. The only difference: Linear has no inline-comment selection-anchor primitive at the project level β€” `prd_anchor` is the anchor a downstream caller would use to *post a comment on the related sub-issue* (typically the issue identifier, e.g. `LIN-123`, scoped to a section heading). When the failure does not map to any single sub-issue, set `prd_anchor: null` and the caller falls back to its sentinel feedback channel.
30
+ Dry-run output format is identical to `lisa-notion-to-tracker`'s and `lisa-confluence-to-tracker`'s. Reuse the same fields, including `prd_anchor` and `prd_section`, the `### Requirement register` section, and the per-node `requirements:` lists. The only difference: Linear has no inline-comment selection-anchor primitive at the project level β€” `prd_anchor` is the anchor a downstream caller would use to *post a comment on the related sub-issue* (typically the issue identifier, e.g. `LIN-123`, scoped to a section heading). When the failure does not map to any single sub-issue, set `prd_anchor: null` and the caller falls back to its sentinel feedback channel.
31
31
 
32
32
  ```text
33
33
  ## linear-to-tracker dry-run: <PRD title>
34
34
 
35
+ ### Requirement register
36
+ - R1 Β§"<section heading>": "<verbatim requirement text>"
37
+ - R2 Β§"<section heading>": "<verbatim requirement text>"
38
+ - ...
39
+
35
40
  ### Planned hierarchy
36
41
  - Epic: <summary>
37
42
  prd_section: "<heading text from the project description / document that produced this epic>"
38
43
  prd_anchor: "<linear issue identifier or null>"
44
+ requirements: [R1, R2] # register ids this ticket exists to satisfy; [] only for derived work
39
45
  - Story 1.1: <summary>
40
46
  prd_section: "<heading or user-story line>"
41
47
  prd_anchor: "<linear issue identifier or null>"
48
+ requirements: [R1]
42
49
  - Sub-task [<repo>]: <summary>
43
50
  prd_section: "<heading or AC bullet>"
44
51
  prd_anchor: "<linear issue identifier or null>"
52
+ requirements: [R1]
45
53
  - ...
46
54
  - Story 1.2: ...
47
55
 
@@ -77,6 +85,38 @@ The dry-run mode never writes to JIRA and never calls `mcp__atlassian__createJir
77
85
 
78
86
  Bypassing `lisa-tracker-write` produces thin tickets that the rest of the lifecycle (triage, ticket-verify, journey, evidence) treats as broken. Atlassian reads in this skill are limited to the tools listed in `allowed-tools` (currently `getJiraIssueRemoteIssueLinks`) for the Phase 5.5 preservation gate. The Linear read tools listed in `allowed-tools` above are PRD-side only and never write.
79
87
 
88
+ ## Source Requirement Section (shared format)
89
+
90
+ Every ticket created by this skill β€” epic, story, and sub-task alike β€”
91
+ carries a `## Source Requirement` section in its description so anyone can
92
+ answer "why was this done?" without leaving the ticket:
93
+
94
+ ```markdown
95
+ ## Source Requirement
96
+
97
+ - **PRD**: [<PRD title>](<PRD URL>) Β§"<section heading>"
98
+ - **Requirement (R3)**: "<verbatim requirement text from the PRD>"
99
+
100
+ This ticket exists to satisfy the quoted requirement. If implementation
101
+ scope drifts from the quoted text, the PRD is the authority β€” raise the
102
+ conflict rather than silently reinterpreting it.
103
+ ```
104
+
105
+ Rules:
106
+
107
+ - **Verbatim quotes, never paraphrases.** The quote is what survives later
108
+ PRD edits, and it must be readable by a non-technical operator.
109
+ - **Multiple requirements** β†’ one `**Requirement (Rn)**` line each.
110
+ - **Derived / cross-cutting work** (no single requirement) uses the
111
+ supporting form instead:
112
+ `- **Requirement**: Derived work supporting R3, R7 β€” no single PRD section.`
113
+ - **All the way down**: sub-tasks carry full quotes, not just a pointer at
114
+ the parent Story, so a leaf claimed by build-intake in isolation is
115
+ self-explanatory.
116
+ - JIRA descriptions render the section as `h2. Source Requirement`;
117
+ GitHub/Linear use the markdown heading. `lisa-tracker-write` and the
118
+ validators treat the section as mandatory for PRD-sourced tickets.
119
+
80
120
  ## Input
81
121
 
82
122
  A Linear project URL, slug, or ID. The PRD is expected to have:
@@ -132,6 +172,37 @@ If env vars are not available, ask the user to provide them explicitly before pr
132
172
  - Engineering comments (prefixed with "Engineering:" or wrench emoji) that identify technical constraints
133
173
  - Cross-PRD dependencies (references to other Linear projects, documents, or shared infrastructure)
134
174
 
175
+ ### Phase 1.4: Requirement Register (traceability)
176
+
177
+ Every ticket this skill creates must be able to answer "why was this done?"
178
+ by pointing at the PRD requirement it satisfies. Build that mapping now,
179
+ while parsing the PRD β€” it cannot be reliably reconstructed afterwards.
180
+
181
+ 1. **Atomize the PRD into requirements** in document order: goals, user
182
+ stories, functional and non-functional requirements, acceptance-criteria
183
+ bullets, and important notes β€” across the project description, every
184
+ attached document, and every sub-issue description. Use the same
185
+ atomization `lisa-prd-ticket-coverage` uses so the two views line up.
186
+ 2. **Assign sequential register ids** (`R1`, `R2`, …). Ids are
187
+ per-generation, not durable β€” the **verbatim quote is the durable
188
+ anchor**; if the PRD is edited and re-planned, ids may shift but quotes
189
+ still identify the requirement.
190
+ 3. **Record each entry** as `{ id, verbatim_text, section_heading }`,
191
+ where `section_heading` is the markdown heading (or the sub-issue
192
+ identifier) the requirement lives under β€” the same value used for
193
+ `prd_anchor`.
194
+ 4. **Tag every planned ticket** β€” epic, story, AND sub-task β€” with the
195
+ register ids it exists to satisfy. All the way down: sub-tasks carry
196
+ their own requirement quotes so a leaf dispatched in isolation is
197
+ self-explanatory. A ticket that genuinely traces to no single
198
+ requirement (cross-cutting infrastructure, derived enablement work)
199
+ gets `requirements: []` and must say which requirements it *supports*
200
+ in its Source Requirement section instead.
201
+
202
+ The register feeds three consumers: the `## Source Requirement` section on
203
+ every created ticket (Phases 3–5), the dry-run report (above), and the
204
+ requirement tokens in the PRD back-link (Phase 7).
205
+
135
206
  ### Phase 1.5: Extract Source Artifacts
136
207
 
137
208
  PRDs typically reference external design, UX, and data artifacts (Figma files, Lovable prototypes, Loom walkthroughs, screenshots, example payloads, peer Linear or Confluence pages). These MUST be preserved onto the resulting tickets β€” otherwise developers picking up a ticket lose the source of truth. This is the failure mode this step exists to prevent.
@@ -178,8 +249,10 @@ For each epic identified in Phase 1, **invoke the `lisa-tracker-write` skill** (
178
249
 
179
250
  - `project_key`: resolved by `lisa-tracker-write` from `.lisa.config.json`
180
251
  - `issue_type`: `Epic`
252
+ - `prd_source`: the originating PRD URL β€” mandatory for every ticket this skill creates; it arms the validator's S16 traceability gate
181
253
  - `summary`: epic title from the PRD
182
254
  - `description_body`: a draft of the 3-audience description containing:
255
+ - A **Source Requirement** section (see the shared format above) citing the Linear project URL, section heading, and the verbatim text of every register requirement (`R-id`) this epic exists to satisfy
183
256
  - **Context / Business Value**: epic summary from the PRD, originating Linear project URL, business outcome
184
257
  - **Technical Approach**: cross-cutting integration points and constraints surfaced in Phase 2 codebase research
185
258
  - List of user stories the epic contains
@@ -208,9 +281,10 @@ For each story, **invoke `lisa-tracker-write`** with:
208
281
 
209
282
  - `project_key`: resolved by `lisa-tracker-write` from `.lisa.config.json`
210
283
  - `issue_type`: `Story`
284
+ - `prd_source`: the originating PRD URL β€” mandatory for every ticket this skill creates; it arms the validator's S16 traceability gate
211
285
  - `epic_parent`: the Epic key captured in Phase 3 (mandatory)
212
286
  - `summary`: prefixed per the naming convention above
213
- - `description_body`: 3-audience description as in `lisa-notion-to-tracker` Phase 4
287
+ - `description_body`: 3-audience description as in `lisa-notion-to-tracker` Phase 4, including as its first element a **Source Requirement** section (shared format above) quoting the register requirement(s) this story satisfies
214
288
  - `artifacts`: the Phase 1.5 artifacts filtered by domain per the inheritance table below
215
289
 
216
290
  | Story type | Inherits domains |
@@ -235,6 +309,7 @@ Delegate sub-task creation to **parallel agents** (one per epic or batch of stor
235
309
  Each sub-task MUST:
236
310
  1. **Be scoped to exactly ONE repo** β€” indicated in brackets in the summary: `[repo-name]` and in the description's `## Repository` / `h2. Repository` section
237
311
  2. **Include an Empirical Verification Plan** β€” real user-like verification, NOT unit tests, linting, or typechecking
312
+ 3. **Carry its own `## Source Requirement` section** (shared format above) with the full verbatim quote(s) from the Phase 1.4 register β€” a leaf claimed by build-intake in isolation must be self-explanatory. When a sub-task is split per-repo, every split child inherits the same requirement quote(s).
238
313
 
239
314
  **Leaf-only build-ready (`leaf-only-lifecycle`)**: Sub-tasks are the **leaf work units** of the decomposition β€” they are the ONLY items in the hierarchy that receive the build-ready label. `lisa-tracker-write` applies `status:ready` here so downstream build intake (`lisa-tracker-build-intake`) claims the leaves and never the Epic or Stories. Apply `status:ready` to each Sub-task; never to its parent Story or Epic (Phases 3–4). `lisa-tracker-write` enforces the same invariant on the write side, so a Sub-task split into per-repo children (the cross-repo case above) carries build-ready on the children, not on any intermediate parent that gains child work.
240
315
 
@@ -259,6 +334,7 @@ After all tickets are created, present a summary table to the user:
259
334
  - All Epics with keys and URLs
260
335
  - All Stories grouped by Epic
261
336
  - All Sub-tasks grouped by Story with repo tags
337
+ - **Requirement coverage** β€” one row per Phase 1.4 register entry (`R-id`, quote excerpt, tickets that declare it); requirements with zero tickets are a gap to resolve before reporting success
262
338
  - Repo distribution
263
339
  - **Artifact Preservation Matrix**
264
340
  - Blockers list with recommendations and alternatives
@@ -274,7 +350,8 @@ Invoke `lisa-prd-backlink` with:
274
350
 
275
351
  - `source_type: "linear"`
276
352
  - `source_ref`: the original Linear project URL
277
- - `tickets`: the full list created in Phases 3–5, each entry as `{ key, title, type, url, parent_key }`
353
+ - `tickets`: the full list created in Phases 3–5, each entry as `{ key, title, type, url, parent_key, requirements }` β€” `requirements` is the list of Phase 1.4 register ids the ticket satisfies (empty for derived work)
354
+ - `requirement_register`: the Phase 1.4 register (`{ id, verbatim_text, section_heading }` entries), so the back-link section can render the requirement β†’ tickets view
278
355
 
279
356
  If `lisa-prd-backlink` fails (permission denied, Linear unreachable), surface the error in the Phase 6 report rather than aborting β€” the tickets are already created. Recommend the user re-run `lisa-prd-backlink` standalone once the source is reachable.
280
357
 
@@ -302,10 +379,11 @@ produces broken tickets that downstream skills (triage, journey, evidence) canno
302
379
 
303
380
  For each sub-task, invoke `lisa-tracker-write` with:
304
381
  - issue_type: "Sub-task"
382
+ - prd_source: [the originating PRD URL β€” mandatory; arms the S16 traceability gate]
305
383
  - parent: the parent story key
306
384
  - project_key: [PROJECT]
307
385
  - summary: prefixed with the repo in brackets, e.g. "[backend-api] Add audit log table"
308
- - description_body: a 3-section draft (Context / Technical Approach / Acceptance Criteria) plus `h2. Repository` naming exactly one repo
386
+ - description_body: a 3-section draft (Context / Technical Approach / Acceptance Criteria) plus `h2. Repository` naming exactly one repo, plus `h2. Source Requirement` quoting the PRD requirement(s) this sub-task satisfies VERBATIM with the PRD link and register id(s) β€” [paste the exact requirement text and R-ids for each sub-task from the requirement register; do not let the agent paraphrase]
309
387
  - gherkin_acceptance_criteria: derived from the story's functional requirements
310
388
  - sign_in_account: [test user credentials from config β€” name + role + how to obtain]
311
389
  - target_environment: "dev"
@@ -63,6 +63,7 @@ relations: [{ id: "ENG-99", type: "blocked_by" }] # known issue relations (may
63
63
  remote_links: [{ url: "https://github.com/...", title: "PR #42" }]
64
64
  build_ready: true # caller asserts the build-ready role (status:ready) is/would be applied β€” see S15
65
65
  child_refs: ["ENG-601", "ENG-602"] # known child work (sub-issues / project-member issues / blocked_by parentage) β€” see S15
66
+ prd_source: "https://notion.so/..." # set when the Issue was generated from a PRD β€” requires the Source Requirement section, see S16
66
67
  ```
67
68
 
68
69
  If the caller passes only an identifier, fetch the item via `lisa-linear-access operation: get-issue` (Issue) or `lisa-linear-access operation: get-project` (Project), derive the same fields from the fetched data β€” including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa-linear-read-issue`) so S15 can classify the item β€” then run gates.
@@ -90,6 +91,7 @@ Each gate is tagged with a fixed `category` and a `product_relevant` boolean. Ca
90
91
  | S13 Relationship Search | `dependency` | true |
91
92
  | S14 Evidence manifest binding (leaf work units) | `acceptance-criteria` | true |
92
93
  | S15 Leaf-only build-ready | `structural` | false |
94
+ | S16 Source Requirement traceability | `product-clarity` | true |
93
95
  | F1 Issue type valid in team | `structural` | false |
94
96
  | F2 Project parent exists and is in same team | `structural` | false |
95
97
  | F3 Linked items exist | `structural` | false |
@@ -239,6 +241,34 @@ Remediation: `"Build-ready (status:ready) is leaf-only per leaf-only-lifecycle.
239
241
 
240
242
  `product_relevant: false` β€” a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
241
243
 
244
+ #### S16 β€” Source Requirement traceability (PRD-sourced Issues)
245
+
246
+ Answers "why was this done?": every Issue generated from a PRD must carry
247
+ the requirement it exists to satisfy, quoted verbatim, at every level of
248
+ the hierarchy β€” sub-issues included, so a leaf claimed by build-intake in
249
+ isolation is self-explanatory.
250
+
251
+ **When the gate applies.** Run S16 whenever the spec declares `prd_source`
252
+ (all `*-to-tracker` decomposition paths set it). Without `prd_source`
253
+ (ad-hoc issues with no PRD lineage) the gate is `N/A` β€” but if a
254
+ `Source Requirement` section is present anyway, still validate its shape
255
+ so a malformed section never passes silently.
256
+
257
+ **What must be present.** a `Source Requirement` section (`##` markdown heading) containing:
258
+
259
+ 1. A link to the source PRD (the `**PRD**:` line), and
260
+ 2. At least one `**Requirement` line with **verbatim quoted text**, or the
261
+ explicit derived-work form (`Derived work supporting R3, R7 β€” no single
262
+ PRD section.`).
263
+
264
+ Missing section, missing PRD link, empty/paraphrased requirement text
265
+ (quotes shorter than a few words, or prose with no quotation), or a bare
266
+ R-id with no quote: FAIL with remediation
267
+ `"Add a Source Requirement section citing the PRD link and quoting the requirement(s) this issue satisfies verbatim (see the Source Requirement shared format in the *-to-tracker skills). Derived work must name the requirements it supports."`
268
+
269
+ `product_relevant: true` β€” a issue whose requirement cannot be traced is
270
+ a product-clarity problem: nobody can tell why the work exists.
271
+
242
272
  ### Feasibility Gates (require Linear lookups; skip in dry-run if requested)
243
273
 
244
274
  #### F1 β€” Issue type valid in team
@@ -317,6 +347,7 @@ Output is a single fenced text block. Callers parse it; do not add free-form pro
317
347
  - [PASS|FAIL|N/A] S13 Relationship Search β€” <one-line reason>
318
348
  - [PASS|FAIL|N/A] S14 Evidence manifest binding β€” <one-line reason>
319
349
  - [PASS|FAIL|N/A] S15 Leaf-only build-ready β€” <one-line reason>
350
+ - [PASS|FAIL|N/A] S16 Source Requirement traceability β€” <one-line reason>
320
351
 
321
352
  ### Feasibility Gates (omit when --spec-only)
322
353
  - [PASS|FAIL|N/A] F1 Issue type valid in team β€” <one-line reason>
@@ -60,6 +60,7 @@ Required fields (stop and ask if missing β€” never invent values):
60
60
  | Target backend environment | Runtime-behavior changes | `dev` / `staging` / `prod`; recorded in description (Phase 3). Skip only for doc/config/type-only items. |
61
61
  | Sign-in account / credentials | Items that touch authenticated surfaces | Name the account (or source β€” 1Password item, env var, seeded fixture) and role; recorded in description. Omit when sign-in is not required. |
62
62
  | Single-repo scope | Bug, Task, Sub-task | These types MUST cover one repo only. If the work crosses repos, split it before creating. Epic / Spike / Story may span repos. |
63
+ | Source Requirement | PRD-sourced Issues (`prd_source` provided) | `## Source Requirement` with PRD link + verbatim requirement quote(s) β€” see Phase 3; enforced at every level, sub-issues included. |
63
64
 
64
65
  Optional but recommended: assignee, estimate (story points), labels, project milestone (fix-version equivalent), cycle.
65
66
 
@@ -68,6 +69,20 @@ Optional but recommended: assignee, estimate (story points), labels, project mil
68
69
  Linear descriptions are markdown (NOT Jira wiki markup β€” no `h2.` headings, use `##` instead). The description MUST address three audiences. Reject and rewrite if any are missing.
69
70
 
70
71
  ```markdown
72
+ ## Source Requirement
73
+ [Required whenever the Issue originates from a PRD (the caller passes
74
+ `prd_source`). Answers "why was this done?" β€” cite the PRD and quote the
75
+ requirement(s) VERBATIM, never paraphrased:
76
+ - **PRD**: <PRD title + link> Β§"<section heading>"
77
+ - **Requirement (R3)**: "<verbatim requirement text from the PRD>"
78
+ One Requirement line per satisfied requirement. Derived / cross-cutting
79
+ work that traces to no single requirement uses the supporting form:
80
+ "Derived work supporting R3, R7 β€” no single PRD section." Close with:
81
+ "This Issue exists to satisfy the quoted requirement. If implementation
82
+ scope drifts from the quoted text, the PRD is the authority β€” raise the
83
+ conflict rather than silently reinterpreting it." Omit the section only
84
+ for ad-hoc Issues with no PRD lineage.]
85
+
71
86
  ## Context / Business Value
72
87
  [Why this matters. Stakeholder-facing. Concrete user impact or business outcome.
73
88
  Link to the originating Slack thread, Notion doc, incident, or customer report.]
@@ -108,6 +123,7 @@ Linear descriptions are markdown (NOT Jira wiki markup β€” no `h2.` headings, us
108
123
  ```
109
124
 
110
125
  Rules:
126
+ - PRD-sourced Issues (caller passed `prd_source`) MUST carry the Source Requirement section with verbatim quotes β€” paraphrases are rejected (validator gate S16). This applies at every level, sub-issues included: a leaf claimed in isolation must explain its own "why".
111
127
  - Every acceptance criterion uses Given/When/Then. No vague "should work" language.
112
128
  - Every criterion is independently verifiable (UI, API, data, or performance check).
113
129
  - If the item is a Bug, include reproduction steps, expected vs. actual behavior, and environment.
@@ -22,16 +22,24 @@ Dry-run output format:
22
22
  ```text
23
23
  ## notion-to-tracker dry-run: <PRD title>
24
24
 
25
+ ### Requirement register
26
+ - R1 Β§"<section heading>": "<verbatim requirement text>"
27
+ - R2 Β§"<section heading>": "<verbatim requirement text>"
28
+ - ...
29
+
25
30
  ### Planned hierarchy
26
31
  - Epic: <summary>
27
32
  prd_section: "<heading text from the PRD that produced this epic>"
28
33
  prd_anchor: "<first ~10 chars>...<last ~10 chars>" # for selection_with_ellipsis; null if no specific section
34
+ requirements: [R1, R2] # register ids this ticket exists to satisfy; [] only for derived work
29
35
  - Story 1.1: <summary>
30
36
  prd_section: "<heading or user-story line>"
31
37
  prd_anchor: "<start>...<end>"
38
+ requirements: [R1]
32
39
  - Sub-task [<repo>]: <summary>
33
40
  prd_section: "<heading or AC bullet>"
34
41
  prd_anchor: "<start>...<end>"
42
+ requirements: [R1]
35
43
  - ...
36
44
  - Story 1.2: ...
37
45
 
@@ -71,6 +79,38 @@ The dry-run mode never writes to JIRA and never calls `mcp__atlassian__createJir
71
79
 
72
80
  Bypassing `lisa-tracker-write` produces thin tickets that the rest of the lifecycle (triage, ticket-verify, journey, evidence) treats as broken. This is the most common failure mode this skill has had β€” calling `createJiraIssue` directly is a regression, not an optimization. The Atlassian read tools (`getJiraIssue`, `searchJiraIssuesUsingJql`, `getJiraIssueRemoteIssueLinks`, `getAccessibleAtlassianResources`, `getJiraProjectIssueTypesMetadata`, `getVisibleJiraProjects`) ARE allowed for context gathering and the Phase 5.5 preservation gate.
73
81
 
82
+ ## Source Requirement Section (shared format)
83
+
84
+ Every ticket created by this skill β€” epic, story, and sub-task alike β€”
85
+ carries a `## Source Requirement` section in its description so anyone can
86
+ answer "why was this done?" without leaving the ticket:
87
+
88
+ ```markdown
89
+ ## Source Requirement
90
+
91
+ - **PRD**: [<PRD title>](<PRD URL>) Β§"<section heading>"
92
+ - **Requirement (R3)**: "<verbatim requirement text from the PRD>"
93
+
94
+ This ticket exists to satisfy the quoted requirement. If implementation
95
+ scope drifts from the quoted text, the PRD is the authority β€” raise the
96
+ conflict rather than silently reinterpreting it.
97
+ ```
98
+
99
+ Rules:
100
+
101
+ - **Verbatim quotes, never paraphrases.** The quote is what survives later
102
+ PRD edits, and it must be readable by a non-technical operator.
103
+ - **Multiple requirements** β†’ one `**Requirement (Rn)**` line each.
104
+ - **Derived / cross-cutting work** (no single requirement) uses the
105
+ supporting form instead:
106
+ `- **Requirement**: Derived work supporting R3, R7 β€” no single PRD section.`
107
+ - **All the way down**: sub-tasks carry full quotes, not just a pointer at
108
+ the parent Story, so a leaf claimed by build-intake in isolation is
109
+ self-explanatory.
110
+ - JIRA descriptions render the section as `h2. Source Requirement`;
111
+ GitHub/Linear use the markdown heading. `lisa-tracker-write` and the
112
+ validators treat the section as mandatory for PRD-sourced tickets.
113
+
74
114
  ## Input
75
115
 
76
116
  A Notion PRD URL. The PRD is expected to have:
@@ -116,6 +156,34 @@ If env vars are not available, ask the user to provide them explicitly before pr
116
156
  - Engineering comments (prefixed with "Engineering:" or wrench emoji) that identify technical constraints
117
157
  - Cross-PRD dependencies (references to other features or shared infrastructure)
118
158
 
159
+ ### Phase 1.4: Requirement Register (traceability)
160
+
161
+ Every ticket this skill creates must be able to answer "why was this done?"
162
+ by pointing at the PRD requirement it satisfies. Build that mapping now,
163
+ while parsing the PRD β€” it cannot be reliably reconstructed afterwards.
164
+
165
+ 1. **Atomize the PRD into requirements** in document order: goals, user
166
+ stories, functional and non-functional requirements, acceptance-criteria
167
+ bullets, and important notes. Use the same atomization
168
+ `lisa-prd-ticket-coverage` uses so the two views line up.
169
+ 2. **Assign sequential register ids** (`R1`, `R2`, …). Ids are
170
+ per-generation, not durable β€” the **verbatim quote is the durable
171
+ anchor**; if the PRD is edited and re-planned, ids may shift but quotes
172
+ still identify the requirement.
173
+ 3. **Record each entry** as `{ id, verbatim_text, section_heading }` plus
174
+ the `prd_anchor` capture described above.
175
+ 4. **Tag every planned ticket** β€” epic, story, AND sub-task β€” with the
176
+ register ids it exists to satisfy. All the way down: sub-tasks carry
177
+ their own requirement quotes so a leaf dispatched in isolation is
178
+ self-explanatory. A ticket that genuinely traces to no single
179
+ requirement (cross-cutting infrastructure, derived enablement work)
180
+ gets `requirements: []` and must say which requirements it *supports*
181
+ in its Source Requirement section instead.
182
+
183
+ The register feeds three consumers: the `## Source Requirement` section on
184
+ every created ticket (Phases 3–5), the dry-run report (above), and the
185
+ requirement tokens in the PRD back-link (Phase 7).
186
+
119
187
  ### Phase 1.5: Extract Source Artifacts
120
188
 
121
189
  PRDs typically reference external design, UX, and data artifacts (Figma files, Lovable prototypes, Loom walkthroughs, screenshots, example payloads, Confluence pages). These MUST be preserved onto the resulting tickets β€” otherwise developers picking up a ticket lose the source of truth. This is the failure mode this step exists to prevent.
@@ -167,9 +235,11 @@ Walkthrough findings are attached to the originating Notion PRD as a comment ("C
167
235
  For each PRD epic, **invoke the `lisa-tracker-write` skill** (do not call `createJiraIssue` directly). Pass it everything it needs to enforce its quality gates:
168
236
 
169
237
  - `project_key`: resolved by `lisa-tracker-write` from `.lisa.config.json`
238
+ - `prd_source`: the originating PRD URL β€” mandatory for every ticket this skill creates; it arms the validator's S16 traceability gate
170
239
  - `issue_type`: `Epic`
171
240
  - `summary`: epic title from the PRD
172
241
  - `description_body`: a draft of the 3-audience description containing:
242
+ - A **Source Requirement** section (see the shared format below) citing the PRD URL, section heading, and the verbatim text of every register requirement (`R-id`) this epic exists to satisfy
173
243
  - **Context / Business Value**: epic summary from the PRD, originating Notion URL, business outcome
174
244
  - **Technical Approach**: cross-cutting integration points and constraints surfaced in Phase 2 codebase research
175
245
  - List of user stories the epic contains
@@ -200,10 +270,12 @@ For each Epic, plan two kinds of stories:
200
270
  For each story, **invoke `lisa-tracker-write`** with:
201
271
 
202
272
  - `project_key`: resolved by `lisa-tracker-write` from `.lisa.config.json`
273
+ - `prd_source`: the originating PRD URL (arms S16)
203
274
  - `issue_type`: `Story`
204
275
  - `epic_parent`: the Epic key captured in Phase 3 (mandatory β€” `lisa-tracker-write` rejects non-bug, non-epic tickets without an epic parent)
205
276
  - `summary`: prefixed per the naming convention above
206
277
  - `description_body`: a draft of the 3-audience description containing:
278
+ - A **Source Requirement** section (shared format below) quoting the register requirement(s) this story satisfies
207
279
  - **Context / Business Value**: the user story statement from the PRD
208
280
  - **Technical Approach**: notes from engineering comments and Phase 2 codebase research
209
281
  - **Acceptance Criteria** (Gherkin) derived from the functional requirements β€” `lisa-tracker-write` will reject prose-only acceptance criteria
@@ -238,6 +310,7 @@ Delegate sub-task creation to **parallel agents** (one per epic or batch of stor
238
310
  Each sub-task MUST:
239
311
  1. **Be scoped to exactly ONE repo** β€” indicated in brackets in the summary: `[repo-name]` and in the description's `## Repository` / `h2. Repository` section. `lisa-tracker-write` enforces single-repo scope on Sub-task; cross-repo or unscoped sub-tasks will be rejected and must be split/restamped before delegation.
240
312
  2. **Include an Empirical Verification Plan** β€” real user-like verification, NOT unit tests, linting, or typechecking
313
+ 3. **Carry its own `## Source Requirement` section** (shared format above) with the full verbatim quote(s) from the Phase 1.4 register β€” a leaf claimed by build-intake in isolation must be self-explanatory. When a sub-task is split per-repo, every split child inherits the same requirement quote(s).
241
314
 
242
315
  **Leaf-only build-ready (`leaf-only-lifecycle`)**: Sub-tasks are the **leaf work units** of the decomposition β€” they are the ONLY items in the hierarchy that receive the build-ready label. `lisa-tracker-write` applies `status:ready` here so downstream build intake (`lisa-tracker-build-intake`) claims the leaves and never the Epic or Stories. Apply `status:ready` to each Sub-task; never to its parent Story or Epic (Phases 3–4). `lisa-tracker-write` enforces the same invariant on the write side, so a Sub-task split into per-repo children (the cross-repo case above) carries build-ready on the children, not on any intermediate parent that gains child work.
243
316
 
@@ -271,6 +344,7 @@ After all tickets are created, present a summary table to the user:
271
344
  - All Epics with keys and URLs
272
345
  - All Stories grouped by Epic
273
346
  - All Sub-tasks grouped by Story with repo tags
347
+ - **Requirement coverage** β€” one row per Phase 1.4 register entry (`R-id`, quote excerpt, tickets that declare it); requirements with zero tickets are a gap to resolve before reporting success
274
348
  - Repo distribution (how many tasks per repo)
275
349
  - **Artifact Preservation Matrix** β€” one row per artifact showing which epic/stories reference it
276
350
  - Blockers list with recommendations and alternatives
@@ -286,7 +360,8 @@ Invoke `lisa-prd-backlink` with:
286
360
 
287
361
  - `source_type: "notion"`
288
362
  - `source_ref`: the original PRD URL
289
- - `tickets`: the full list created in Phases 3–5, each entry as `{ key, title, type, url, parent_key }`
363
+ - `tickets`: the full list created in Phases 3–5, each entry as `{ key, title, type, url, parent_key, requirements }` β€” `requirements` is the list of Phase 1.4 register ids the ticket satisfies (empty for derived work)
364
+ - `requirement_register`: the Phase 1.4 register (`{ id, verbatim_text, section_heading }` entries), so the back-link section can render the requirement β†’ tickets view
290
365
 
291
366
  If `lisa-prd-backlink` fails (PRD permission denied, Notion unreachable, source mutated mid-run), surface the error in the Phase 6 report rather than aborting β€” the tickets are already created and their value to the team is not blocked by the back-link write. Recommend the user re-run `lisa-prd-backlink` standalone once the source is reachable again.
292
367
 
@@ -323,8 +398,9 @@ For each sub-task, invoke `lisa-tracker-write` with:
323
398
  - issue_type: "Sub-task"
324
399
  - parent: the parent story key
325
400
  - project_key: [PROJECT]
401
+ - prd_source: [the originating PRD URL β€” mandatory; arms the S16 traceability gate]
326
402
  - summary: prefixed with the repo in brackets, e.g. "[backend-api] Add audit log table"
327
- - description_body: a 3-section draft (Context / Technical Approach / Acceptance Criteria) plus `h2. Repository` naming exactly one repo
403
+ - description_body: a 3-section draft (Context / Technical Approach / Acceptance Criteria) plus `h2. Repository` naming exactly one repo, plus `h2. Source Requirement` quoting the PRD requirement(s) this sub-task satisfies VERBATIM with the PRD link and register id(s) β€” [paste the exact requirement text and R-ids for each sub-task from the requirement register; do not let the agent paraphrase]
328
404
  - gherkin_acceptance_criteria: derived from the story's functional requirements
329
405
  - sign_in_account: [test user credentials from config β€” name + role + how to obtain]
330
406
  - target_environment: "dev"
@@ -19,7 +19,10 @@ Pass `$ARGUMENTS` as a single JSON-style block:
19
19
  "source_type": "notion" | "confluence" | "linear" | "github" | "file",
20
20
  "source_ref": "<URL, page id, project id, issue ref, or absolute file path>",
21
21
  "tickets": [
22
- { "key": "<tracker-key>", "title": "<summary>", "type": "Epic|Story|Task|Sub-task|Bug|Spike", "url": "<link>", "parent_key": "<key or null>" }
22
+ { "key": "<tracker-key>", "title": "<summary>", "type": "Epic|Story|Task|Sub-task|Bug|Spike", "url": "<link>", "parent_key": "<key or null>", "requirements": ["R1", "R3"] }
23
+ ],
24
+ "requirement_register": [
25
+ { "id": "R1", "verbatim_text": "<requirement text quoted from the PRD>", "section_heading": "<PRD heading>" }
23
26
  ],
24
27
  "section_heading": "## Tickets" // optional override; default "## Tickets"
25
28
  }
@@ -58,6 +61,11 @@ The rendered section must be deterministic β€” same inputs produce identical out
58
61
 
59
62
  _Generated by `lisa-prd-backlink`. Regenerated on every Plan run; do not edit by hand._
60
63
 
64
+ ### Requirement coverage
65
+
66
+ - **R1** Β§"<PRD heading>": "<verbatim requirement text>" β€” [<key>](<url>), [<key>](<url>)
67
+ - **R2** Β§"<PRD heading>": "<verbatim requirement text>" β€” _no tickets β€” gap_
68
+
61
69
  ### <Epic key>: <Epic title>
62
70
 
63
71
  - [<Epic key>](<url>) β€” Epic <!-- lisa:gw ref=<ref> url=<url> type=Epic parent= -->
@@ -80,7 +88,7 @@ _Generated by `lisa-prd-backlink`. Regenerated on every Plan run; do not edit by
80
88
  Every list entry ends with a single-line HTML comment β€” invisible in rendered markdown, so the section stays clean for humans, but a stable, greppable record for machines:
81
89
 
82
90
  ```text
83
- <!-- lisa:gw ref=<ref> url=<url> type=<type> parent=<parent-ref or empty> -->
91
+ <!-- lisa:gw ref=<ref> url=<url> type=<type> parent=<parent-ref or empty> reqs=<comma-separated requirement ids or empty> -->
84
92
  ```
85
93
 
86
94
  - **`lisa-gw`** β€” a fixed sentinel (`gw` = generated work). A reader enumerates the generated child set by matching `<!-- lisa:gw ` lines; it never has to parse the surrounding prose, headings, or indentation.
@@ -88,8 +96,9 @@ Every list entry ends with a single-line HTML comment β€” invisible in rendered
88
96
  - **`url`** β€” the canonical URL of the work item.
89
97
  - **`type`** β€” `Epic | Story | Task | Sub-task | Bug | Spike` (verbatim from the ticket's `type`).
90
98
  - **`parent`** β€” the **`ref`** of this entry's parent (its `parent_key` resolved to the parent's ref), or **empty** when the entry is top-level (`parent_key` null/empty). A reader selects the **generated top-level child set** β€” exactly what the PRD owns per the rule β€” as every `lisa-gw` line whose `parent` is empty.
99
+ - **`reqs`** β€” comma-separated requirement register ids (`R1,R3`) the ticket's `requirements` list declares, or **empty** for derived work or tickets created before traceability. This makes the requirement β†’ tickets mapping parseable from the PRD alone: a reader answers "which tickets carry R3?" by matching `reqs=` tokens, deterministically β€” no inference.
91
100
 
92
- The visible markdown link and the token always carry the same `ref`/`url`/`type`; the token is the authoritative machine field (the prose may wrap or be reflowed by a host editor, the comment line will not). Field order within the token is fixed (`ref`, `url`, `type`, `parent`) so output is byte-stable.
101
+ The visible markdown link and the token always carry the same `ref`/`url`/`type`; the token is the authoritative machine field (the prose may wrap or be reflowed by a host editor, the comment line will not). Field order within the token is fixed (`ref`, `url`, `type`, `parent`, `reqs`) so output is byte-stable.
93
102
 
94
103
  If the input contains zero items, write the section header with a single line: `_No tickets created β€” Plan flow may not have completed._` Do not omit the section; presence-of-section is itself a signal to Debrief, and the always-written guarantee means a reader can always distinguish "ran, produced nothing" from "never ran."
95
104
 
@@ -96,6 +96,21 @@ PRD item id β†’ [ticket keys that cover it]
96
96
 
97
97
  Matching rules (in priority order):
98
98
 
99
+ 0. **Declared trace (deterministic β€” preferred)**: tickets created after
100
+ requirement traceability landed carry a `Source Requirement` section
101
+ (verbatim requirement quotes + register `R-ids`), and the PRD's
102
+ `## Tickets` section carries the same ids in its `lisa:gw … reqs=`
103
+ tokens. When present, the declared trace IS the mapping β€” match the
104
+ quoted text against the extracted atomic items (match on the verbatim
105
+ quote, not the `R-id`: ids are per-generation and may have shifted if
106
+ the PRD was re-planned; quotes are the durable anchor). A declared
107
+ trace is definitive: do not second-guess it with keyword inference,
108
+ but DO flag a declared quote that no longer appears anywhere in the
109
+ PRD (the requirement was edited or removed β€” surface it as a drift
110
+ finding, not silently). The derived-work form ("Derived work
111
+ supporting R3, R7") counts as a trace to the named requirements.
112
+ Fall back to rules 1–4 only for tickets with no Source Requirement
113
+ section (created before traceability existed).
99
114
  1. **Direct quote / strong keyword overlap**: the ticket's summary or AC explicitly names the PRD item's keywords. High confidence.
100
115
  2. **Domain match**: PRD item describes a UI affordance ("Tasks widget") and a ticket scopes that affordance (`[CU-2.1] Tasks widget β€” empty state`). Medium-high confidence.
101
116
  3. **Scope inheritance**: PRD item is a sub-detail of a parent (e.g. an AC under a user story); the ticket covers the parent user story. Medium confidence β€” flag for review if no more specific ticket exists.
@@ -107,6 +122,8 @@ Items with **zero** matching tickets are coverage gaps.
107
122
 
108
123
  For each created ticket, identify any tickets whose scope_signals do NOT trace back to a PRD item, AND are not justifiable as standard infrastructure tasks (e.g. `X.0 Setup` stories for data model / migrations are typically infrastructure scaffolding, not scope creep).
109
124
 
125
+ With declared traces this becomes precise: a ticket whose `Source Requirement` section is absent (on a post-traceability ticket set), or whose declared quotes match nothing in the PRD, is an orphan β€” the strongest scope-creep signal available. A ticket using the derived-work form is by definition not scope creep; it declares which requirements it supports.
126
+
110
127
  Scope creep is informational, not blocking β€” but worth surfacing because it usually indicates the agent invented work.
111
128
 
112
129
  ### Phase 5 β€” Determine verdict