@codyswann/lisa 2.61.0 → 2.62.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/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/agents/confluence-prd-intake.md +1 -1
- package/plugins/lisa/agents/github-agent.md +4 -5
- package/plugins/lisa/agents/github-build-intake.md +1 -1
- package/plugins/lisa/agents/github-prd-intake.md +1 -1
- package/plugins/lisa/agents/linear-prd-intake.md +1 -1
- package/plugins/lisa/agents/notion-prd-intake.md +1 -1
- package/plugins/lisa/commands/intake.md +1 -1
- package/plugins/lisa/commands/project-ideation.md +3 -3
- package/plugins/lisa/commands/repair-intake.md +6 -0
- package/plugins/lisa/commands/research.md +3 -3
- package/plugins/lisa/commands/setup-automations.md +6 -0
- package/plugins/lisa/commands/tear-down-automations.md +6 -0
- package/plugins/lisa/commands/verify-prd.md +2 -2
- package/plugins/lisa/rules/config-resolution.md +63 -4
- package/plugins/lisa/rules/intent-routing.md +4 -3
- package/plugins/lisa/rules/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa/rules/prd-lifecycle-rollup.md +10 -2
- package/plugins/lisa/rules/repo-scope-split.md +18 -1
- package/plugins/lisa/skills/confluence-prd-intake/SKILL.md +24 -14
- package/plugins/lisa/skills/confluence-prd-intake/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/confluence-write-prd/SKILL.md +103 -0
- package/plugins/lisa/skills/confluence-write-prd/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/github-build-intake/SKILL.md +32 -21
- package/plugins/lisa/skills/github-evidence/SKILL.md +3 -26
- package/plugins/lisa/skills/github-evidence/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/github-journey/SKILL.md +2 -2
- package/plugins/lisa/skills/github-prd-intake/SKILL.md +25 -11
- package/plugins/lisa/skills/github-prd-intake/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/github-sync/SKILL.md +5 -5
- package/plugins/lisa/skills/github-write-issue/SKILL.md +15 -6
- package/plugins/lisa/skills/github-write-prd/SKILL.md +100 -0
- package/plugins/lisa/skills/github-write-prd/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/implement/SKILL.md +13 -6
- package/plugins/lisa/skills/intake/SKILL.md +13 -12
- package/plugins/lisa/skills/intake/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/jira-build-intake/SKILL.md +24 -11
- package/plugins/lisa/skills/jira-write-ticket/SKILL.md +8 -0
- package/plugins/lisa/skills/linear-build-intake/SKILL.md +22 -9
- package/plugins/lisa/skills/linear-prd-intake/SKILL.md +23 -13
- package/plugins/lisa/skills/linear-prd-intake/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/linear-write-issue/SKILL.md +10 -2
- package/plugins/lisa/skills/linear-write-prd/SKILL.md +90 -0
- package/plugins/lisa/skills/linear-write-prd/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/notion-access/SKILL.md +2 -0
- package/plugins/lisa/skills/notion-prd-intake/SKILL.md +22 -12
- package/plugins/lisa/skills/notion-prd-intake/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/notion-write-prd/SKILL.md +107 -0
- package/plugins/lisa/skills/notion-write-prd/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/prd-source-write/SKILL.md +80 -0
- package/plugins/lisa/skills/prd-source-write/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/project-ideation/SKILL.md +183 -80
- package/plugins/lisa/skills/repair-intake/SKILL.md +403 -0
- package/plugins/lisa/skills/repair-intake/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/research/SKILL.md +19 -3
- package/plugins/lisa/skills/research/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/setup-automations/SKILL.md +78 -0
- package/plugins/lisa/skills/setup-automations/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/setup-github/SKILL.md +0 -1
- package/plugins/lisa/skills/tear-down-automations/SKILL.md +34 -0
- package/plugins/lisa/skills/tear-down-automations/agents/openai.yaml +4 -0
- package/plugins/lisa/skills/tracker-build-intake/SKILL.md +6 -2
- package/plugins/lisa/skills/tracker-build-intake/agents/openai.yaml +2 -2
- package/plugins/lisa/skills/tracker-evidence/SKILL.md +2 -2
- package/plugins/lisa/skills/tracker-sync/SKILL.md +1 -1
- package/plugins/lisa/skills/verify-prd/SKILL.md +41 -38
- 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-expo/commands/exploratory-qa.md +3 -3
- package/plugins/lisa-expo/skills/exploratory-qa/SKILL.md +48 -18
- package/plugins/lisa-expo/skills/exploratory-qa/agents/openai.yaml +2 -2
- 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-harper-fabric/commands/exploratory-qa.md +3 -3
- package/plugins/lisa-harper-fabric/skills/exploratory-qa/SKILL.md +48 -18
- package/plugins/lisa-harper-fabric/skills/exploratory-qa/agents/openai.yaml +2 -2
- 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-rails/commands/exploratory-qa.md +3 -3
- package/plugins/lisa-rails/skills/exploratory-qa/SKILL.md +48 -18
- package/plugins/lisa-rails/skills/exploratory-qa/agents/openai.yaml +2 -2
- 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/lisa-wiki/skills/lisa-wiki-ingest/SKILL.md +30 -1
- package/plugins/src/base/agents/confluence-prd-intake.md +1 -1
- package/plugins/src/base/agents/github-agent.md +4 -5
- package/plugins/src/base/agents/github-build-intake.md +1 -1
- package/plugins/src/base/agents/github-prd-intake.md +1 -1
- package/plugins/src/base/agents/linear-prd-intake.md +1 -1
- package/plugins/src/base/agents/notion-prd-intake.md +1 -1
- package/plugins/src/base/commands/intake.md +1 -1
- package/plugins/src/base/commands/project-ideation.md +3 -3
- package/plugins/src/base/commands/repair-intake.md +6 -0
- package/plugins/src/base/commands/research.md +3 -3
- package/plugins/src/base/commands/setup-automations.md +6 -0
- package/plugins/src/base/commands/tear-down-automations.md +6 -0
- package/plugins/src/base/commands/verify-prd.md +2 -2
- package/plugins/src/base/rules/config-resolution.md +63 -4
- package/plugins/src/base/rules/intent-routing.md +4 -3
- package/plugins/src/base/rules/leaf-only-lifecycle.md +1 -1
- package/plugins/src/base/rules/prd-lifecycle-rollup.md +10 -2
- package/plugins/src/base/rules/repo-scope-split.md +18 -1
- package/plugins/src/base/skills/confluence-prd-intake/SKILL.md +24 -14
- package/plugins/src/base/skills/confluence-write-prd/SKILL.md +103 -0
- package/plugins/src/base/skills/github-build-intake/SKILL.md +32 -21
- package/plugins/src/base/skills/github-evidence/SKILL.md +3 -26
- package/plugins/src/base/skills/github-journey/SKILL.md +2 -2
- package/plugins/src/base/skills/github-prd-intake/SKILL.md +25 -11
- package/plugins/src/base/skills/github-sync/SKILL.md +5 -5
- package/plugins/src/base/skills/github-write-issue/SKILL.md +15 -6
- package/plugins/src/base/skills/github-write-prd/SKILL.md +100 -0
- package/plugins/src/base/skills/implement/SKILL.md +13 -6
- package/plugins/src/base/skills/intake/SKILL.md +13 -12
- package/plugins/src/base/skills/jira-build-intake/SKILL.md +24 -11
- package/plugins/src/base/skills/jira-write-ticket/SKILL.md +8 -0
- package/plugins/src/base/skills/linear-build-intake/SKILL.md +22 -9
- package/plugins/src/base/skills/linear-prd-intake/SKILL.md +23 -13
- package/plugins/src/base/skills/linear-write-issue/SKILL.md +10 -2
- package/plugins/src/base/skills/linear-write-prd/SKILL.md +90 -0
- package/plugins/src/base/skills/notion-access/SKILL.md +2 -0
- package/plugins/src/base/skills/notion-prd-intake/SKILL.md +22 -12
- package/plugins/src/base/skills/notion-write-prd/SKILL.md +107 -0
- package/plugins/src/base/skills/prd-source-write/SKILL.md +80 -0
- package/plugins/src/base/skills/project-ideation/SKILL.md +183 -80
- package/plugins/src/base/skills/repair-intake/SKILL.md +403 -0
- package/plugins/src/base/skills/research/SKILL.md +19 -3
- package/plugins/src/base/skills/setup-automations/SKILL.md +78 -0
- package/plugins/src/base/skills/setup-github/SKILL.md +0 -1
- package/plugins/src/base/skills/tear-down-automations/SKILL.md +34 -0
- package/plugins/src/base/skills/tracker-build-intake/SKILL.md +6 -2
- package/plugins/src/base/skills/tracker-evidence/SKILL.md +2 -2
- package/plugins/src/base/skills/tracker-sync/SKILL.md +1 -1
- package/plugins/src/base/skills/verify-prd/SKILL.md +41 -38
- package/plugins/src/expo/commands/exploratory-qa.md +3 -3
- package/plugins/src/expo/skills/exploratory-qa/SKILL.md +48 -18
- package/plugins/src/harper-fabric/commands/exploratory-qa.md +3 -3
- package/plugins/src/harper-fabric/skills/exploratory-qa/SKILL.md +48 -18
- package/plugins/src/rails/commands/exploratory-qa.md +3 -3
- package/plugins/src/rails/skills/exploratory-qa/SKILL.md +48 -18
- package/plugins/src/wiki/skills/lisa-wiki-ingest/SKILL.md +30 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: confluence-write-prd
|
|
3
|
+
description: "Creates or idempotently updates a PRD as a Confluence page parented under the configured lifecycle parent page (the draft parent by default, or the ready parent when initial_role is ready so lisa:confluence-prd-intake auto-claims it). The Confluence PRD-source writer behind lisa:prd-source-write. Confluence models PRD state by PARENT PAGE (not labels), per config-resolution. Dedupes by a stable marker embedded in the page body, found via CQL (matched by marker, never by title). All Atlassian access goes through lisa:atlassian-access."
|
|
4
|
+
allowed-tools: ["Skill", "Bash"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Write Confluence PRD: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Create (or update) a PRD page in Confluence. Invoked by `lisa:prd-source-write` when
|
|
10
|
+
`source = confluence`; do not call directly from a vendor-neutral caller. **All Confluence
|
|
11
|
+
operations go through `lisa:atlassian-access`** — never call the Atlassian API/MCP or `acli` directly.
|
|
12
|
+
|
|
13
|
+
Confluence's PRD lifecycle uses **parent pages**, not labels (scoped API tokens can't write
|
|
14
|
+
Confluence labels — see `config-resolution` "Confluence PRD lifecycle uses parent pages"). A PRD's
|
|
15
|
+
state is which lifecycle parent it lives under; "promote to ready" = re-parent to the ready parent.
|
|
16
|
+
|
|
17
|
+
`$ARGUMENTS` carries the `lisa:prd-source-write` spec: `title`, `body` (full PRD markdown),
|
|
18
|
+
`initial_role` (`draft` | `ready`, default `draft`), `dedupe_key`, `marker`, optional `source_ref`.
|
|
19
|
+
|
|
20
|
+
## Phase 1 — Resolve lifecycle parents
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
read_g() { local lv gv; lv=$(jq -r "$1 // empty" .lisa.config.local.json 2>/dev/null); gv=$(jq -r "$1 // empty" .lisa.config.json 2>/dev/null); echo "${lv:-${gv:-$2}}"; }
|
|
24
|
+
SPACE=$(read_g '.confluence.spaceKey' '')
|
|
25
|
+
CLOUDID=$(read_g '.atlassian.cloudId' '')
|
|
26
|
+
[ -z "$CLOUDID" ] && { echo "Error: atlassian.cloudId not set in .lisa.config.json."; exit 1; }
|
|
27
|
+
# Resolve the FULL set of lifecycle parents from config (never hard-code) — needed for the target
|
|
28
|
+
# parent, the past-ready reverse-lookup, and to derive the space when spaceKey is absent.
|
|
29
|
+
DRAFT_PARENT=$(read_g '.confluence.parents.draft' '')
|
|
30
|
+
READY_PARENT=$(read_g '.confluence.parents.ready' '')
|
|
31
|
+
IN_REVIEW_PARENT=$(read_g '.confluence.parents.in_review' '')
|
|
32
|
+
BLOCKED_PARENT=$(read_g '.confluence.parents.blocked' '')
|
|
33
|
+
TICKETED_PARENT=$(read_g '.confluence.parents.ticketed' '')
|
|
34
|
+
SHIPPED_PARENT=$(read_g '.confluence.parents.shipped' '')
|
|
35
|
+
VERIFIED_PARENT=$(read_g '.confluence.parents.verified' '')
|
|
36
|
+
# "Progressed past ready" parents (never re-parent a PRD down from these):
|
|
37
|
+
PROGRESSED_PARENTS=("$IN_REVIEW_PARENT" "$BLOCKED_PARENT" "$TICKETED_PARENT" "$SHIPPED_PARENT" "$VERIFIED_PARENT")
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Resolve the target parent from `initial_role`: `ready` → `$READY_PARENT`, otherwise `$DRAFT_PARENT`.
|
|
41
|
+
If the needed parent id is unset, stop and report that `/lisa:setup:confluence` must provision the
|
|
42
|
+
lifecycle parent pages — do not create a PRD outside the lifecycle scaffolding.
|
|
43
|
+
|
|
44
|
+
**Resolve the space (config allows parent-page-only setups with no `spaceKey`).** If `$SPACE` is
|
|
45
|
+
empty, derive it from the target lifecycle parent: `lisa:atlassian-access` `operation: read-page id:
|
|
46
|
+
<target parent>` and read its space key from the response. If neither `confluence.spaceKey` is set nor
|
|
47
|
+
a space can be derived from the parent, **stop and report** that a space could not be established —
|
|
48
|
+
do not attempt a CQL search or create without it.
|
|
49
|
+
|
|
50
|
+
## Phase 2 — Dedupe by marker (CQL search before create)
|
|
51
|
+
|
|
52
|
+
The `marker` is embedded in the page body. Find an existing PRD page carrying it — match the marker,
|
|
53
|
+
**never** the title:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
lisa:atlassian-access operation: search-pages cql: 'space = "<SPACE>" AND text ~ "<marker>"'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If `source_ref` was passed, target that page directly. If a page with the marker exists → **update**;
|
|
60
|
+
else → **create**.
|
|
61
|
+
|
|
62
|
+
## Phase 3 — Create or update
|
|
63
|
+
|
|
64
|
+
**Storage-format body + marker (both paths).** Convert the PRD markdown to Confluence **storage
|
|
65
|
+
format** (XHTML): `#`/`##`/`###` → `<h1>/<h2>/<h3>`, paragraphs → `<p>`, lists → `<ul>/<ol><li>`,
|
|
66
|
+
fenced code → `<ac:structured-macro ac:name="code">`. Embed the marker as a storage comment
|
|
67
|
+
(`<!-- $MARKER -->`) or a small `<p>` so future CQL dedupe finds it. The body must always contain
|
|
68
|
+
**exactly one** marker; never write a markerless page (CREATE or UPDATE).
|
|
69
|
+
|
|
70
|
+
**CREATE:** `lisa:atlassian-access` `operation: write-page` (create form) with a payload that sets:
|
|
71
|
+
- `title`: `$TITLE`
|
|
72
|
+
- `space`: `$SPACE` (resolved in Phase 1)
|
|
73
|
+
- `ancestors`/`parentId`: the resolved lifecycle parent (`$DRAFT_PARENT` or `$READY_PARENT`)
|
|
74
|
+
- `body`: the storage-format, marker-normalized body above.
|
|
75
|
+
|
|
76
|
+
**UPDATE** (existing page or `source_ref`):
|
|
77
|
+
1. **GET-then-PUT** (load-bearing, as `confluence-prd-intake` documents): first `operation: read-page
|
|
78
|
+
id: <page-id>` to read the current `version.number`, then `operation: write-page` (edit form) with
|
|
79
|
+
the marker-normalized storage body and `version.number` bumped to current+1. A PUT without the
|
|
80
|
+
current version is rejected; never drop the marker on the edit.
|
|
81
|
+
2. Re-parent to the target lifecycle parent if the role changed — **unless** the page's current
|
|
82
|
+
parent is in the resolved `${PROGRESSED_PARENTS[@]}` set (already past `ready`). If so, leave it
|
|
83
|
+
and report `reused (already past ready)`. Reverse-lookup the current parent in
|
|
84
|
+
`confluence.parents.*` to determine its role before re-parenting.
|
|
85
|
+
|
|
86
|
+
## Phase 4 — Return
|
|
87
|
+
|
|
88
|
+
```yaml
|
|
89
|
+
ref: "<confluence-page-id>"
|
|
90
|
+
url: "<page url>"
|
|
91
|
+
role: draft | ready # derived from the lifecycle parent the page now lives under (or its current role when reused past ready)
|
|
92
|
+
marker: "<MARKER>"
|
|
93
|
+
outcome: created | reused
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Rules
|
|
97
|
+
|
|
98
|
+
- All access via `lisa:atlassian-access`; never call Atlassian directly.
|
|
99
|
+
- State is the parent page, not a label — never attempt Confluence label writes (they 401 on scoped
|
|
100
|
+
tokens; see `config-resolution`).
|
|
101
|
+
- Match dedupe by marker, never by title.
|
|
102
|
+
- Never re-parent a PRD already past `ready` down to draft/ready.
|
|
103
|
+
- Resolve parents from config (`confluence.parents.{draft,ready}`) — never hardcode page ids.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
display_name: "Confluence Write PRD"
|
|
2
|
+
short_description: "Creates or idempotently updates a PRD as a Confluence page parented under the configured lifecycle parent page (the draft parent by…"
|
|
3
|
+
default_prompt:
|
|
4
|
+
- "Use $confluence-write-prd: Creates or idempotently updates a PRD as a Confluence page parented under the configured lifecycle parent page (the draft parent by…."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github-build-intake
|
|
3
|
-
description: "GitHub counterpart to lisa:jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label,
|
|
3
|
+
description: "GitHub counterpart to lisa:jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label, processes the first eligible issue, runs leaf work via lisa:github-agent, relabels to the configured `done` label on completion, then exits. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic/Story/Spike) that still carries a stale build-ready label is moved out of the ready pickup queue into the configured `claimed` label with a lifecycle-repair comment, never dispatched to lisa:github-agent. The `ready` label is the human-flipped signal that an issue is truly ready for direct development pickup — mirroring how Notion PRDs work product Draft → Ready → (us) In Review → Blocked|Ticketed."
|
|
4
4
|
allowed-tools: ["Skill", "Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ allowed-tools: ["Skill", "Bash"]
|
|
|
12
12
|
2. A full GitHub repo URL (e.g., `https://github.com/acme/frontend-v2`).
|
|
13
13
|
3. The literal token `github` — falls back to `.lisa.config.json` (`github.org` / `github.repo`).
|
|
14
14
|
|
|
15
|
-
Run one build-intake cycle.
|
|
15
|
+
Run one build-intake cycle. The first eligible issue in the configured `ready` build label is claimed, built via the `lisa:github-agent` flow, relabeled to the configured `done` label (env-aware — see Workflow resolution), then the cycle exits. Remaining ready issues stay queued for later scheduler invocations.
|
|
16
16
|
|
|
17
17
|
## Workflow resolution
|
|
18
18
|
|
|
@@ -30,7 +30,6 @@ read_role() {
|
|
|
30
30
|
|
|
31
31
|
READY=$(read_role ready "status:ready")
|
|
32
32
|
CLAIMED=$(read_role claimed "status:in-progress")
|
|
33
|
-
REVIEW=$(read_role review "status:code-review")
|
|
34
33
|
```
|
|
35
34
|
|
|
36
35
|
For env-keyed `done`, resolve the env first, then look up `done[<env>]`:
|
|
@@ -51,10 +50,12 @@ fi
|
|
|
51
50
|
DONE_TYPE=$(jq -r '.github.labels.build.done | type' .lisa.config.json 2>/dev/null)
|
|
52
51
|
if [ "$DONE_TYPE" = "string" ]; then
|
|
53
52
|
DONE=$(jq -r '.github.labels.build.done' .lisa.config.json)
|
|
53
|
+
DONE_LABELS_JSON=$(jq -c '[.github.labels.build.done]' .lisa.config.json)
|
|
54
54
|
elif [ "$DONE_TYPE" = "object" ]; then
|
|
55
55
|
[ -z "$TARGET_ENV" ] && { echo "ERROR: github.labels.build.done is env-keyed but env not resolvable"; exit 1; }
|
|
56
56
|
DONE=$(jq -r --arg e "$TARGET_ENV" '.github.labels.build.done[$e] // empty' .lisa.config.json)
|
|
57
57
|
[ -z "$DONE" ] && { echo "ERROR: github.labels.build.done has no entry for env '$TARGET_ENV'"; exit 1; }
|
|
58
|
+
DONE_LABELS_JSON=$(jq -c '[.github.labels.build.done[]]' .lisa.config.json)
|
|
58
59
|
else
|
|
59
60
|
case "$TARGET_ENV" in
|
|
60
61
|
dev) DONE="status:on-dev" ;;
|
|
@@ -62,6 +63,7 @@ else
|
|
|
62
63
|
production) DONE="status:done" ;;
|
|
63
64
|
*) echo "ERROR: cannot resolve done label without env"; exit 1 ;;
|
|
64
65
|
esac
|
|
66
|
+
DONE_LABELS_JSON=$(jq -cn --arg d "$DONE" '[$d]')
|
|
65
67
|
fi
|
|
66
68
|
```
|
|
67
69
|
|
|
@@ -69,7 +71,7 @@ In prose below, the role names refer to the resolved labels: e.g. "the `ready` l
|
|
|
69
71
|
|
|
70
72
|
## Confirmation policy
|
|
71
73
|
|
|
72
|
-
Do NOT ask the caller whether to proceed. Once invoked with a repo, run the cycle to completion — claim
|
|
74
|
+
Do NOT ask the caller whether to proceed. Once invoked with a repo, run the cycle to completion — claim and dispatch the first eligible issue through `lisa:github-agent`, relabel a successful build to `$DONE`, write the summary, and exit. The caller (a human or a cron) has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background queue.
|
|
73
75
|
|
|
74
76
|
Specifically forbidden:
|
|
75
77
|
|
|
@@ -81,7 +83,7 @@ Specifically forbidden:
|
|
|
81
83
|
The only legitimate reasons to stop early:
|
|
82
84
|
|
|
83
85
|
- Missing repo or required configuration. Surface the missing value and exit.
|
|
84
|
-
- Label namespace not adopted (no issue carries any of `$READY` / `$CLAIMED` / `$
|
|
86
|
+
- Label namespace not adopted (no issue carries any of `$READY` / `$CLAIMED` / `$DONE`). Surface a label-convention error and exit (this is setup, not a normal idle cycle — see "Adoption" at the bottom).
|
|
85
87
|
- Empty ready set. Exit cleanly with `"No GitHub issues labeled $READY in <org>/<repo>. Nothing to do."`
|
|
86
88
|
|
|
87
89
|
## Lifecycle assumed
|
|
@@ -89,22 +91,20 @@ The only legitimate reasons to stop early:
|
|
|
89
91
|
The GitHub Issues build lifecycle uses **labels** (we deliberately do NOT key off open/closed alone — closed issues aren't always the right post-build state):
|
|
90
92
|
|
|
91
93
|
```text
|
|
92
|
-
ready → claimed →
|
|
93
|
-
(human) (us claim) (us
|
|
94
|
+
ready → claimed → done(env-keyed)
|
|
95
|
+
(human) (us claim) (us done; PR ready)
|
|
94
96
|
```
|
|
95
97
|
|
|
96
|
-
(Defaults: `status:ready` / `status:in-progress` / `status:
|
|
98
|
+
(Defaults: `status:ready` / `status:in-progress` / `status:on-dev`/`status:on-stg`/`status:done`.)
|
|
97
99
|
|
|
98
100
|
This skill ONLY transitions:
|
|
99
101
|
|
|
100
102
|
- `$READY` → `$CLAIMED` (claim)
|
|
101
103
|
- `$CLAIMED` → `$DONE` (build complete, PR ready)
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
A "transition" means: remove the old role label and add the new one, in two `gh issue edit` calls (`--remove-label` + `--add-label`) or one combined call. The skill MUST verify exactly one build-lifecycle label (from the resolved `$READY`/`$CLAIMED`/`$DONE` set) is present after the update — having two simultaneously breaks idempotency.
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
**Pre-flight check**: at the start of each cycle, confirm at least one of the resolved role labels (`$READY`, `$CLAIMED`, `$REVIEW`, or any `$DONE` value) exists on the repo via `gh label list --repo <org>/<repo> --json name`. If none exist, the convention has not been adopted — surface the label-convention error and exit.
|
|
107
|
+
**Pre-flight check**: at the start of each cycle, confirm at least one of the resolved role labels (`$READY`, `$CLAIMED`, or any `$DONE` value) exists on the repo via `gh label list --repo <org>/<repo> --json name`. If none exist, the convention has not been adopted — surface the label-convention error and exit.
|
|
108
108
|
|
|
109
109
|
## Phases
|
|
110
110
|
|
|
@@ -127,19 +127,32 @@ If empty, run a secondary check to distinguish a genuinely empty queue from an u
|
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
129
|
gh label list --repo <org>/<repo> --json name \
|
|
130
|
-
| jq -r --arg r "$READY" --arg c "$CLAIMED" --
|
|
131
|
-
'[.[] | .name | select(. == $r or . == $c or .
|
|
130
|
+
| jq -r --arg r "$READY" --arg c "$CLAIMED" --argjson d "$DONE_LABELS_JSON" \
|
|
131
|
+
'[.[] | .name | select(. == $r or . == $c or (. as $n | $d | index($n)))] | length'
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
If none of the configured role labels exist on the repo → label convention not adopted, surface a setup error and exit. If the role labels exist but none are `$READY` on any open issue → genuinely empty queue, exit cleanly with `"No GitHub issues labeled $READY. Nothing to do."`
|
|
135
135
|
|
|
136
|
-
### Phase 3 — Process
|
|
136
|
+
### Phase 3 — Process the first eligible ready issue
|
|
137
|
+
|
|
138
|
+
#### 3a.0 Repo-scope gate (claim only current-repo issues)
|
|
139
|
+
|
|
140
|
+
GitHub Issues live in one repo by definition, so the scanned repo's issues are usually inherently current-repo. But a planning/umbrella repo's issues can target sibling repos, so this skill still claims only issues for the repo it is running in. Run this gate **before** the leaf-only gate (3a) and the claim (3b), per the `repo-scope-split` rule's "Claim-time repo scoping" section (cite it by slug; do not restate its decision table).
|
|
141
|
+
|
|
142
|
+
1. **Resolve the current repo** per `config-resolution` "Repo scoping" (`.repo` → `.github.repo` → `git remote get-url origin` basename). If unresolvable, stop and report.
|
|
143
|
+
2. **Cheap path first.** Prefer candidates already carrying the `repo:<current>` label. Keep the Phase 2 scan broad so unlabeled issues are still seen, determined, and stamped.
|
|
144
|
+
3. **Per candidate, apply the repo-scope decision (`repo-scope-split`):**
|
|
145
|
+
- Carries `repo:<other>` → **skip** (leave it `ready` for that repo's own intake); next candidate.
|
|
146
|
+
- **Unlabeled** → determine the target repo(s) from the issue + code surfaces, then **stamp** `repo:<name>` via `gh issue edit <n> --add-label "repo:<name>"` (create the label lazily) so later cycles filter cheaply; re-apply with the now-known repo. (An issue whose work is entirely in the scanned repo is simply labeled `repo:<current>`.)
|
|
147
|
+
- **Multi-repo leaf → split, never claim.** Run the `repo-scope-split` work-time procedure into single-repo siblings, each created **build-ready** (`build_ready: true`) and stamped with its own `repo:<name>`; the current repo's sibling becomes a normal candidate.
|
|
148
|
+
- **Single-repo leaf for the current repo** → fall through to 3a (leaf-only gate) and 3b (claim).
|
|
149
|
+
4. Continue until a claimable current-repo leaf is found (claim it; one per cycle) or the ready set is exhausted — exit cleanly with `"No ready issues for repo <current>. Nothing to do."`.
|
|
137
150
|
|
|
138
151
|
#### 3a. Leaf-only claim gate (repair containers)
|
|
139
152
|
|
|
140
153
|
Build intake dispatches **only independently implementable leaf work units** to the build agent. This enforces the claim-time arm of the vendor-neutral `leaf-only-lifecycle` rule: a parent/container that still carries a stale build-ready role (e.g. `status:ready` applied before this rule existed, or hand-applied to an Epic/Story) is **never dispatched** — intake moves it out of the pickup queue by replacing `$READY` with `$CLAIMED`, then posts a clear lifecycle-repair message. It is the claim-time complement to the write-time labeling in `lisa:github-write-issue` and the validate-time S15 gate in `lisa:github-validate-issue`; all three cite the same rule so the classification never drifts. **Never silently implement a container.**
|
|
141
154
|
|
|
142
|
-
Run this gate **before** the leaf claim relabel,
|
|
155
|
+
Run this gate **before** the leaf claim relabel, starting with the oldest/highest-priority ready candidate. Do NOT comment "Claimed" or invoke `lisa:github-agent` for an issue that fails the gate. A container repair still changes labels: remove `$READY`, add `$CLAIMED`, explain that parent/container `$CLAIMED` means rollup/build-lane progress through child/leaf work rather than direct implementation, record it, and end the cycle.
|
|
143
156
|
|
|
144
157
|
**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
158
|
|
|
@@ -254,9 +267,9 @@ This close is idempotent: if the issue is already closed, record that native clo
|
|
|
254
267
|
|
|
255
268
|
For any non-Success outcome, do NOT transition. The issue sits in `$CLAIMED` (or wherever `lisa:github-agent` left it) — humans take it from there.
|
|
256
269
|
|
|
257
|
-
#### 3e.
|
|
270
|
+
#### 3e. Stop
|
|
258
271
|
|
|
259
|
-
|
|
272
|
+
Stop immediately after the first claimed, skipped, blocked, held, or errored issue. Later scheduler invocations process the remaining ready issues.
|
|
260
273
|
|
|
261
274
|
### Phase 4 — Summary report
|
|
262
275
|
|
|
@@ -291,7 +304,7 @@ Total PRs opened: <n>
|
|
|
291
304
|
- **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:github-agent` invocation for leaves; containers are also moved to `$CLAIMED` to leave the ready pickup queue, but are not dispatched.
|
|
292
305
|
- **No writes outside the lifecycle**: this skill only relabels `$READY → $CLAIMED` and `$CLAIMED → $DONE`. For containers, `$READY → $CLAIMED` is a lifecycle repair, not a direct build claim. Every other label change is owned by `lisa:github-agent`.
|
|
293
306
|
- **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.
|
|
294
|
-
- **
|
|
307
|
+
- **One item per cycle**: per-issue exceptions are caught and recorded, then the cycle exits. The scheduler owns retrying or moving on to the next ready item.
|
|
295
308
|
- **Single cycle per repo**: do not run two `lisa:github-build-intake` cycles in parallel against the same repo — concurrent claims could race. The scheduling layer is responsible for serialization.
|
|
296
309
|
- **Single-label invariant**: after every transition, verify exactly one `status:*` label is present on the issue. If two are present (rare race), surface as an Error and skip — do NOT auto-resolve.
|
|
297
310
|
- **Never pick an arbitrary env for `$DONE`**. If `done` is a map and env is ambiguous, fail loudly.
|
|
@@ -304,7 +317,6 @@ Total PRs opened: <n>
|
|
|
304
317
|
| `.lisa.config.json` `github.repo` | (from `$ARGUMENTS`) | GitHub repo for the default queue |
|
|
305
318
|
| `.lisa.config.json` `github.labels.build.ready` | `status:ready` | The label that signals "human says this is buildable" |
|
|
306
319
|
| `.lisa.config.json` `github.labels.build.claimed` | `status:in-progress` | The label set on pickup |
|
|
307
|
-
| `.lisa.config.json` `github.labels.build.review` | `status:code-review` | The label set when the PR opens (owned by `lisa:github-evidence`) |
|
|
308
320
|
| `.lisa.config.json` `github.labels.build.done` | env-keyed map or string | The label set after a successful build; env-aware |
|
|
309
321
|
| `.lisa.config.json` `deploy.branches` | — | Reverse-lookup map for env inference from PR base branch |
|
|
310
322
|
|
|
@@ -329,7 +341,6 @@ Before this skill can run, the repo must adopt the `status:*` label namespace. U
|
|
|
329
341
|
```bash
|
|
330
342
|
gh label create status:ready --color FBCA04 --description "Ready for build" --repo <org>/<repo>
|
|
331
343
|
gh label create status:in-progress --color 0E8A16 --description "Build in progress" --repo <org>/<repo>
|
|
332
|
-
gh label create status:code-review --color 5319E7 --description "PR open, awaiting review" --repo <org>/<repo>
|
|
333
344
|
gh label create status:on-dev --color 1D76DB --description "Built, deployed to dev" --repo <org>/<repo>
|
|
334
345
|
gh label create status:done --color 0E8A16 --description "Shipped" --repo <org>/<repo>
|
|
335
346
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github-evidence
|
|
3
|
-
description: "Upload text evidence to the GitHub `pr-assets` release, update PR description, post a GitHub Issue comment with code blocks
|
|
3
|
+
description: "Upload text evidence to the GitHub `pr-assets` release, update PR description, and post a GitHub Issue comment with code blocks. Reusable by any skill that captures evidence and generates evidence/comment.md (and optionally evidence/comment.txt). The GitHub counterpart of lisa:jira-evidence."
|
|
4
4
|
allowed-tools: ["Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,23 +8,6 @@ allowed-tools: ["Bash"]
|
|
|
8
8
|
|
|
9
9
|
Upload captured evidence and generated templates to the GitHub PR description and the originating GitHub Issue. This skill is the posting step — it assumes evidence files and a comment template already exist in the evidence directory.
|
|
10
10
|
|
|
11
|
-
## Workflow resolution
|
|
12
|
-
|
|
13
|
-
The `claimed` and `review` build labels are read from `.lisa.config.json` `github.labels.build.*`, falling back to the defaults documented in the `config-resolution` rule (`status:in-progress` and `status:code-review`).
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
read_role() {
|
|
17
|
-
local role="$1" default="$2"
|
|
18
|
-
local local_v global_v
|
|
19
|
-
local_v=$(jq -r ".github.labels.build.${role} // empty" .lisa.config.local.json 2>/dev/null)
|
|
20
|
-
global_v=$(jq -r ".github.labels.build.${role} // empty" .lisa.config.json 2>/dev/null)
|
|
21
|
-
echo "${local_v:-${global_v:-$default}}"
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
CLAIMED=$(read_role claimed "status:in-progress")
|
|
25
|
-
REVIEW=$(read_role review "status:code-review")
|
|
26
|
-
```
|
|
27
|
-
|
|
28
11
|
## Arguments
|
|
29
12
|
|
|
30
13
|
`$ARGUMENTS`: `<ISSUE_REF> <EVIDENCE_DIR> <PR_NUMBER>`
|
|
@@ -92,15 +75,9 @@ REVIEW=$(read_role review "status:code-review")
|
|
|
92
75
|
gh issue comment <issue-number> --repo <issue-org>/<issue-repo> --body-file "$EVIDENCE_DIR/comment.md"
|
|
93
76
|
```
|
|
94
77
|
|
|
95
|
-
6. **
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
gh issue edit <issue-number> --repo <issue-org>/<issue-repo> \
|
|
99
|
-
--remove-label "$CLAIMED" \
|
|
100
|
-
--add-label "$REVIEW"
|
|
101
|
-
```
|
|
78
|
+
6. **Leave lifecycle labels unchanged**
|
|
102
79
|
|
|
103
|
-
|
|
80
|
+
GitHub evidence posting is evidence-only. The caller that owns the build lifecycle (`lisa:github-build-intake` / `lisa:github-agent`) transitions the issue from the configured `claimed` label directly to the configured `done` label after a successful build. Do not apply `status:code-review` here.
|
|
104
81
|
|
|
105
82
|
## Evidence Naming Convention
|
|
106
83
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
display_name: "Github Evidence"
|
|
2
|
-
short_description: "Upload text evidence to the GitHub `pr-assets` release, update PR description, post a GitHub Issue comment with code blocks
|
|
2
|
+
short_description: "Upload text evidence to the GitHub `pr-assets` release, update PR description, and post a GitHub Issue comment with code blocks"
|
|
3
3
|
default_prompt:
|
|
4
|
-
- "Use $github-evidence: Upload text evidence to the GitHub `pr-assets` release, update PR description, post a GitHub Issue comment with code blocks
|
|
4
|
+
- "Use $github-evidence: Upload text evidence to the GitHub `pr-assets` release, update PR description, and post a GitHub Issue comment with code blocks."
|
|
@@ -89,7 +89,7 @@ Use `lisa:github-evidence` to post everything:
|
|
|
89
89
|
# Equivalent of: bash scripts/post-evidence.sh — but invoked via the Skill tool
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
Invoke the skill with `<ISSUE_REF> ./evidence <PR_NUMBER>`. It uploads the files to the `pr-assets` release, edits the PR's `## Evidence` section, posts a comment on the issue
|
|
92
|
+
Invoke the skill with `<ISSUE_REF> ./evidence <PR_NUMBER>`. It uploads the files to the `pr-assets` release, edits the PR's `## Evidence` section, and posts a comment on the issue. The build-intake owner performs the direct `claimed` → `done` lifecycle transition after success.
|
|
93
93
|
|
|
94
94
|
### Step 6: Verify
|
|
95
95
|
|
|
@@ -97,7 +97,7 @@ Confirm:
|
|
|
97
97
|
- Evidence files exist as release assets named `pr-<PR>-NN-name.{txt,json}`.
|
|
98
98
|
- The PR description contains the `## Evidence` section with code-block embeds.
|
|
99
99
|
- The issue has a new comment whose body matches `comment.md`.
|
|
100
|
-
- The issue
|
|
100
|
+
- The issue has the evidence comment, and the build-intake owner can transition it from `status:in-progress` directly to the configured `done` label.
|
|
101
101
|
|
|
102
102
|
## Verification Patterns Reference
|
|
103
103
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github-prd-intake
|
|
3
|
-
description: "Scans a GitHub repository for issues carrying the configured `ready` PRD label and runs
|
|
3
|
+
description: "Scans a GitHub repository for issues carrying the configured `ready` PRD label and runs the first eligible one through the dry-run validation pipeline. A PRD that passes every gate gets tickets written (to whatever destination tracker is configured — JIRA, GitHub Issues itself, or Linear) and the label flipped to the configured `ticketed` label; a PRD that fails gets clarifying-question comments and the label flipped to the configured `blocked` label. The GitHub counterpart of lisa:notion-prd-intake / lisa:confluence-prd-intake / lisa:linear-prd-intake. Composes existing skills (github-to-tracker, tracker-validate, tracker-source-artifacts, product-walkthrough)."
|
|
4
4
|
allowed-tools: ["Skill", "Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ allowed-tools: ["Skill", "Bash"]
|
|
|
12
12
|
- A full GitHub repo URL (e.g., `https://github.com/acme/product-prds`).
|
|
13
13
|
- The literal token `github` — falls back to `.lisa.config.json` (`github.org` / `github.repo`).
|
|
14
14
|
|
|
15
|
-
Run one intake cycle against that repo.
|
|
15
|
+
Run one intake cycle against that repo. The first eligible issue with the `ready` label is claimed, validated, routed to either the `blocked` label (with clarifying comments) or the `ticketed` label (with destination tickets created), then the cycle exits. Remaining ready PRDs stay queued for later scheduler invocations.
|
|
16
16
|
|
|
17
17
|
## Workflow resolution
|
|
18
18
|
|
|
@@ -43,7 +43,7 @@ The **PRD closure rollup phase (3f)** transitions a `$TICKETED` PRD to `$SHIPPED
|
|
|
43
43
|
|
|
44
44
|
## Confirmation policy
|
|
45
45
|
|
|
46
|
-
Do NOT ask the caller whether to proceed. Once invoked with a repo, run the cycle to completion — claim, validate, branch to `$BLOCKED` or `$TICKETED`, write the summary. The caller has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background
|
|
46
|
+
Do NOT ask the caller whether to proceed. Once invoked with a repo, run the cycle to completion for the first eligible PRD — claim, validate, branch to `$BLOCKED` or `$TICKETED`, write the summary, and exit. The caller has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background queue.
|
|
47
47
|
|
|
48
48
|
Specifically forbidden:
|
|
49
49
|
|
|
@@ -69,7 +69,7 @@ draft → ready → in_review → blocked | ticketed → shipped → verified
|
|
|
69
69
|
|
|
70
70
|
(Defaults: `prd-draft` / `prd-ready` / `prd-in-review` / `prd-blocked` / `prd-ticketed` / `prd-shipped` / `prd-verified`.)
|
|
71
71
|
|
|
72
|
-
`verified` is the terminal state after `shipped`: it means the shipped product has been empirically checked against the PRD (set by `/lisa:verify-prd`, not by this intake skill). A failed post-ship verification
|
|
72
|
+
`verified` is the terminal state after `shipped`: it means the shipped product has been empirically checked against the PRD (set by `/lisa:verify-prd`, not by this intake skill). A failed post-ship verification does **not** use `blocked`; `/lisa:verify-prd` re-opens the PRD `shipped → ticketed` and creates build-ready fix tickets that auto-build and trigger a re-verify (the self-healing loop), introducing no `verifying` / `verification-failed` state. Like `draft` and `shipped`, `verified` is **product-owned** — this intake skill never sets, clears, or otherwise touches it. See the "PRD-level verification vs ticket verification" section of the `prd-lifecycle-rollup` rule.
|
|
73
73
|
|
|
74
74
|
Exactly one of these labels is expected on a PRD issue at any time.
|
|
75
75
|
|
|
@@ -124,9 +124,9 @@ gh issue list --repo <org>/<repo> --state open --limit 100 --json number,labels
|
|
|
124
124
|
|
|
125
125
|
If no PRD lifecycle labels appear on any open issue → convention not adopted; surface error and exit. If lifecycle labels exist but none are `$READY` → genuinely empty queue, exit cleanly with the idle message.
|
|
126
126
|
|
|
127
|
-
### Phase 3 — Process
|
|
127
|
+
### Phase 3 — Process the first eligible ready PRD
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
Select the first ready PRD issue returned by Phase 2 and process only that issue. Later scheduler invocations process the remaining ready PRDs.
|
|
130
130
|
|
|
131
131
|
#### 3a. Claim
|
|
132
132
|
|
|
@@ -225,9 +225,9 @@ For unanchored failures (`prd_anchor: null`), post one rollup comment prefixed w
|
|
|
225
225
|
|
|
226
226
|
After all comments are posted, transition: `gh issue edit <num> --remove-label "$IN_REVIEW" --add-label "$BLOCKED"`. Do NOT write any tickets.
|
|
227
227
|
|
|
228
|
-
#### 3d.
|
|
228
|
+
#### 3d. Stop
|
|
229
229
|
|
|
230
|
-
|
|
230
|
+
Stop immediately after the claimed PRD is ticketed, blocked, or recorded as an error.
|
|
231
231
|
|
|
232
232
|
#### 3e. Coverage audit (mandatory after $TICKETED)
|
|
233
233
|
|
|
@@ -238,7 +238,7 @@ Per-ticket gates prove each ticket is well-formed; they do NOT prove the *set* o
|
|
|
238
238
|
|
|
239
239
|
| Verdict | Action |
|
|
240
240
|
|---------|--------|
|
|
241
|
-
| `COMPLETE` | Done. Leave label as `$TICKETED`.
|
|
241
|
+
| `COMPLETE` | Done. Leave label as `$TICKETED`. End the cycle. |
|
|
242
242
|
| `COMPLETE_WITH_SCOPE_CREEP` | Post an advisory comment on the PRD issue naming the scope-creep tickets. Leave label as `$TICKETED`. |
|
|
243
243
|
| `GAPS_FOUND` | The created ticket set is incomplete. (a) For each gap, post a comment using the same product-facing template as Phase 3c.2 — anchored when `prd_anchor` is non-null. (b) Post one summary comment listing the tickets that *were* successfully created. (c) Transition labels from `$TICKETED` back to `$BLOCKED`. |
|
|
244
244
|
| `NO_TICKETS_FOUND` | Should not happen if step 2 succeeded. Log as Error; leave label as `$TICKETED` with a flag comment. |
|
|
@@ -338,6 +338,20 @@ The set of **required** children for the all-terminal check is the top-level chi
|
|
|
338
338
|
|
|
339
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.
|
|
340
340
|
|
|
341
|
+
#### 3g. PRD verification dispatch (close the loop on shipped PRDs)
|
|
342
|
+
|
|
343
|
+
`shipped` and `verified` are distinct facts about a PRD (see the `prd-lifecycle-rollup` rule's "PRD-level verification vs ticket verification" and "Closing the loop" sections). Rollup (3f) only reaches `$SHIPPED`; the `shipped → verified` (pass) / `shipped → ticketed` (fail) hops are owned by `/lisa:verify-prd`. This phase **closes that loop** by dispatching the initiative-level acceptance gate for shipped PRDs. It never performs the verification transition itself — the "never sets the verification outcome" invariant holds: `lisa:verify-prd`, not this skill, sets `verified` (or, on failure, re-opens the PRD to `ticketed`).
|
|
344
|
+
|
|
345
|
+
Re-query the PRDs currently carrying `$SHIPPED` via `gh issue list --repo <org>/<repo> --label "$SHIPPED" --state open`. Pick the **first** one and invoke `lisa:verify-prd <issue-url>`. Process **one shipped PRD per cycle** — `lisa:verify-prd` is a heavy full flow (spec-conformance + empirical verification + fix-issue creation), so it is bounded exactly like the single-ready-PRD claim in Phase 3; the scheduler drains the rest.
|
|
346
|
+
|
|
347
|
+
**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).
|
|
348
|
+
|
|
349
|
+
`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
|
+
|
|
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
|
+
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
|
+
|
|
341
355
|
### Phase 4 — Summary report
|
|
342
356
|
|
|
343
357
|
```text
|
|
@@ -379,10 +393,10 @@ When the configured destination tracker is GitHub Issues AND the PRD repo is the
|
|
|
379
393
|
|
|
380
394
|
## Idempotency & safety
|
|
381
395
|
|
|
382
|
-
- **
|
|
396
|
+
- **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.
|
|
383
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.
|
|
384
398
|
- **Claim-first ordering**: the label flip to `$IN_REVIEW` happens BEFORE validation runs.
|
|
385
|
-
- **Failure
|
|
399
|
+
- **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.
|
|
386
400
|
- **Single-label invariant**: after every transition, verify exactly one lifecycle label is present.
|
|
387
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.
|
|
388
402
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
display_name: "Github PRD Intake"
|
|
2
|
-
short_description: "Scans a GitHub repository for issues carrying the configured `ready` PRD label and runs
|
|
2
|
+
short_description: "Scans a GitHub repository for issues carrying the configured `ready` PRD label and runs the first eligible one through the dry-run…"
|
|
3
3
|
default_prompt:
|
|
4
|
-
- "Use $github-prd-intake: Scans a GitHub repository for issues carrying the configured `ready` PRD label and runs
|
|
4
|
+
- "Use $github-prd-intake: Scans a GitHub repository for issues carrying the configured `ready` PRD label and runs the first eligible one through the dry-run…."
|
|
@@ -57,10 +57,10 @@ Based on the milestone, suggest (but do NOT automatically perform) a label trans
|
|
|
57
57
|
| Milestone | Suggested label |
|
|
58
58
|
|-----------|-----------------|
|
|
59
59
|
| Plan created | `status:in-progress` |
|
|
60
|
-
| PR ready | `status:
|
|
61
|
-
| PR merged |
|
|
60
|
+
| PR ready | configured `done` label (`status:done` in this repo) |
|
|
61
|
+
| PR merged | no additional build-label transition |
|
|
62
62
|
|
|
63
|
-
The actual `status:in-progress` flip is owned by `lisa:github-build-intake` (claim) and `lisa:github-agent`. The `
|
|
63
|
+
The actual `status:in-progress` flip is owned by `lisa:github-build-intake` (claim) and `lisa:github-agent`. The configured `done` flip is owned by the build-intake owner after a successful build and evidence post. This skill never relabels.
|
|
64
64
|
|
|
65
65
|
### Step 5: Parent Status Rollup (`--rollup`)
|
|
66
66
|
|
|
@@ -82,12 +82,12 @@ gh api graphql -f query='
|
|
|
82
82
|
|
|
83
83
|
If the `subIssues` field is unavailable (older GHES), fall back to body parentage exactly as `lisa:github-read-issue` does. If the issue has **no** children it is a leaf, not a parent — rollup is N/A; behave as a normal milestone sync.
|
|
84
84
|
|
|
85
|
-
**Evaluate the required children in priority order and take the first match** (canonical roles from `config-resolution`; the GitHub label map is `status:blocked`, `status:in-progress`, `status:
|
|
85
|
+
**Evaluate the required children in priority order and take the first match** (canonical roles from `config-resolution`; the GitHub label map is `status:blocked`, `status:in-progress`, `status:done`):
|
|
86
86
|
|
|
87
87
|
| If among the required child leaves… | Derived parent role | GitHub label |
|
|
88
88
|
|---|---|---|
|
|
89
89
|
| any child carries `status:blocked` (or is otherwise blocked) | `blocked` | `status:blocked` |
|
|
90
|
-
| else any child carries `status:in-progress`
|
|
90
|
+
| else any child carries `status:in-progress` | `claimed` | `status:in-progress` |
|
|
91
91
|
| else **all** required children are terminal (closed / `status:done`) | `done` | the configured terminal `done` label |
|
|
92
92
|
| else (children exist, none started) | — | unchanged — parent keeps its non-ready container label |
|
|
93
93
|
|
|
@@ -194,7 +194,7 @@ GitHub Issues uses **labels** for the structured metadata that JIRA stores in cu
|
|
|
194
194
|
| Concept | Label format | Example |
|
|
195
195
|
|---------|--------------|---------|
|
|
196
196
|
| Issue type | `type:<value>` | `type:Story`, `type:Bug`, `type:Epic`, `type:Sub-task`, `type:Spike`, `type:Improvement` |
|
|
197
|
-
| Status | `status:<value>` | `status:ready`, `status:in-progress`, `status:
|
|
197
|
+
| Status | `status:<value>` | `status:ready`, `status:in-progress`, `status:on-dev`, `status:done` |
|
|
198
198
|
| Priority | `priority:<value>` | `priority:low`, `priority:medium`, `priority:high`, `priority:critical` |
|
|
199
199
|
| Components | `component:<name>` | `component:auth`, `component:billing` |
|
|
200
200
|
| Story points | `points:<n>` | `points:3`, `points:5`, `points:8` |
|
|
@@ -212,6 +212,14 @@ The build-ready status label (`status:ready`) is governed by the `leaf-only-life
|
|
|
212
212
|
|
|
213
213
|
For non-build-ready issues created fresh (Epics, Stories, and other containers), omit the status label entirely; the container's rollup state is derived, not set directly.
|
|
214
214
|
|
|
215
|
+
### Build-ready control input (`build_ready`)
|
|
216
|
+
|
|
217
|
+
`build_ready` is an optional write-control input (default: **omitted**). It governs whether a **leaf** work unit is stamped with the build-ready role on create. It never overrides `leaf-only-lifecycle` — a container is never stamped build-ready regardless of `build_ready`. "Not build-ready" is not a special status: it simply means the issue is created in its natural default (a plain open issue with **no `status:ready` label**), which a human can promote later.
|
|
218
|
+
|
|
219
|
+
- **Omitted** → current behavior: a leaf work unit receives `status:ready`. Preserves what every existing caller (`lisa:plan`, the `*-to-tracker` skills) relies on.
|
|
220
|
+
- **`build_ready: false`** → create the leaf **without** `status:ready`, so it sits in the backlog for a human to review and promote into the queue.
|
|
221
|
+
- **`build_ready: true`** → ensure the leaf carries `status:ready` so `lisa:intake` / `lisa:github-build-intake` auto-picks it up.
|
|
222
|
+
|
|
215
223
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
216
224
|
|
|
217
225
|
Before any write, invoke `lisa:github-validate-issue` with the full proposed spec assembled from Phases 2 / 3 / 4 / 5. Pass it as a YAML block per the `lisa:github-validate-issue` schema, including `runtime_behavior_change`, `authenticated_surface`, and `artifacts_attached` flags so the right gates run.
|
|
@@ -224,9 +232,9 @@ If the validator reports `FAIL`, do NOT proceed to Phase 6. Fix the spec and re-
|
|
|
224
232
|
|
|
225
233
|
### CREATE
|
|
226
234
|
|
|
227
|
-
1. Compose the body markdown from Phases 2/3/4 in a temp file (avoid quoting hell). Apply `status:ready` **only for a leaf work unit** per the Phase 5 leaf-only rule (`leaf-only-lifecycle`) — omit it for `Epic` / `Story` / `Spike` and any issue that has child work:
|
|
235
|
+
1. Compose the body markdown from Phases 2/3/4 in a temp file (avoid quoting hell). Apply `status:ready` **only for a leaf work unit** per the Phase 5 leaf-only rule (`leaf-only-lifecycle`) — omit it for `Epic` / `Story` / `Spike` and any issue that has child work, **and** only when `build_ready` is not `false` (a leaf with `build_ready: false` is created without `status:ready`; see the Build-ready control input):
|
|
228
236
|
```bash
|
|
229
|
-
# Leaf work unit (Bug / Task / Sub-task / Improvement with no children):
|
|
237
|
+
# Leaf work unit (Bug / Task / Sub-task / Improvement with no children), build_ready not false:
|
|
230
238
|
gh issue create \
|
|
231
239
|
--repo <org>/<repo> \
|
|
232
240
|
--title "<summary>" \
|
|
@@ -235,8 +243,9 @@ If the validator reports `FAIL`, do NOT proceed to Phase 6. Fix the spec and re-
|
|
|
235
243
|
[--label "component:<name>" ...] [--milestone "<milestone>"] \
|
|
236
244
|
[--assignee "<login>"]
|
|
237
245
|
|
|
238
|
-
# Container (Epic / Story / Spike / any issue with child work):
|
|
239
|
-
# identical, but WITHOUT --label "status:ready" —
|
|
246
|
+
# Container (Epic / Story / Spike / any issue with child work), OR a leaf with build_ready: false:
|
|
247
|
+
# identical, but WITHOUT --label "status:ready" — a container's state rolls up from children;
|
|
248
|
+
# a build_ready: false leaf waits in the backlog for a human to promote it.
|
|
240
249
|
gh issue create \
|
|
241
250
|
--repo <org>/<repo> \
|
|
242
251
|
--title "<summary>" \
|
|
@@ -293,7 +302,7 @@ The mapping below is the single source of truth for how JIRA concepts translate
|
|
|
293
302
|
| JIRA concept | GitHub Issues equivalent |
|
|
294
303
|
|---|---|
|
|
295
304
|
| Issue type | Label `type:<value>` |
|
|
296
|
-
| Status (Ready / In Progress /
|
|
305
|
+
| Status (Ready / In Progress / On Dev / Done) | Label `status:<value>` |
|
|
297
306
|
| Epic / Story / Sub-task hierarchy | Native sub-issues via `gh api graphql addSubIssue` |
|
|
298
307
|
| Acceptance Criteria | `## Acceptance Criteria` markdown section with a Gherkin code-fence |
|
|
299
308
|
| Validation Journey | `## Validation Journey` markdown section |
|