@codyswann/lisa 2.21.1 → 2.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- 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 +11 -9
- package/plugins/lisa/agents/github-agent.md +18 -10
- package/plugins/lisa/agents/github-build-intake.md +10 -8
- package/plugins/lisa/agents/github-prd-intake.md +11 -9
- package/plugins/lisa/agents/jira-agent.md +12 -8
- package/plugins/lisa/agents/jira-build-intake.md +9 -7
- package/plugins/lisa/agents/learnings-synthesizer.md +1 -1
- package/plugins/lisa/agents/linear-agent.md +15 -9
- package/plugins/lisa/agents/linear-build-intake.md +13 -11
- package/plugins/lisa/agents/linear-prd-intake.md +11 -9
- package/plugins/lisa/agents/notion-prd-intake.md +11 -9
- package/plugins/lisa/agents/pr-mining-specialist.md +1 -1
- package/plugins/lisa/agents/tracker-mining-specialist.md +1 -1
- package/plugins/lisa/commands/setup/atlassian.md +7 -0
- package/plugins/lisa/commands/setup/confluence.md +7 -0
- package/plugins/lisa/commands/setup/jira.md +7 -0
- package/plugins/lisa/commands/setup/notion.md +7 -0
- package/plugins/lisa/hooks/enforce-team-first.sh +14 -6
- package/plugins/lisa/rules/base-rules.md +3 -3
- package/plugins/lisa/rules/config-resolution.md +242 -24
- package/plugins/lisa/rules/intent-routing.md +4 -4
- package/plugins/lisa/rules/repo-scope-split.md +41 -0
- package/plugins/lisa/rules/verification.md +13 -0
- package/plugins/lisa/skills/atlassian-access/SKILL.md +260 -0
- package/plugins/lisa/skills/confluence-prd-intake/SKILL.md +167 -82
- package/plugins/lisa/skills/confluence-to-tracker/SKILL.md +39 -26
- package/plugins/lisa/skills/debrief/SKILL.md +4 -5
- package/plugins/lisa/skills/github-add-journey/SKILL.md +1 -0
- package/plugins/lisa/skills/github-build-intake/SKILL.md +104 -40
- package/plugins/lisa/skills/github-evidence/SKILL.md +22 -5
- package/plugins/lisa/skills/github-prd-intake/SKILL.md +87 -51
- package/plugins/lisa/skills/github-to-tracker/SKILL.md +2 -2
- package/plugins/lisa/skills/github-validate-issue/SKILL.md +11 -1
- package/plugins/lisa/skills/implement/SKILL.md +5 -6
- package/plugins/lisa/skills/intake/SKILL.md +5 -6
- package/plugins/lisa/skills/jira-add-journey/SKILL.md +1 -0
- package/plugins/lisa/skills/jira-build-intake/SKILL.md +110 -45
- package/plugins/lisa/skills/jira-create/SKILL.md +5 -3
- package/plugins/lisa/skills/jira-evidence/SKILL.md +19 -2
- package/plugins/lisa/skills/jira-journey/SKILL.md +3 -1
- package/plugins/lisa/skills/jira-read-ticket/SKILL.md +10 -8
- package/plugins/lisa/skills/jira-sync/SKILL.md +11 -5
- package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +22 -10
- package/plugins/lisa/skills/jira-verify/SKILL.md +5 -3
- package/plugins/lisa/skills/jira-write-ticket/SKILL.md +16 -14
- package/plugins/lisa/skills/linear-add-journey/SKILL.md +1 -0
- package/plugins/lisa/skills/linear-build-intake/SKILL.md +90 -32
- package/plugins/lisa/skills/linear-evidence/SKILL.md +22 -5
- package/plugins/lisa/skills/linear-prd-intake/SKILL.md +92 -57
- package/plugins/lisa/skills/linear-validate-issue/SKILL.md +10 -0
- package/plugins/lisa/skills/monitor/SKILL.md +4 -5
- package/plugins/lisa/skills/notion-access/SKILL.md +193 -0
- package/plugins/lisa/skills/notion-prd-intake/SKILL.md +105 -46
- package/plugins/lisa/skills/notion-to-tracker/SKILL.md +7 -5
- package/plugins/lisa/skills/plan/SKILL.md +4 -5
- package/plugins/lisa/skills/research/SKILL.md +4 -5
- package/plugins/lisa/skills/setup-atlassian/SKILL.md +316 -0
- package/plugins/lisa/skills/setup-confluence/SKILL.md +245 -0
- package/plugins/lisa/skills/setup-jira/SKILL.md +198 -0
- package/plugins/lisa/skills/setup-notion/SKILL.md +283 -0
- package/plugins/lisa/skills/task-decomposition/SKILL.md +2 -0
- package/plugins/lisa/skills/ticket-triage/SKILL.md +4 -1
- package/plugins/lisa/skills/tracker-evidence/SKILL.md +1 -0
- package/plugins/lisa/skills/verification-lifecycle/SKILL.md +2 -0
- package/plugins/lisa/skills/verify/SKILL.md +4 -5
- 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/skills/ops-browser-uat/SKILL.md +1 -1
- package/plugins/lisa-expo/skills/ops-check-logs/SKILL.md +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-nestjs/skills/nestjs-graphql/references/project-patterns.md +48 -0
- 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/src/base/agents/confluence-prd-intake.md +11 -9
- package/plugins/src/base/agents/github-agent.md +18 -10
- package/plugins/src/base/agents/github-build-intake.md +10 -8
- package/plugins/src/base/agents/github-prd-intake.md +11 -9
- package/plugins/src/base/agents/jira-agent.md +12 -8
- package/plugins/src/base/agents/jira-build-intake.md +9 -7
- package/plugins/src/base/agents/learnings-synthesizer.md +1 -1
- package/plugins/src/base/agents/linear-agent.md +15 -9
- package/plugins/src/base/agents/linear-build-intake.md +13 -11
- package/plugins/src/base/agents/linear-prd-intake.md +11 -9
- package/plugins/src/base/agents/notion-prd-intake.md +11 -9
- package/plugins/src/base/agents/pr-mining-specialist.md +1 -1
- package/plugins/src/base/agents/tracker-mining-specialist.md +1 -1
- package/plugins/src/base/commands/setup/atlassian.md +7 -0
- package/plugins/src/base/commands/setup/confluence.md +7 -0
- package/plugins/src/base/commands/setup/jira.md +7 -0
- package/plugins/src/base/commands/setup/notion.md +7 -0
- package/plugins/src/base/hooks/enforce-team-first.sh +14 -6
- package/plugins/src/base/rules/base-rules.md +3 -3
- package/plugins/src/base/rules/config-resolution.md +242 -24
- package/plugins/src/base/rules/intent-routing.md +4 -4
- package/plugins/src/base/rules/repo-scope-split.md +41 -0
- package/plugins/src/base/rules/verification.md +13 -0
- package/plugins/src/base/skills/atlassian-access/SKILL.md +260 -0
- package/plugins/src/base/skills/confluence-prd-intake/SKILL.md +167 -82
- package/plugins/src/base/skills/confluence-to-tracker/SKILL.md +39 -26
- package/plugins/src/base/skills/debrief/SKILL.md +4 -5
- package/plugins/src/base/skills/github-add-journey/SKILL.md +1 -0
- package/plugins/src/base/skills/github-build-intake/SKILL.md +104 -40
- package/plugins/src/base/skills/github-evidence/SKILL.md +22 -5
- package/plugins/src/base/skills/github-prd-intake/SKILL.md +87 -51
- package/plugins/src/base/skills/github-to-tracker/SKILL.md +2 -2
- package/plugins/src/base/skills/github-validate-issue/SKILL.md +11 -1
- package/plugins/src/base/skills/implement/SKILL.md +5 -6
- package/plugins/src/base/skills/intake/SKILL.md +5 -6
- package/plugins/src/base/skills/jira-add-journey/SKILL.md +1 -0
- package/plugins/src/base/skills/jira-build-intake/SKILL.md +110 -45
- package/plugins/src/base/skills/jira-create/SKILL.md +5 -3
- package/plugins/src/base/skills/jira-evidence/SKILL.md +19 -2
- package/plugins/src/base/skills/jira-journey/SKILL.md +3 -1
- package/plugins/src/base/skills/jira-read-ticket/SKILL.md +10 -8
- package/plugins/src/base/skills/jira-sync/SKILL.md +11 -5
- package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +22 -10
- package/plugins/src/base/skills/jira-verify/SKILL.md +5 -3
- package/plugins/src/base/skills/jira-write-ticket/SKILL.md +16 -14
- package/plugins/src/base/skills/linear-add-journey/SKILL.md +1 -0
- package/plugins/src/base/skills/linear-build-intake/SKILL.md +90 -32
- package/plugins/src/base/skills/linear-evidence/SKILL.md +22 -5
- package/plugins/src/base/skills/linear-prd-intake/SKILL.md +92 -57
- package/plugins/src/base/skills/linear-validate-issue/SKILL.md +10 -0
- package/plugins/src/base/skills/monitor/SKILL.md +4 -5
- package/plugins/src/base/skills/notion-access/SKILL.md +193 -0
- package/plugins/src/base/skills/notion-prd-intake/SKILL.md +105 -46
- package/plugins/src/base/skills/notion-to-tracker/SKILL.md +7 -5
- package/plugins/src/base/skills/plan/SKILL.md +4 -5
- package/plugins/src/base/skills/research/SKILL.md +4 -5
- package/plugins/src/base/skills/setup-atlassian/SKILL.md +316 -0
- package/plugins/src/base/skills/setup-confluence/SKILL.md +245 -0
- package/plugins/src/base/skills/setup-jira/SKILL.md +198 -0
- package/plugins/src/base/skills/setup-notion/SKILL.md +283 -0
- package/plugins/src/base/skills/task-decomposition/SKILL.md +2 -0
- package/plugins/src/base/skills/ticket-triage/SKILL.md +4 -1
- package/plugins/src/base/skills/tracker-evidence/SKILL.md +1 -0
- package/plugins/src/base/skills/verification-lifecycle/SKILL.md +2 -0
- package/plugins/src/base/skills/verify/SKILL.md +4 -5
- package/plugins/src/expo/skills/ops-browser-uat/SKILL.md +1 -1
- package/plugins/src/expo/skills/ops-check-logs/SKILL.md +1 -1
- package/plugins/src/nestjs/skills/nestjs-graphql/references/project-patterns.md +48 -0
- package/scripts/check-plugins-sync.sh +45 -0
|
@@ -1,101 +1,176 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: confluence-prd-intake
|
|
3
|
-
description: "Scans a Confluence space (or a parent page) for PRD pages
|
|
4
|
-
allowed-tools: ["Skill", "Bash"
|
|
3
|
+
description: "Scans a Confluence space (or a parent page) for PRD pages currently parented under the configured `ready` lifecycle page and runs each one through the dry-run validation pipeline. PRDs that pass every gate get tickets written and are re-parented under the `ticketed` lifecycle page; PRDs that fail get clarifying-question comments and are re-parented under the `blocked` lifecycle page. Confluence counterpart of `lisa:notion-prd-intake` — the workflow is identical; only the source-of-truth tools and the state encoding differ (parent-page re-parenting instead of a status property). Composes existing skills (confluence-to-tracker, tracker-validate, tracker-source-artifacts, product-walkthrough)."
|
|
4
|
+
allowed-tools: ["Skill", "Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Confluence PRD Intake: $ARGUMENTS
|
|
8
8
|
|
|
9
|
+
All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
|
|
10
|
+
|
|
9
11
|
`$ARGUMENTS` is one of:
|
|
10
12
|
|
|
11
|
-
- A Confluence **space** URL or space key —
|
|
12
|
-
- A Confluence **parent page** URL or page ID —
|
|
13
|
+
- A Confluence **space** URL or space key — used as the surrounding scope sanity check. Example: `https://mycompany.atlassian.net/wiki/spaces/PRD` or `PRD`.
|
|
14
|
+
- A Confluence **parent page** URL or page ID — overrides the configured `confluence.parents.ready` page for this run (useful when an operator wants to drain an alternative lifecycle parent). Example: `https://mycompany.atlassian.net/wiki/spaces/PRD/pages/123456789/PRDs`.
|
|
15
|
+
- Empty — use `confluence.parents.ready` from `.lisa.config.json` as the scope.
|
|
16
|
+
|
|
17
|
+
Run one intake cycle against the resolved `ready` lifecycle parent. Each direct child of that parent is treated as a PRD currently in the `ready` state. Each PRD is claimed (re-parented to `in_review`), validated, and routed to either the `blocked` parent (with clarifying comments) or the `ticketed` parent (with destination tickets created).
|
|
18
|
+
|
|
19
|
+
## Why parent pages, not labels
|
|
20
|
+
|
|
21
|
+
GitHub and Linear PRD lifecycles use labels (`prd-ready` / `prd-in-review` / etc.). Confluence does NOT — it uses parent pages instead. Scoped Atlassian API tokens (the only secure form Atlassian offers) cannot write Confluence labels via the v1 endpoint, and the v2 Label API group has no POST endpoint at all. Parent-id transitions, by contrast, are first-class in v2 and work with `write:page:confluence` scope. See `config-resolution` rule, section "Confluence PRD lifecycle uses parent pages, not labels," for the full rationale.
|
|
22
|
+
|
|
23
|
+
## Workflow resolution
|
|
24
|
+
|
|
25
|
+
Lifecycle parent-page IDs are read from `.lisa.config.json` `confluence.parents.*`. Local overrides global per-key. Bash pattern:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Read a lifecycle parent-page id by role. Local overrides global per-key.
|
|
29
|
+
read_parent_id() {
|
|
30
|
+
local role="$1"
|
|
31
|
+
local local_v global_v
|
|
32
|
+
local_v=$(jq -r ".confluence.parents.${role} // empty" .lisa.config.local.json 2>/dev/null)
|
|
33
|
+
global_v=$(jq -r ".confluence.parents.${role} // empty" .lisa.config.json 2>/dev/null)
|
|
34
|
+
echo "${local_v:-$global_v}"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
READY_PARENT=$(read_parent_id ready)
|
|
38
|
+
IN_REVIEW_PARENT=$(read_parent_id in_review)
|
|
39
|
+
BLOCKED_PARENT=$(read_parent_id blocked)
|
|
40
|
+
TICKETED_PARENT=$(read_parent_id ticketed)
|
|
41
|
+
SHIPPED_PARENT=$(read_parent_id shipped)
|
|
42
|
+
DRAFT_PARENT=$(read_parent_id draft)
|
|
43
|
+
|
|
44
|
+
# Fail fast if any required role is unmapped — the lifecycle scaffolding hasn't been provisioned.
|
|
45
|
+
for role in ready in_review blocked ticketed; do
|
|
46
|
+
if [ -z "$(read_parent_id "$role")" ]; then
|
|
47
|
+
echo "Error: confluence.parents.${role} is not set in .lisa.config.json. Run /lisa:setup:confluence to provision the lifecycle parent pages." >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
done
|
|
51
|
+
|
|
52
|
+
# Reverse-lookup: given a page's parentId, return which lifecycle role it currently occupies.
|
|
53
|
+
current_role_for_prd() {
|
|
54
|
+
local parent_id="$1"
|
|
55
|
+
for role in draft ready in_review blocked ticketed shipped; do
|
|
56
|
+
if [ "$(read_parent_id "$role")" = "$parent_id" ]; then
|
|
57
|
+
echo "$role"; return
|
|
58
|
+
fi
|
|
59
|
+
done
|
|
60
|
+
echo "unknown"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
13
63
|
|
|
14
|
-
|
|
64
|
+
In prose below, the role names refer to the resolved parent-page IDs: e.g. "the `ready` parent" means whatever `confluence.parents.ready` resolves to.
|
|
15
65
|
|
|
16
|
-
This skill is the Confluence counterpart of `lisa:notion-prd-intake`. The phases, gates, comment templates, and rules are identical — the only differences are (1) the lifecycle is encoded as **page
|
|
66
|
+
This skill is the Confluence counterpart of `lisa:notion-prd-intake`. The phases, gates, comment templates, and rules are identical — the only differences are (1) the lifecycle is encoded as **parent-page placement** instead of a status property, and (2) the fetch / comment / update tools route through `lisa:atlassian-access`. Keep the two skills behaviorally aligned: when changing intake logic, change BOTH skills together.
|
|
17
67
|
|
|
18
68
|
## Confirmation policy
|
|
19
69
|
|
|
20
|
-
Do NOT ask the caller whether to proceed. Once invoked
|
|
70
|
+
Do NOT ask the caller whether to proceed. Once invoked, run the cycle to completion — claim, validate, branch to the `blocked` or `ticketed` parent, write the summary. The caller (a human or a cron) has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background batch.
|
|
21
71
|
|
|
22
72
|
Specifically forbidden:
|
|
23
73
|
|
|
24
74
|
- Previewing projected scope (epic count, story count, write count) and asking whether to continue.
|
|
25
75
|
- Offering A/B/C-style choices like "proceed / skip / dry-run only" — the documented behavior IS the default.
|
|
26
|
-
- Pausing because a PRD looks large, has many open questions, or is likely to end
|
|
76
|
+
- Pausing because a PRD looks large, has many open questions, or is likely to end under the `blocked` parent. The `blocked` parent is a valid terminal state of this lifecycle, not a failure mode — routing a PRD there with gate-failure comments is exactly how this skill communicates "the PRD needs more work before it can be ticketed." That outcome is success.
|
|
27
77
|
- Pausing because the dry-run validation looks expensive. The cost of one cycle is bounded; the cost of stalling a scheduled cron waiting on a human is unbounded.
|
|
28
78
|
|
|
29
79
|
The only legitimate reasons to stop early:
|
|
30
80
|
|
|
31
|
-
- Missing
|
|
32
|
-
-
|
|
33
|
-
- Empty
|
|
81
|
+
- Missing required configuration (`atlassian.cloudId`, `confluence.parents.{ready,in_review,blocked,ticketed}` in `.lisa.config.json`, `E2E_BASE_URL`, etc.). Surface the missing value and exit.
|
|
82
|
+
- Lifecycle parent unreachable. Surface and exit.
|
|
83
|
+
- Empty ready set. Exit cleanly with `"No PRDs currently parented under the 'ready' lifecycle page. Nothing to do."`
|
|
34
84
|
|
|
35
85
|
## Lifecycle assumed
|
|
36
86
|
|
|
37
|
-
The Confluence PRD lifecycle is encoded as **page
|
|
87
|
+
The Confluence PRD lifecycle is encoded as **parent-page placement** — Confluence has no native status field, and scoped API tokens cannot write labels. Each lifecycle role corresponds to a dedicated parent page in the project's Confluence space:
|
|
38
88
|
|
|
39
89
|
```text
|
|
40
|
-
|
|
41
|
-
|
|
90
|
+
draft → ready → in_review → blocked | ticketed → shipped
|
|
91
|
+
(product) (us) (us) (product)
|
|
42
92
|
```
|
|
43
93
|
|
|
94
|
+
A PRD's current state is determined entirely by which lifecycle parent it sits under. Re-parenting is the transition.
|
|
95
|
+
|
|
44
96
|
This skill ONLY transitions:
|
|
45
97
|
|
|
46
|
-
- `
|
|
47
|
-
- `
|
|
48
|
-
- `
|
|
98
|
+
- `ready` → `in_review` (claim)
|
|
99
|
+
- `in_review` → `blocked` (gate failures or coverage gaps)
|
|
100
|
+
- `in_review` → `ticketed` (success)
|
|
49
101
|
|
|
50
|
-
It never
|
|
102
|
+
It never re-parents PRDs into or out of the `draft` or `shipped` parents. Those parents are owned by product.
|
|
51
103
|
|
|
52
|
-
A "transition" means:
|
|
104
|
+
A "transition" means: update the PRD's `parentId` to the new role's parent-page id via `lisa:atlassian-access` `operation: write-page payload: { id, parentId, title, version: { number: <next> } }`. The v2 PUT endpoint requires the next version number and the page title in the payload; the body content is not strictly required for a re-parent-only edit, but some Atlassian deployments reject PUTs without a body. The skill MUST therefore GET the page first via `read-page`, capture title + current version + current body, then PUT with `parentId` swapped and `version.number` bumped — preserving body content is non-negotiable, this skill never edits PRD content. See `transition_prd` helper in Phase 3a for the canonical implementation.
|
|
53
105
|
|
|
54
|
-
If the project does not yet
|
|
106
|
+
If the project does not yet have the lifecycle parent pages provisioned, this skill cannot run. Provisioning is a one-time setup the project owner does (see "Adoption" at the bottom of this file).
|
|
55
107
|
|
|
56
108
|
## Phases
|
|
57
109
|
|
|
58
110
|
### Phase 1 — Resolve the scope
|
|
59
111
|
|
|
60
112
|
1. Parse `$ARGUMENTS`:
|
|
61
|
-
- Space URL → extract space key from `/wiki/spaces/<KEY>`.
|
|
62
|
-
- Bare space key →
|
|
63
|
-
- Parent page URL → extract numeric page ID from `/pages/<ID
|
|
64
|
-
- Bare page ID →
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
- For a parent page: call `mcp__atlassian__getConfluencePage` on the ID and confirm it loads.
|
|
69
|
-
|
|
70
|
-
### Phase 2 — Find Ready PRDs
|
|
71
|
-
|
|
72
|
-
Build a CQL query and call `mcp__atlassian__searchConfluenceUsingCql`:
|
|
113
|
+
- Space URL → extract space key from `/wiki/spaces/<KEY>`. (Used only as a sanity check that the operator's scope matches the configured space.)
|
|
114
|
+
- Bare space key → same.
|
|
115
|
+
- Parent page URL → extract numeric page ID from `/pages/<ID>/...`; use as the override for `READY_PARENT` for this run.
|
|
116
|
+
- Bare page ID → same.
|
|
117
|
+
- Empty → use `confluence.parents.ready` from config as `READY_PARENT`.
|
|
118
|
+
2. Confirm the configured Atlassian site by invoking `lisa:atlassian-access` `operation: list-sites` (it enforces connection match against `.lisa.config.json`).
|
|
119
|
+
3. Verify `READY_PARENT` is reachable: invoke `lisa:atlassian-access` `operation: read-page id: $READY_PARENT` and confirm it loads. If 404, surface a provisioning error and exit.
|
|
73
120
|
|
|
74
|
-
|
|
75
|
-
- For a parent: `ancestor = <PARENT-ID> AND label = "prd-ready" AND type = page`
|
|
121
|
+
### Phase 2 — Find ready PRDs
|
|
76
122
|
|
|
77
|
-
|
|
123
|
+
Invoke `lisa:atlassian-access` `operation: read-page-descendants id: $READY_PARENT` and take the **direct children** (depth 1) of the ready lifecycle parent. Those are the PRDs currently in the `ready` state. Capture each child's id and title.
|
|
78
124
|
|
|
79
|
-
|
|
125
|
+
For each candidate, follow up with `lisa:atlassian-access` `operation: read-page id: <PAGE-ID>` and read its `parentId` to confirm it is still parented under `$READY_PARENT` (guards against eventual-consistency lag and concurrent re-parenting by another operator).
|
|
80
126
|
|
|
81
|
-
|
|
82
|
-
- Secondary query (parent scope): `ancestor = <PARENT-ID> AND (label = "prd-ready" OR label = "prd-in-review" OR label = "prd-blocked" OR label = "prd-ticketed") AND type = page`
|
|
127
|
+
If the result set is empty, run a sanity probe across the other lifecycle parents to distinguish between a genuinely empty queue and a project where the lifecycle scaffolding is misconfigured:
|
|
83
128
|
|
|
84
|
-
|
|
129
|
+
- For each of `IN_REVIEW_PARENT`, `BLOCKED_PARENT`, `TICKETED_PARENT`: invoke `read-page-descendants id: <parent>` and count direct children.
|
|
130
|
+
- If every lifecycle parent has zero direct children → the lifecycle scaffolding is provisioned but unused, OR PRDs are still parented under the legacy structure. Surface: `"No PRDs found under any of the configured lifecycle parent pages (ready, in_review, blocked, ticketed). If this is a new project, move PRDs that are ready for ticketing under the configured 'ready' parent page (see Adoption section)."` Exit with an error — this is a setup / migration issue, not a normal idle cycle.
|
|
131
|
+
- If any non-ready parent has children → the queue is genuinely empty (PRDs exist but are in `in_review`, `blocked`, `ticketed`, or `shipped`). Exit cleanly with `"No PRDs currently parented under the 'ready' lifecycle page. Nothing to do."`
|
|
85
132
|
|
|
86
|
-
|
|
133
|
+
### Phase 3 — Process each ready PRD
|
|
87
134
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
For each PRD page (process serially to keep label transitions auditable):
|
|
135
|
+
For each PRD page (process serially to keep transitions auditable):
|
|
91
136
|
|
|
92
137
|
#### 3a. Claim
|
|
93
138
|
|
|
94
|
-
Transition
|
|
139
|
+
Transition the PRD from `ready` to `in_review` by re-parenting it:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Pseudo-code; the actual call is a Skill tool invocation of lisa:atlassian-access.
|
|
143
|
+
#
|
|
144
|
+
# NOTE: the v2 PUT endpoint that backs write-page requires:
|
|
145
|
+
# - id
|
|
146
|
+
# - title (unchanged)
|
|
147
|
+
# - version.number (current + 1)
|
|
148
|
+
# - parentId (the new lifecycle parent)
|
|
149
|
+
# - body (some deployments reject PUTs without a body; preserving the body
|
|
150
|
+
# also matches this skill's invariant of never editing PRD content)
|
|
151
|
+
# We therefore GET-then-PUT: fetch via read-page to capture title, version,
|
|
152
|
+
# and body, then write-page with parentId swapped.
|
|
153
|
+
transition_prd() {
|
|
154
|
+
local prd_id="$1" target_role="$2"
|
|
155
|
+
local new_parent
|
|
156
|
+
new_parent=$(read_parent_id "$target_role")
|
|
157
|
+
# 1. read-page id: $prd_id -> capture title, version.number (=N), body.storage.value
|
|
158
|
+
# 2. write-page payload: {
|
|
159
|
+
# "id": "$prd_id",
|
|
160
|
+
# "title": "<unchanged>",
|
|
161
|
+
# "parentId": "$new_parent",
|
|
162
|
+
# "version": { "number": N+1 },
|
|
163
|
+
# "body": { "storage": { "value": "<unchanged>", "representation": "storage" } }
|
|
164
|
+
# }
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
# Claim:
|
|
168
|
+
transition_prd "$PRD_ID" in_review
|
|
169
|
+
```
|
|
95
170
|
|
|
96
|
-
|
|
171
|
+
This re-parent is the idempotency lock — a re-entrant cycle running concurrently won't see this PRD because `read-page-descendants id: $READY_PARENT` no longer includes it once parentId has moved.
|
|
97
172
|
|
|
98
|
-
|
|
173
|
+
If the update fails (permission error, version conflict / 409 race), log it and skip this PRD. Do not proceed to validation on a PRD you didn't successfully claim.
|
|
99
174
|
|
|
100
175
|
#### 3b. Dry-run validation
|
|
101
176
|
|
|
@@ -113,8 +188,8 @@ This call also indirectly invokes `lisa:tracker-source-artifacts` (artifact extr
|
|
|
113
188
|
|
|
114
189
|
1. Re-invoke `lisa:confluence-to-tracker` with `dry_run: false` to actually write the tickets. This re-runs Phases 1-5 and runs the preservation gate (Phase 5.5).
|
|
115
190
|
2. Capture the created ticket keys from the skill's output.
|
|
116
|
-
3. Post a Confluence **footer comment** on the PRD via `
|
|
117
|
-
4.
|
|
191
|
+
3. Post a Confluence **footer comment** on the PRD via `lisa:atlassian-access` `operation: comment-page id: <PAGE-ID> kind: footer body: "..."` listing the created tickets (epic, stories, sub-tasks) with their JIRA URLs. Lead with: `"Ticketed by Claude. Created N JIRA issues — see below. Move this page under the 'shipped' lifecycle parent after the work is delivered."`
|
|
192
|
+
4. Re-parent to `ticketed`: `transition_prd "$PRD_ID" ticketed`.
|
|
118
193
|
5. **Run Phase 3e (coverage audit)** before considering this PRD done.
|
|
119
194
|
|
|
120
195
|
**If `FAIL`** (one or more planned tickets failed one or more gates):
|
|
@@ -128,14 +203,14 @@ The audience for these comments is the **product team**, not engineers. They are
|
|
|
128
203
|
|
|
129
204
|
##### 3c.2 Render each comment
|
|
130
205
|
|
|
131
|
-
For each anchored group,
|
|
132
|
-
- `
|
|
133
|
-
- `
|
|
206
|
+
For each anchored group, invoke `lisa:atlassian-access` `operation: comment-page kind: inline` with:
|
|
207
|
+
- `id`: the PRD page ID
|
|
208
|
+
- `anchor`: the `prd_anchor` value (the substring the inline comment will be attached to)
|
|
134
209
|
- `body`: the comment body, formatted using the template below
|
|
135
210
|
|
|
136
|
-
For the unanchored group, post a single footer comment via `
|
|
211
|
+
For the unanchored group, post a single footer comment via `lisa:atlassian-access` `operation: comment-page kind: footer body: "..."` using the same template, prefixed with `Issues without a specific section anchor:` and one block per failure.
|
|
137
212
|
|
|
138
|
-
If
|
|
213
|
+
If the inline comment call returns "anchor not found" (the page text changed between fetch and post), fall back to a footer comment for that group via the same access skill operation. Do not silently drop the failure.
|
|
139
214
|
|
|
140
215
|
##### 3c.3 Comment template
|
|
141
216
|
|
|
@@ -148,7 +223,7 @@ Each comment body MUST contain these four parts, in this order, no exceptions:
|
|
|
148
223
|
|
|
149
224
|
**Recommendation:** <validator's `recommendation` field, verbatim — must contain 1–3 concrete options, never a generic "please clarify">
|
|
150
225
|
|
|
151
|
-
**Action:** Update this section in the PRD, then
|
|
226
|
+
**Action:** Update this section in the PRD, then move the page back under the 'ready' lifecycle parent and Claude will re-run intake.
|
|
152
227
|
```
|
|
153
228
|
|
|
154
229
|
If multiple failures share an anchor, render each as its own `**What's unclear:** ... **Recommendation:** ...` block within the same comment, separated by horizontal lines (`---`). Keep the single `[Category badge]` heading at the top using the most-severe / most-blocking category from the group.
|
|
@@ -177,15 +252,15 @@ Use these exact badge labels — they are the validator's category values transl
|
|
|
177
252
|
- Engineering shorthand (`AC`, `OOS`, `repo`, `env var`).
|
|
178
253
|
- "Clarify this" / "Please specify" without candidate resolutions. The validator is required to provide candidates; if `recommendation` is empty or vague, treat the failure as an Error and surface internally rather than posting a useless comment.
|
|
179
254
|
|
|
180
|
-
##### 3c.6
|
|
255
|
+
##### 3c.6 Lifecycle transition
|
|
181
256
|
|
|
182
|
-
After all comments are posted (anchored groups + the optional footer summary),
|
|
257
|
+
After all comments are posted (anchored groups + the optional footer summary), re-parent the PRD to the `blocked` lifecycle parent: `transition_prd "$PRD_ID" blocked`. Do NOT write any destination tickets.
|
|
183
258
|
|
|
184
259
|
#### 3d. Continue
|
|
185
260
|
|
|
186
|
-
Move to the next
|
|
261
|
+
Move to the next ready PRD. One PRD failing does not affect others.
|
|
187
262
|
|
|
188
|
-
#### 3e. Coverage audit (mandatory after
|
|
263
|
+
#### 3e. Coverage audit (mandatory after re-parenting to `ticketed`)
|
|
189
264
|
|
|
190
265
|
Per-ticket gates prove each ticket is well-formed; they do NOT prove the *set* of created tickets covers the *whole* PRD. Silent drops happen — invoke the `lisa:prd-ticket-coverage` skill to catch them.
|
|
191
266
|
|
|
@@ -194,71 +269,81 @@ Per-ticket gates prove each ticket is well-formed; they do NOT prove the *set* o
|
|
|
194
269
|
|
|
195
270
|
| Verdict | Action |
|
|
196
271
|
|---------|--------|
|
|
197
|
-
| `COMPLETE` | Done. Leave
|
|
198
|
-
| `COMPLETE_WITH_SCOPE_CREEP` | Post an advisory footer comment naming the scope-creep tickets (so product can decide whether to close them as out-of-scope). Leave
|
|
199
|
-
| `GAPS_FOUND` | The created ticket set is incomplete. (a) For each gap, post a comment using the same product-facing template as Phase 3c.3 — inline-anchored when `prd_anchor` is non-null, footer otherwise; category badge from the gap's `category` field; `What's unclear` and `Recommendation` from the audit report's `what` and `recommendation` fields. Apply the same forbidden-language rules from Phase 3c.5. (b) Post one footer summary comment listing the tickets that *were* successfully created (so product knows what to keep vs. what to extend). (c)
|
|
200
|
-
| `NO_TICKETS_FOUND` | Should not happen if step 2 succeeded. If it does, log it as an Error in the cycle summary and leave
|
|
272
|
+
| `COMPLETE` | Done. Leave PRD under `ticketed` parent. Move to next PRD. |
|
|
273
|
+
| `COMPLETE_WITH_SCOPE_CREEP` | Post an advisory footer comment naming the scope-creep tickets (so product can decide whether to close them as out-of-scope). Leave PRD under `ticketed` parent. |
|
|
274
|
+
| `GAPS_FOUND` | The created ticket set is incomplete. (a) For each gap, post a comment using the same product-facing template as Phase 3c.3 — inline-anchored when `prd_anchor` is non-null, footer otherwise; category badge from the gap's `category` field; `What's unclear` and `Recommendation` from the audit report's `what` and `recommendation` fields. Apply the same forbidden-language rules from Phase 3c.5. (b) Post one footer summary comment listing the tickets that *were* successfully created (so product knows what to keep vs. what to extend). (c) Re-parent the PRD from `ticketed` back to `blocked`: `transition_prd "$PRD_ID" blocked`. |
|
|
275
|
+
| `NO_TICKETS_FOUND` | Should not happen if step 2 succeeded. If it does, log it as an Error in the cycle summary and leave the PRD under `ticketed` with a comment flagging the audit failure for human review. |
|
|
201
276
|
|
|
202
277
|
3. The created tickets remain in the destination tracker regardless of the verdict — they are valid in their own right. The audit only tells us whether *more* are needed.
|
|
203
278
|
|
|
204
279
|
### Phase 4 — Summary report
|
|
205
280
|
|
|
206
|
-
After processing every
|
|
281
|
+
After processing every ready PRD, emit a summary:
|
|
207
282
|
|
|
208
283
|
```text
|
|
209
284
|
## confluence-prd-intake summary
|
|
210
285
|
|
|
211
|
-
Scope:
|
|
286
|
+
Scope: ready parent = <READY_PARENT> (<URL>)
|
|
212
287
|
Cycle started: <ISO timestamp>
|
|
213
288
|
Cycle completed: <ISO timestamp>
|
|
214
289
|
|
|
215
290
|
PRDs processed: <n>
|
|
216
|
-
-
|
|
291
|
+
- Ticketed: <n>
|
|
217
292
|
- <PRD title> → <epic-key> + <story-count> stories + <subtask-count> sub-tasks (coverage: COMPLETE | COMPLETE_WITH_SCOPE_CREEP)
|
|
218
|
-
-
|
|
293
|
+
- Blocked: <n>
|
|
219
294
|
- <PRD title> → <gate-failure-count> gate failures (pre-write) OR <gap-count> coverage gaps (post-write)
|
|
220
295
|
- Errors (claim failed, etc): <n>
|
|
221
296
|
- <PRD title> — <reason>
|
|
222
297
|
|
|
223
|
-
Total
|
|
298
|
+
Total destination tickets created: <n>
|
|
224
299
|
Coverage audit summary: <n> COMPLETE / <n> COMPLETE_WITH_SCOPE_CREEP / <n> GAPS_FOUND
|
|
225
300
|
```
|
|
226
301
|
|
|
227
|
-
Print to the agent's output. Do not write this summary to Confluence or
|
|
302
|
+
Print to the agent's output. Do not write this summary to Confluence or the destination tracker — it's an operational record for the human.
|
|
228
303
|
|
|
229
304
|
## Idempotency & safety
|
|
230
305
|
|
|
231
|
-
- **Single-cycle scope**: this skill processes the
|
|
232
|
-
- **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa:confluence-to-tracker` (which delegates to `lisa:tracker-write`), and only ever
|
|
233
|
-
- **Claim-first ordering**: the
|
|
234
|
-
- **Failure isolation**: an exception processing one PRD must not stop the cycle. Catch, record under "Errors" in the summary, continue to the next PRD. The PRD that errored is left
|
|
235
|
-
- **Single-
|
|
306
|
+
- **Single-cycle scope**: this skill processes the ready set as it exists at the start of Phase 2. New PRDs moved under the `ready` parent mid-cycle are picked up next run.
|
|
307
|
+
- **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa:confluence-to-tracker` (which delegates to `lisa:tracker-write`), and only ever re-parents PRDs among `in_review`, `blocked`, and `ticketed` via `lisa:atlassian-access` `operation: write-page`. It never edits PRD body content, never re-parents into or out of `draft` / `shipped`, never deletes pages.
|
|
308
|
+
- **Claim-first ordering**: the re-parent to `in_review` happens BEFORE validation runs, so a re-entrant call won't double-process.
|
|
309
|
+
- **Failure isolation**: an exception processing one PRD must not stop the cycle. Catch, record under "Errors" in the summary, continue to the next PRD. The PRD that errored is left under whatever parent it currently occupies (usually `in_review` if claim succeeded) — the human investigates from there.
|
|
310
|
+
- **Single-parent invariant**: a page has exactly one parent by construction in Confluence — the multi-state ambiguity that label-based systems can hit (two `prd-*` labels simultaneously) cannot occur here. After every transition, re-read the page and confirm `parentId` matches the expected role; if not, surface as an Error and skip.
|
|
236
311
|
|
|
237
312
|
## Configuration
|
|
238
313
|
|
|
239
314
|
Same configuration as `lisa:confluence-to-tracker`. See that skill for the full table. Key items:
|
|
240
315
|
|
|
241
|
-
- **From `.lisa.config.json`**: `atlassian.cloudId` (required
|
|
316
|
+
- **From `.lisa.config.json`**: `atlassian.cloudId` (required), `confluence.spaceKey` and/or `confluence.parentPageId` (for breadth-of-scope sanity checks), and `confluence.parents.{draft,ready,in_review,blocked,ticketed,shipped}` for the lifecycle parent-page IDs.
|
|
242
317
|
- **From environment variables**: `E2E_BASE_URL`, `E2E_TEST_PHONE`, `E2E_TEST_OTP`, `E2E_TEST_ORG`, `E2E_GRAPHQL_URL` (operational E2E test config).
|
|
243
318
|
|
|
244
319
|
Destination tracker config (jira / github / linear) is consumed by `lisa:tracker-write` internally — this skill does NOT read it. If any required value is missing, surface the missing key(s) and exit this cycle — never invent values.
|
|
245
320
|
|
|
321
|
+
| Field | Required | Purpose |
|
|
322
|
+
|-------|----------|---------|
|
|
323
|
+
| `.lisa.config.json` `confluence.parents.ready` | yes | Parent page id for "ready for ticketing" |
|
|
324
|
+
| `.lisa.config.json` `confluence.parents.in_review` | yes | Parent page id for "claimed by the agent" |
|
|
325
|
+
| `.lisa.config.json` `confluence.parents.blocked` | yes | Parent page id for "validation failure" |
|
|
326
|
+
| `.lisa.config.json` `confluence.parents.ticketed` | yes | Parent page id for "successfully ticketed" |
|
|
327
|
+
| `.lisa.config.json` `confluence.parents.draft` | recommended | Parent page id for PRDs still being drafted by product |
|
|
328
|
+
| `.lisa.config.json` `confluence.parents.shipped` | recommended | Parent page id for delivered PRDs |
|
|
329
|
+
|
|
246
330
|
## Rules
|
|
247
331
|
|
|
248
332
|
- Never write to the destination tracker outside of `lisa:confluence-to-tracker` → `lisa:tracker-write`. The validator's verdict gates progress; bypassing it produces broken tickets.
|
|
249
|
-
- Never
|
|
250
|
-
- Never edit the PRD's body. Communication with product happens only through Confluence comments.
|
|
333
|
+
- Never re-parent a PRD into a lifecycle parent this skill doesn't own (`in_review`, `blocked`, `ticketed`). Product owns `draft`, `ready` (as the entry signal), and `shipped`.
|
|
334
|
+
- Never edit the PRD's body. Communication with product happens only through Confluence comments. The `write-page` call preserves the body verbatim — fetch then PUT with body unchanged.
|
|
251
335
|
- Never post a single page-level dump of all gate failures. One inline comment per `prd_anchor` group (or one footer summary for unanchored failures only). Comments must be inline-anchored where possible, categorized, plain-language, and contain a concrete recommendation.
|
|
252
336
|
- Never include a gate ID, internal skill name, or engineering shorthand in a comment body.
|
|
253
337
|
- Never run more than one intake cycle concurrently against the same scope. This skill assumes serial execution.
|
|
254
|
-
- If `lisa:confluence-to-tracker` returns errors, treat them as gate failures: comment + `
|
|
338
|
+
- If `lisa:confluence-to-tracker` returns errors, treat them as gate failures: comment + re-parent to `blocked`. Don't silently fail.
|
|
255
339
|
|
|
256
340
|
## Adoption (one-time per project)
|
|
257
341
|
|
|
258
|
-
Before this skill can run against a project, the project must adopt the
|
|
342
|
+
Before this skill can run against a project, the project must adopt the lifecycle parent-page convention:
|
|
259
343
|
|
|
260
|
-
1.
|
|
261
|
-
2.
|
|
262
|
-
3.
|
|
344
|
+
1. Create six pages in the project's Confluence space, one per lifecycle role: `Draft`, `Ready`, `In Review`, `Blocked`, `Ticketed`, `Shipped`. (Page titles are not significant — they exist to be re-parenting targets.)
|
|
345
|
+
2. Record each page's numeric id in `.lisa.config.json` under `confluence.parents.<role>`. `/lisa:setup:confluence` automates this.
|
|
346
|
+
3. Move each existing PRD page under the appropriate lifecycle parent based on its current state. Product moves PRDs from `draft` → `ready` when they are ready for ticketing (replaces the Notion `Status = Ready` flip).
|
|
347
|
+
4. Reserve the `in_review`, `blocked`, and `ticketed` parents for this skill — humans should not re-parent PRDs into them manually except to recover from an error.
|
|
263
348
|
|
|
264
|
-
If the project hasn't adopted these
|
|
349
|
+
If the project hasn't adopted these parent pages, the first run exits with a provisioning error (not the idle empty-set message) — this distinguishes a setup issue from a genuinely empty queue so operators know to run `/lisa:setup:confluence` rather than assuming the queue is drained. See Phase 2 for how the skill detects this case.
|
|
@@ -7,11 +7,13 @@ description: >
|
|
|
7
7
|
or similar. This skill mirrors `lisa:notion-to-tracker` for projects whose PRDs live in Confluence —
|
|
8
8
|
the workflow, gates, dry-run mode, and validation rules are identical; only the source-of-truth tool
|
|
9
9
|
surface differs (Confluence MCP instead of Notion MCP).
|
|
10
|
-
allowed-tools: ["Skill", "Bash"
|
|
10
|
+
allowed-tools: ["Skill", "Bash"]
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
# Confluence PRD to Tracker Breakdown
|
|
14
14
|
|
|
15
|
+
All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
|
|
16
|
+
|
|
15
17
|
Convert a Confluence PRD into a structured ticket hierarchy in the configured destination tracker (JIRA, GitHub Issues, or Linear per .lisa.config.json): Epics > Stories > Sub-tasks.
|
|
16
18
|
Each sub-task is scoped to exactly one repo and includes an empirical verification plan.
|
|
17
19
|
|
|
@@ -29,8 +31,9 @@ This skill supports two modes, controlled by a `dry_run` flag in `$ARGUMENTS`:
|
|
|
29
31
|
|
|
30
32
|
Dry-run output format is identical to `lisa:notion-to-tracker`'s. Reuse the same fields, including
|
|
31
33
|
`prd_anchor` and `prd_section`. The only difference: `prd_anchor` is the inline-comment anchor text
|
|
32
|
-
that `
|
|
33
|
-
exceeds the
|
|
34
|
+
that `lisa:atlassian-access` `operation: comment-page kind: inline` accepts (typically the full
|
|
35
|
+
selected substring; truncate if it exceeds the substrate's max anchor length and emit `null` if no
|
|
36
|
+
resolvable anchor exists).
|
|
34
37
|
|
|
35
38
|
```text
|
|
36
39
|
## confluence-to-tracker dry-run: <PRD title>
|
|
@@ -63,13 +66,21 @@ exceeds the tool's max anchor length and emit `null` if no resolvable anchor exi
|
|
|
63
66
|
### Total failures: <n>
|
|
64
67
|
```
|
|
65
68
|
|
|
66
|
-
The dry-run mode never writes to
|
|
67
|
-
|
|
69
|
+
The dry-run mode never writes to the destination tracker. It also never modifies the source Confluence
|
|
70
|
+
page, never re-parents the PRD between lifecycle parents, and never posts comments — that is the
|
|
68
71
|
orchestrating skill's responsibility (`lisa:confluence-prd-intake`).
|
|
69
72
|
|
|
73
|
+
## PRD lifecycle is parent-page-based on Confluence
|
|
74
|
+
|
|
75
|
+
Unlike GitHub and Linear (which use labels for PRD lifecycle state), Confluence encodes PRD lifecycle as **parent-page placement**: each lifecycle role (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`) corresponds to a dedicated parent page in the project's Confluence space, listed in `.lisa.config.json` under `confluence.parents.<role>`. A PRD's current state is determined by which of those parents it sits under; a "transition" is a `PUT /wiki/api/v2/pages/{id}` that swaps `parentId`.
|
|
76
|
+
|
|
77
|
+
This skill itself does NOT transition the PRD between lifecycle parents — that is the orchestrating skill's job (`lisa:confluence-prd-intake`). This skill consumes the PRD content and produces tickets; lifecycle state changes (`ready` → `in_review`, `in_review` → `ticketed` / `blocked`) happen in the orchestrator, before and after this skill runs.
|
|
78
|
+
|
|
79
|
+
Why parent-page-based, not label-based: scoped Atlassian API tokens cannot write Confluence labels via the v1 endpoint, and the v2 Label API group has no POST endpoint at all. Parent-id transitions, by contrast, are first-class in v2 and work with `write:page:confluence` scope. See `config-resolution` rule, section "Confluence PRD lifecycle uses parent pages, not labels," for the full rationale.
|
|
80
|
+
|
|
70
81
|
## Hard Rule: All Writes Go Through `lisa:tracker-write`
|
|
71
82
|
|
|
72
|
-
**Every
|
|
83
|
+
**Every ticket created by this skill — every epic, story, and sub-task — MUST be created by invoking the `lisa:tracker-write` skill. Never invoke `lisa:atlassian-access` write operations (`write-ticket`, `link`, `comment`, `transition`) directly from this skill or from any sub-agent it spawns.**
|
|
73
84
|
|
|
74
85
|
`lisa:tracker-write` enforces gates this skill does not:
|
|
75
86
|
- 3-audience description (Context / Technical Approach / Acceptance Criteria)
|
|
@@ -80,7 +91,7 @@ orchestrating skill's responsibility (`lisa:confluence-prd-intake`).
|
|
|
80
91
|
- Sign-in account and target environment recorded in description
|
|
81
92
|
- Post-create verification
|
|
82
93
|
|
|
83
|
-
Bypassing `lisa:tracker-write` produces thin tickets that the rest of the lifecycle (triage, ticket-verify, journey, evidence) treats as broken.
|
|
94
|
+
Bypassing `lisa:tracker-write` produces thin tickets that the rest of the lifecycle (triage, ticket-verify, journey, evidence) treats as broken. Read operations on Atlassian (ticket reads, JQL search, Confluence page reads, comment fetches) are still performed in this skill — but ONLY via `lisa:atlassian-access` (`operation: read-ticket | search-issues | read-page | search-pages | list-sites`), never via direct MCP tool calls or `acli`.
|
|
84
95
|
|
|
85
96
|
## Input
|
|
86
97
|
|
|
@@ -130,14 +141,15 @@ If env vars are not available, ask the user to provide them explicitly before pr
|
|
|
130
141
|
|
|
131
142
|
### Phase 1: Fetch & Analyze the PRD
|
|
132
143
|
|
|
133
|
-
1. **
|
|
134
|
-
2. **Fetch the main PRD page**
|
|
135
|
-
3. **Identify all Epic child pages**
|
|
136
|
-
4. **Fetch all Epic pages** in parallel via `
|
|
137
|
-
5. **Fetch full comments** for the main page and every epic page in parallel:
|
|
138
|
-
- `
|
|
139
|
-
- `
|
|
140
|
-
- For any comment with replies, walk the tree via `
|
|
144
|
+
1. **Confirm the configured Atlassian site** by invoking `lisa:atlassian-access` `operation: list-sites` (it enforces connection match against `.lisa.config.json`).
|
|
145
|
+
2. **Fetch the main PRD page** by invoking `lisa:atlassian-access` `operation: read-page id: <PAGE-ID>`. Capture body, parent page id (used by `lisa:confluence-prd-intake` to determine the PRD's lifecycle state — see "PRD lifecycle is parent-page-based" below), and child page references.
|
|
146
|
+
3. **Identify all Epic child pages** by invoking `lisa:atlassian-access` `operation: read-page-descendants id: <PAGE-ID>` (one level deep first; recurse if the PRD nests epics under a "Specs" parent). If `atlassian-access` does not yet expose `read-page-descendants`, request its addition (see report at bottom).
|
|
147
|
+
4. **Fetch all Epic pages** in parallel via `lisa:atlassian-access` `operation: read-page id: <EPIC-PAGE-ID>`.
|
|
148
|
+
5. **Fetch full comments** for the main page and every epic page in parallel via `lisa:atlassian-access`:
|
|
149
|
+
- `operation: read-page-comments id: <PAGE-ID> kind: footer` — page-level threaded comments (equivalent to Notion's page-level discussions)
|
|
150
|
+
- `operation: read-page-comments id: <PAGE-ID> kind: inline` — block-anchored comments tied to specific text spans
|
|
151
|
+
- For any comment with replies, walk the tree via `operation: read-comment-children id: <COMMENT-ID>` until exhausted
|
|
152
|
+
(If any of these read-comment operations is not yet in `atlassian-access`'s dispatch table, request their addition — they are intentionally listed here so the access skill can be extended.)
|
|
141
153
|
6. **Synthesize decisions and blockers** from the PRD content + all comments:
|
|
142
154
|
- Decisions already confirmed by the team (look for agreement in comment threads)
|
|
143
155
|
- Open questions that need product/engineering input
|
|
@@ -180,13 +192,13 @@ Identical to `lisa:notion-to-tracker` Phase 2. Two complementary inputs ground P
|
|
|
180
192
|
|
|
181
193
|
Skip 2b only when the work is purely backend with no user-visible surface, or affects a screen that does not yet exist in dev/prod.
|
|
182
194
|
|
|
183
|
-
Walkthrough findings are attached to the originating Confluence PRD as a **footer comment** (Confluence has no general "page-level discussion attached to a heading" — footer comments are the page-level equivalent), via `
|
|
195
|
+
Walkthrough findings are attached to the originating Confluence PRD as a **footer comment** (Confluence has no general "page-level discussion attached to a heading" — footer comments are the page-level equivalent), via `lisa:atlassian-access` `operation: comment-page id: <PAGE-ID> kind: footer body: "..."`. Title the comment "Current product walkthrough — `<route>`". Inherited onto the resulting epic / stories under a `## Current Product` subsection.
|
|
184
196
|
|
|
185
197
|
### Phase 3: Create Epics
|
|
186
198
|
|
|
187
199
|
> **Mode guard**: In `dry_run: true` mode, do not invoke `lisa:tracker-write` in this phase. Instead, draft the epic spec (summary, description_body, artifacts) and validate it with `lisa:tracker-validate --spec-only`. Record the drafted spec (including a placeholder epic key like `DRY-RUN-EPIC-1`) for Phase 4 to use as parent references. In `dry_run: false` mode (default), proceed as described below.
|
|
188
200
|
|
|
189
|
-
For each PRD epic, **invoke the `lisa:tracker-write` skill** (do not
|
|
201
|
+
For each PRD epic, **invoke the `lisa:tracker-write` skill** (do not invoke `lisa:atlassian-access` write operations directly). Pass it everything it needs to enforce its quality gates:
|
|
190
202
|
|
|
191
203
|
- `project_key`: resolved by `lisa:tracker-write` from `.lisa.config.json`
|
|
192
204
|
- `issue_type`: `Epic`
|
|
@@ -236,7 +248,7 @@ Capture each returned story key — Phase 5 needs it as the parent for sub-tasks
|
|
|
236
248
|
|
|
237
249
|
**Auto-split cross-repo work before delegation.** For each candidate sub-task, apply `lisa:task-decomposition` step 1.5: if the work touches more than one repo, split it into one sub-task per repo under the same parent Story (e.g., `[backend-api] Add field` + `[mobile-app] Display field`), and encode the producer-before-consumer ordering via dependencies. Work units that may span repos (Epic, Story, Spike) stay as planned; work units that must be single-repo (Bug, Task, Sub-task, Improvement) are split now. Splitting is this skill's responsibility — the validator's S10 gate is `product_relevant: false` because cross-repo failures are decomposition errors caught here, not product questions sent back to the PRD.
|
|
238
250
|
|
|
239
|
-
Delegate sub-task creation to **parallel agents** (one per epic or batch of stories) for efficiency. **Every spawned agent must invoke `lisa:tracker-write` for each sub-task — no agent may
|
|
251
|
+
Delegate sub-task creation to **parallel agents** (one per epic or batch of stories) for efficiency. **Every spawned agent must invoke `lisa:tracker-write` for each sub-task — no agent may invoke `lisa:atlassian-access` write operations directly.**
|
|
240
252
|
|
|
241
253
|
Each sub-task MUST:
|
|
242
254
|
1. **Be scoped to exactly ONE repo** — indicated in brackets in the summary: `[repo-name]`
|
|
@@ -293,16 +305,17 @@ When you encounter something the PRD + comments + codebase can't resolve:
|
|
|
293
305
|
|
|
294
306
|
## Agent Prompt Template for Sub-task Creation
|
|
295
307
|
|
|
296
|
-
When delegating to agents, provide this context. **The "MUST invoke
|
|
308
|
+
When delegating to agents, provide this context. **The "MUST invoke lisa:tracker-write" instruction is load-bearing — do not edit it out when adapting this template.**
|
|
297
309
|
|
|
298
310
|
```text
|
|
299
|
-
Create
|
|
311
|
+
Create sub-tasks in the [PROJECT] project.
|
|
300
312
|
|
|
301
313
|
CRITICAL: For each sub-task, invoke the `lisa:tracker-write` skill via the Skill tool.
|
|
302
|
-
Do NOT
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
314
|
+
Do NOT invoke `lisa:atlassian-access` write operations (write-ticket / link / comment /
|
|
315
|
+
transition) directly. The `lisa:tracker-write` skill enforces required quality gates
|
|
316
|
+
(Gherkin acceptance criteria, 3-audience description, single-repo scope,
|
|
317
|
+
sign-in/environment fields, post-create verification). Bypassing it produces broken
|
|
318
|
+
tickets that downstream skills (triage, journey, evidence) cannot use.
|
|
306
319
|
|
|
307
320
|
For each sub-task, invoke `lisa:tracker-write` with:
|
|
308
321
|
- issue_type: "Sub-task"
|
|
@@ -320,10 +333,10 @@ For each sub-task, invoke `lisa:tracker-write` with:
|
|
|
320
333
|
Each sub-task must:
|
|
321
334
|
1. Be scoped to ONE repo only — repo named in brackets in the summary
|
|
322
335
|
2. Include the Empirical Verification Plan in the description
|
|
323
|
-
3. Be created via `lisa:tracker-write`, not via direct
|
|
336
|
+
3. Be created via `lisa:tracker-write`, not via direct `lisa:atlassian-access` write operations
|
|
324
337
|
|
|
325
338
|
If `lisa:tracker-write` rejects a sub-task, fix the input and re-invoke. Do NOT fall back
|
|
326
|
-
to a direct `
|
|
339
|
+
to a direct `lisa:atlassian-access` `operation: write-ticket` call to bypass the gate.
|
|
327
340
|
|
|
328
341
|
Test user info: [credentials from config]
|
|
329
342
|
|
|
@@ -10,14 +10,13 @@ Walk the original Plan for `$ARGUMENTS`, mine the completed work items and their
|
|
|
10
10
|
|
|
11
11
|
## Orchestration: agent team
|
|
12
12
|
|
|
13
|
-
If you are NOT already operating inside an agent team (no prior
|
|
13
|
+
If you are NOT already operating inside an agent team (no prior successful team-creation tool call in this session, not spawned into a team context), the very first thing you do is establish team orchestration.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
2. `TeamCreate` — actually create the team.
|
|
15
|
+
Use `TeamCreate` if available. In Claude, if `TeamCreate` has not been loaded yet, first use `ToolSearch` with `query: "select:TeamCreate"` to load its schema. If `TeamCreate` is not available, use the current runtime's tool-discovery mechanism (for Codex, `tool_search`) to discover available multi-agent/team tools, then call the appropriate team creation tool. If no team creation tool is available, explicitly state that team orchestration is unavailable in this runtime, continue as the lead agent, and preserve the workflow's review, verification, and task-tracking obligations locally.
|
|
17
16
|
|
|
18
|
-
Until
|
|
17
|
+
Until the team is established or the no-team fallback has been declared, do NOT call any of: `Agent`, `TaskCreate`, `Skill`, MCP tools (Atlassian / Linear / GitHub / Notion), `Read`, `Write`, `Edit`, `Bash`, `Grep`, `Glob`. Resolving the work-item set, fetching tickets, walking PRs — all of those are tasks for the team you are about to create, not for the lead session before orchestration exists.
|
|
19
18
|
|
|
20
|
-
If you ARE already inside an agent team (e.g., a teammate invoked this skill via the Skill tool), do NOT
|
|
19
|
+
If you ARE already inside an agent team (e.g., a teammate invoked this skill via the Skill tool), do NOT create a second team — many harnesses reject double-creates. Continue within the existing team.
|
|
21
20
|
|
|
22
21
|
## Input
|
|
23
22
|
|