@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,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: notion-prd-intake
|
|
3
|
-
description: PRD intake agent. Runs one intake cycle against a Notion PRD database — claims
|
|
3
|
+
description: PRD intake agent. Runs one intake cycle against a Notion PRD database — claims PRDs in the configured `ready` status, validates each through the dry-run pipeline, and routes to the `blocked` status (with clarifying comments) or the `ticketed` status (with destination tickets created). Designed to be invoked manually via /notion-prd-intake or autonomously via a scheduled cron.
|
|
4
4
|
skills:
|
|
5
5
|
- notion-prd-intake
|
|
6
6
|
- notion-to-tracker
|
|
@@ -15,9 +15,11 @@ skills:
|
|
|
15
15
|
|
|
16
16
|
You are a PRD intake agent. Your single job is to run one intake cycle against the Notion PRD database whose URL is given to you, then report what happened.
|
|
17
17
|
|
|
18
|
+
Status role names (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`) are resolved from `.lisa.config.json` `notion.values.*` by the `notion-prd-intake` skill. The defaults match the legacy hardcoded names (`Draft`, `Ready`, `In Review`, `Blocked`, `Ticketed`, `Shipped`).
|
|
19
|
+
|
|
18
20
|
## Confirmation policy
|
|
19
21
|
|
|
20
|
-
Once you have a database URL, RUN. Do not ask the caller whether to proceed, do not preview projected scope, do not offer "proceed / skip / dry-run" choices. The caller has already authorized the run by invoking you; re-prompting defeats the purpose of a background batch. `
|
|
22
|
+
Once you have a database URL, RUN. Do not ask the caller whether to proceed, do not preview projected scope, do not offer "proceed / skip / dry-run" choices. The caller has already authorized the run by invoking you; re-prompting defeats the purpose of a background batch. The `blocked` status is a valid terminal state of the lifecycle, not a failure mode — large PRDs and PRDs full of open questions are exactly what this skill is for. The `notion-prd-intake` skill defines the only legitimate early-exit conditions (missing URL, misconfigured database, empty ready set); ask only when one of those applies.
|
|
21
23
|
|
|
22
24
|
## Workflow
|
|
23
25
|
|
|
@@ -31,30 +33,30 @@ If no URL is provided, stop and ask. Never run intake against a default or guess
|
|
|
31
33
|
|
|
32
34
|
Invoke the `notion-prd-intake` skill with the database URL as `$ARGUMENTS`. The skill owns the cycle logic — claim, dry-run, branch, write or comment, status transition, summary. Do not duplicate that logic here.
|
|
33
35
|
|
|
34
|
-
Treat the skill's output as the source of truth.
|
|
36
|
+
Treat the skill's output as the source of truth (e.g. `ticketed: 3 / blocked: 1 / errors: 0`).
|
|
35
37
|
|
|
36
38
|
### 3. Surface the summary
|
|
37
39
|
|
|
38
40
|
Pass the skill's summary block through to the caller verbatim — do not paraphrase or condense. The caller (often a human running `/notion-prd-intake` ad-hoc, or a future schedule wrapper) needs the structured record:
|
|
39
41
|
|
|
40
42
|
- Total processed
|
|
41
|
-
- Per-PRD outcomes (
|
|
42
|
-
-
|
|
43
|
+
- Per-PRD outcomes (ticketed → which tickets created; blocked → how many gate failures; errors → reason)
|
|
44
|
+
- Destination ticket count
|
|
43
45
|
|
|
44
46
|
If the cycle errored before processing any PRDs (e.g. database misconfigured, missing config), surface the failure cause in plain language and stop.
|
|
45
47
|
|
|
46
48
|
### 4. Suggest next actions when warranted
|
|
47
49
|
|
|
48
|
-
After a successful cycle, if any PRDs ended in `
|
|
50
|
+
After a successful cycle, if any PRDs ended in the `blocked` status, mention to the caller that those PRDs need product attention before they can be re-ticketed. Do not auto-notify product — Notion comments on the PRDs are the channel; the caller decides whether to ping anyone.
|
|
49
51
|
|
|
50
|
-
When reporting
|
|
52
|
+
When reporting `blocked` outcomes, distinguish the cause: **pre-write gate failure** (per-ticket validator caught a problem before any tickets were created) vs **post-write coverage gap** (tickets were created and remain in the destination tracker, but the PRD has uncovered requirements that the next intake cycle will address). Both result in the `blocked` status, but the implication for product is different — coverage gaps mean some tickets are already real and product should not re-author the PRD from scratch.
|
|
51
53
|
|
|
52
|
-
If all PRDs ended in `
|
|
54
|
+
If all PRDs ended in the `ticketed` status with coverage `COMPLETE`, mention that the next step is for product to monitor the created tickets and flip the PRDs to the configured `shipped` status after delivery. If any are `COMPLETE_WITH_SCOPE_CREEP`, point that out so product can review the flagged tickets.
|
|
53
55
|
|
|
54
56
|
## Rules
|
|
55
57
|
|
|
56
58
|
- **Never run a cycle without an explicit database URL.** Side effects are too high to default.
|
|
57
|
-
- **Never modify the lifecycle**: only `
|
|
59
|
+
- **Never modify the lifecycle**: only `ready → in_review → blocked|ticketed`. Never touch `draft` or `shipped`. Never invent new status values.
|
|
58
60
|
- **Never write destination tickets directly.** All writes go through the skill chain (intake → notion-to-tracker → tracker-write). Bypassing this skips quality gates.
|
|
59
61
|
- **Never edit a PRD's body.** Communication with product happens only via Notion comments on the PRD.
|
|
60
62
|
- **Never start a second cycle while one is in flight against the same database.** This agent assumes serial execution; the scheduling layer is responsible for not double-firing.
|
|
@@ -80,6 +80,6 @@ If there are no findings under a checklist row, write `(none)`.
|
|
|
80
80
|
- **Never judge.** Surface every match. The synthesizer reconciles signal vs. noise.
|
|
81
81
|
- **Quote verbatim.** Don't paraphrase review comments; the exact wording often carries the learning.
|
|
82
82
|
- **Link, don't summarize.** Every finding has at least one evidence link (PR comment anchor, commit URL, file blob URL).
|
|
83
|
-
- **Run within the team.** Do not
|
|
83
|
+
- **Run within the team.** Do not create a second team. The Debrief skill created the team; you are a teammate.
|
|
84
84
|
- **Read-only.** No `gh pr merge`, no `gh pr review`, no commits. You observe; you do not mutate.
|
|
85
85
|
- **Parallel-safe.** You run alongside `tracker-mining-specialist`; do not coordinate with them. The synthesizer reconciles.
|
|
@@ -80,6 +80,6 @@ If there are no findings under a checklist row, write `(none)` — silence is it
|
|
|
80
80
|
- **Never judge.** "Probably not interesting" is not a category. Every signal that matches a checklist row goes in.
|
|
81
81
|
- **Quote verbatim.** Paraphrasing comments loses author voice and the specifics that make a finding actionable.
|
|
82
82
|
- **Link, don't summarize.** Every finding has at least one evidence link to the source artifact (comment URL, ticket URL fragment, PR URL).
|
|
83
|
-
- **Run within the team.** Do not
|
|
83
|
+
- **Run within the team.** Do not create a second team. The Debrief skill created the team; you are a teammate.
|
|
84
84
|
- **Read-only.** Never call write MCP tools. You report; you do not mutate.
|
|
85
85
|
- **Parallel-safe.** You run alongside `pr-mining-specialist`; do not coordinate with them. The synthesizer reconciles.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up Atlassian (cloudId + acli profile) for this project. Writes the `atlassian` section of `.lisa.config.json` and enables the Atlassian MCP and/or installs acli as needed. Prerequisite for /lisa:setup:jira and /lisa:setup:confluence."
|
|
3
|
+
allowed-tools: ["Skill"]
|
|
4
|
+
argument-hint: "[--site=<site>] [--email=<email>]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use the /lisa:setup-atlassian skill to configure Atlassian access for this project. $ARGUMENTS
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up Confluence as the PRD source for this project. Writes the `confluence` section of `.lisa.config.json` (spaceKey and/or parentPageId) and offers to set top-level `source: \"confluence\"`. Depends on /lisa:setup:atlassian."
|
|
3
|
+
allowed-tools: ["Skill"]
|
|
4
|
+
argument-hint: "[--space=<KEY>] [--parent=<pageId>]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use the /lisa:setup-confluence skill to configure Confluence as the PRD source. $ARGUMENTS
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up JIRA as the tracker for this project. Writes `jira.project` and offers to set top-level `tracker: \"jira\"` in `.lisa.config.json`. Depends on /lisa:setup:atlassian (needs cloudId)."
|
|
3
|
+
allowed-tools: ["Skill"]
|
|
4
|
+
argument-hint: "[--project=<KEY>]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use the /lisa:setup-jira skill to configure JIRA as the project tracker. $ARGUMENTS
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Set up Notion as the PRD source for this project. Walks the user through creating a workspace-scoped internal-integration token, sharing the PRD database with it, and stores the token in OS keychain. Writes `notion.workspaceId`, `notion.prdDatabaseId`, and `notion.values` into `.lisa.config.json`. Offers to set top-level `source: \"notion\"`."
|
|
3
|
+
allowed-tools: ["Skill"]
|
|
4
|
+
argument-hint: "[--database=<uuid>] [--workspace=<slug>]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use the /lisa:setup-notion skill to configure Notion as the PRD source. $ARGUMENTS
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# Enforces
|
|
2
|
+
# Enforces Claude's TeamCreate-first orchestration for lifecycle skills.
|
|
3
|
+
#
|
|
4
|
+
# This hook is intentionally Claude-specific. Other harnesses may use different
|
|
5
|
+
# team tooling or an explicit no-team fallback; those paths are described in the
|
|
6
|
+
# shared rules/skills but are not enforced by this Claude hook.
|
|
3
7
|
#
|
|
4
8
|
# Triggered on four hook events:
|
|
5
9
|
# - UserPromptSubmit : detects /lisa:research|plan|implement|intake|debrief in the
|
|
6
10
|
# raw prompt and arms enforcement for the session
|
|
7
11
|
# - PreToolUse : detects the same skills via a `Skill` tool call,
|
|
8
12
|
# arms enforcement, and blocks bypass tool calls
|
|
9
|
-
# until ToolSearch+TeamCreate have fired
|
|
10
|
-
# - PostToolUse : on a successful TeamCreate, marks the session as
|
|
13
|
+
# until ToolSearch+TeamCreate have fired in Claude
|
|
14
|
+
# - PostToolUse : on a successful Claude TeamCreate, marks the session as
|
|
11
15
|
# team-created (lifts enforcement)
|
|
12
16
|
# - SubagentStart : marks the new subagent session as a teammate so
|
|
13
17
|
# it is exempt — teammates inherit the lead's team
|
|
14
|
-
# and must never
|
|
15
|
-
# is rejected by the harness)
|
|
18
|
+
# and must never create a second team (double-create
|
|
19
|
+
# is rejected by the Claude harness)
|
|
16
20
|
#
|
|
17
21
|
# Per-session state lives under "$STATE_DIR" as flag files keyed by
|
|
18
22
|
# session_id. Stale state (>24h) is cleaned on each invocation.
|
|
@@ -159,7 +163,7 @@ fi
|
|
|
159
163
|
ACTIVE_SKILL=$(cat "$SKILL_FLAG" 2>/dev/null || echo "lisa:???")
|
|
160
164
|
cat >&2 <<EOF
|
|
161
165
|
Blocked: this session invoked /${ACTIVE_SKILL}, which is an agent-team flow.
|
|
162
|
-
|
|
166
|
+
In Claude, before any other tool call, you must:
|
|
163
167
|
|
|
164
168
|
1. ToolSearch with query: "select:TeamCreate" (load the deferred schema)
|
|
165
169
|
2. TeamCreate (actually create the team)
|
|
@@ -169,6 +173,10 @@ the ticket, exploring the code, fetching context — those are tasks for the
|
|
|
169
173
|
team you are about to create, not for the lead session before the team
|
|
170
174
|
exists.
|
|
171
175
|
|
|
176
|
+
If you are running Lisa in a non-Claude harness, this Claude enforcement hook
|
|
177
|
+
should not be installed; follow the runtime-aware orchestration preamble in the
|
|
178
|
+
skill instead.
|
|
179
|
+
|
|
172
180
|
Re-read the orchestration preamble in /${ACTIVE_SKILL} and start with
|
|
173
181
|
ToolSearch.
|
|
174
182
|
EOF
|
|
@@ -8,7 +8,7 @@ After echoing the chosen flow and BEFORE doing any work, state the orchestration
|
|
|
8
8
|
|
|
9
9
|
Default to an agent team for Research, Plan, Implement (Build/Fix/Improve/Investigate-Only), and any flow that invokes the Review sub-flow. Use a single agent only for Verify (standalone) and Monitor (standalone). See the `intent-routing` rule's Orchestration section for the full decision matrix.
|
|
10
10
|
|
|
11
|
-
When the mode is `agent team` **and you are not already operating inside an agent team**, your FIRST tool calls after the classification echo MUST
|
|
11
|
+
When the mode is `agent team` **and you are not already operating inside an agent team**, your FIRST tool calls after the classification echo MUST establish team orchestration before any content-gathering work. 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. Do not reach for `TaskCreate`, `Agent`, `Skill`, MCP tools, `Read`, `Bash`, or any other content-gathering call before the team exists or the no-team fallback has been declared — those are bypass paths that skip durable task state and parallel review. Reading the ticket, exploring the code, querying the API are all tasks for the team, not for the lead session before orchestration exists.
|
|
12
12
|
|
|
13
13
|
Requirement Verification:
|
|
14
14
|
|
|
@@ -70,7 +70,7 @@ JIRA Discipline:
|
|
|
70
70
|
- When reading a JIRA issue, always read ALL comments on the ticket — not just the description. Comments contain critical context: stakeholder decisions, scope changes, blockers, triage findings from other repos, and implementation notes. Use the Atlassian MCP or `jira issue view <TICKET_ID> --comments 100` to fetch them.
|
|
71
71
|
- When requesting clarification on a JIRA issue, post the question as a comment using ADF (Atlassian Document Format) and @mention the Reporter so they receive a notification.
|
|
72
72
|
- When creating JIRA tickets, establish issue link relationships (e.g. "is blocked by", "blocks", "relates to", "is duplicated by") between tickets that have dependencies or logical connections. Do not leave related tickets unlinked. Relationship discovery is mandatory on every create and update — search BOTH the local git history (`git log --all --grep=<keyword>`, `git log -- <path>`) AND Jira (JQL by component, keyword, label, epic siblings) before declaring "no related work." Record the searches you ran and their outcomes in the description (or a comment) so a reviewer can see the search was real.
|
|
73
|
-
- Ticket scope by type: Bug, Task, and Sub-task tickets MUST be single-repo (one work unit, one repo). Epic, Spike, and Story tickets MAY span multiple repos. If a Bug/Task/Sub-task crosses repos, split it.
|
|
73
|
+
- Ticket scope by type: Bug, Task, and Sub-task tickets MUST be single-repo (one work unit, one repo). Epic, Spike, and Story tickets MAY span multiple repos. If a Bug/Task/Sub-task crosses repos, split it per the `repo-scope-split` rule — at PRD-decomposition time via `task-decomposition` step 1.5 (parent Story + per-repo children); at work-time (an existing ticket an agent is about to implement) via the work-time split procedure (narrow the original to one repo, spin off a sibling per additional repo cloning its metadata, link the producer→consumer dependency, then proceed). A cross-repo work unit is a decomposition error the agent fixes by splitting, not a reason to bounce the ticket to the reporter.
|
|
74
74
|
- Ticket descriptions MUST contain everything an implementer needs to start work without asking the reporter. In particular:
|
|
75
75
|
- **Target backend environment** (`dev` / `staging` / `prod`) when the ticket has runtime behavior. QA/product report against a deployed env; the implementer verifies locally first against that backend before CI/CD. Skip only for doc-only, config-only, type-only, or Epic tickets.
|
|
76
76
|
- **Sign-in account / credentials** when the work requires being signed in. Name the account (or the source — 1Password item, env var, seeded fixture) and the role. Omit entirely when sign-in is not required.
|
|
@@ -130,4 +130,4 @@ When you detect any of the above:
|
|
|
130
130
|
1. Do NOT guess or make assumptions about what the external code does
|
|
131
131
|
2. Identify which repository contains the missing code
|
|
132
132
|
3. Add that repository to your current session before proceeding
|
|
133
|
-
4. If you cannot determine which repository contains the code, ask — do not proceed without it
|
|
133
|
+
4. If you cannot determine which repository contains the code, ask — do not proceed without it
|
|
@@ -18,9 +18,15 @@ A typical Bash read:
|
|
|
18
18
|
```bash
|
|
19
19
|
local_value=$(jq -r '.tracker // empty' .lisa.config.local.json 2>/dev/null)
|
|
20
20
|
global_value=$(jq -r '.tracker // empty' .lisa.config.json 2>/dev/null)
|
|
21
|
-
tracker="${local_value:-${global_value
|
|
21
|
+
tracker="${local_value:-${global_value}}"
|
|
22
|
+
if [ -z "$tracker" ]; then
|
|
23
|
+
echo "Error: 'tracker' not set in .lisa.config.json. Run /lisa:setup:jira (or :github, :linear) to configure." >&2
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
22
26
|
```
|
|
23
27
|
|
|
28
|
+
`tracker` is **required** — there is no implicit default. Projects must declare their destination explicitly via one of the `/lisa:setup:*` skills.
|
|
29
|
+
|
|
24
30
|
## Schema
|
|
25
31
|
|
|
26
32
|
```json
|
|
@@ -28,12 +34,88 @@ tracker="${local_value:-${global_value:-jira}}"
|
|
|
28
34
|
"tracker": "jira",
|
|
29
35
|
"source": "notion",
|
|
30
36
|
|
|
31
|
-
"atlassian": { "cloudId": "<uuid>" },
|
|
32
|
-
"jira":
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
"atlassian": { "cloudId": "<uuid>", "site": "<host>" },
|
|
38
|
+
"jira": {
|
|
39
|
+
"project": "<KEY>",
|
|
40
|
+
"workflow": {
|
|
41
|
+
"ready": "Ready",
|
|
42
|
+
"claimed": "In Progress",
|
|
43
|
+
"review": "Code Review",
|
|
44
|
+
"blocked": "Blocked",
|
|
45
|
+
"done": { "dev": "On Dev", "staging": "On Stg", "production": "Done" }
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"confluence": {
|
|
49
|
+
"spaceKey": "<KEY>",
|
|
50
|
+
"parentPageId": "<id>",
|
|
51
|
+
"parents": {
|
|
52
|
+
"draft": "<page-id>",
|
|
53
|
+
"ready": "<page-id>",
|
|
54
|
+
"in_review": "<page-id>",
|
|
55
|
+
"blocked": "<page-id>",
|
|
56
|
+
"ticketed": "<page-id>",
|
|
57
|
+
"shipped": "<page-id>"
|
|
58
|
+
},
|
|
59
|
+
"dashboardPageId": "<page-id>",
|
|
60
|
+
"feedbackPageId": "<page-id>"
|
|
61
|
+
},
|
|
62
|
+
"github": {
|
|
63
|
+
"org": "<org-or-user>",
|
|
64
|
+
"repo": "<repo>",
|
|
65
|
+
"labels": {
|
|
66
|
+
"build": {
|
|
67
|
+
"ready": "status:ready",
|
|
68
|
+
"claimed": "status:in-progress",
|
|
69
|
+
"review": "status:code-review",
|
|
70
|
+
"blocked": "status:blocked",
|
|
71
|
+
"done": { "dev": "status:on-dev", "staging": "status:on-stg", "production": "status:done" }
|
|
72
|
+
},
|
|
73
|
+
"prd": {
|
|
74
|
+
"draft": "prd-draft",
|
|
75
|
+
"ready": "prd-ready", "in_review": "prd-in-review",
|
|
76
|
+
"blocked": "prd-blocked", "ticketed": "prd-ticketed",
|
|
77
|
+
"shipped": "prd-shipped",
|
|
78
|
+
"sentinel": "prd-intake-feedback"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"notion": {
|
|
83
|
+
"workspaceId": "<workspace-uuid-or-human-slug>",
|
|
84
|
+
"prdDatabaseId": "<uuid>",
|
|
85
|
+
"statusProperty": "Status",
|
|
86
|
+
"values": {
|
|
87
|
+
"draft": "Draft", "ready": "Ready", "in_review": "In Review",
|
|
88
|
+
"blocked": "Blocked", "ticketed": "Ticketed", "shipped": "Shipped"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"linear": {
|
|
92
|
+
"workspace": "<workspace-slug>",
|
|
93
|
+
"teamKey": "<TEAM>",
|
|
94
|
+
"labels": {
|
|
95
|
+
"build": {
|
|
96
|
+
"ready": "status:ready",
|
|
97
|
+
"claimed": "status:in-progress",
|
|
98
|
+
"review": "status:code-review",
|
|
99
|
+
"blocked": "status:blocked",
|
|
100
|
+
"done": { "dev": "status:on-dev", "staging": "status:on-stg", "production": "status:done" }
|
|
101
|
+
},
|
|
102
|
+
"prd": {
|
|
103
|
+
"draft": "prd-draft",
|
|
104
|
+
"ready": "prd-ready", "in_review": "prd-in-review",
|
|
105
|
+
"blocked": "prd-blocked", "ticketed": "prd-ticketed",
|
|
106
|
+
"shipped": "prd-shipped",
|
|
107
|
+
"sentinel": "prd-intake-feedback"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
"deploy": {
|
|
113
|
+
"branches": {
|
|
114
|
+
"dev": "dev",
|
|
115
|
+
"staging": "staging",
|
|
116
|
+
"production": "main"
|
|
117
|
+
}
|
|
118
|
+
}
|
|
37
119
|
}
|
|
38
120
|
```
|
|
39
121
|
|
|
@@ -41,7 +123,7 @@ tracker="${local_value:-${global_value:-jira}}"
|
|
|
41
123
|
|
|
42
124
|
| Field | Required | Default | Notes |
|
|
43
125
|
|-------|----------|---------|-------|
|
|
44
|
-
| `tracker` |
|
|
126
|
+
| `tracker` | **yes** | — | Destination for ticket writes. One of `"jira"`, `"github"`, `"linear"`. Missing → fail with instruction to run the matching `/lisa:setup:*` skill. |
|
|
45
127
|
| `source` | no | — | Default PRD source for batch skills (`/lisa:intake`) and arg-less single-PRD skills. One of `"notion"`, `"confluence"`, `"linear"`, `"github"`, `"jira"`. Explicit URLs/keys passed to a skill always win over `source`; this is a default, not a lock. |
|
|
46
128
|
|
|
47
129
|
### Vendor sections
|
|
@@ -50,9 +132,11 @@ Each vendor section is **conditionally required**: required only when that vendo
|
|
|
50
132
|
|
|
51
133
|
#### `atlassian`
|
|
52
134
|
|
|
53
|
-
| Field | Required when | Notes |
|
|
54
|
-
|
|
55
|
-
| `atlassian.cloudId` | `tracker = "jira"`, `source = "jira"`, `source = "confluence"`, or any `confluence-*` / `jira-*` skill is invoked | Atlassian Cloud site UUID. Resolve once via
|
|
135
|
+
| Field | Required when | Where it lives | Notes |
|
|
136
|
+
|-------|---------------|----------------|-------|
|
|
137
|
+
| `atlassian.cloudId` | `tracker = "jira"`, `source = "jira"`, `source = "confluence"`, or any `confluence-*` / `jira-*` skill is invoked | **committed** (`.lisa.config.json`) | Atlassian Cloud site UUID. Same for every developer on the project. Resolve once via `curl https://<site>/_edge/tenant_info` or `getAccessibleAtlassianResources`. Shared between JIRA and Confluence (same Atlassian site). |
|
|
138
|
+
| `atlassian.site` | same as above | **committed** | Human-readable site URL (e.g. `propswap.atlassian.net`). Same for every developer. |
|
|
139
|
+
| `atlassian.email` | when the developer's machine has multiple Atlassian accounts that can access the configured site | **local** (`.lisa.config.local.json`) | Per-developer. `--site` alone cannot disambiguate which acli profile to switch to when two accounts both have access to the same site (e.g., a personal account and a work account both invited to a customer's site). The setup skill writes this to the local override file, NEVER the committed file. |
|
|
56
140
|
|
|
57
141
|
#### `jira`
|
|
58
142
|
|
|
@@ -78,11 +162,12 @@ When `tracker = "github"` AND `source = "github"` (self-host), both reads and wr
|
|
|
78
162
|
|
|
79
163
|
#### `notion`
|
|
80
164
|
|
|
81
|
-
| Field | Required when | Notes |
|
|
82
|
-
|
|
83
|
-
| `notion.
|
|
84
|
-
| `notion.
|
|
85
|
-
| `notion.
|
|
165
|
+
| Field | Required when | Where it lives | Notes |
|
|
166
|
+
|-------|---------------|----------------|-------|
|
|
167
|
+
| `notion.workspaceId` | `source = "notion"` | **committed** | Workspace identifier (Notion workspace UUID, or a stable human slug the user picks at setup). Same for every developer on the project. Used as the keychain `account` value when looking up the Notion API token, so each project's `notion-access` finds the right per-workspace token. |
|
|
168
|
+
| `notion.prdDatabaseId` | `source = "notion"` | **committed** | Notion database ID (UUID, dashes optional). The database is the PRD queue. Same for every developer on the project. |
|
|
169
|
+
| `notion.statusProperty` | `source = "notion"` | **committed** | Name of the database property that drives the lifecycle. Defaults to `"Status"` if absent. |
|
|
170
|
+
| `notion.values` | optional | **committed** | Map of role → Notion status-value name (`draft`, `ready`, `in_review`, `blocked`, `ticketed`, `shipped`). Defaults match the role names in title case. Override here if your Notion DB uses different value names. |
|
|
86
171
|
|
|
87
172
|
#### `linear`
|
|
88
173
|
|
|
@@ -91,12 +176,70 @@ When `tracker = "github"` AND `source = "github"` (self-host), both reads and wr
|
|
|
91
176
|
| `linear.workspace` | `tracker = "linear"`, `source = "linear"`, or any `linear-*` skill is invoked | Linear workspace slug (e.g. `acme`). |
|
|
92
177
|
| `linear.teamKey` | `tracker = "linear"` | Linear team key (e.g. `ENG`). The team owns the destination Issues. For source mode, projects are workspace-scoped or team-scoped per the URL passed. |
|
|
93
178
|
|
|
179
|
+
## Workflow & vocabulary roles
|
|
180
|
+
|
|
181
|
+
Every lifecycle skill operates on a fixed set of **roles** (`ready`, `claimed`, `done`, etc.), not concrete status/label strings. The role → string mapping lives in the per-vendor section above, with defaults that match the legacy hardcoded names. A project that uses different names overrides the relevant key; everything else inherits.
|
|
182
|
+
|
|
183
|
+
### Roles
|
|
184
|
+
|
|
185
|
+
**Build lifecycle** (work items):
|
|
186
|
+
|
|
187
|
+
| Role | What it means | JIRA default | GitHub/Linear default |
|
|
188
|
+
|---|---|---|---|
|
|
189
|
+
| `ready` | Human signal "this is buildable; agent may claim" | `Ready` (status) | `status:ready` (label) |
|
|
190
|
+
| `claimed` | Agent has picked the item up | `In Progress` (status) | `status:in-progress` (label) |
|
|
191
|
+
| `review` | Build complete, in code review | `Code Review` (status) | `status:code-review` (label) |
|
|
192
|
+
| `blocked` | Agent stopped on triage ambiguities or external blocker | `Blocked` (status) | `status:blocked` (label) |
|
|
193
|
+
| `done` | Terminal state for this work, **env-keyed** | map of env → status | map of env → label |
|
|
194
|
+
|
|
195
|
+
`review` is required for label-driven systems (GitHub, Linear) because that's how the agent signals "PR opened, awaiting human review." For JIRA, `review` is optional — projects that keep the ticket in `claimed` until terminal can omit it and lifecycle skills will skip the intermediate transition.
|
|
196
|
+
|
|
197
|
+
`blocked` is what every vendor agent flips to when triage finds unresolved ambiguities or the build path is blocked by something the agent can't resolve. Different from `claimed` because it explicitly signals "human attention required."
|
|
198
|
+
|
|
199
|
+
**PRD lifecycle** (specifications):
|
|
200
|
+
|
|
201
|
+
| Role | What it means | Notion default | Confluence/GitHub/Linear default |
|
|
202
|
+
|---|---|---|---|
|
|
203
|
+
| `draft` | Author drafting; agent ignores until promoted to `ready` | `Draft` (status) | `prd-draft` (GitHub/Linear label); parent-page lookup (Confluence) |
|
|
204
|
+
| `ready` | "Ready for ticketing"; agent claims | `Ready` (status) | `prd-ready` (label) |
|
|
205
|
+
| `in_review` | Agent has claimed and is validating | `In Review` (status) | `prd-in-review` (label) |
|
|
206
|
+
| `blocked` | Validation failed; clarifying-comments posted | `Blocked` (status) | `prd-blocked` (label) |
|
|
207
|
+
| `ticketed` | Validated and tickets created | `Ticketed` (status) | `prd-ticketed` (label) |
|
|
208
|
+
| `shipped` | All child tickets shipped | `Shipped` (status) | `prd-shipped` (label) |
|
|
209
|
+
| `sentinel` | (PRD-intake feedback issue marker, GitHub/Linear self-host only) | — | `prd-intake-feedback` |
|
|
210
|
+
|
|
211
|
+
### Env-keyed `done`
|
|
212
|
+
|
|
213
|
+
The `done` role is special: the terminal status/label depends on which environment a PR was merged into. A hotfix to staging ends at `On Stg`; a production hotfix ends at `Done`. So `done` is a **map** keyed by env name (`dev`, `staging`, `production`).
|
|
214
|
+
|
|
215
|
+
Skills that transition to `done` MUST resolve the env first:
|
|
216
|
+
|
|
217
|
+
1. **Explicit caller arg** (`target_env=staging`) — always wins.
|
|
218
|
+
2. **Branch inference** — derive from the PR's base branch via `deploy.branches`. Reverse-lookup: if base branch is `staging`, env is `staging`.
|
|
219
|
+
3. **Failure** — if neither resolves and `done` is a map, fail loudly. Never pick arbitrarily.
|
|
220
|
+
|
|
221
|
+
If a project's terminal state is the same regardless of env, set `done` to a string instead of a map (lifecycle skills accept either shape).
|
|
222
|
+
|
|
223
|
+
### What's configurable, what's not
|
|
224
|
+
|
|
225
|
+
- **Status / label NAMES** are configurable per project — that's the point of the vocabulary maps.
|
|
226
|
+
- **Role SEMANTICS and TRANSITIONS** are not. The build lifecycle is always `ready → claimed → done` (with optional `review` for label-driven systems). The PRD lifecycle is always `ready → in_review → (blocked | ticketed) → shipped`. Lisa skills hardcode these transitions because they encode the design intent of the framework, not the project's preferences.
|
|
227
|
+
- **Extra statuses/labels** the project uses outside these roles are fine — lisa never touches them.
|
|
228
|
+
|
|
229
|
+
### Defaults vs. requirements
|
|
230
|
+
|
|
231
|
+
Vocabulary maps are **optional** in `.lisa.config.json`. Missing keys inherit the defaults shown in the schema above. The setup skills probe the project's actual workflow / labels at setup time and either:
|
|
232
|
+
|
|
233
|
+
- Confirm the default name exists → proceed silently.
|
|
234
|
+
- Confirm a different name exists (e.g., `Resolved` instead of `Done`) → prompt the user to either rename in the tracker or override the key in config.
|
|
235
|
+
- Find nothing matching → stop and ask the user to (a) create the missing status/label in the tracker, or (b) provide the actual name to write into config.
|
|
236
|
+
|
|
94
237
|
## Resolution algorithm
|
|
95
238
|
|
|
96
239
|
Every `tracker-*` shim and every vendor-neutral caller follows this:
|
|
97
240
|
|
|
98
241
|
1. Read `.lisa.config.local.json` first (if present), then `.lisa.config.json`. Local overrides global on a per-key basis. Use `jq` — never hand-parse JSON.
|
|
99
|
-
2. Extract the `tracker` field. If missing or null,
|
|
242
|
+
2. Extract the `tracker` field. If missing or null, stop and report: `"'tracker' is not set in .lisa.config.json. Run /lisa:setup:jira (or :github, :linear) to configure."`
|
|
100
243
|
3. Dispatch:
|
|
101
244
|
- `tracker = "jira"` → delegate to the matching `jira-*` skill. Validate `atlassian.cloudId` and `jira.project` are present.
|
|
102
245
|
- `tracker = "github"` → delegate to the matching `github-*` skill. Validate `github.org` and `github.repo` are present.
|
|
@@ -167,21 +310,96 @@ Never overload one label across both lifecycles.
|
|
|
167
310
|
|
|
168
311
|
The same separation applies for Linear self-host (`source = "linear"` AND `tracker = "linear"`): project-level labels (`prd-*`) drive the PRD lifecycle; issue-level labels (`status:*`) drive the build lifecycle; the sentinel feedback issue carries the issue-level `prd-intake-feedback` label.
|
|
169
312
|
|
|
313
|
+
## Notion access (substrate ladder)
|
|
314
|
+
|
|
315
|
+
`notion-access` selects a substrate per operation in this order:
|
|
316
|
+
|
|
317
|
+
1. **Notion MCP** — used when authenticated and its identity covers `notion.workspaceId`. Identity-match is verified by attempting to fetch `notion.prdDatabaseId` through the MCP; success means the MCP is authed to the correct workspace. If the MCP is authed elsewhere or unauthenticated, this tier is skipped.
|
|
318
|
+
2. **curl + API token** — used when MCP isn't viable. Token is read via the standard lookup ladder (env → workspace-suffixed env → keychain → `tokenSource`).
|
|
319
|
+
3. Fail with a clear diagnostic.
|
|
320
|
+
|
|
321
|
+
(No CLI tier — Notion has no first-party CLI; community wrappers aren't taken as a dependency.)
|
|
322
|
+
|
|
323
|
+
**Identity-match is mandatory.** A Notion MCP authed to the wrong workspace must be skipped, not used. `notion-access` verifies the configured `prdDatabaseId` is fetchable through the MCP before any operation; failure routes to the next tier.
|
|
324
|
+
|
|
325
|
+
**Token type**: Notion **internal-integration tokens** (`ntn_*` prefix). Created at notion.so/profile/integrations or workspace settings → Connections → New integration. Each token is **bound to one workspace** by construction. There is no v1/v2 scope mess like Atlassian — the token's access is uniform across whichever pages have been explicitly shared with the integration.
|
|
326
|
+
|
|
327
|
+
**Multi-account / multi-workspace**: same approach as Atlassian. The keychain entry is keyed by the workspace identifier (workspace id or human slug) declared in `.lisa.config.json` `notion.workspaceId`. Different projects targeting different Notion workspaces resolve to different keychain entries, no collision.
|
|
328
|
+
|
|
329
|
+
**Per-page access**: Notion's integration model requires each PRD page (or the parent database) to be explicitly **shared** with the integration before the API can see it. `setup-notion` prompts the user to share the PRD database with the freshly-created integration; downstream lifecycle skills assume the share has happened and fail loudly if a page isn't visible.
|
|
330
|
+
|
|
331
|
+
**Token storage and lookup ladder** (mirrors `atlassian-access`):
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
read_notion_token() {
|
|
335
|
+
local workspace="$1"
|
|
336
|
+
[ -n "$NOTION_API_TOKEN" ] && { echo "$NOTION_API_TOKEN"; return; }
|
|
337
|
+
local slug=$(echo "$workspace" | tr '[:upper:]-' '[:lower:]_')
|
|
338
|
+
local varname="NOTION_API_TOKEN_${slug}"
|
|
339
|
+
[ -n "${!varname}" ] && { echo "${!varname}"; return; }
|
|
340
|
+
case "$(uname -s)" in
|
|
341
|
+
Darwin) security find-generic-password -s lisa-notion -a "$workspace" -w 2>/dev/null ;;
|
|
342
|
+
Linux) command -v secret-tool >/dev/null && \
|
|
343
|
+
secret-tool lookup service lisa-notion account "$workspace" 2>/dev/null ;;
|
|
344
|
+
MINGW*|MSYS*|CYGWIN*) cmdkey /list:"lisa-notion-${workspace}" 2>/dev/null | grep Password | awk '{print $NF}' ;;
|
|
345
|
+
esac
|
|
346
|
+
}
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Schema additions** to `notion` section:
|
|
350
|
+
|
|
351
|
+
```json
|
|
352
|
+
"notion": {
|
|
353
|
+
"workspaceId": "<uuid-or-human-slug>",
|
|
354
|
+
"prdDatabaseId": "<uuid>",
|
|
355
|
+
"statusProperty": "Status",
|
|
356
|
+
"values": { "draft": "Draft", "ready": "Ready", ... }
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
`workspaceId` is the connection-match key. The notion-access skill calls `GET /v1/users/me` with the token and verifies the returned `bot.workspace_name` (or workspace id when Notion exposes it) matches the configured value before allowing operations to proceed.
|
|
361
|
+
|
|
362
|
+
## Confluence PRD lifecycle uses parent pages, not labels
|
|
363
|
+
|
|
364
|
+
GitHub and Linear PRD lifecycles use labels (`prd-ready` / `prd-in-review` / etc.). **Confluence does not** — it uses parent pages instead. Each lifecycle role maps to a parent page; a PRD's current state is determined by which parent it's a child of; transitions are `PUT /wiki/api/v2/pages/{id}` with a new `parentId`.
|
|
365
|
+
|
|
366
|
+
**Why this asymmetry exists**: scoped API tokens (the only secure form Atlassian offers) cannot write labels on Confluence pages. The v1 label endpoint `POST /wiki/rest/api/content/{id}/label` rejects scoped-token granular scopes with 401 "scope does not match"; the v2 Label API group has no POST endpoint at all (see open bug `CONFCLOUD-76866`). Until Atlassian ships v2 label writes, labels are read-only via scoped tokens. Parent-id transitions, by contrast, are first-class in v2 and work with `write:page:confluence` scope.
|
|
367
|
+
|
|
368
|
+
**`confluence.parents` map**: each role's parent page id is stored in `.lisa.config.json` after `setup-confluence` creates the lifecycle scaffolding. Skills that need to discover the current state of a PRD read its `parentId` and reverse-lookup in `confluence.parents`. Skills that need to transition update the page's `parentId` to the new role's value.
|
|
369
|
+
|
|
370
|
+
**Native UX benefit**: parent-page state shows up automatically in Confluence's left-sidebar page tree — users see PRDs grouped by state without ever opening the Dashboard page. The Dashboard is still produced, but as a `Children Display`-macro aggregation rather than `Content by Label`.
|
|
371
|
+
|
|
372
|
+
## Atlassian access (substrate ladder)
|
|
373
|
+
|
|
374
|
+
`atlassian-access` selects a substrate per operation in this order:
|
|
375
|
+
|
|
376
|
+
1. **acli** — preferred when installed and authenticated, and when its active profile's site matches `atlassian.site` from config. `atlassian-access` calls `acli auth status` and compares the returned site/email to config before routing.
|
|
377
|
+
2. **Atlassian MCP** — used when acli is unavailable for an op (e.g., Confluence page writes — acli has no `confluence page` write surface), or when acli isn't installed at all. Before routing, `atlassian-access` calls `getAccessibleAtlassianResources` and verifies `atlassian.cloudId` is in the returned list. If the configured cloudId isn't visible to the MCP's authed identity, the MCP tier is skipped.
|
|
378
|
+
3. **curl + API token** — used when neither acli nor MCP is viable (headless, multi-account where MCP is authed elsewhere, scoped-token-only deployments). Token is read via the standard lookup ladder (env → email-suffixed env → keychain → `tokenSource`).
|
|
379
|
+
4. Fail with a clear diagnostic listing what was attempted.
|
|
380
|
+
|
|
381
|
+
**Identity-match is mandatory at every tier.** A substrate that's authenticated as the *wrong* Atlassian account is more dangerous than no substrate — it silently performs operations against the wrong workspace. `atlassian-access` verifies identity before every operation and skips substrates that don't match.
|
|
382
|
+
|
|
383
|
+
**Why curl is still needed**: acli's Confluence surface only covers `space` and `page view`. v1 page-write endpoints accept scoped tokens but return 410 Gone (deprecated); v2 endpoints require granular OAuth scopes acli doesn't request. API tokens via Basic auth bypass this with full user scope, so curl is the headless-friendly path for ops neither acli nor MCP can do.
|
|
384
|
+
|
|
170
385
|
## Invariants
|
|
171
386
|
|
|
172
387
|
- Project tracker selection is **persistent** within a project — always read from config, never infer from the shape of `$ARGUMENTS`. If a developer wants a different destination for one run, they edit `.lisa.config.local.json`.
|
|
388
|
+
- **Developer-specific fields (e.g., `atlassian.email`) live in `.lisa.config.local.json`, never in the committed file.** The committed file describes the project (which site, which tracker, which space); the local file describes the developer's identity (which account, which profile, which override). Setup skills MUST write developer-specific fields to the local override and shared fields to the committed file.
|
|
173
389
|
- A vendor-neutral skill never embeds vendor-specific terminology in its prompts (no "JIRA ticket key", "epic parent" — use "tracker key", "parent issue"). The vendor skill is responsible for translating its inputs.
|
|
174
390
|
- The shim layer is intentionally thin — its only job is dispatch. Gate logic, validation rules, and field schemas all live in the vendor skills.
|
|
175
|
-
- Secrets stay in env (`
|
|
391
|
+
- Secrets stay in env (`ATLASSIAN_API_TOKEN`, `NOTION_API_TOKEN`, `LINEAR_API_KEY`, `GH_TOKEN`). Configuration in `.lisa.config.json` is non-secret only — IDs, keys, slugs, project codes.
|
|
392
|
+
- **`ATLASSIAN_API_TOKEN`** is required when the project uses JIRA or Confluence and any operation that acli doesn't cover (Confluence page writes, label edits, etc. — see `atlassian-access` skill's dispatch table). It's per-developer and per-project (different projects under different Atlassian accounts get different tokens). Setup-atlassian guides token generation and persists it to a gitignored `.envrc` (direnv) or `.env.lisa` (manual source); CI sets it directly as a pipeline secret. The token MUST belong to the account whose email is declared in `.lisa.config.local.json` `atlassian.email` — `atlassian-access` validates the pairing on first use of the curl substrate.
|
|
176
393
|
- E2E test config (`E2E_BASE_URL`, `E2E_TEST_PHONE`, `E2E_TEST_OTP`, `E2E_TEST_ORG`, `E2E_GRAPHQL_URL`) stays in env for now — not tracker-related and frequently per-environment.
|
|
177
394
|
|
|
178
395
|
## Migration from the previous schema
|
|
179
396
|
|
|
180
|
-
The pre-expansion `.lisa.config.json` had only `tracker` and `github.{org,repo}
|
|
397
|
+
The pre-expansion `.lisa.config.json` had only `tracker` and `github.{org,repo}`, and a missing `tracker` defaulted to `"jira"`. That default has been removed — `tracker` is now required.
|
|
398
|
+
|
|
399
|
+
To migrate a project to the new requirements:
|
|
181
400
|
|
|
182
|
-
|
|
401
|
+
1. Run `/lisa:setup:atlassian` (or `/lisa:setup:github`, `/lisa:setup:linear`) — installs the vendor MCP if needed, authenticates, and writes the vendor section.
|
|
402
|
+
2. Run `/lisa:setup:jira` (or matching) — writes `jira.project` and prompts to set top-level `tracker`.
|
|
403
|
+
3. Optionally run `/lisa:setup:confluence` / `/lisa:setup:notion` / etc. for source vendors — writes their sections and prompts to set top-level `source`.
|
|
183
404
|
|
|
184
|
-
|
|
185
|
-
2. Add `jira.project` (was `JIRA_PROJECT`).
|
|
186
|
-
3. Drop `JIRA_SERVER` from env (replaced by `atlassian.cloudId`).
|
|
187
|
-
4. Optionally add `source` to set the default PRD source for batch skills.
|
|
405
|
+
Projects that previously relied on the `"jira"` default will now fail loudly at the next vendor-neutral skill invocation; the error message points the user at the right setup skill.
|
|
@@ -32,11 +32,11 @@ What this rule still enforces:
|
|
|
32
32
|
> **Orchestration: agent team** (or **single agent**)
|
|
33
33
|
> One-sentence justification.
|
|
34
34
|
|
|
35
|
-
2. **Cascade rule (load-bearing)**: Before
|
|
35
|
+
2. **Cascade rule (load-bearing)**: Before creating a team, check whether you are already operating inside an agent team. Signs you are inside a team: a prior successful team-creation tool call exists in this session; you were spawned into a team context; your context references a team lead. If any of these are true, **do NOT create a second team** — many harnesses reject double-creates and the work stalls. Continue within the existing team. Invoke flows via the Skill tool; the team lead inherits responsibility for orchestration.
|
|
36
36
|
|
|
37
37
|
3. **Default mode**: `Research`, `Plan`, `Implement`, `Intake`, and `Debrief` run as agent teams. The `Implement` flow — including every work type (`Build`, `Fix`, `Improve`, `Investigate-Only`) — is **always** a team flow. Bug fixes that "look simple" are not an exception: the Reproduce sub-flow, debug-specialist, bug-fixer, parallel reviewers, and verification-specialist all need to compose. `Debrief` runs as a team because tracker-mining and pr-mining parallelize cleanly and synthesis gates on both completing. `Verify` (standalone) and `Monitor` (standalone) use the One-shot Sub-agents pattern (see `## Orchestration` below) — these flows are linear with no parallelism and the team overhead is not warranted. Single-agent mode is otherwise reserved for: `product-walkthrough` invoked standalone (not as part of Research/Plan), `debrief-apply` (deterministic routing of human-marked dispositions), and one-off diagnostic Bash/Read sessions that don't invoke any lifecycle skill. When in doubt, use a team.
|
|
38
38
|
|
|
39
|
-
The mechanical
|
|
39
|
+
The mechanical team bootstrap directive lives inside each lifecycle skill — see those skills' orchestration preambles for the exact wording. The Claude path uses `TeamCreate`; other runtimes must use their equivalent team-discovery and team-creation tools, or explicitly declare the no-team fallback when no such tool exists.
|
|
40
40
|
|
|
41
41
|
## Readiness Gate Protocol
|
|
42
42
|
|
|
@@ -364,7 +364,7 @@ Lifecycle skills dispatch their agents according to the flow's shape. The follow
|
|
|
364
364
|
|
|
365
365
|
### Agent Teams (default for multi-step flows)
|
|
366
366
|
|
|
367
|
-
Use an **agent team** (
|
|
367
|
+
Use an **agent team** (runtime team creation + durable task state per step) for:
|
|
368
368
|
|
|
369
369
|
- **Implement** (Build, Fix, Improve) — long sequences with parallel review and a real risk of compaction
|
|
370
370
|
- **Plan** — multiple specialists feeding a shared decomposition
|
|
@@ -390,7 +390,7 @@ Use direct `Agent` tool invocations (no team) for:
|
|
|
390
390
|
- **Investigate Only** spikes — single investigation, findings out
|
|
391
391
|
- Any flow chained as a sub-flow inside a larger team — its agents become tasks in the parent team, not a new team
|
|
392
392
|
|
|
393
|
-
Why:
|
|
393
|
+
Why: team creation plus per-step task state is real overhead. For a one-or-two-agent flow with no parallelism, the bookkeeping cost outweighs the recovery and orchestration benefits.
|
|
394
394
|
|
|
395
395
|
### When in doubt
|
|
396
396
|
|