@codyswann/lisa 2.59.1 → 2.60.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.
- package/README.md +2 -0
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/rules/config-resolution.md +10 -7
- package/plugins/lisa/rules/prd-lifecycle-rollup.md +13 -0
- package/plugins/lisa/skills/github-build-intake/SKILL.md +22 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/src/base/rules/config-resolution.md +10 -7
- package/plugins/src/base/rules/prd-lifecycle-rollup.md +13 -0
- package/plugins/src/base/skills/github-build-intake/SKILL.md +22 -1
package/README.md
CHANGED
|
@@ -80,6 +80,8 @@ Most users only ever call `/lisa:research`, `/lisa:plan`, and `/lisa:implement`.
|
|
|
80
80
|
| --- | --- |
|
|
81
81
|
| `/lisa:intake <queue-url>` | Scans a Ready queue (Notion PRD database, JIRA project, GitHub repo, Linear team, Confluence space) and dispatches each item through the right lifecycle command. Designed as the cron target for unattended runs. |
|
|
82
82
|
|
|
83
|
+
PRD intake records generated work with native hierarchy where the source and tracker support it, and with a durable generated-work fallback everywhere else. The vendor matrix for GitHub, Linear, JIRA/Atlassian, Confluence, Notion, and cross-vendor queues lives in `plugins/src/base/rules/prd-lifecycle-rollup.md`.
|
|
84
|
+
|
|
83
85
|
### Maintenance and Operations
|
|
84
86
|
|
|
85
87
|
| Command | What it does |
|
package/package.json
CHANGED
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"lodash": ">=4.18.1"
|
|
83
83
|
},
|
|
84
84
|
"name": "@codyswann/lisa",
|
|
85
|
-
"version": "2.
|
|
85
|
+
"version": "2.60.0",
|
|
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": {
|
|
@@ -54,7 +54,8 @@ fi
|
|
|
54
54
|
"in_review": "<page-id>",
|
|
55
55
|
"blocked": "<page-id>",
|
|
56
56
|
"ticketed": "<page-id>",
|
|
57
|
-
"shipped": "<page-id>"
|
|
57
|
+
"shipped": "<page-id>",
|
|
58
|
+
"verified": "<page-id>"
|
|
58
59
|
},
|
|
59
60
|
"dashboardPageId": "<page-id>",
|
|
60
61
|
"feedbackPageId": "<page-id>",
|
|
@@ -75,7 +76,7 @@ fi
|
|
|
75
76
|
"draft": "prd-draft",
|
|
76
77
|
"ready": "prd-ready", "in_review": "prd-in-review",
|
|
77
78
|
"blocked": "prd-blocked", "ticketed": "prd-ticketed",
|
|
78
|
-
"shipped": "prd-shipped",
|
|
79
|
+
"shipped": "prd-shipped", "verified": "prd-verified",
|
|
79
80
|
"sentinel": "prd-intake-feedback",
|
|
80
81
|
"rollup": { "closeOnShipped": false }
|
|
81
82
|
}
|
|
@@ -87,7 +88,8 @@ fi
|
|
|
87
88
|
"statusProperty": "Status",
|
|
88
89
|
"values": {
|
|
89
90
|
"draft": "Draft", "ready": "Ready", "in_review": "In Review",
|
|
90
|
-
"blocked": "Blocked", "ticketed": "Ticketed", "shipped": "Shipped"
|
|
91
|
+
"blocked": "Blocked", "ticketed": "Ticketed", "shipped": "Shipped",
|
|
92
|
+
"verified": "Verified"
|
|
91
93
|
},
|
|
92
94
|
"rollup": { "closeOnShipped": false }
|
|
93
95
|
},
|
|
@@ -106,7 +108,7 @@ fi
|
|
|
106
108
|
"draft": "prd-draft",
|
|
107
109
|
"ready": "prd-ready", "in_review": "prd-in-review",
|
|
108
110
|
"blocked": "prd-blocked", "ticketed": "prd-ticketed",
|
|
109
|
-
"shipped": "prd-shipped",
|
|
111
|
+
"shipped": "prd-shipped", "verified": "prd-verified",
|
|
110
112
|
"sentinel": "prd-intake-feedback",
|
|
111
113
|
"rollup": { "closeOnShipped": false }
|
|
112
114
|
}
|
|
@@ -171,7 +173,7 @@ When `tracker = "github"` AND `source = "github"` (self-host), both reads and wr
|
|
|
171
173
|
| `notion.workspaceId` | `source = "notion"` | **committed** | Workspace identifier (Notion workspace UUID, or a stable human slug the user picks at setup). Same for every developer on the project. Used as the keychain `account` value when looking up the Notion API token, so each project's `notion-access` finds the right per-workspace token. |
|
|
172
174
|
| `notion.prdDatabaseId` | `source = "notion"` | **committed** | Notion database ID (UUID, dashes optional). The database is the PRD queue. Same for every developer on the project. |
|
|
173
175
|
| `notion.statusProperty` | `source = "notion"` | **committed** | Name of the database property that drives the lifecycle. Defaults to `"Status"` if absent. |
|
|
174
|
-
| `notion.values` | optional | **committed** | Map of role → Notion status-value name (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`). Defaults match the role names in title case. Override here if your Notion DB uses different value names. |
|
|
176
|
+
| `notion.values` | optional | **committed** | Map of role → Notion status-value name (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`, `verified`). Defaults match the role names in title case. Override here if your Notion DB uses different value names. |
|
|
175
177
|
|
|
176
178
|
#### `linear`
|
|
177
179
|
|
|
@@ -210,6 +212,7 @@ Every lifecycle skill operates on a fixed set of **roles** (`ready`, `claimed`,
|
|
|
210
212
|
| `blocked` | Validation failed; clarifying-comments posted | `Blocked` (status) | `prd-blocked` (label) |
|
|
211
213
|
| `ticketed` | Validated and tickets created | `Ticketed` (status) | `prd-ticketed` (label) |
|
|
212
214
|
| `shipped` | All child tickets shipped | `Shipped` (status) | `prd-shipped` (label) |
|
|
215
|
+
| `verified` | Shipped product empirically checked against the PRD | `Verified` (status) | `prd-verified` (label); parent-page lookup (Confluence) |
|
|
213
216
|
| `sentinel` | (PRD-intake feedback issue marker, GitHub/Linear self-host only) | — | `prd-intake-feedback` |
|
|
214
217
|
|
|
215
218
|
### PRD rollup config (`prd.rollup`)
|
|
@@ -245,7 +248,7 @@ The true terminal `done` value is also the only value that triggers provider-nat
|
|
|
245
248
|
### What's configurable, what's not
|
|
246
249
|
|
|
247
250
|
- **Status / label NAMES** are configurable per project — that's the point of the vocabulary maps.
|
|
248
|
-
- **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
|
|
251
|
+
- **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.
|
|
249
252
|
- **Extra statuses/labels** the project uses outside these roles are fine — lisa never touches them.
|
|
250
253
|
|
|
251
254
|
### Defaults vs. requirements
|
|
@@ -324,7 +327,7 @@ Initiatives (Linear's cross-Project rollup) are NOT used — they're intended fo
|
|
|
324
327
|
|
|
325
328
|
When `github-to-tracker` is invoked AND `tracker = "github"`, both reads and writes hit the same GitHub repo. Label namespaces are kept separate so the two flows don't collide:
|
|
326
329
|
|
|
327
|
-
- PRD-source labels: `prd-draft`, `prd-ready`, `prd-in-review`, `prd-blocked`, `prd-ticketed`, `prd-shipped` — owned by `github-prd-intake` and the human PM.
|
|
330
|
+
- PRD-source labels: `prd-draft`, `prd-ready`, `prd-in-review`, `prd-blocked`, `prd-ticketed`, `prd-shipped`, `prd-verified` — owned by `github-prd-intake`, `verify-prd`, and the human PM.
|
|
328
331
|
- Build-queue labels: `status:ready`, `status:in-progress`, `status:code-review`, `status:on-dev`, `status:done` — owned by `github-build-intake` and `github-agent`.
|
|
329
332
|
- Sentinel issue label: `prd-intake-feedback` — owned by `github-prd-intake`.
|
|
330
333
|
|
|
@@ -46,6 +46,19 @@ The relationship is recorded with the source tool's **native hierarchy first**,
|
|
|
46
46
|
|
|
47
47
|
The documented-section fallback is always written so the generated child set is readable later without relying only on free-form comments. Comment summaries are still useful human-facing audit trails and are not removed (PRD #525 non-goal).
|
|
48
48
|
|
|
49
|
+
### Vendor relationship and closure matrix
|
|
50
|
+
|
|
51
|
+
Use this matrix when implementing or auditing a PRD-source integration. It describes the native relationship to prefer, the documented fallback that must remain durable, and the closure behavior after the all-terminal rollup condition is met.
|
|
52
|
+
|
|
53
|
+
| PRD source / tracker shape | Native hierarchy mechanism | Documented fallback | Closure behavior |
|
|
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. |
|
|
61
|
+
|
|
49
62
|
## Per-vendor terminal-state predicate
|
|
50
63
|
|
|
51
64
|
A generated top-level child is **terminal** (counts as done for rollup) when it reaches the source/tracker's done/shipped state. The predicate is vendor-specific; the *semantics* ("this child has shipped") are not:
|
|
@@ -141,7 +141,7 @@ Build intake claims **only independently implementable leaf work units**. This e
|
|
|
141
141
|
|
|
142
142
|
Run this gate **before** the claim relabel, for every candidate issue. Do NOT relabel, comment "Claimed", or invoke `lisa:github-agent` for an issue that fails the gate.
|
|
143
143
|
|
|
144
|
-
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an issue is a **container** if it has **open** child work, whatever its declared type; otherwise the **type label** decides. Resolve child work using the same hierarchy `lisa:github-read-issue` uses — native sub-issues first, then body parentage (task-list checkboxes referencing other issues, `
|
|
144
|
+
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an issue is a **container** if it has **open** child work, whatever its declared type; otherwise the **type label** decides. Resolve child work using the same hierarchy `lisa:github-read-issue` uses — native sub-issues first, then body parentage (task-list checkboxes referencing other issues, `Parent: #<n>` references). Dependency links such as `Blocked by:` are not parentage; they are handled by the active dependency hold gate below.
|
|
145
145
|
|
|
146
146
|
```bash
|
|
147
147
|
# Native sub-issues via GraphQL (same query lisa:github-read-issue uses).
|
|
@@ -182,6 +182,24 @@ gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Not
|
|
|
182
182
|
|
|
183
183
|
This gate never blocks a legitimate flat Task/Bug: those have no open children and a leaf `type:`, so they fall straight through to the claim in 3b.
|
|
184
184
|
|
|
185
|
+
**Active dependency hold gate.** After the leaf-only gate passes, but still before the claim relabel, parse explicit blocker relationships from the issue body and durable Lisa relationship sections. Support these forms at minimum:
|
|
186
|
+
|
|
187
|
+
- `Blocked by: #123`
|
|
188
|
+
- `Blocked by: #123, #456`
|
|
189
|
+
- `Blocked by: owner/repo#123`
|
|
190
|
+
- `Blocked by: https://github.com/owner/repo/issues/123`
|
|
191
|
+
|
|
192
|
+
Resolve local `#123` references against the candidate issue's repo. Resolve qualified refs and GitHub issue URLs against their named repo. For each blocker, read the blocker issue's status labels with `gh issue view <number> --repo <owner>/<repo> --json labels,state`.
|
|
193
|
+
|
|
194
|
+
Default cleared blocker labels for GitHub build intake are:
|
|
195
|
+
|
|
196
|
+
- `status:code-review`
|
|
197
|
+
- `status:on-dev`
|
|
198
|
+
- `status:on-stg`
|
|
199
|
+
- `status:done`
|
|
200
|
+
|
|
201
|
+
A blocker is active if it is open and has no cleared status label. Treat `status:ready`, `status:in-progress`, missing status labels, and inaccessible blockers as active. Closed blockers are cleared. If any blocker is active, skip the candidate without changing lifecycle labels, without posting "Claimed", and without invoking `lisa:github-agent`. Record it under "Skipped (active blockers)" in the summary and include the active blocker refs. Keep any dependency-hold comment idempotent with a `[claude-build-intake]` prefix.
|
|
202
|
+
|
|
185
203
|
#### 3b. Claim
|
|
186
204
|
|
|
187
205
|
```bash
|
|
@@ -253,6 +271,8 @@ Issues processed: <n>
|
|
|
253
271
|
- <org>/<repo>#<number> <title> → PR <URL>
|
|
254
272
|
- Skipped (container — leaf-only-lifecycle): <n>
|
|
255
273
|
- <org>/<repo>#<number> <title> — build-ready on a parent with open child work; lifecycle-repair comment posted
|
|
274
|
+
- Skipped (active blockers): <n>
|
|
275
|
+
- <org>/<repo>#<number> <title> — waiting on <blocker refs>
|
|
256
276
|
- Blocked (pre-flight verify failed): <n>
|
|
257
277
|
- <org>/<repo>#<number> <title> — see issue comments
|
|
258
278
|
- Held (triage found ambiguities): <n>
|
|
@@ -266,6 +286,7 @@ Total PRs opened: <n>
|
|
|
266
286
|
## Idempotency & safety
|
|
267
287
|
|
|
268
288
|
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic/Story/Spike) is skipped/safe-blocked, never claimed. The safe-block comment is idempotent — a re-entrant cycle does not re-post it.
|
|
289
|
+
- **Dependency hold runs before claim**: explicit `Blocked by:` relationships are resolved before `$READY → $CLAIMED`; active blockers leave the candidate in `$READY` and are reported as skipped, not blocked.
|
|
269
290
|
- **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:github-agent` invocation — no double-pickup.
|
|
270
291
|
- **No writes outside the lifecycle**: this skill only relabels `$READY → $CLAIMED` and `$CLAIMED → $DONE`. Every other label change is owned by `lisa:github-agent`.
|
|
271
292
|
- **Terminal native closure**: after `$CLAIMED → $DONE`, close the GitHub issue only when `$DONE` is the true terminal done value per `leaf-only-lifecycle`; intermediate env labels stay open.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.60.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.60.0",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -54,7 +54,8 @@ fi
|
|
|
54
54
|
"in_review": "<page-id>",
|
|
55
55
|
"blocked": "<page-id>",
|
|
56
56
|
"ticketed": "<page-id>",
|
|
57
|
-
"shipped": "<page-id>"
|
|
57
|
+
"shipped": "<page-id>",
|
|
58
|
+
"verified": "<page-id>"
|
|
58
59
|
},
|
|
59
60
|
"dashboardPageId": "<page-id>",
|
|
60
61
|
"feedbackPageId": "<page-id>",
|
|
@@ -75,7 +76,7 @@ fi
|
|
|
75
76
|
"draft": "prd-draft",
|
|
76
77
|
"ready": "prd-ready", "in_review": "prd-in-review",
|
|
77
78
|
"blocked": "prd-blocked", "ticketed": "prd-ticketed",
|
|
78
|
-
"shipped": "prd-shipped",
|
|
79
|
+
"shipped": "prd-shipped", "verified": "prd-verified",
|
|
79
80
|
"sentinel": "prd-intake-feedback",
|
|
80
81
|
"rollup": { "closeOnShipped": false }
|
|
81
82
|
}
|
|
@@ -87,7 +88,8 @@ fi
|
|
|
87
88
|
"statusProperty": "Status",
|
|
88
89
|
"values": {
|
|
89
90
|
"draft": "Draft", "ready": "Ready", "in_review": "In Review",
|
|
90
|
-
"blocked": "Blocked", "ticketed": "Ticketed", "shipped": "Shipped"
|
|
91
|
+
"blocked": "Blocked", "ticketed": "Ticketed", "shipped": "Shipped",
|
|
92
|
+
"verified": "Verified"
|
|
91
93
|
},
|
|
92
94
|
"rollup": { "closeOnShipped": false }
|
|
93
95
|
},
|
|
@@ -106,7 +108,7 @@ fi
|
|
|
106
108
|
"draft": "prd-draft",
|
|
107
109
|
"ready": "prd-ready", "in_review": "prd-in-review",
|
|
108
110
|
"blocked": "prd-blocked", "ticketed": "prd-ticketed",
|
|
109
|
-
"shipped": "prd-shipped",
|
|
111
|
+
"shipped": "prd-shipped", "verified": "prd-verified",
|
|
110
112
|
"sentinel": "prd-intake-feedback",
|
|
111
113
|
"rollup": { "closeOnShipped": false }
|
|
112
114
|
}
|
|
@@ -171,7 +173,7 @@ When `tracker = "github"` AND `source = "github"` (self-host), both reads and wr
|
|
|
171
173
|
| `notion.workspaceId` | `source = "notion"` | **committed** | Workspace identifier (Notion workspace UUID, or a stable human slug the user picks at setup). Same for every developer on the project. Used as the keychain `account` value when looking up the Notion API token, so each project's `notion-access` finds the right per-workspace token. |
|
|
172
174
|
| `notion.prdDatabaseId` | `source = "notion"` | **committed** | Notion database ID (UUID, dashes optional). The database is the PRD queue. Same for every developer on the project. |
|
|
173
175
|
| `notion.statusProperty` | `source = "notion"` | **committed** | Name of the database property that drives the lifecycle. Defaults to `"Status"` if absent. |
|
|
174
|
-
| `notion.values` | optional | **committed** | Map of role → Notion status-value name (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`). Defaults match the role names in title case. Override here if your Notion DB uses different value names. |
|
|
176
|
+
| `notion.values` | optional | **committed** | Map of role → Notion status-value name (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`, `verified`). Defaults match the role names in title case. Override here if your Notion DB uses different value names. |
|
|
175
177
|
|
|
176
178
|
#### `linear`
|
|
177
179
|
|
|
@@ -210,6 +212,7 @@ Every lifecycle skill operates on a fixed set of **roles** (`ready`, `claimed`,
|
|
|
210
212
|
| `blocked` | Validation failed; clarifying-comments posted | `Blocked` (status) | `prd-blocked` (label) |
|
|
211
213
|
| `ticketed` | Validated and tickets created | `Ticketed` (status) | `prd-ticketed` (label) |
|
|
212
214
|
| `shipped` | All child tickets shipped | `Shipped` (status) | `prd-shipped` (label) |
|
|
215
|
+
| `verified` | Shipped product empirically checked against the PRD | `Verified` (status) | `prd-verified` (label); parent-page lookup (Confluence) |
|
|
213
216
|
| `sentinel` | (PRD-intake feedback issue marker, GitHub/Linear self-host only) | — | `prd-intake-feedback` |
|
|
214
217
|
|
|
215
218
|
### PRD rollup config (`prd.rollup`)
|
|
@@ -245,7 +248,7 @@ The true terminal `done` value is also the only value that triggers provider-nat
|
|
|
245
248
|
### What's configurable, what's not
|
|
246
249
|
|
|
247
250
|
- **Status / label NAMES** are configurable per project — that's the point of the vocabulary maps.
|
|
248
|
-
- **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
|
|
251
|
+
- **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.
|
|
249
252
|
- **Extra statuses/labels** the project uses outside these roles are fine — lisa never touches them.
|
|
250
253
|
|
|
251
254
|
### Defaults vs. requirements
|
|
@@ -324,7 +327,7 @@ Initiatives (Linear's cross-Project rollup) are NOT used — they're intended fo
|
|
|
324
327
|
|
|
325
328
|
When `github-to-tracker` is invoked AND `tracker = "github"`, both reads and writes hit the same GitHub repo. Label namespaces are kept separate so the two flows don't collide:
|
|
326
329
|
|
|
327
|
-
- PRD-source labels: `prd-draft`, `prd-ready`, `prd-in-review`, `prd-blocked`, `prd-ticketed`, `prd-shipped` — owned by `github-prd-intake` and the human PM.
|
|
330
|
+
- PRD-source labels: `prd-draft`, `prd-ready`, `prd-in-review`, `prd-blocked`, `prd-ticketed`, `prd-shipped`, `prd-verified` — owned by `github-prd-intake`, `verify-prd`, and the human PM.
|
|
328
331
|
- Build-queue labels: `status:ready`, `status:in-progress`, `status:code-review`, `status:on-dev`, `status:done` — owned by `github-build-intake` and `github-agent`.
|
|
329
332
|
- Sentinel issue label: `prd-intake-feedback` — owned by `github-prd-intake`.
|
|
330
333
|
|
|
@@ -46,6 +46,19 @@ The relationship is recorded with the source tool's **native hierarchy first**,
|
|
|
46
46
|
|
|
47
47
|
The documented-section fallback is always written so the generated child set is readable later without relying only on free-form comments. Comment summaries are still useful human-facing audit trails and are not removed (PRD #525 non-goal).
|
|
48
48
|
|
|
49
|
+
### Vendor relationship and closure matrix
|
|
50
|
+
|
|
51
|
+
Use this matrix when implementing or auditing a PRD-source integration. It describes the native relationship to prefer, the documented fallback that must remain durable, and the closure behavior after the all-terminal rollup condition is met.
|
|
52
|
+
|
|
53
|
+
| PRD source / tracker shape | Native hierarchy mechanism | Documented fallback | Closure behavior |
|
|
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. |
|
|
61
|
+
|
|
49
62
|
## Per-vendor terminal-state predicate
|
|
50
63
|
|
|
51
64
|
A generated top-level child is **terminal** (counts as done for rollup) when it reaches the source/tracker's done/shipped state. The predicate is vendor-specific; the *semantics* ("this child has shipped") are not:
|
|
@@ -141,7 +141,7 @@ Build intake claims **only independently implementable leaf work units**. This e
|
|
|
141
141
|
|
|
142
142
|
Run this gate **before** the claim relabel, for every candidate issue. Do NOT relabel, comment "Claimed", or invoke `lisa:github-agent` for an issue that fails the gate.
|
|
143
143
|
|
|
144
|
-
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an issue is a **container** if it has **open** child work, whatever its declared type; otherwise the **type label** decides. Resolve child work using the same hierarchy `lisa:github-read-issue` uses — native sub-issues first, then body parentage (task-list checkboxes referencing other issues, `
|
|
144
|
+
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an issue is a **container** if it has **open** child work, whatever its declared type; otherwise the **type label** decides. Resolve child work using the same hierarchy `lisa:github-read-issue` uses — native sub-issues first, then body parentage (task-list checkboxes referencing other issues, `Parent: #<n>` references). Dependency links such as `Blocked by:` are not parentage; they are handled by the active dependency hold gate below.
|
|
145
145
|
|
|
146
146
|
```bash
|
|
147
147
|
# Native sub-issues via GraphQL (same query lisa:github-read-issue uses).
|
|
@@ -182,6 +182,24 @@ gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Not
|
|
|
182
182
|
|
|
183
183
|
This gate never blocks a legitimate flat Task/Bug: those have no open children and a leaf `type:`, so they fall straight through to the claim in 3b.
|
|
184
184
|
|
|
185
|
+
**Active dependency hold gate.** After the leaf-only gate passes, but still before the claim relabel, parse explicit blocker relationships from the issue body and durable Lisa relationship sections. Support these forms at minimum:
|
|
186
|
+
|
|
187
|
+
- `Blocked by: #123`
|
|
188
|
+
- `Blocked by: #123, #456`
|
|
189
|
+
- `Blocked by: owner/repo#123`
|
|
190
|
+
- `Blocked by: https://github.com/owner/repo/issues/123`
|
|
191
|
+
|
|
192
|
+
Resolve local `#123` references against the candidate issue's repo. Resolve qualified refs and GitHub issue URLs against their named repo. For each blocker, read the blocker issue's status labels with `gh issue view <number> --repo <owner>/<repo> --json labels,state`.
|
|
193
|
+
|
|
194
|
+
Default cleared blocker labels for GitHub build intake are:
|
|
195
|
+
|
|
196
|
+
- `status:code-review`
|
|
197
|
+
- `status:on-dev`
|
|
198
|
+
- `status:on-stg`
|
|
199
|
+
- `status:done`
|
|
200
|
+
|
|
201
|
+
A blocker is active if it is open and has no cleared status label. Treat `status:ready`, `status:in-progress`, missing status labels, and inaccessible blockers as active. Closed blockers are cleared. If any blocker is active, skip the candidate without changing lifecycle labels, without posting "Claimed", and without invoking `lisa:github-agent`. Record it under "Skipped (active blockers)" in the summary and include the active blocker refs. Keep any dependency-hold comment idempotent with a `[claude-build-intake]` prefix.
|
|
202
|
+
|
|
185
203
|
#### 3b. Claim
|
|
186
204
|
|
|
187
205
|
```bash
|
|
@@ -253,6 +271,8 @@ Issues processed: <n>
|
|
|
253
271
|
- <org>/<repo>#<number> <title> → PR <URL>
|
|
254
272
|
- Skipped (container — leaf-only-lifecycle): <n>
|
|
255
273
|
- <org>/<repo>#<number> <title> — build-ready on a parent with open child work; lifecycle-repair comment posted
|
|
274
|
+
- Skipped (active blockers): <n>
|
|
275
|
+
- <org>/<repo>#<number> <title> — waiting on <blocker refs>
|
|
256
276
|
- Blocked (pre-flight verify failed): <n>
|
|
257
277
|
- <org>/<repo>#<number> <title> — see issue comments
|
|
258
278
|
- Held (triage found ambiguities): <n>
|
|
@@ -266,6 +286,7 @@ Total PRs opened: <n>
|
|
|
266
286
|
## Idempotency & safety
|
|
267
287
|
|
|
268
288
|
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic/Story/Spike) is skipped/safe-blocked, never claimed. The safe-block comment is idempotent — a re-entrant cycle does not re-post it.
|
|
289
|
+
- **Dependency hold runs before claim**: explicit `Blocked by:` relationships are resolved before `$READY → $CLAIMED`; active blockers leave the candidate in `$READY` and are reported as skipped, not blocked.
|
|
269
290
|
- **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:github-agent` invocation — no double-pickup.
|
|
270
291
|
- **No writes outside the lifecycle**: this skill only relabels `$READY → $CLAIMED` and `$CLAIMED → $DONE`. Every other label change is owned by `lisa:github-agent`.
|
|
271
292
|
- **Terminal native closure**: after `$CLAIMED → $DONE`, close the GitHub issue only when `$DONE` is the true terminal done value per `leaf-only-lifecycle`; intermediate env labels stay open.
|