@codyswann/lisa 2.104.6 → 2.104.7

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 (37) 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/rules/config-resolution.md +7 -19
  5. package/plugins/lisa/rules/prd-lifecycle-rollup.md +16 -15
  6. package/plugins/lisa/scripts/queue-contract-resolution.mjs +0 -20
  7. package/plugins/lisa/skills/confluence-prd-intake/SKILL.md +14 -35
  8. package/plugins/lisa/skills/github-prd-intake/SKILL.md +13 -30
  9. package/plugins/lisa/skills/linear-prd-intake/SKILL.md +14 -32
  10. package/plugins/lisa/skills/notion-prd-intake/SKILL.md +12 -31
  11. package/plugins/lisa/skills/setup-confluence/SKILL.md +1 -1
  12. package/plugins/lisa/skills/verify-prd/SKILL.md +7 -7
  13. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  14. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  15. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  17. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  19. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  21. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  23. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  25. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  27. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  28. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  29. package/plugins/src/base/rules/config-resolution.md +7 -19
  30. package/plugins/src/base/rules/prd-lifecycle-rollup.md +16 -15
  31. package/plugins/src/base/scripts/queue-contract-resolution.mjs +0 -20
  32. package/plugins/src/base/skills/confluence-prd-intake/SKILL.md +14 -35
  33. package/plugins/src/base/skills/github-prd-intake/SKILL.md +13 -30
  34. package/plugins/src/base/skills/linear-prd-intake/SKILL.md +14 -32
  35. package/plugins/src/base/skills/notion-prd-intake/SKILL.md +12 -31
  36. package/plugins/src/base/skills/setup-confluence/SKILL.md +1 -1
  37. package/plugins/src/base/skills/verify-prd/SKILL.md +7 -7
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  "lodash": ">=4.18.1"
83
83
  },
84
84
  "name": "@codyswann/lisa",
85
- "version": "2.104.6",
85
+ "version": "2.104.7",
86
86
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
87
87
  "main": "dist/index.js",
88
88
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.104.6",
3
+ "version": "2.104.7",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.104.6",
3
+ "version": "2.104.7",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -58,8 +58,7 @@ fi
58
58
  "verified": "<page-id>"
59
59
  },
60
60
  "dashboardPageId": "<page-id>",
61
- "feedbackPageId": "<page-id>",
62
- "rollup": { "closeOnShipped": false }
61
+ "feedbackPageId": "<page-id>"
63
62
  },
64
63
  "github": {
65
64
  "org": "<org-or-user>",
@@ -86,8 +85,7 @@ fi
86
85
  "ready": "prd-ready", "in_review": "prd-in-review",
87
86
  "blocked": "prd-blocked", "ticketed": "prd-ticketed",
88
87
  "shipped": "prd-shipped", "verified": "prd-verified",
89
- "sentinel": "prd-intake-feedback",
90
- "rollup": { "closeOnShipped": false }
88
+ "sentinel": "prd-intake-feedback"
91
89
  }
92
90
  }
93
91
  },
@@ -99,8 +97,7 @@ fi
99
97
  "draft": "Draft", "ready": "Ready", "in_review": "In Review",
100
98
  "blocked": "Blocked", "ticketed": "Ticketed", "shipped": "Shipped",
101
99
  "verified": "Verified"
102
- },
103
- "rollup": { "closeOnShipped": false }
100
+ }
104
101
  },
105
102
  "linear": {
106
103
  "workspace": "<workspace-slug>",
@@ -118,8 +115,7 @@ fi
118
115
  "ready": "prd-ready", "in_review": "prd-in-review",
119
116
  "blocked": "prd-blocked", "ticketed": "prd-ticketed",
120
117
  "shipped": "prd-shipped", "verified": "prd-verified",
121
- "sentinel": "prd-intake-feedback",
122
- "rollup": { "closeOnShipped": false }
118
+ "sentinel": "prd-intake-feedback"
123
119
  }
124
120
  }
125
121
  },
@@ -291,17 +287,9 @@ Every lifecycle skill operates on a fixed set of **roles** (`ready`, `claimed`,
291
287
  | `verified` | Shipped product empirically checked against the PRD | `Verified` (status) | `prd-verified` (label); parent-page lookup (Confluence) |
292
288
  | `sentinel` | (PRD-intake feedback issue marker, GitHub/Linear self-host only) | — | `prd-intake-feedback` |
293
289
 
294
- ### PRD rollup config (`prd.rollup`)
295
-
296
- PRD lifecycle completion is **derived** from the PRD's generated top-level work, not set independently — see the `prd-lifecycle-rollup` rule for the full contract (generated-top-level-work definition, per-vendor terminal-state predicate, the `shipped` transition, and the child-ref idempotency key). When all required generated top-level children are terminal, rollup transitions the PRD to its `shipped` role; the `prd.rollup` block configures the optional close/archive step that follows.
297
-
298
- The `rollup` object lives in each PRD-source vendor section (`github.labels.prd.rollup`, `linear.labels.prd.rollup`, `notion.rollup`, `confluence.rollup`):
299
-
300
- | Key | Required | Default | Notes |
301
- |-----|----------|---------|-------|
302
- | `closeOnShipped` | no | `false` | When `true`, rollup closes/archives the PRD after the `shipped` transition (GitHub: close the issue; Linear: move to a closed/archived state; JIRA: transition to Done; Confluence/Notion: archive where supported). When `false` (the default), the PRD is set to `shipped` but left open for a human to close. Closure never happens before all generated top-level work is terminal. |
290
+ ### PRD rollup behavior
303
291
 
304
- Like every other vocabulary key, `prd.rollup` is **optional** a missing block inherits `closeOnShipped: false`. The `shipped` transition itself is unconditional on the all-terminal condition; only the close/archive step is gated by this flag.
292
+ PRD lifecycle completion is **derived** from the PRD's generated top-level work, not set independently — see the `prd-lifecycle-rollup` rule for the full contract (generated-top-level-work definition, per-vendor terminal-state predicate, the `shipped` transition, verified native closure, and the child-ref idempotency key). When all required generated top-level children are terminal, rollup transitions the PRD to its `shipped` role and leaves it open/active for `/lisa:verify-prd`. There is no project-configurable close-on-shipped flag: provider-native closure/archive/completion happens only after `/lisa:verify-prd` passes and moves the PRD to `verified`.
305
293
 
306
294
  ### Repair intake config (`intake.repair`)
307
295
 
@@ -370,7 +358,7 @@ The true terminal `done` value is also the only value that triggers provider-nat
370
358
  ### What's configurable, what's not
371
359
 
372
360
  - **Status / label NAMES** are configurable per project — that's the point of the vocabulary maps.
373
- - **Role SEMANTICS and TRANSITIONS** are not. The build lifecycle is always `ready → claimed → done` (with optional `review` for label-driven systems). The PRD lifecycle is always `ready → in_review → (blocked | ticketed) → shipped`, then verification may move `shipped → verified` on a pass or `shipped → blocked` on a failed verification. `verified` is terminal and product-owned like `draft` and `shipped`; Lisa does not add `prd-verifying` or `prd-verification-failed` states. Skills hardcode these transitions because they encode the design intent of the framework, not the project's preferences.
361
+ - **Role SEMANTICS and TRANSITIONS** are not. The build lifecycle is always `ready → claimed → done` (with optional `review` for label-driven systems). The PRD lifecycle is always `ready → in_review → (blocked | ticketed) → shipped`, then verification may move `shipped → verified` on a pass or `shipped → ticketed` on a failed verification. `verified` is terminal and product-owned like `draft` and `shipped`; Lisa does not add `prd-verifying` or `prd-verification-failed` states. Skills hardcode these transitions because they encode the design intent of the framework, not the project's preferences.
374
362
  - **Extra statuses/labels** the project uses outside these roles are fine — lisa never touches them.
375
363
 
376
364
  ### Defaults vs. requirements
@@ -6,7 +6,7 @@ It defines four coupled things:
6
6
 
7
7
  1. **Generated top-level work** — what a PRD owns as children (its created Epics / top-level Stories), explicitly **excluding** leaf Sub-tasks.
8
8
  2. **Per-vendor terminal-state predicate** — how "this generated child is done" is decided for each source/tracker.
9
- 3. **PRD `shipped` transition + config-gated close/archive** — when and how a PRD rolls up to its terminal state and is closed/archived.
9
+ 3. **PRD `shipped` transition + verified native closure** — when and how a PRD rolls up to shipped, remains eligible for verification, and closes only after verified.
10
10
  4. **Idempotency dedupe key** — the child-ref identity that makes linking and rollup safe to re-run.
11
11
 
12
12
  This is the PRD-level companion to `leaf-only-lifecycle`: that rule governs the *build* lifecycle of leaf work units and how a **parent container** rolls up from its leaf children; this rule governs the *PRD* lifecycle and how the **PRD** rolls up from its generated top-level children. The two share the rollup shape (terminal children → parent advances) and the multi-env terminal handling, applied at different levels of the hierarchy.
@@ -52,12 +52,12 @@ Use this matrix when implementing or auditing a PRD-source integration. It descr
52
52
 
53
53
  | PRD source / tracker shape | Native hierarchy mechanism | Documented fallback | Closure behavior |
54
54
  |---|---|---|---|
55
- | **GitHub Issues (source and tracker in the same repo)** | Link generated top-level work as native sub-issues of the PRD issue when the repo supports GitHub sub-issues. The PRD's direct sub-issues are the generated top-level child set; descendants under those children are excluded from PRD rollup. | Always maintain the machine-readable `## Tickets` / `## Generated Work` section keyed by `owner/repo#number`, and use it when sub-issues are unavailable, disabled, or incomplete. | Rollup changes the PRD lifecycle label from `prd-ticketed` to `prd-shipped` when every required generated top-level issue is terminal. Close the PRD issue only when `github.labels.prd.rollup.closeOnShipped` is `true`; the default is to leave it open. |
56
- | **Linear** | Use Linear native grouping where the PRD also lives in Linear: generated top-level Issues are related through `parentId`, or a generated Project groups the generated Issues. Read only top-level Issues for PRD rollup. | Use the PRD's machine-readable generated-work section when the destination tracker is not Linear or native project / parent relationships cannot represent the PRD-to-work link. Entries are keyed by Linear issue or project identifier / UUID. | Rollup removes `prd-ticketed` and adds `prd-shipped` to the PRD project when every required generated top-level Issue / Project is completed. Archive or close the project only when `linear.labels.prd.rollup.closeOnShipped` is `true`; otherwise leave it active. |
57
- | **JIRA / Atlassian tracker work** | Prefer native Epic / parent fields, or a documented issue-link type where the PRD-to-Epic relationship can be represented in JIRA. JIRA child terminal state is read from the issue's Done status category. | If the PRD source is not JIRA or the native link cannot attach tracker work to the PRD artifact, record generated top-level JIRA issue keys in the PRD's generated-work section. | Rollup may transition a JIRA-hosted PRD to the configured shipped / Done status only after all required generated top-level issues are in the Done status category. Native resolution / closure is config-gated through the PRD rollup close-on-shipped setting. |
58
- | **Confluence PRDs** | No native issue hierarchy for tracker work. Confluence's native structure is used for PRD lifecycle lanes by parent page, not for destination work children. | The Confluence page's machine-readable `## Tickets` / `## Generated Work` section is the primary child source. Top-level generated work entries are keyed by destination ticket ref. | Rollup re-parents the PRD page from the `ticketed` parent to the `shipped` parent when every required generated-work entry is marked done. Archive the page only when `confluence.rollup.closeOnShipped` is `true`; otherwise leave it active. |
59
- | **Notion PRDs** | No native issue hierarchy for tracker work. Notion's native status/select property stores PRD lifecycle state, not generated ticket parentage. | The Notion page's machine-readable `## Tickets` / `## Generated Work` section is the primary child source. Top-level generated work entries are keyed by destination ticket ref. | Rollup sets the configured Notion status/select value to `Shipped` when every required generated-work entry is marked done. Archive the page only when `notion.rollup.closeOnShipped` is `true`; otherwise leave it active. |
60
- | **Cross-vendor PRD -> tracker** | Native hierarchy cannot cross systems, so the destination ticket is not expected to become a native child of the PRD artifact. Native tracker hierarchy still applies inside the destination system among generated Epics, Stories, and Sub-tasks. | The source PRD artifact's generated-work section is authoritative for the PRD-to-top-level-work child set, and each entry links to the destination ticket URL / key. | The PRD source owns the final lifecycle transition and optional close/archive. It evaluates terminal state using the destination tracker's predicate, then applies the source vendor's `shipped` transition and close-on-shipped behavior. |
55
+ | **GitHub Issues (source and tracker in the same repo)** | Link generated top-level work as native sub-issues of the PRD issue when the repo supports GitHub sub-issues. The PRD's direct sub-issues are the generated top-level child set; descendants under those children are excluded from PRD rollup. | Always maintain the machine-readable `## Tickets` / `## Generated Work` section keyed by `owner/repo#number`, and use it when sub-issues are unavailable, disabled, or incomplete. | Rollup changes the PRD lifecycle label from `prd-ticketed` to `prd-shipped` when every required generated top-level issue is terminal and leaves the issue open for `/lisa:verify-prd`. Verified PASS closes the issue natively. |
56
+ | **Linear** | Use Linear native grouping where the PRD also lives in Linear: generated top-level Issues are related through `parentId`, or a generated Project groups the generated Issues. Read only top-level Issues for PRD rollup. | Use the PRD's machine-readable generated-work section when the destination tracker is not Linear or native project / parent relationships cannot represent the PRD-to-work link. Entries are keyed by Linear issue or project identifier / UUID. | Rollup removes `prd-ticketed` and adds `prd-shipped` to the PRD project when every required generated top-level Issue / Project is completed and leaves it active for `/lisa:verify-prd`. Verified PASS archives/completes it natively. |
57
+ | **JIRA / Atlassian tracker work** | Prefer native Epic / parent fields, or a documented issue-link type where the PRD-to-Epic relationship can be represented in JIRA. JIRA child terminal state is read from the issue's Done status category. | If the PRD source is not JIRA or the native link cannot attach tracker work to the PRD artifact, record generated top-level JIRA issue keys in the PRD's generated-work section. | Rollup may transition a JIRA-hosted PRD to the configured shipped status only after all required generated top-level issues are in the Done status category. Verified PASS performs native completion where supported. |
58
+ | **Confluence PRDs** | No native issue hierarchy for tracker work. Confluence's native structure is used for PRD lifecycle lanes by parent page, not for destination work children. | The Confluence page's machine-readable `## Tickets` / `## Generated Work` section is the primary child source. Top-level generated work entries are keyed by destination ticket ref. | Rollup re-parents the PRD page from the `ticketed` parent to the `shipped` parent when every required generated-work entry is marked done and leaves the page active for `/lisa:verify-prd`. Verified PASS archives it where supported. |
59
+ | **Notion PRDs** | No native issue hierarchy for tracker work. Notion's native status/select property stores PRD lifecycle state, not generated ticket parentage. | The Notion page's machine-readable `## Tickets` / `## Generated Work` section is the primary child source. Top-level generated work entries are keyed by destination ticket ref. | Rollup sets the configured Notion status/select value to `Shipped` when every required generated-work entry is marked done and leaves the page active for `/lisa:verify-prd`. Verified PASS archives it where supported. |
60
+ | **Cross-vendor PRD -> tracker** | Native hierarchy cannot cross systems, so the destination ticket is not expected to become a native child of the PRD artifact. Native tracker hierarchy still applies inside the destination system among generated Epics, Stories, and Sub-tasks. | The source PRD artifact's generated-work section is authoritative for the PRD-to-top-level-work child set, and each entry links to the destination ticket URL / key. | The PRD source owns the lifecycle transition. It evaluates terminal state using the destination tracker's predicate, applies the source vendor's `shipped` transition, leaves the PRD open/active, then `/lisa:verify-prd` owns verified native closure. |
61
61
 
62
62
  ## Per-vendor terminal-state predicate
63
63
 
@@ -82,13 +82,14 @@ Where a vendor's terminal predicate references the build-status `done` role (Git
82
82
 
83
83
  **Single-environment collapse (this repo).** Lisa's own deploy has only `main`/`production` (`deploy.branches = production: main`, no dev/staging), so `done` is a single value, not a map, and the build lifecycle collapses to one chain: `ready → claimed (in-progress) → review (code-review) → done`. A generated top-level child is terminal when it reaches the single `status:done`; rollup never resolves a `dev` or `staging` `done` in this repo. This is the *collapsed* case of the generic rule, not a different rule — projects with more environments keep the env-keyed map.
84
84
 
85
- ## PRD `shipped` transition + config-gated close/archive
85
+ ## PRD `shipped` transition and verified native closure
86
86
 
87
- When **all required** generated top-level children are terminal, the PRD rolls up to its terminal PRD-lifecycle state and, where configured, is closed/archived:
87
+ When **all required** generated top-level children are terminal, the PRD rolls up to its `shipped` PRD-lifecycle state and remains open/active for the initiative-level verification loop:
88
88
 
89
- 1. **Transition to `shipped`.** Set the PRD to the configured `shipped` role (`config-resolution` PRD-lifecycle roles: `prd-shipped` label for GitHub/Linear, `Shipped` status for Notion, the shipped parent page for Confluence). The PRD lifecycle is `ready → in_review → (blocked | ticketed) → shipped → verified`; rollup performs the `ticketed → shipped` hop only, and only on the all-terminal condition. The subsequent `shipped → verified` (pass) / `shipped → blocked` (fail) hops are owned by PRD-level verification (`/lisa:verify-prd`), **not** by this rollup — see "PRD-level verification vs ticket verification" below.
90
- 2. **Config-gated close/archive.** When the source tool supports closure/archival *and* the project configures it, also close (GitHub: close the issue; Linear: move to a closed/archived state; JIRA: transition to Done; Confluence/Notion: archive where supported). Closure is **gated on configuration** via `prd.rollup.closeOnShipped` (`config-resolution`): when false (the default), the PRD is set to `shipped` but left open for a human to close; when true, rollup closes/archives it after the `shipped` transition. Never close a PRD before all generated top-level work is terminal (PRD #525 non-goal).
91
- 3. **Partial completion is a no-op + report.** If only some required children are terminal, leave the PRD in its current state and report the incomplete/blocked child set. Do not advance, do not close.
89
+ 1. **Transition to `shipped`.** Set the PRD to the configured `shipped` role (`config-resolution` PRD-lifecycle roles: `prd-shipped` label for GitHub/Linear, `Shipped` status for Notion, the shipped parent page for Confluence). The PRD lifecycle is `ready → in_review → (blocked | ticketed) → shipped → verified`; rollup performs the `ticketed → shipped` hop only, and only on the all-terminal condition. The subsequent `shipped → verified` (pass) / `shipped → ticketed` (fail) hops are owned by PRD-level verification (`/lisa:verify-prd`), **not** by this rollup — see "PRD-level verification vs ticket verification" below.
90
+ 2. **Leave `shipped` open for verification.** Rollup never closes, archives, or completes the PRD at the `shipped` hop. `shipped` is the queue for `/lisa:verify-prd`, so closing here would hide the PRD from the acceptance gate.
91
+ 3. **Verified closes natively.** When `/lisa:verify-prd` passes, it transitions `shipped verified` and then closes, archives, or completes the PRD where the source tool supports a native terminal action. The verified native close is mandatory and idempotent; there is no project-configurable close-on-verified escape hatch.
92
+ 4. **Partial completion is a no-op + report.** If only some required children are terminal, leave the PRD in its current state and report the incomplete/blocked child set. Do not advance, do not close.
92
93
 
93
94
  The PRD never advances to `shipped` on its own authority — it is **derived** from the generated-top-level-child set, exactly as a container's state is derived from its leaves in `leaf-only-lifecycle`.
94
95
 
@@ -118,7 +119,7 @@ The PRD never advances to `shipped` on its own authority — it is **derived** f
118
119
 
119
120
  **The self-healing FAIL loop.** When verify-prd fails it re-opens the PRD `shipped → ticketed` and creates **build-ready** fix tickets (registered as the PRD's generated work). Because the fix tickets are build-ready they are auto-claimed by the build queue with no human promotion; once they reach terminal, the `ticketed → shipped` rollup (Phase 3f) re-ships the PRD, and the next cycle's verify dispatch (Phase 3g) re-verifies. PASS ends at `verified`; FAIL starts another round. The loop **never auto-halts** (the failure report carries a verification-round count for human visibility) and **never** parks the PRD in `blocked`.
120
121
 
121
- Bounded, like the ready claim: `/lisa:verify-prd` is a heavy full flow (spec-conformance + empirical verification + fix-ticket creation), so a scanner verifies **one shipped PRD per cycle** and lets the scheduler drain the rest — the same one-item-per-cycle discipline the `ready` claim uses. After verify-prd runs, the PRD leaves `shipped` (to `verified` on pass, or `ticketed` on fail), so it is not re-picked by the shipped query that cycle; a PRD whose generated work is not actually terminal is guard-stopped by verify-prd and left `shipped` (verify-prd's gate, not the scanner's). A PRD that the project chose to close on ship (`*.rollup.closeOnShipped = true`) is out of the open verification queue — closing on ship is an explicit opt-out of the open loop. This dispatch is **behaviorally identical across all four PRD-intake skills** (the `github` / `linear` / `notion` / `confluence` `*-prd-intake` Phase 3g); only the `shipped`-role query surface differs.
122
+ Bounded, like the ready claim: `/lisa:verify-prd` is a heavy full flow (spec-conformance + empirical verification + fix-ticket creation), so a scanner verifies **one shipped PRD per cycle** and lets the scheduler drain the rest — the same one-item-per-cycle discipline the `ready` claim uses. After verify-prd runs, the PRD leaves `shipped` (to `verified` on pass, or `ticketed` on fail), so it is not re-picked by the shipped query that cycle; a PRD whose generated work is not actually terminal is guard-stopped by verify-prd and left `shipped` (verify-prd's gate, not the scanner's). This dispatch is **behaviorally identical across all four PRD-intake skills** (the `github` / `linear` / `notion` / `confluence` `*-prd-intake` Phase 3g); only the `shipped`-role query surface differs.
122
123
 
123
124
  ## Idempotency dedupe key
124
125
 
@@ -144,8 +145,8 @@ Skills that link generated work to a PRD or roll a PRD up cite this rule by slug
144
145
 
145
146
  - **PRD backlink / native linking** (`prd-backlink`) — record generated top-level work as native PRD children where supported; always write the documented generated-work fallback; dedupe by child-ref. *(LPC-1.1 #580, LPC-1.2 #582)*
146
147
  - **PRD coverage** (`prd-ticket-coverage`) — read the generated top-level child set deterministically from the recorded relationship, not from free-form comments.
147
- - **GitHub PRD closure rollup** (`github-prd-intake`) — detect terminal/incomplete/blocked child sets, transition to `prd-shipped`, and close the PRD issue when `prd.rollup.closeOnShipped` is configured. *(LPC-1.3 #583)*
148
- - **Linear / Confluence / Notion PRD rollup** (`linear-prd-intake`, `confluence-prd-intake`, `notion-prd-intake`) — mirror the GitHub closure rollup with each vendor's terminal predicate and close/archive support. *(LPC-1.3 #584)*
148
+ - **GitHub PRD shipped rollup** (`github-prd-intake`) — detect terminal/incomplete/blocked child sets, transition to `prd-shipped`, and leave the PRD open for `/lisa:verify-prd`. *(LPC-1.3 #583)*
149
+ - **Linear / Confluence / Notion PRD shipped rollup** (`linear-prd-intake`, `confluence-prd-intake`, `notion-prd-intake`) — mirror the GitHub shipped rollup with each vendor's terminal predicate and keep the PRD active for verification. *(LPC-1.3 #584)*
149
150
  - **Repair close-out** (`repair-intake`) — re-run the same generated-top-level-work terminal
150
151
  predicate to close out PRDs that were left open after all associated child work became terminal,
151
152
  without setting the product-owned `verified` role.
@@ -219,11 +219,6 @@ export function resolvePrdLifecycleRoles(
219
219
  DEFAULT_GITHUB_LINEAR_PRD_ROLES,
220
220
  { allowNull: false }
221
221
  ),
222
- rollup: {
223
- closeOnShipped: Boolean(
224
- config.github?.labels?.prd?.rollup?.closeOnShipped ?? false
225
- ),
226
- },
227
222
  };
228
223
  case "linear":
229
224
  return {
@@ -234,11 +229,6 @@ export function resolvePrdLifecycleRoles(
234
229
  DEFAULT_GITHUB_LINEAR_PRD_ROLES,
235
230
  { allowNull: false }
236
231
  ),
237
- rollup: {
238
- closeOnShipped: Boolean(
239
- config.linear?.labels?.prd?.rollup?.closeOnShipped ?? false
240
- ),
241
- },
242
232
  };
243
233
  case "notion":
244
234
  return {
@@ -250,11 +240,6 @@ export function resolvePrdLifecycleRoles(
250
240
  DEFAULT_NOTION_PRD_ROLES,
251
241
  { allowNull: false }
252
242
  ),
253
- rollup: {
254
- closeOnShipped: Boolean(
255
- config.notion?.rollup?.closeOnShipped ?? false
256
- ),
257
- },
258
243
  };
259
244
  case "confluence":
260
245
  return {
@@ -265,11 +250,6 @@ export function resolvePrdLifecycleRoles(
265
250
  DEFAULT_CONFLUENCE_PARENT_ROLES,
266
251
  { allowNull: true }
267
252
  ),
268
- rollup: {
269
- closeOnShipped: Boolean(
270
- config.confluence?.rollup?.closeOnShipped ?? false
271
- ),
272
- },
273
253
  };
274
254
  default:
275
255
  throw new Error(
@@ -59,26 +59,13 @@ current_role_for_prd() {
59
59
  done
60
60
  echo "unknown"
61
61
  }
62
-
63
- # Resolve a boolean rollup flag. Local overrides global per-key; default when unset.
64
- # NOTE: Confluence rollup config lives under `confluence.rollup` (NOT
65
- # `confluence.parents.rollup`) — see the config-resolution rule.
66
- read_rollup_flag() {
67
- local key="$1" default="$2"
68
- local local_v global_v
69
- local_v=$(jq -r ".confluence.rollup.${key} // empty" .lisa.config.local.json 2>/dev/null)
70
- global_v=$(jq -r ".confluence.rollup.${key} // empty" .lisa.config.json 2>/dev/null)
71
- echo "${local_v:-${global_v:-$default}}"
72
- }
73
-
74
- CLOSE_ON_SHIPPED=$(read_rollup_flag closeOnShipped false)
75
62
  ```
76
63
 
77
64
  In prose below, the role names refer to the resolved parent-page IDs: e.g. "the `ready` parent" means whatever `confluence.parents.ready` resolves to.
78
65
 
79
- This skill is the Confluence counterpart of `lisa:notion-prd-intake`, and shares its PRD closure rollup phase (3f) with `lisa:github-prd-intake` and `lisa:linear-prd-intake`. The phases, gates, comment templates, and rules are identical — the only differences are (1) the lifecycle is encoded as **parent-page placement** instead of a status property, and (2) the fetch / comment / update tools route through `lisa:atlassian-access`. Keep all four intake skills behaviorally aligned: when changing intake logic — including the rollup phase — change them together.
66
+ This skill is the Confluence counterpart of `lisa:notion-prd-intake`, and shares its PRD shipped rollup phase (3f) with `lisa:github-prd-intake` and `lisa:linear-prd-intake`. The phases, gates, comment templates, and rules are identical — the only differences are (1) the lifecycle is encoded as **parent-page placement** instead of a status property, and (2) the fetch / comment / update tools route through `lisa:atlassian-access`. Keep all four intake skills behaviorally aligned: when changing intake logic — including the rollup phase — change them together.
80
67
 
81
- The **PRD closure rollup phase (3f)** re-parents a `ticketed` PRD to the `shipped` parent (and optionally archives it) once all its generated top-level work is terminal, per the `prd-lifecycle-rollup` rule. This is the Confluence leg of the same vendor-neutral rollup that `lisa:github-prd-intake` implements for GitHub (LPC-1.3 #584); only the vendor surface (parent-page placement + documented generated-work section, since Confluence has no native ticket hierarchy) differs.
68
+ The **PRD shipped rollup phase (3f)** re-parents a `ticketed` PRD to the `shipped` parent once all its generated top-level work is terminal, per the `prd-lifecycle-rollup` rule. This is the Confluence leg of the same vendor-neutral rollup that `lisa:github-prd-intake` implements for GitHub (LPC-1.3 #584); only the vendor surface (parent-page placement + documented generated-work section, since Confluence has no native ticket hierarchy) differs.
82
69
 
83
70
  ## Confirmation policy
84
71
 
@@ -118,9 +105,9 @@ This skill transitions:
118
105
  - `in_review` → `blocked` (gate failures or coverage gaps)
119
106
  - `in_review` → `ticketed` (success)
120
107
  - `ticketed` → `blocked` (post-write coverage gaps from Phase 3e)
121
- - `ticketed` → `shipped` (PRD closure rollup, Phase 3f — only when **all** generated top-level children are terminal)
108
+ - `ticketed` → `shipped` (PRD shipped rollup, Phase 3f — only when **all** generated top-level children are terminal)
122
109
 
123
- It never re-parents PRDs into or out of the `draft` or `verified` parents — those parents are owned by product (`verified` is set by `/lisa:verify-prd` after empirical PRD-level acceptance). The `shipped` parent is set by this skill's **rollup phase (3f)** when, and only when, the PRD's generated top-level work is all terminal — per the `prd-lifecycle-rollup` rule; product may also re-parent there by hand. Rollup never advances a PRD to `shipped` on partial completion, and never archives a PRD page unless `confluence.rollup.closeOnShipped` is configured `true` (default `false` re-parent under `shipped`, leave the page active).
110
+ It never re-parents PRDs into or out of the `draft` or `verified` parents — those parents are owned by product (`verified` is set by `/lisa:verify-prd` after empirical PRD-level acceptance). The `shipped` parent is set by this skill's **rollup phase (3f)** when, and only when, the PRD's generated top-level work is all terminal — per the `prd-lifecycle-rollup` rule; product may also re-parent there by hand. Rollup never advances a PRD to `shipped` on partial completion, and never archives a PRD page at shipped. `/lisa:verify-prd` archives the page only after a verified PASS.
124
111
 
125
112
  A "transition" means: update the PRD's `parentId` to the new role's parent-page id via `lisa:atlassian-access` `operation: write-page payload: { id, parentId, title, version: { number: <next> } }`. The v2 PUT endpoint requires the next version number and the page title in the payload; the body content is not strictly required for a re-parent-only edit, but some Atlassian deployments reject PUTs without a body. The skill MUST therefore GET the page first via `read-page`, capture title + current version + current body, then PUT with `parentId` swapped and `version.number` bumped — preserving body content is non-negotiable, this skill never edits PRD content. See `transition_prd` helper in Phase 3a for the canonical implementation.
126
113
 
@@ -297,25 +284,19 @@ Per-ticket gates prove each ticket is well-formed; they do NOT prove the *set* o
297
284
 
298
285
  3. The created tickets remain in the destination tracker regardless of the verdict — they are valid in their own right. The audit only tells us whether *more* are needed.
299
286
 
300
- #### 3f. PRD closure rollup (config-gated)
287
+ #### 3f. PRD shipped rollup
301
288
 
302
289
  A PRD's lifecycle terminal state (`shipped`) is **derived** from whether the work it generated is done — it is never set by hand here on its own authority. This phase implements the Confluence leg of that derivation, per the `prd-lifecycle-rollup` rule (cite it by slug; do not restate its taxonomy or terminal-state semantics here). It is behaviorally identical to `lisa:github-prd-intake`'s Phase 3f — only the vendor surface (parent-page re-parenting via `lisa:atlassian-access` + the documented generated-work section) differs from GitHub's (issue close + labels via `gh`).
303
290
 
304
291
  Rollup runs over PRD pages that are already under the `ticketed` parent (the only state from which a PRD can ship): the freshly-ticketed PRD from Phase 3c, and — because rollup also catches PRDs whose children finished in a *later* cycle — every page currently parented under `$TICKETED_PARENT`. (Re-read its direct children via `lisa:atlassian-access` `operation: read-page-descendants id: $TICKETED_PARENT`.) Process each independently; one PRD never blocks another's rollup.
305
292
 
306
- ##### 3f.0 Resolve closure config
293
+ ##### 3f.0 Shipped remains active for verification
307
294
 
308
- Closure is gated on `confluence.rollup.closeOnShipped` (default `false`), resolved via `read_rollup_flag` (defined in the Workflow resolution block, same local-overrides-global precedence the lifecycle parents use). Note the config lives under `confluence.rollup` (NOT `confluence.parents.rollup`):
309
-
310
- ```bash
311
- CLOSE_ON_SHIPPED=$(read_rollup_flag closeOnShipped false)
312
- ```
313
-
314
- When `false` (the default), rollup re-parents the PRD under `$SHIPPED_PARENT` but leaves the page **active** for a human to archive. When `true`, rollup also archives the page (where the deployment supports archival) after the `shipped` re-parent. Closure NEVER happens before all generated top-level work is terminal (`prd-lifecycle-rollup` rule; PRD #525 non-goal).
295
+ There is no archive configuration at the shipped hop. Rollup re-parents the PRD under `$SHIPPED_PARENT` and leaves the page **active** so Phase 3g can dispatch `/lisa:verify-prd`. Provider-native archival is owned by `/lisa:verify-prd` after it transitions the PRD to the verified parent on a PASS.
315
296
 
316
297
  ##### 3f.1 Idempotency guard (no-op if already shipped)
317
298
 
318
- Rollup is keyed by the PRD's current state. If the PRD is already parented under `$SHIPPED_PARENT` (and is already archived, when `$CLOSE_ON_SHIPPED` is `true`), it is a **no-op** — do not re-parent, do not re-archive, do not re-comment. Record it as `already shipped (no-op)` in the cycle summary and move on. This is what makes re-running intake safe.
299
+ Rollup is keyed by the PRD's current state. If the PRD is already parented under `$SHIPPED_PARENT`, it is a **no-op** — do not re-parent, do not archive, do not re-comment. Record it as `already shipped (no-op)` in the cycle summary and move on. This is what makes re-running intake safe.
319
300
 
320
301
  ##### 3f.2 Read the generated top-level child set
321
302
 
@@ -340,7 +321,7 @@ The set of **required** children for the all-terminal check is the top-level chi
340
321
  **All required children terminal** (every required top-level child is terminal; at least one required child exists):
341
322
 
342
323
  1. Re-parent to `shipped`: `transition_prd "$PRD_ID" shipped` (GET-then-PUT via `lisa:atlassian-access` preserving the body verbatim). After the re-parent, re-read the page and confirm `parentId` matches `$SHIPPED_PARENT` (the single-parent invariant).
343
- 2. **If `$CLOSE_ON_SHIPPED` is `true`**, archive the PRD page where the deployment supports archival. When `false`, leave it active.
324
+ 2. Leave the PRD active for `/lisa:verify-prd`; do not archive at the shipped hop.
344
325
  3. Post a short rollup footer comment via `lisa:atlassian-access` `operation: comment-page kind: footer` naming the terminal child set and (when dropped children exist) the dropped set, so the audit trail records *why* the PRD shipped. Lead with `"Shipped by Claude — all generated top-level work is complete."`
345
326
 
346
327
  **Any required child incomplete / blocked**:
@@ -350,7 +331,7 @@ The set of **required** children for the all-terminal check is the top-level chi
350
331
 
351
332
  ##### 3f.5 Rollup cites the rule
352
333
 
353
- This phase implements exactly one PRD-lifecycle hop — `ticketed → shipped` — and the optional config-gated archive that follows it. All terminal-state semantics, the generated-top-level-work boundary, and the dedupe-by-child-ref idempotency come from the `prd-lifecycle-rollup` rule; this skill is its Confluence implementation, not a second source of truth.
334
+ This phase implements exactly one PRD-lifecycle hop — `ticketed → shipped` — and deliberately leaves native archival to `/lisa:verify-prd` after the verified PASS. All terminal-state semantics, the generated-top-level-work boundary, and the dedupe-by-child-ref idempotency come from the `prd-lifecycle-rollup` rule; this skill is its Confluence implementation, not a second source of truth.
354
335
 
355
336
  #### 3g. PRD verification dispatch (close the loop on shipped PRDs)
356
337
 
@@ -360,7 +341,7 @@ Re-query the PRDs currently parented under the shipped lifecycle parent via `lis
360
341
 
361
342
  **Per-cycle combined bound:** each scheduler cycle dispatches at most one ready PRD (the Phase 3 single-ready-PRD claim) **and** at most one shipped PRD for verification (this Phase 3g dispatch), for a maximum of two PRD operations per cycle. Ready intake runs first (Phase 3), then shipped verify (Phase 3g).
362
343
 
363
- `lisa:verify-prd` owns the outcome: on a CONFORMS verdict with all empirical checks passing it transitions the PRD to the verified parent and posts evidence; on a conformance miss or a failing/unavailable check it **re-parents the PRD shipped → ticketed** (never the blocked parent) and creates **build-ready** fix tickets registered as the PRD's generated work, then posts a failure report — the fix tickets auto-build, rollup (3f) re-ships the PRD once they are terminal, and a later cycle re-verifies (the self-healing loop). Either branch moves the PRD out of the shipped parent, so it is not re-picked this cycle; a PRD whose generated work is not actually terminal is guard-stopped by `lisa:verify-prd` (left under shipped) — that is verify-prd's gate, not this skill's. A PRD archived on ship (`confluence.rollup.closeOnShipped = true`) is out of the open verification queue. This phase, like 3f, is **behaviorally identical across all four intake skills** (`github-prd-intake`, `linear-prd-intake`, `notion-prd-intake`, `confluence-prd-intake`) — only the `$SHIPPED` query surface differs; keep them aligned. Record the dispatched PRD + verify-prd's verdict in the summary.
344
+ `lisa:verify-prd` owns the outcome: on a CONFORMS verdict with all empirical checks passing it transitions the PRD to the verified parent and posts evidence; on a conformance miss or a failing/unavailable check it **re-parents the PRD shipped → ticketed** (never the blocked parent) and creates **build-ready** fix tickets registered as the PRD's generated work, then posts a failure report — the fix tickets auto-build, rollup (3f) re-ships the PRD once they are terminal, and a later cycle re-verifies (the self-healing loop). Either branch moves the PRD out of the shipped parent, so it is not re-picked this cycle; a PRD whose generated work is not actually terminal is guard-stopped by `lisa:verify-prd` (left under shipped) — that is verify-prd's gate, not this skill's. This phase, like 3f, is **behaviorally identical across all four intake skills** (`github-prd-intake`, `linear-prd-intake`, `notion-prd-intake`, `confluence-prd-intake`) — only the `$SHIPPED` query surface differs; keep them aligned. Record the dispatched PRD + verify-prd's verdict in the summary.
364
345
 
365
346
  ### Phase 4 — Summary report
366
347
 
@@ -390,11 +371,11 @@ Print to the agent's output. Do not write this summary to Confluence or the dest
390
371
  ## Idempotency & safety
391
372
 
392
373
  - **One item per cycle**: this skill processes the first eligible ready PRD from Phase 2, then exits. New or remaining PRDs under the `ready` parent are picked up by later scheduler invocations.
393
- - **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa:confluence-to-tracker` (which delegates to `lisa:tracker-write`), and only ever re-parents PRDs among `in_review`, `blocked`, `ticketed`, and `shipped` (the last via the rollup phase 3f only) via `lisa:atlassian-access` `operation: write-page`. It never edits PRD body content, never re-parents into or out of `draft`, never deletes pages. It re-parents under `shipped` and may archive the PRD page **only** through the config-gated rollup phase (3f).
374
+ - **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa:confluence-to-tracker` (which delegates to `lisa:tracker-write`), and only ever re-parents PRDs among `in_review`, `blocked`, `ticketed`, and `shipped` (the last via the rollup phase 3f only) via `lisa:atlassian-access` `operation: write-page`. It never edits PRD body content, never re-parents into or out of `draft`, never archives pages at the shipped hop, and never deletes pages.
394
375
  - **Claim-first ordering**: the re-parent to `in_review` happens BEFORE validation runs, so a re-entrant call won't double-process.
395
376
  - **Failure handling**: an exception processing the selected PRD is caught and recorded under "Errors" in the summary, then the cycle exits. The PRD that errored is left under whatever parent it currently occupies (usually `in_review` if claim succeeded) — the human investigates from there.
396
377
  - **Single-parent invariant**: a page has exactly one parent by construction in Confluence — the multi-state ambiguity that label-based systems can hit (two `prd-*` labels simultaneously) cannot occur here. After every transition, re-read the page and confirm `parentId` matches the expected role; if not, surface as an Error and skip.
397
- - **Rollup idempotency**: rollup (Phase 3f) is a no-op on a PRD already parented under `$SHIPPED_PARENT` (and already archived when `closeOnShipped` is `true`) — no duplicate re-parent, no duplicate archive, no duplicate comment. The all-terminal condition is a pure function of the children's current states (deduped by child-ref identity), so recomputing it is safe to re-run. Archival NEVER precedes the all-terminal condition.
378
+ - **Rollup idempotency**: rollup (Phase 3f) is a no-op on a PRD already parented under `$SHIPPED_PARENT` — no duplicate re-parent, no shipped-time archive, no duplicate comment. The all-terminal condition is a pure function of the children's current states (deduped by child-ref identity), so recomputing it is safe to re-run. Native archival only follows verified PASS in `/lisa:verify-prd`.
398
379
 
399
380
  ## Configuration
400
381
 
@@ -413,13 +394,11 @@ Destination tracker config (jira / github / linear) is consumed by `lisa:tracker
413
394
  | `.lisa.config.json` `confluence.parents.ticketed` | yes | Parent page id for "successfully ticketed" |
414
395
  | `.lisa.config.json` `confluence.parents.draft` | recommended | Parent page id for PRDs still being drafted by product |
415
396
  | `.lisa.config.json` `confluence.parents.shipped` | recommended | Parent page id the rollup phase (3f) re-parents delivered PRDs under; product may also use it by hand |
416
- | `.lisa.config.json` `confluence.rollup.closeOnShipped` | no (default `false`) | When `true`, rollup archives the PRD page after the `shipped` re-parent; when `false`, re-parents under `shipped` and leaves the page active |
417
-
418
397
  ## Rules
419
398
 
420
399
  - Never write to the destination tracker outside of `lisa:confluence-to-tracker` → `lisa:tracker-write`. The validator's verdict gates progress; bypassing it produces broken tickets.
421
400
  - Never re-parent a PRD into a lifecycle parent this skill doesn't own (`in_review`, `blocked`, `ticketed`, and `shipped` via the rollup phase only). Product owns `draft` and `ready` (as the entry signal); product and the rollup phase (3f) both re-parent under `shipped`.
422
- - Re-parent under `shipped` (and archive the PRD page when `closeOnShipped` is configured) only from the rollup phase, and only when all generated top-level children are terminal per the `prd-lifecycle-rollup` rule. Never ship or archive on partial completion.
401
+ - Re-parent under `shipped` only from the rollup phase, and only when all generated top-level children are terminal per the `prd-lifecycle-rollup` rule. Never ship on partial completion and never archive at shipped.
423
402
  - Never edit the PRD's body. Communication with product happens only through Confluence comments. The `write-page` call preserves the body verbatim — fetch then PUT with body unchanged.
424
403
  - Never post a single page-level dump of all gate failures. One inline comment per `prd_anchor` group (or one footer summary for unanchored failures only). Comments must be inline-anchored where possible, categorized, plain-language, and contain a concrete recommendation.
425
404
  - Never include a gate ID, internal skill name, or engineering shorthand in a comment body.
@@ -39,7 +39,7 @@ In prose below, the role names refer to the resolved labels: e.g. "the `ready` l
39
39
 
40
40
  This skill is the GitHub counterpart of `lisa:notion-prd-intake`, `lisa:confluence-prd-intake`, and `lisa:linear-prd-intake`. Phases, gates, comment templates, and rules are identical — the only differences are (1) the lifecycle is encoded as **issue labels** (mirroring Linear's project labels and Confluence's page labels), (2) the fetch / update tools are the `gh` CLI, and (3) clarifying-question comments land directly on the source PRD issue (because GitHub Issues *do* have native comments — no sentinel issue required, unlike Linear). Keep all four skills behaviorally aligned: when changing intake logic, change them together.
41
41
 
42
- The **PRD closure rollup phase (3f)** transitions a `$TICKETED` PRD to `$SHIPPED` (and optionally closes it) once all its generated top-level work is terminal, per the `prd-lifecycle-rollup` rule. This phase is GitHub-only here because its vendor surface (issue close + labels via `gh`) is GitHub-specific; the Linear / Confluence / Notion intake skills carry the **same** vendor-neutral rollup with their own surfaces (sibling sub-task #584, now landed). All four intake skills are behaviorally aligned across the rollup phase too — keep them in sync when changing rollup logic.
42
+ The **PRD shipped rollup phase (3f)** transitions a `$TICKETED` PRD to `$SHIPPED` once all its generated top-level work is terminal, per the `prd-lifecycle-rollup` rule. This phase is GitHub-only here because its vendor surface (issue close + labels via `gh`) is GitHub-specific; the Linear / Confluence / Notion intake skills carry the **same** vendor-neutral rollup with their own surfaces (sibling sub-task #584, now landed). All four intake skills are behaviorally aligned across the rollup phase too — keep them in sync when changing rollup logic.
43
43
 
44
44
  ## Confirmation policy
45
45
 
@@ -79,9 +79,9 @@ This skill transitions:
79
79
  - `$IN_REVIEW` → `$BLOCKED` (gate failures or coverage gaps)
80
80
  - `$IN_REVIEW` → `$TICKETED` (success)
81
81
  - `$TICKETED` → `$BLOCKED` (post-write coverage gaps from Phase 3e)
82
- - `$TICKETED` → `$SHIPPED` (PRD closure rollup, Phase 3f — only when **all** generated top-level children are terminal)
82
+ - `$TICKETED` → `$SHIPPED` (PRD shipped rollup, Phase 3f — only when **all** generated top-level children are terminal)
83
83
 
84
- The `draft` and `verified` labels are owned by product and are never touched here (`verified` is set by `/lisa:verify-prd` after empirical PRD-level acceptance). The `shipped` label is set by this skill's **rollup phase (3f)** when, and only when, the PRD's generated top-level work is all terminal — per the `prd-lifecycle-rollup` rule; product may also set it by hand. Rollup never advances a PRD to `shipped` on partial completion, and never closes a PRD issue unless `github.labels.prd.rollup.closeOnShipped` is configured `true` (default `false` set `shipped`, leave open).
84
+ The `draft` and `verified` labels are owned by product and are never touched here (`verified` is set by `/lisa:verify-prd` after empirical PRD-level acceptance). The `shipped` label is set by this skill's **rollup phase (3f)** when, and only when, the PRD's generated top-level work is all terminal — per the `prd-lifecycle-rollup` rule; product may also set it by hand. Rollup never advances a PRD to `shipped` on partial completion, and never closes a PRD issue at shipped. `/lisa:verify-prd` closes the issue only after a verified PASS.
85
85
 
86
86
  A "transition" means: remove the old lifecycle label and add the new one (`gh issue edit <num> --remove-label <old> --add-label <new>`). The skill MUST verify exactly one lifecycle label is present after the update.
87
87
 
@@ -245,34 +245,19 @@ Per-ticket gates prove each ticket is well-formed; they do NOT prove the *set* o
245
245
 
246
246
  3. The created tickets remain in the destination tracker regardless of the verdict. The audit only tells us whether *more* are needed.
247
247
 
248
- #### 3f. PRD closure rollup (config-gated)
248
+ #### 3f. PRD shipped rollup
249
249
 
250
250
  A PRD's lifecycle terminal state (`shipped`) is **derived** from whether the work it generated is done — it is never set by hand here on its own authority. This phase implements the GitHub leg of that derivation, per the `prd-lifecycle-rollup` rule (cite it by slug; do not restate its taxonomy or terminal-state semantics here). Linear / Confluence / Notion rollup is a sibling sub-task (#584) and is out of scope for this skill.
251
251
 
252
252
  Rollup runs over PRD issues that are already `$TICKETED` (the only state from which a PRD can ship): the freshly-ticketed PRD from Phase 3c, and — because rollup also catches PRDs whose children finished in a *later* cycle — every issue currently carrying `$TICKETED`. Process each independently; one PRD never blocks another's rollup.
253
253
 
254
- ##### 3f.0 Resolve closure config
254
+ ##### 3f.0 Shipped remains open for verification
255
255
 
256
- Closure is gated on `github.labels.prd.rollup.closeOnShipped` (default `false`). Resolve it with the same local-overrides-global precedence the lifecycle labels use:
257
-
258
- ```bash
259
- # Resolve a boolean rollup flag. Local overrides global per-key; default when unset.
260
- read_rollup_flag() {
261
- local key="$1" default="$2"
262
- local local_v global_v
263
- local_v=$(jq -r ".github.labels.prd.rollup.${key} // empty" .lisa.config.local.json 2>/dev/null)
264
- global_v=$(jq -r ".github.labels.prd.rollup.${key} // empty" .lisa.config.json 2>/dev/null)
265
- echo "${local_v:-${global_v:-$default}}"
266
- }
267
-
268
- CLOSE_ON_SHIPPED=$(read_rollup_flag closeOnShipped false)
269
- ```
270
-
271
- When `false` (the default), rollup sets `$SHIPPED` but leaves the PRD issue **open** for a human to close. When `true`, rollup also closes the PRD issue after the `$SHIPPED` transition. Closure NEVER happens before all generated top-level work is terminal (`prd-lifecycle-rollup` rule; PRD #525 non-goal).
256
+ There is no close/archive configuration at the shipped hop. Rollup sets `$SHIPPED` and leaves the PRD issue **open** so Phase 3g can dispatch `/lisa:verify-prd`. Provider-native issue closure is owned by `/lisa:verify-prd` after it transitions `$SHIPPED → verified` on a PASS.
272
257
 
273
258
  ##### 3f.1 Idempotency guard (no-op if already shipped)
274
259
 
275
- Rollup is keyed by the PRD's current state. If the PRD already carries `$SHIPPED` (and is already closed, when `$CLOSE_ON_SHIPPED` is `true`), it is a **no-op** — do not re-transition, do not re-close, do not re-comment. Record it as `already shipped (no-op)` in the cycle summary and move on. This is what makes re-running intake safe.
260
+ Rollup is keyed by the PRD's current state. If the PRD already carries `$SHIPPED`, it is a **no-op** — do not re-transition, do not close, do not re-comment. Record it as `already shipped (no-op)` in the cycle summary and move on. This is what makes re-running intake safe.
276
261
 
277
262
  ##### 3f.2 Read the generated top-level child set
278
263
 
@@ -326,7 +311,7 @@ The set of **required** children for the all-terminal check is the top-level chi
326
311
  **All required children terminal** (every required top-level child is terminal; at least one required child exists):
327
312
 
328
313
  1. Transition labels: `gh issue edit <prd-num> --repo <org>/<repo> --remove-label "$TICKETED" --add-label "$SHIPPED"`. Verify exactly one lifecycle label remains (the single-label invariant).
329
- 2. **If `$CLOSE_ON_SHIPPED` is `true`**, close the PRD issue: `gh issue close <prd-num> --repo <org>/<repo> --reason completed`. When `false`, leave it open.
314
+ 2. Leave the PRD issue open for `/lisa:verify-prd`; do not close at the shipped hop.
330
315
  3. Post a short rollup comment naming the terminal child set and (when dropped children exist) the dropped set, so the audit trail records *why* the PRD shipped. Lead with `"Shipped by Claude — all generated top-level work is complete."`
331
316
 
332
317
  **Any required child incomplete / blocked**:
@@ -336,7 +321,7 @@ The set of **required** children for the all-terminal check is the top-level chi
336
321
 
337
322
  ##### 3f.5 Rollup is GitHub-only and cites the rule
338
323
 
339
- This phase only touches GitHub PRD issues. It implements exactly one PRD-lifecycle hop — `$TICKETED → $SHIPPED` — and the optional config-gated close that follows it. All terminal-state semantics, the generated-top-level-work boundary, the env-keyed `done` resolution, and the dedupe-by-child-ref idempotency come from the `prd-lifecycle-rollup` rule; this skill is its GitHub implementation, not a second source of truth.
324
+ This phase only touches GitHub PRD issues. It implements exactly one PRD-lifecycle hop — `$TICKETED → $SHIPPED` — and deliberately leaves native closure to `/lisa:verify-prd` after `$SHIPPED verified`. All terminal-state semantics, the generated-top-level-work boundary, the env-keyed `done` resolution, and the dedupe-by-child-ref idempotency come from the `prd-lifecycle-rollup` rule; this skill is its GitHub implementation, not a second source of truth.
340
325
 
341
326
  #### 3g. PRD verification dispatch (close the loop on shipped PRDs)
342
327
 
@@ -348,8 +333,6 @@ Re-query the PRDs currently carrying `$SHIPPED` via `gh issue list --repo <org>/
348
333
 
349
334
  `lisa:verify-prd` owns the outcome: on a CONFORMS verdict with all empirical checks passing it transitions `$SHIPPED → verified` and posts evidence; on a conformance miss or a failing/unavailable check it **re-opens the PRD `$SHIPPED → ticketed`** (never `blocked`) and creates **build-ready** fix tickets registered as the PRD's generated work, then posts a failure report — the fix tickets auto-build, rollup (3f) re-ships the PRD once they are terminal, and a later cycle re-verifies (the self-healing loop). Either branch moves the PRD out of `$SHIPPED`, so it is not re-picked this cycle; a PRD whose generated work is not actually terminal is guard-stopped by `lisa:verify-prd` (left `$SHIPPED`) — that is verify-prd's gate, not this skill's.
350
335
 
351
- **`closeOnShipped` constraint:** when `github.labels.prd.rollup.closeOnShipped = true`, issues are closed immediately after reaching `$SHIPPED`. This Phase 3g query (`--state open`) will not find them, so those PRDs are permanently excluded from `lisa:verify-prd` dispatch. If PRD verification is required, set `github.labels.prd.rollup.closeOnShipped = false` (or omit it); closing on ship is an explicit opt-out of the shipped→verified verification loop.
352
-
353
336
  This phase, like 3f, is **behaviorally identical across all four intake skills** (`github-prd-intake`, `linear-prd-intake`, `notion-prd-intake`, `confluence-prd-intake`) — only the `$SHIPPED` query surface differs; keep them aligned. Record the dispatched PRD + verify-prd's verdict in the summary.
354
337
 
355
338
  ### Phase 4 — Summary report
@@ -371,7 +354,7 @@ PRDs processed: <n>
371
354
 
372
355
  Rollup (Phase 3f):
373
356
  - $SHIPPED: <n>
374
- - <issue-ref> "<title>" → all <child-count> top-level children terminal (<dropped-count> dropped); closed: <yes|no (closeOnShipped off)>
357
+ - <issue-ref> "<title>" → all <child-count> top-level children terminal (<dropped-count> dropped); left open for verify-prd
375
358
  - Held open (incomplete children): <n>
376
359
  - <issue-ref> "<title>" → <incomplete-count> of <child-count> top-level children still open
377
360
  - Already shipped (no-op): <n>
@@ -394,11 +377,11 @@ When the configured destination tracker is GitHub Issues AND the PRD repo is the
394
377
  ## Idempotency & safety
395
378
 
396
379
  - **One item per cycle**: this skill processes the first eligible ready PRD issue from Phase 2, then exits. New or remaining ready issues are picked up by later scheduler invocations.
397
- - **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa:github-to-tracker` (which delegates to `lisa:tracker-write`), only ever changes labels among `$IN_REVIEW`, `$BLOCKED`, `$TICKETED`, `$SHIPPED`, only ever comments on the source PRD issue. It never edits PRD bodies and never touches the `draft` label. It sets the `$SHIPPED` label and may close the PRD issue **only** through the config-gated rollup phase (3f), and never deletes any issue.
380
+ - **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa:github-to-tracker` (which delegates to `lisa:tracker-write`), only ever changes labels among `$IN_REVIEW`, `$BLOCKED`, `$TICKETED`, `$SHIPPED`, only ever comments on the source PRD issue. It never edits PRD bodies, never touches the `draft` label, never closes PRD issues at the shipped hop, and never deletes any issue.
398
381
  - **Claim-first ordering**: the label flip to `$IN_REVIEW` happens BEFORE validation runs.
399
382
  - **Failure handling**: an exception processing the selected PRD is caught and recorded under "Errors" in the summary, then the cycle exits. The PRD that errored is left labeled `$IN_REVIEW` — humans investigate from there.
400
383
  - **Single-label invariant**: after every transition, verify exactly one lifecycle label is present.
401
- - **Rollup idempotency**: rollup (Phase 3f) is a no-op on a PRD already carrying `$SHIPPED` (and already closed when `closeOnShipped` is `true`) — no duplicate transition, no duplicate close, no duplicate comment. The all-terminal condition is a pure function of the children's current states, so recomputing it is safe to re-run. Closure NEVER precedes the all-terminal condition.
384
+ - **Rollup idempotency**: rollup (Phase 3f) is a no-op on a PRD already carrying `$SHIPPED` — no duplicate transition, no shipped-time close, no duplicate comment. The all-terminal condition is a pure function of the children's current states, so recomputing it is safe to re-run. Native closure only follows verified PASS in `/lisa:verify-prd`.
402
385
 
403
386
  ## Configuration
404
387
 
@@ -421,7 +404,7 @@ Destination tracker config (jira / github / linear) is consumed by `lisa:tracker
421
404
 
422
405
  - Never write to the destination tracker outside of `lisa:github-to-tracker` → `lisa:tracker-write`.
423
406
  - Never add or remove a label this skill doesn't own (`$IN_REVIEW`, `$BLOCKED`, `$TICKETED`, and `$SHIPPED` via the rollup phase only). Product owns the `draft` and `ready` PRD labels; product and the rollup phase (3f) both set `shipped`.
424
- - Set `$SHIPPED` (and close the PRD when `closeOnShipped` is configured) only from the rollup phase, and only when all generated top-level children are terminal per the `prd-lifecycle-rollup` rule. Never ship or close on partial completion.
407
+ - Set `$SHIPPED` only from the rollup phase, and only when all generated top-level children are terminal per the `prd-lifecycle-rollup` rule. Never ship on partial completion and never close at shipped.
425
408
  - Never edit a PRD's body. Communication with product happens only via comments.
426
409
  - Never post a single dump of all gate failures on one comment. One comment per `prd_anchor` group, plus one rollup for unanchored failures.
427
410
  - Never include a gate ID, internal skill name, or engineering shorthand in a comment body.