@codyswann/lisa 2.316.0 → 2.316.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  2. package/dist/core/upstream-evidence-manifest.js +20 -10
  3. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  4. package/package.json +1 -1
  5. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  6. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  7. package/plugins/lisa/.codex-plugin/skills/lisa-atlassian-access/SKILL.md +10 -1
  8. package/plugins/lisa/.codex-plugin/skills/lisa-github-to-tracker/SKILL.md +1 -1
  9. package/plugins/lisa/.codex-plugin/skills/lisa-intake/SKILL.md +1 -1
  10. package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  11. package/plugins/lisa/.codex-plugin/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  12. package/plugins/lisa/.codex-plugin/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  13. package/plugins/lisa/.codex-plugin/skills/lisa-spec-conformance/SKILL.md +1 -1
  14. package/plugins/lisa/.codex-plugin/skills/lisa-verify-prd/SKILL.md +6 -4
  15. package/plugins/lisa/agents/jira-agent.md +3 -3
  16. package/plugins/lisa/rules/eager/report-actionability.md +23 -0
  17. package/plugins/lisa/rules/reference/repo-scope-split.md +1 -1
  18. package/plugins/lisa/rules/reference/report-actionability.md +61 -0
  19. package/plugins/lisa/skills/lisa-atlassian-access/SKILL.md +10 -1
  20. package/plugins/lisa/skills/lisa-github-to-tracker/SKILL.md +1 -1
  21. package/plugins/lisa/skills/lisa-intake/SKILL.md +1 -1
  22. package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  23. package/plugins/lisa/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  24. package/plugins/lisa/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  25. package/plugins/lisa/skills/lisa-spec-conformance/SKILL.md +1 -1
  26. package/plugins/lisa/skills/lisa-verify-prd/SKILL.md +6 -4
  27. package/plugins/lisa-agy/agents/jira-agent.md +3 -3
  28. package/plugins/lisa-agy/plugin.json +1 -1
  29. package/plugins/lisa-agy/skills/lisa-atlassian-access/SKILL.md +10 -1
  30. package/plugins/lisa-agy/skills/lisa-github-to-tracker/SKILL.md +1 -1
  31. package/plugins/lisa-agy/skills/lisa-intake/SKILL.md +1 -1
  32. package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  33. package/plugins/lisa-agy/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  34. package/plugins/lisa-agy/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  35. package/plugins/lisa-agy/skills/lisa-spec-conformance/SKILL.md +1 -1
  36. package/plugins/lisa-agy/skills/lisa-verify-prd/SKILL.md +6 -4
  37. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  38. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  39. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  40. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-copilot/agents/jira-agent.agent.md +3 -3
  44. package/plugins/lisa-copilot/rules/eager/report-actionability.md +23 -0
  45. package/plugins/lisa-copilot/rules/reference/repo-scope-split.md +1 -1
  46. package/plugins/lisa-copilot/rules/reference/report-actionability.md +61 -0
  47. package/plugins/lisa-copilot/skills/lisa-atlassian-access/SKILL.md +10 -1
  48. package/plugins/lisa-copilot/skills/lisa-github-to-tracker/SKILL.md +1 -1
  49. package/plugins/lisa-copilot/skills/lisa-intake/SKILL.md +1 -1
  50. package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  51. package/plugins/lisa-copilot/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  52. package/plugins/lisa-copilot/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  53. package/plugins/lisa-copilot/skills/lisa-spec-conformance/SKILL.md +1 -1
  54. package/plugins/lisa-copilot/skills/lisa-verify-prd/SKILL.md +6 -4
  55. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-cursor/agents/jira-agent.md +3 -3
  57. package/plugins/lisa-cursor/rules/repo-scope-split-reference.mdc +1 -1
  58. package/plugins/lisa-cursor/rules/report-actionability-reference.mdc +66 -0
  59. package/plugins/lisa-cursor/rules/report-actionability.mdc +28 -0
  60. package/plugins/lisa-cursor/skills/lisa-atlassian-access/SKILL.md +10 -1
  61. package/plugins/lisa-cursor/skills/lisa-github-to-tracker/SKILL.md +1 -1
  62. package/plugins/lisa-cursor/skills/lisa-intake/SKILL.md +1 -1
  63. package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  64. package/plugins/lisa-cursor/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  65. package/plugins/lisa-cursor/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  66. package/plugins/lisa-cursor/skills/lisa-spec-conformance/SKILL.md +1 -1
  67. package/plugins/lisa-cursor/skills/lisa-verify-prd/SKILL.md +6 -4
  68. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  70. package/plugins/lisa-expo-agy/plugin.json +1 -1
  71. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  75. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  76. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  81. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  86. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  91. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-rails-agy/plugin.json +1 -1
  96. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  100. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  101. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  105. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  106. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  108. package/plugins/src/base/agents/jira-agent.md +3 -3
  109. package/plugins/src/base/rules/eager/report-actionability.md +23 -0
  110. package/plugins/src/base/rules/reference/repo-scope-split.md +1 -1
  111. package/plugins/src/base/rules/reference/report-actionability.md +61 -0
  112. package/plugins/src/base/skills/lisa-atlassian-access/SKILL.md +10 -1
  113. package/plugins/src/base/skills/lisa-github-to-tracker/SKILL.md +1 -1
  114. package/plugins/src/base/skills/lisa-intake/SKILL.md +1 -1
  115. package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  116. package/plugins/src/base/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  117. package/plugins/src/base/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  118. package/plugins/src/base/skills/lisa-spec-conformance/SKILL.md +1 -1
  119. package/plugins/src/base/skills/lisa-verify-prd/SKILL.md +6 -4
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lisa-prd-ticket-coverage
3
3
  description: "Verifies that every requirement in a PRD (Notion, Confluence, Linear, or GitHub Issues) is covered by at least one created destination ticket (JIRA, GitHub Issues, or Linear) — no silent drops. Parses the PRD into atomic items (goals, user stories, functional/non-functional requirements, acceptance criteria, important notes), maps each to the created tickets, and produces a coverage matrix and verdict (COMPLETE / COMPLETE_WITH_SCOPE_CREEP / GAPS_FOUND / NO_TICKETS_FOUND). Used by notion-prd-intake / confluence-prd-intake / linear-prd-intake / github-prd-intake post-write to gate the Ticketed transition; can also be invoked standalone for after-the-fact audits."
4
- allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-get-comments", "mcp__atlassian__getConfluencePage", "mcp__atlassian__getConfluencePageDescendants", "mcp__atlassian__getConfluencePageFooterComments", "mcp__atlassian__getConfluencePageInlineComments", "mcp__atlassian__getConfluenceCommentChildren", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Skill", "Bash"]
5
5
  ---
6
6
 
7
7
  # PRD Ticket Coverage Audit: $ARGUMENTS
@@ -14,7 +14,7 @@ allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__cl
14
14
  The PRD URL can be a **Notion page URL**, a **Confluence page URL**, a **Linear project URL**, or a **GitHub issue URL**. Detect the vendor from the host:
15
15
 
16
16
  - `notion.so` / `notion.site` → Notion. Fetch with `mcp__claude_ai_Notion__notion-fetch` (`include_discussions: true`) and `mcp__claude_ai_Notion__notion-get-comments`.
17
- - Atlassian Confluence host (e.g. `*.atlassian.net/wiki/...`) → Confluence. Fetch with `mcp__atlassian__getConfluencePage`, `mcp__atlassian__getConfluencePageDescendants` (for child epic pages), `mcp__atlassian__getConfluencePageFooterComments`, `mcp__atlassian__getConfluencePageInlineComments`, and `mcp__atlassian__getConfluenceCommentChildren` for nested replies.
17
+ - Atlassian Confluence host (e.g. `*.atlassian.net/wiki/...`) → Confluence. Through `lisa-atlassian-access`, fetch the page, its descendants (for child epic pages), and its footer + inline comments including nested replies. State the operation, not a vendor tool name — the access skill owns substrate selection (`integration-access-layer`).
18
18
  - `linear.app` host → Linear. Fetch with `lisa-linear-access operation: get-project` (capture description, labels, state, attached resources), `lisa-linear-access operation: list-documents({projectId})` + `lisa-linear-access operation: get-document` per attached document, `lisa-linear-access operation: list-issues({project})` for sub-issues that act as child epics / user stories, and `lisa-linear-access operation: list-comments({issueId})` per sub-issue for decisions and engineering notes. Comments do not exist on the project itself in the MCP surface — sub-issue comments are the substitute.
19
19
  - `github.com` host → GitHub Issues. Fetch with the `gh` CLI (no GitHub MCP — Lisa uses the CLI exclusively for GitHub):
20
20
  - `gh issue view <number> --repo <org>/<repo> --json number,title,body,labels,milestone,assignees,author,createdAt,comments,url` for the PRD body and comments.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lisa-spec-conformance
3
3
  description: "Verifies that shipped work matches its spec section-by-section — acceptance criteria, Out of Scope, Technical Approach, Validation Journey assertions, and any explicit deliverables. Builds a coverage matrix mapping each requirement to evidence, flags scope creep separately from misses, and produces a verdict (CONFORMS / PARTIAL / DIVERGES). Runs during the verification phase alongside empirical system verification."
4
- allowed-tools: ["Read", "Glob", "Grep", "Bash", "Skill", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Read", "Glob", "Grep", "Bash", "Skill"]
5
5
  ---
6
6
 
7
7
  # Spec Conformance: $ARGUMENTS
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lisa-verify-prd
3
3
  description: "Initiative-level PRD acceptance gate. Given a PRD ref/URL (GitHub, Linear, Notion, Confluence, or JIRA), resolves the source vendor, reads the PRD and its generated top-level child work via the prd-lifecycle-rollup contract, and confirms every required child is terminal before any verification runs — if any is non-terminal it reports the incomplete set and STOPS. When the guard passes it runs spec-conformance against the original PRD requirements plus empirical verification via verification-lifecycle. On CONFORMS with all checks passing: transitions the PRD shipped → verified and posts evidence. On PARTIAL/DIVERGES or any failing check: re-opens the PRD shipped → ticketed (NEVER blocked), creates build-ready fix tickets for each divergence, and posts a product-readable failure report — the fix tickets auto-build, rollup re-ships the PRD, and a later intake cycle re-verifies, so the loop closes itself. Idempotent re-runs: comments regenerate in place via sentinel markers; fix tickets dedupe by stable ref."
4
- allowed-tools: ["Skill", "Bash", "Read", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-get-comments", "mcp__atlassian__getConfluencePage", "mcp__atlassian__getConfluencePageDescendants", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Skill", "Bash", "Read"]
5
5
  ---
6
6
 
7
7
  # PRD-level Verification: $ARGUMENTS
@@ -39,9 +39,11 @@ Detect the vendor from `$ARGUMENTS` the same way `prd-ticket-coverage` / `prd-ba
39
39
  |---|---|---|
40
40
  | `github.com/<org>/<repo>/issues/<n>` or `<org>/<repo>#<n>` | **GitHub Issues** | `gh` CLI (Lisa uses the CLI exclusively for GitHub — no GitHub MCP) |
41
41
  | `linear.app/...` | **Linear** | `lisa-linear-access operation: get-project` / `lisa-linear-access operation: get-issue` |
42
- | `notion.so` / `notion.site` | **Notion** | `mcp__claude_ai_Notion__notion-fetch` (`include_discussions: true`) |
43
- | `*.atlassian.net/wiki/...` | **Confluence** | `mcp__atlassian__getConfluencePage` (+ descendants) |
44
- | JIRA issue key (e.g. `PROJ-123`) or `*.atlassian.net/browse/...` | **JIRA** | `mcp__atlassian__getJiraIssue` |
42
+ | `notion.so` / `notion.site` | **Notion** | `lisa-notion-access` fetch the page **with its discussions** |
43
+ | `*.atlassian.net/wiki/...` | **Confluence** | `lisa-atlassian-access` read the page and its descendants |
44
+ | JIRA issue key (e.g. `PROJ-123`) or `*.atlassian.net/browse/...` | **JIRA** | `lisa-atlassian-access` — read the issue (and JQL-search when resolving a set) |
45
+
46
+ State the operation you need, never a vendor tool name: the access skills own substrate selection, and a hardcoded MCP tool name is not portable. The same server registers under different prefixes depending on install path (`mcp__atlassian__*`, `mcp__claude_ai_Atlassian__*`, `mcp__plugin_atlassian_atlassian__*`), and its data tools register only once OAuth completes — so a named tool fails outright in a context that has the CLI or token substrate available and would otherwise have worked. See the `integration-access-layer` rule.
45
47
 
46
48
  Read the PRD body via the vendor-appropriate surface. The vendor that owns the PRD source is what Phase 2 reads the child set from; it is independent of which tracker hosts the generated tickets (a Notion PRD can own JIRA tickets — the cross-vendor case is handled by the documented generated-work section in Phase 2).
47
49
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.316.0",
3
+ "version": "2.316.2",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.316.0",
3
+ "version": "2.316.2",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.316.0",
3
+ "version": "2.316.2",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.316.0",
3
+ "version": "2.316.2",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.316.0",
3
+ "version": "2.316.2",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.316.0",
3
+ "version": "2.316.2",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -49,10 +49,10 @@ Use the `jira-verify` skill to check the ticket against organizational standards
49
49
 
50
50
  If `jira-verify` returns `FAIL` on any of the above, do NOT continue to build. **Draft the missing spec content first, then block for confirmation** — never bounce a raw "go write all this" checklist back to the reporter:
51
51
  1. **Best-effort autofill (before blocking).** Run `pre-flight-autofill` for every work item. Preserve a human bare configured key or `Confirmed: <env>`; automation writes `Inferred: <env> — evidence: <title|body|reproduction|hostname>`, `Assumption: <env> — remote default branch <branch>` for a unique reverse-map, or `Assumption: remote default branch <branch>` otherwise. Human confirmation replaces the annotation with the bare key or `Confirmed: <env>`. For a legacy bare value, use managed draft markers and current ticket content only; provider edit history is not required. A marker proves automation and requires re-annotation; otherwise unknown provenance plus conflicting evidence stops for confirmation. Resolve one exact `deploy.branches` key from the human-authored title, body, and reproduction steps or URL hostname; exclude the complete `Target Backend Environment` section and other machine-authored metadata/draft blocks so annotations cannot become evidence. A reported bug environment is an example, not a restriction. Evidence supersedes only `Assumption:`. Normalize `prod` ↔ `production` only when exactly one is configured; no other aliases exist. Conflicts stop; never infer from arbitrary branch text, URL paths/query strings, or substrings. Write through `jira-write-ticket`, never overwrite human prose, then re-run `jira-verify`.
52
- 2. Transition the ticket status to the configured `blocked` status (typically `Blocked` — read from `.lisa.config.json` `jira.workflow.blocked` if present, otherwise the project's standard blocked status). Use `mcp__atlassian__transitionJiraIssue` or equivalent.
53
- 3. **Add the `human_needed` marker label.** Even after the agent drafted what it could, a pre-flight gate failure bounces the ticket back to its reporter because the ticket still needs a human to **confirm the drafted assumptions** or supply something no agent can invent — real missing credentials, access, or an irreducible product/scoping decision. Add the configured label (`jira.labels.human_needed`, default `Human Needed`) to the ticket's `labels` field via `mcp__atlassian__editJiraIssue` — a lightweight metadata update permitted under this same gate exception. This is additive to (not a replacement for) the `blocked` status, so a human scanning the board sees at a glance which blocked tickets are waiting on them. If the label does not exist in the project, record that and proceed — the marker is best-effort. (See the `config-resolution` rule's "Build markers" for when the marker applies and when it must NOT.)
52
+ 2. Transition the ticket status to the configured `blocked` status (typically `Blocked` — read from `.lisa.config.json` `jira.workflow.blocked` if present, otherwise the project's standard blocked status). Transition through `tracker-write` (which routes via the matching `*-access` skill); never name a vendor MCP tool here.
53
+ 3. **Add the `human_needed` marker label.** Even after the agent drafted what it could, a pre-flight gate failure bounces the ticket back to its reporter because the ticket still needs a human to **confirm the drafted assumptions** or supply something no agent can invent — real missing credentials, access, or an irreducible product/scoping decision. Add the configured label (`jira.labels.human_needed`, default `Human Needed`) to the ticket's `labels` field through `tracker-write` — a lightweight metadata update permitted under this same gate exception. This is additive to (not a replacement for) the `blocked` status, so a human scanning the board sees at a glance which blocked tickets are waiting on them. If the label does not exist in the project, record that and proceed — the marker is best-effort. (See the `config-resolution` rule's "Build markers" for when the marker applies and when it must NOT.)
54
54
  4. Reassign the ticket to the **Reporter** (the human who filed it — not the Creator field, which may be a bot/integration).
55
- 5. Post a comment using `mcp__atlassian__addCommentToJiraIssue` — the **confirmation comment** from the `pre-flight-autofill` rule, **not** a bare remediation checklist: disclose it is a Claude draft, give one line per drafted section naming the key assumption made, list any remaining human-only item as a specific question with a recommended default, and close with *"review the drafted sections, correct anything wrong, then flip back to Ready and it builds — or reply with corrections."* Prefix with `[{repo}]`.
55
+ 5. Post a comment through `tracker-write` — the **confirmation comment** from the `pre-flight-autofill` rule, **not** a bare remediation checklist: disclose it is a Claude draft, give one line per drafted section naming the key assumption made, list any remaining human-only item as a specific question with a recommended default, and close with *"review the drafted sections, correct anything wrong, then flip back to Ready and it builds — or reply with corrections."* Prefix with `[{repo}]`.
56
56
  6. Stop. Do not run triage, do not delegate to a flow, do not start work.
57
57
 
58
58
  **Exception — single-repo scope is split, not blocked.** A single-repo-scope FAIL is the one gate failure the agent fixes rather than bounces to the reporter: a cross-repo work unit is a decomposition error the agent owns (S10 is `product_relevant: false`), not a product question. Instead of blocking, run the **work-time split procedure** in the `repo-scope-split` rule — narrow this ticket to one repo, create a sibling per additional repo cloning its metadata, link the producer→consumer dependency (`Blocks` / `is blocked by`), comment on the original, then re-run `jira-verify` on the original and every new sibling. Block (per the path above) only if the split is ambiguous (see "When to block instead of split"). If single-repo scope was the only FAIL and the split succeeded, proceed to Step 3 once every resulting ticket passes.
@@ -0,0 +1,23 @@
1
+ # Report Actionability — Every Report Says What the Reader Must Do (load-bearing)
2
+
3
+ A report that describes real work accurately can still fail, because the reader cannot tell **which items need them and which are already handled**. Prose that mixes fixed and open items reads as a single undifferentiated pile of problems; the reader either acts on something already done, or assumes something open was handled. Both are caused by the report, not by the work.
4
+
5
+ The specific failure this rule exists to prevent, observed in a review cycle: six findings were returned, three were fixed, and the report described **two of them in detail without ever stating that six existed**. Every sentence in it was true. The reader still had to ask "did you fix them?" — and the answer was partly yes, partly no, and one finding had not even been read. A subset presented in the shape of a whole is worse than silence, because silence does not create false confidence.
6
+
7
+ ## Mandatory
8
+
9
+ 1. **State the denominator first.** Any report of findings, failures, checks, or review comments opens with the total — "6 findings: 3 fixed, 2 open, 1 needs your decision". A reader must never have to ask how many there were.
10
+ 2. **Account for every item.** Each one gets an explicit disposition. Nothing is omitted because it is minor, because it was fixed, or because it is embarrassing. An item you have not yet read is itself a disposition — say **"not read yet"** rather than leaving it out.
11
+ 3. **Label each item with who acts.** Exactly one of:
12
+ - **DONE** — handled; no action from the reader. Say so in the same breath as describing it.
13
+ - **OPEN** — needs work; state whether you are about to do it or waiting.
14
+ - **DECISION** — blocked on the reader; state the question and the options.
15
+ 4. **Never describe a fixed item as if it were live.** If you are reporting a defect you already fixed — which is often right, because the reader may need to know it existed — mark it fixed in the *first* sentence, not the last.
16
+ 5. **A subset must announce itself as one.** "Here are the two most serious" is fine. "Here is what the review said", when it was two of six, is not.
17
+ 6. **Lead the whole report with the action line**, per `automation-runbook-contract` — which already requires a terminating flow to open with its outcome and the operator action. This rule extends that requirement to reports that do **not** terminate a flow: a mid-run status update, a review summary, a "here is what CI said". The originating incident was one of those, which is how it slipped past a contract that only bound final messages.
18
+
19
+ ## Applies to
20
+
21
+ Code-review findings, CI failures, test results, audit output, security scans, deploy status, and any list of problems handed to a human. It applies equally to reports you are proud of and reports that expose your own mistake — the second kind is where the temptation to describe a flattering subset is strongest.
22
+
23
+ Detail, worked examples and the failure taxonomy: [reference/report-actionability.md](../reference/report-actionability.md).
@@ -67,6 +67,6 @@ A container (an Epic, or any item with open child work) is handled by the leaf-o
67
67
 
68
68
  The procedure is vendor-neutral; the create + link + edit mechanics differ:
69
69
 
70
- - **JIRA** — create via `mcp__atlassian__createJiraIssue` (clone fields, set the same epic parent); link via `mcp__atlassian__createIssueLink` with `Blocks` / `is blocked by` (resolve names via `mcp__atlassian__getIssueLinkTypes`); narrow the original via `mcp__atlassian__editJiraIssue`; comment via `mcp__atlassian__addCommentToJiraIssue`. See `jira-write-ticket` Phase 6.
70
+ - **JIRA** — every operation routes through `lisa-atlassian-access`; never name a vendor MCP tool at a call site (see the `integration-access-layer` rule, and #2148 for why the name is not a stable fact). Create the sibling (clone fields, set the same epic parent); link it with `Blocks` / `is blocked by`, resolving the link-type name first; narrow the original; comment on it. See `jira-write-ticket` Phase 6.
71
71
  - **GitHub** — create the sibling issue with the same labels and parent sub-issue; encode the dependency in the body (`Blocked by #<n>` / `Blocks #<n>`) and via the sub-issue/parent graph where used; edit the original's body to narrow scope. See `github-write-issue` Phase 6.
72
72
  - **Linear** — create via `lisa-linear-access operation: save-issue` (clone fields, set the same `projectId`); add a blocking relation via the `relations` field or a paired relation call; edit the original to narrow scope. See `linear-write-issue` Phase 6.
@@ -0,0 +1,61 @@
1
+ # Report Actionability — Reference
2
+
3
+ Long-form body for [eager/report-actionability.md](../eager/report-actionability.md).
4
+
5
+ ## The originating incident
6
+
7
+ A pull request received six review findings. Three were fixed in the working session: a critical ordering defect, a major copy inaccuracy, and a test that asserted call counts where it needed to assert call order.
8
+
9
+ The report to the owner described **two** of the six, in detail, with the reasoning behind each fix. It never said six existed. It never mentioned the three untouched, one of which was a Major finding that had not been opened at all.
10
+
11
+ Nothing in the report was false. The owner's next message was: *"so the findings... did you fix them?"* — followed by *"why did you tell me about those findings? It seems like you fixed them."*
12
+
13
+ Two distinct confusions, from one report:
14
+
15
+ - **Ambiguous disposition.** Items were described without being labelled fixed or open, so the reader could not tell whether the message was a status update or a request for action.
16
+ - **Implied completeness.** A subset was presented in the grammatical shape of a complete account ("the review caught…"), so the reader reasonably assumed the remainder did not exist.
17
+
18
+ ## Why "everything I said was true" is not a defence
19
+
20
+ Accuracy per sentence and accuracy of the whole are different properties. A report is a claim about a **set**: reporting two members of a six-member set, in a frame that does not name the set's size, asserts something false about the set even when every individual sentence is true.
21
+
22
+ This is the reporting analogue of a check that passes because it never ran. The output looks like the real thing and carries the same authority.
23
+
24
+ ## The temptation this rule resists
25
+
26
+ The subset a report drifts toward is rarely random. It skews toward:
27
+
28
+ - **items already fixed** (they make the report feel like progress),
29
+ - **items understood well** (they are easier to write about),
30
+ - **items that flatter** (a bug caught and fixed reads better than one not yet read).
31
+
32
+ The three omitted in the originating incident were: one not yet read, one only partially addressed and for an unrelated reason, and two dismissed internally as trivial formatting nits without ever saying so. Each omission was individually defensible. Together they produced a false picture.
33
+
34
+ ## Worked example
35
+
36
+ **Wrong** — true, and misleading:
37
+
38
+ > The review caught a real bug. `stopAnalytics` called `opt_out_capturing()` then `reset(true)`, and reset clears the opt-out flag… [400 words] …Second finding: the banner said "nothing is stored" while we persist the refusal. Fixed both.
39
+
40
+ **Right:**
41
+
42
+ > **6 review findings: 3 fixed, 3 open. Nothing needed from you unless you want the open ones handled now.**
43
+ >
44
+ > Fixed — no action:
45
+ > - 🔴 `posthog.ts` — withdrawal did not stick; reset wiped the opt-out. Order corrected, test now asserts order, mutation-proven.
46
+ > - 🟠 `site.ts` — banner overstated what a refusal stores. Copy, privacy page and fixtures corrected.
47
+ > - nitpick — test asserted call counts, now asserts order.
48
+ >
49
+ > Open:
50
+ > - 🟠 `lib/consent/index.ts` — uses `localStorage` directly instead of the storage abstraction; consent will not persist on native. **I had not read this one until now.**
51
+ > - 🟡 `audit.ignore.config.json` — obsolete advisory exclusion still present.
52
+ > - 🟡 `CHANGELOG.md` ×2 — formatting.
53
+
54
+ The second is shorter and answers "must I do anything?" in its first line.
55
+
56
+ ## Interaction with other rules
57
+
58
+ - **`automation-runbook-contract`** — requires a terminating flow to open with its run outcome and the operator action. That contract binds the FINAL message of a flow. This rule covers everything else: mid-run updates, review summaries, CI reports. The originating incident was a mid-run report, which is exactly why the existing contract did not catch it. Where both apply, the runbook contract's outcome vocabulary wins for the opening line and this rule governs the body.
59
+ - **`falsifiable-checks`** — that rule governs instruments that cannot fail. This one governs *accounts* that cannot be acted on. Both produce false confidence with no visible defect.
60
+ - **`stale-state-claims`** — a disposition recorded in a report expires exactly like a "not yet" comment. A finding reported OPEN and fixed an hour later must be re-reported, not left standing.
61
+ - **Corrections guidance** — reporting an error you made is required by this rule when it is one of the findings. Mark it fixed in the first sentence and move on; the rule demands completeness, never self-flagellation.
@@ -369,4 +369,13 @@ Do not paraphrase substrate output beyond JSON normalization.
369
369
 
370
370
  ## Headless behavior
371
371
 
372
- In a headless / non-interactive context (no TTY, `CI=true`, or `-p` mode), the MCP tier is unavailable (its OAuth flow needs a browser). The substrate ladder collapses to: acli (if pre-authenticated, e.g., a CI image baked with a service-account token) → curl + `ATLASSIAN_API_TOKEN`. Never block on interactive prompts. If both fail readiness checks, exit non-zero with a deterministic error.
372
+ In a headless / non-interactive context, the MCP tier is unavailable (its OAuth flow needs a browser). The substrate ladder collapses to: acli (if pre-authenticated, e.g., a CI image baked with a service-account token) → curl + `ATLASSIAN_API_TOKEN`. Never block on interactive prompts. If both fail readiness checks, exit non-zero with a deterministic error.
373
+
374
+ Treat all four of these as headless:
375
+
376
+ - no TTY
377
+ - `CI=true`
378
+ - `-p` mode
379
+ - **a subagent / teammate session** — measured (#2148): a subagent sees only the OAuth bootstrap stubs (`…__authenticate`, `…__complete_authentication`), never the data tools, and a direct call returns `No such tool available` rather than an auth error. The request never leaves the harness. This is not a general MCP block — other MCP servers work fine from a subagent — it is specific to servers whose OAuth completed in the lead. Crucially **acli works normally in a subagent**, so the ladder already has a working tier; it just has to skip MCP to reach it.
380
+
381
+ Detecting the subagent case: Lisa's Claude hooks already mark it — `SubagentStart` writes `"${STATE_DIR}/${SESSION_ID}.subagent"`, consumed by `enforce-verification-gate.sh` and `enforce-team-first.sh`. Where that flag is unavailable, probing the MCP tier and finding only `authenticate`-shaped tools is the same signal: treat it as unavailable and fall through rather than attempting a call that cannot succeed.
@@ -81,7 +81,7 @@ The dry-run mode never writes to the destination tracker. It also never modifies
81
81
 
82
82
  ## Hard Rule: All Writes Go Through `lisa-tracker-write`
83
83
 
84
- **Every ticket created by this skill — every Epic, Story, and Sub-task — MUST be created by invoking the `lisa-tracker-write` shim. Never call `lisa-jira-write-ticket`, `lisa-github-write-issue`, `mcp__atlassian__createJiraIssue`, or `gh issue create` directly from this skill or from any sub-agent it spawns.**
84
+ **Every ticket created by this skill — every Epic, Story, and Sub-task — MUST be created by invoking the `lisa-tracker-write` shim. Never call `lisa-jira-write-ticket`, `lisa-github-write-issue`, any vendor MCP tool, or `gh issue create` directly from this skill or from any sub-agent it spawns.**
85
85
 
86
86
  `lisa-tracker-write` enforces:
87
87
  - Vendor-agnostic dispatch (so a project's destination is one config edit away).
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lisa-intake
3
3
  description: "Vendor-agnostic scanner for Ready queues. Notion PRD database URL → first Ready PRD → lisa-plan. Confluence space or parent page URL → first prd-ready PRD → lisa-plan. Linear workspace URL or team key → first prd-ready project → lisa-plan. GitHub repo URL or `org/repo` token → first prd-ready issue → lisa-plan, or first `status:ready` issue → lisa-implement when `tracker = github`. JIRA project key or JQL filter → first Ready ticket → lisa-implement. On the PRD side it also closes the loop: each cycle rolls a ticketed PRD up to shipped and dispatches lisa-verify-prd for one shipped PRD (shipped → verified on pass; on fail, re-opened shipped → ticketed with build-ready fix tickets that auto-build and re-verify — never blocked). Designed as the cron target for /schedule — one eligible item per invocation, exits cleanly on empty. Symmetric counterpart to the single-item lisa-plan and lisa-implement skills."
4
- allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-search", "mcp__atlassian__getConfluencePage", "mcp__atlassian__getConfluenceSpaces", "mcp__atlassian__searchConfluenceUsingCql", "mcp__atlassian__getAccessibleAtlassianResources", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getJiraIssue"]
4
+ allowed-tools: ["Skill", "Bash"]
5
5
  ---
6
6
 
7
7
  # Intake: $ARGUMENTS
@@ -73,11 +73,11 @@ Dry-run output format is identical to `lisa-notion-to-tracker`'s and `lisa-confl
73
73
  ### Total failures: <n>
74
74
  ```
75
75
 
76
- The dry-run mode never writes to JIRA and never calls `mcp__atlassian__createJiraIssue`. It also never modifies the source Linear project, never adds/removes labels, never edits sub-issues, and never posts comments — that is the orchestrating skill's responsibility (`lisa-linear-prd-intake`).
76
+ The dry-run mode never writes to JIRA and never writes through any vendor tool directly. It also never modifies the source Linear project, never adds/removes labels, never edits sub-issues, and never posts comments — that is the orchestrating skill's responsibility (`lisa-linear-prd-intake`).
77
77
 
78
78
  ## Hard Rule: All Writes Go Through `lisa-tracker-write`
79
79
 
80
- **Every JIRA ticket created by this skill — every epic, story, and sub-task — MUST be created by invoking the `lisa-tracker-write` skill. Never call `mcp__atlassian__createJiraIssue`, `mcp__atlassian__editJiraIssue`, `mcp__atlassian__createIssueLink`, or any other Atlassian write tool directly from this skill or from any sub-agent it spawns.**
80
+ **Every JIRA ticket created by this skill — every epic, story, and sub-task — MUST be created by invoking the `lisa-tracker-write` skill. Never call a vendor MCP tool or REST endpoint directly from this skill or from any sub-agent it spawns.**
81
81
 
82
82
  `lisa-tracker-write` enforces gates this skill does not:
83
83
  - 3-audience description (Context / Technical Approach / Acceptance Criteria)
@@ -401,7 +401,7 @@ When delegating to agents, provide this context. **The "MUST invoke jira-write-t
401
401
  Create JIRA sub-tasks in the [PROJECT] project at [CLOUD_ID].
402
402
 
403
403
  CRITICAL: For each sub-task, invoke the `lisa-tracker-write` skill via the Skill tool.
404
- Do NOT call `mcp__atlassian__createJiraIssue` directly. The `lisa-tracker-write` skill
404
+ Do NOT call a vendor MCP tool directly. The `lisa-tracker-write` skill
405
405
  enforces required quality gates (Gherkin acceptance criteria, 3-audience description,
406
406
  single-repo scope, sign-in/environment fields, post-create verification). Bypassing it
407
407
  produces broken tickets that downstream skills (triage, journey, evidence) cannot use.
@@ -68,11 +68,11 @@ Dry-run output format:
68
68
 
69
69
  The `failures` array passes the validator's `Failure details` block through verbatim. Do not re-format `what` or `recommendation` here — those fields are already product-readable per the validator's contract, and re-summarizing risks losing concrete recommendations.
70
70
 
71
- The dry-run mode never writes to JIRA and never calls `mcp__atlassian__createJiraIssue`. It also never sets a Notion status — that is the orchestrating skill's responsibility.
71
+ The dry-run mode never writes to JIRA and never writes through any vendor tool directly. It also never sets a Notion status — that is the orchestrating skill's responsibility.
72
72
 
73
73
  ## Hard Rule: All Writes Go Through `lisa-tracker-write`
74
74
 
75
- **Every JIRA ticket created by this skill — every epic, story, and sub-task — MUST be created by invoking the `lisa-tracker-write` skill. Never call `mcp__atlassian__createJiraIssue`, `mcp__atlassian__editJiraIssue`, `mcp__atlassian__createIssueLink`, or any other Atlassian write tool directly from this skill or from any sub-agent it spawns.**
75
+ **Every JIRA ticket created by this skill — every epic, story, and sub-task — MUST be created by invoking the `lisa-tracker-write` skill. Never call a vendor MCP tool or REST endpoint directly from this skill or from any sub-agent it spawns.**
76
76
 
77
77
  `lisa-tracker-write` enforces gates this skill does not:
78
78
  - 3-audience description (Context / Technical Approach / Acceptance Criteria)
@@ -419,7 +419,7 @@ When delegating to agents, provide this context. **The "MUST invoke jira-write-t
419
419
  Create JIRA sub-tasks in the [PROJECT] project at [CLOUD_ID].
420
420
 
421
421
  CRITICAL: For each sub-task, invoke the `lisa-tracker-write` skill via the Skill tool.
422
- Do NOT call `mcp__atlassian__createJiraIssue` directly. The `lisa-tracker-write` skill
422
+ Do NOT call a vendor MCP tool directly. The `lisa-tracker-write` skill
423
423
  enforces required quality gates (Gherkin acceptance criteria, 3-audience description,
424
424
  single-repo scope, sign-in/environment fields, post-create verification). Bypassing it
425
425
  produces broken tickets that downstream skills (triage, journey, evidence) cannot use.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lisa-prd-ticket-coverage
3
3
  description: "Verifies that every requirement in a PRD (Notion, Confluence, Linear, or GitHub Issues) is covered by at least one created destination ticket (JIRA, GitHub Issues, or Linear) — no silent drops. Parses the PRD into atomic items (goals, user stories, functional/non-functional requirements, acceptance criteria, important notes), maps each to the created tickets, and produces a coverage matrix and verdict (COMPLETE / COMPLETE_WITH_SCOPE_CREEP / GAPS_FOUND / NO_TICKETS_FOUND). Used by notion-prd-intake / confluence-prd-intake / linear-prd-intake / github-prd-intake post-write to gate the Ticketed transition; can also be invoked standalone for after-the-fact audits."
4
- allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-get-comments", "mcp__atlassian__getConfluencePage", "mcp__atlassian__getConfluencePageDescendants", "mcp__atlassian__getConfluencePageFooterComments", "mcp__atlassian__getConfluencePageInlineComments", "mcp__atlassian__getConfluenceCommentChildren", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Skill", "Bash"]
5
5
  ---
6
6
 
7
7
  # PRD Ticket Coverage Audit: $ARGUMENTS
@@ -14,7 +14,7 @@ allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__cl
14
14
  The PRD URL can be a **Notion page URL**, a **Confluence page URL**, a **Linear project URL**, or a **GitHub issue URL**. Detect the vendor from the host:
15
15
 
16
16
  - `notion.so` / `notion.site` → Notion. Fetch with `mcp__claude_ai_Notion__notion-fetch` (`include_discussions: true`) and `mcp__claude_ai_Notion__notion-get-comments`.
17
- - Atlassian Confluence host (e.g. `*.atlassian.net/wiki/...`) → Confluence. Fetch with `mcp__atlassian__getConfluencePage`, `mcp__atlassian__getConfluencePageDescendants` (for child epic pages), `mcp__atlassian__getConfluencePageFooterComments`, `mcp__atlassian__getConfluencePageInlineComments`, and `mcp__atlassian__getConfluenceCommentChildren` for nested replies.
17
+ - Atlassian Confluence host (e.g. `*.atlassian.net/wiki/...`) → Confluence. Through `lisa-atlassian-access`, fetch the page, its descendants (for child epic pages), and its footer + inline comments including nested replies. State the operation, not a vendor tool name — the access skill owns substrate selection (`integration-access-layer`).
18
18
  - `linear.app` host → Linear. Fetch with `lisa-linear-access operation: get-project` (capture description, labels, state, attached resources), `lisa-linear-access operation: list-documents({projectId})` + `lisa-linear-access operation: get-document` per attached document, `lisa-linear-access operation: list-issues({project})` for sub-issues that act as child epics / user stories, and `lisa-linear-access operation: list-comments({issueId})` per sub-issue for decisions and engineering notes. Comments do not exist on the project itself in the MCP surface — sub-issue comments are the substitute.
19
19
  - `github.com` host → GitHub Issues. Fetch with the `gh` CLI (no GitHub MCP — Lisa uses the CLI exclusively for GitHub):
20
20
  - `gh issue view <number> --repo <org>/<repo> --json number,title,body,labels,milestone,assignees,author,createdAt,comments,url` for the PRD body and comments.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lisa-spec-conformance
3
3
  description: "Verifies that shipped work matches its spec section-by-section — acceptance criteria, Out of Scope, Technical Approach, Validation Journey assertions, and any explicit deliverables. Builds a coverage matrix mapping each requirement to evidence, flags scope creep separately from misses, and produces a verdict (CONFORMS / PARTIAL / DIVERGES). Runs during the verification phase alongside empirical system verification."
4
- allowed-tools: ["Read", "Glob", "Grep", "Bash", "Skill", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Read", "Glob", "Grep", "Bash", "Skill"]
5
5
  ---
6
6
 
7
7
  # Spec Conformance: $ARGUMENTS
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lisa-verify-prd
3
3
  description: "Initiative-level PRD acceptance gate. Given a PRD ref/URL (GitHub, Linear, Notion, Confluence, or JIRA), resolves the source vendor, reads the PRD and its generated top-level child work via the prd-lifecycle-rollup contract, and confirms every required child is terminal before any verification runs — if any is non-terminal it reports the incomplete set and STOPS. When the guard passes it runs spec-conformance against the original PRD requirements plus empirical verification via verification-lifecycle. On CONFORMS with all checks passing: transitions the PRD shipped → verified and posts evidence. On PARTIAL/DIVERGES or any failing check: re-opens the PRD shipped → ticketed (NEVER blocked), creates build-ready fix tickets for each divergence, and posts a product-readable failure report — the fix tickets auto-build, rollup re-ships the PRD, and a later intake cycle re-verifies, so the loop closes itself. Idempotent re-runs: comments regenerate in place via sentinel markers; fix tickets dedupe by stable ref."
4
- allowed-tools: ["Skill", "Bash", "Read", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-get-comments", "mcp__atlassian__getConfluencePage", "mcp__atlassian__getConfluencePageDescendants", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Skill", "Bash", "Read"]
5
5
  ---
6
6
 
7
7
  # PRD-level Verification: $ARGUMENTS
@@ -39,9 +39,11 @@ Detect the vendor from `$ARGUMENTS` the same way `prd-ticket-coverage` / `prd-ba
39
39
  |---|---|---|
40
40
  | `github.com/<org>/<repo>/issues/<n>` or `<org>/<repo>#<n>` | **GitHub Issues** | `gh` CLI (Lisa uses the CLI exclusively for GitHub — no GitHub MCP) |
41
41
  | `linear.app/...` | **Linear** | `lisa-linear-access operation: get-project` / `lisa-linear-access operation: get-issue` |
42
- | `notion.so` / `notion.site` | **Notion** | `mcp__claude_ai_Notion__notion-fetch` (`include_discussions: true`) |
43
- | `*.atlassian.net/wiki/...` | **Confluence** | `mcp__atlassian__getConfluencePage` (+ descendants) |
44
- | JIRA issue key (e.g. `PROJ-123`) or `*.atlassian.net/browse/...` | **JIRA** | `mcp__atlassian__getJiraIssue` |
42
+ | `notion.so` / `notion.site` | **Notion** | `lisa-notion-access` fetch the page **with its discussions** |
43
+ | `*.atlassian.net/wiki/...` | **Confluence** | `lisa-atlassian-access` read the page and its descendants |
44
+ | JIRA issue key (e.g. `PROJ-123`) or `*.atlassian.net/browse/...` | **JIRA** | `lisa-atlassian-access` — read the issue (and JQL-search when resolving a set) |
45
+
46
+ State the operation you need, never a vendor tool name: the access skills own substrate selection, and a hardcoded MCP tool name is not portable. The same server registers under different prefixes depending on install path (`mcp__atlassian__*`, `mcp__claude_ai_Atlassian__*`, `mcp__plugin_atlassian_atlassian__*`), and its data tools register only once OAuth completes — so a named tool fails outright in a context that has the CLI or token substrate available and would otherwise have worked. See the `integration-access-layer` rule.
45
47
 
46
48
  Read the PRD body via the vendor-appropriate surface. The vendor that owns the PRD source is what Phase 2 reads the child set from; it is independent of which tracker hosts the generated tickets (a Notion PRD can own JIRA tickets — the cross-vendor case is handled by the documented generated-work section in Phase 2).
47
49
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.316.0",
3
+ "version": "2.316.2",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -49,10 +49,10 @@ Use the `jira-verify` skill to check the ticket against organizational standards
49
49
 
50
50
  If `jira-verify` returns `FAIL` on any of the above, do NOT continue to build. **Draft the missing spec content first, then block for confirmation** — never bounce a raw "go write all this" checklist back to the reporter:
51
51
  1. **Best-effort autofill (before blocking).** Run `pre-flight-autofill` for every work item. Preserve a human bare configured key or `Confirmed: <env>`; automation writes `Inferred: <env> — evidence: <title|body|reproduction|hostname>`, `Assumption: <env> — remote default branch <branch>` for a unique reverse-map, or `Assumption: remote default branch <branch>` otherwise. Human confirmation replaces the annotation with the bare key or `Confirmed: <env>`. For a legacy bare value, use managed draft markers and current ticket content only; provider edit history is not required. A marker proves automation and requires re-annotation; otherwise unknown provenance plus conflicting evidence stops for confirmation. Resolve one exact `deploy.branches` key from the human-authored title, body, and reproduction steps or URL hostname; exclude the complete `Target Backend Environment` section and other machine-authored metadata/draft blocks so annotations cannot become evidence. A reported bug environment is an example, not a restriction. Evidence supersedes only `Assumption:`. Normalize `prod` ↔ `production` only when exactly one is configured; no other aliases exist. Conflicts stop; never infer from arbitrary branch text, URL paths/query strings, or substrings. Write through `jira-write-ticket`, never overwrite human prose, then re-run `jira-verify`.
52
- 2. Transition the ticket status to the configured `blocked` status (typically `Blocked` — read from `.lisa.config.json` `jira.workflow.blocked` if present, otherwise the project's standard blocked status). Use `mcp__atlassian__transitionJiraIssue` or equivalent.
53
- 3. **Add the `human_needed` marker label.** Even after the agent drafted what it could, a pre-flight gate failure bounces the ticket back to its reporter because the ticket still needs a human to **confirm the drafted assumptions** or supply something no agent can invent — real missing credentials, access, or an irreducible product/scoping decision. Add the configured label (`jira.labels.human_needed`, default `Human Needed`) to the ticket's `labels` field via `mcp__atlassian__editJiraIssue` — a lightweight metadata update permitted under this same gate exception. This is additive to (not a replacement for) the `blocked` status, so a human scanning the board sees at a glance which blocked tickets are waiting on them. If the label does not exist in the project, record that and proceed — the marker is best-effort. (See the `config-resolution` rule's "Build markers" for when the marker applies and when it must NOT.)
52
+ 2. Transition the ticket status to the configured `blocked` status (typically `Blocked` — read from `.lisa.config.json` `jira.workflow.blocked` if present, otherwise the project's standard blocked status). Transition through `tracker-write` (which routes via the matching `*-access` skill); never name a vendor MCP tool here.
53
+ 3. **Add the `human_needed` marker label.** Even after the agent drafted what it could, a pre-flight gate failure bounces the ticket back to its reporter because the ticket still needs a human to **confirm the drafted assumptions** or supply something no agent can invent — real missing credentials, access, or an irreducible product/scoping decision. Add the configured label (`jira.labels.human_needed`, default `Human Needed`) to the ticket's `labels` field through `tracker-write` — a lightweight metadata update permitted under this same gate exception. This is additive to (not a replacement for) the `blocked` status, so a human scanning the board sees at a glance which blocked tickets are waiting on them. If the label does not exist in the project, record that and proceed — the marker is best-effort. (See the `config-resolution` rule's "Build markers" for when the marker applies and when it must NOT.)
54
54
  4. Reassign the ticket to the **Reporter** (the human who filed it — not the Creator field, which may be a bot/integration).
55
- 5. Post a comment using `mcp__atlassian__addCommentToJiraIssue` — the **confirmation comment** from the `pre-flight-autofill` rule, **not** a bare remediation checklist: disclose it is a Claude draft, give one line per drafted section naming the key assumption made, list any remaining human-only item as a specific question with a recommended default, and close with *"review the drafted sections, correct anything wrong, then flip back to Ready and it builds — or reply with corrections."* Prefix with `[{repo}]`.
55
+ 5. Post a comment through `tracker-write` — the **confirmation comment** from the `pre-flight-autofill` rule, **not** a bare remediation checklist: disclose it is a Claude draft, give one line per drafted section naming the key assumption made, list any remaining human-only item as a specific question with a recommended default, and close with *"review the drafted sections, correct anything wrong, then flip back to Ready and it builds — or reply with corrections."* Prefix with `[{repo}]`.
56
56
  6. Stop. Do not run triage, do not delegate to a flow, do not start work.
57
57
 
58
58
  **Exception — single-repo scope is split, not blocked.** A single-repo-scope FAIL is the one gate failure the agent fixes rather than bounces to the reporter: a cross-repo work unit is a decomposition error the agent owns (S10 is `product_relevant: false`), not a product question. Instead of blocking, run the **work-time split procedure** in the `repo-scope-split` rule — narrow this ticket to one repo, create a sibling per additional repo cloning its metadata, link the producer→consumer dependency (`Blocks` / `is blocked by`), comment on the original, then re-run `jira-verify` on the original and every new sibling. Block (per the path above) only if the split is ambiguous (see "When to block instead of split"). If single-repo scope was the only FAIL and the split succeeded, proceed to Step 3 once every resulting ticket passes.
@@ -72,6 +72,6 @@ A container (an Epic, or any item with open child work) is handled by the leaf-o
72
72
 
73
73
  The procedure is vendor-neutral; the create + link + edit mechanics differ:
74
74
 
75
- - **JIRA** — create via `mcp__atlassian__createJiraIssue` (clone fields, set the same epic parent); link via `mcp__atlassian__createIssueLink` with `Blocks` / `is blocked by` (resolve names via `mcp__atlassian__getIssueLinkTypes`); narrow the original via `mcp__atlassian__editJiraIssue`; comment via `mcp__atlassian__addCommentToJiraIssue`. See `jira-write-ticket` Phase 6.
75
+ - **JIRA** — every operation routes through `lisa-atlassian-access`; never name a vendor MCP tool at a call site (see the `integration-access-layer` rule, and #2148 for why the name is not a stable fact). Create the sibling (clone fields, set the same epic parent); link it with `Blocks` / `is blocked by`, resolving the link-type name first; narrow the original; comment on it. See `jira-write-ticket` Phase 6.
76
76
  - **GitHub** — create the sibling issue with the same labels and parent sub-issue; encode the dependency in the body (`Blocked by #<n>` / `Blocks #<n>`) and via the sub-issue/parent graph where used; edit the original's body to narrow scope. See `github-write-issue` Phase 6.
77
77
  - **Linear** — create via `lisa-linear-access operation: save-issue` (clone fields, set the same `projectId`); add a blocking relation via the `relations` field or a paired relation call; edit the original to narrow scope. See `linear-write-issue` Phase 6.
@@ -0,0 +1,66 @@
1
+ ---
2
+ description: "Report Actionability — Reference"
3
+ alwaysApply: false
4
+ ---
5
+
6
+ # Report Actionability — Reference
7
+
8
+ Long-form body for [eager/report-actionability.md](report-actionability.mdc).
9
+
10
+ ## The originating incident
11
+
12
+ A pull request received six review findings. Three were fixed in the working session: a critical ordering defect, a major copy inaccuracy, and a test that asserted call counts where it needed to assert call order.
13
+
14
+ The report to the owner described **two** of the six, in detail, with the reasoning behind each fix. It never said six existed. It never mentioned the three untouched, one of which was a Major finding that had not been opened at all.
15
+
16
+ Nothing in the report was false. The owner's next message was: *"so the findings... did you fix them?"* — followed by *"why did you tell me about those findings? It seems like you fixed them."*
17
+
18
+ Two distinct confusions, from one report:
19
+
20
+ - **Ambiguous disposition.** Items were described without being labelled fixed or open, so the reader could not tell whether the message was a status update or a request for action.
21
+ - **Implied completeness.** A subset was presented in the grammatical shape of a complete account ("the review caught…"), so the reader reasonably assumed the remainder did not exist.
22
+
23
+ ## Why "everything I said was true" is not a defence
24
+
25
+ Accuracy per sentence and accuracy of the whole are different properties. A report is a claim about a **set**: reporting two members of a six-member set, in a frame that does not name the set's size, asserts something false about the set even when every individual sentence is true.
26
+
27
+ This is the reporting analogue of a check that passes because it never ran. The output looks like the real thing and carries the same authority.
28
+
29
+ ## The temptation this rule resists
30
+
31
+ The subset a report drifts toward is rarely random. It skews toward:
32
+
33
+ - **items already fixed** (they make the report feel like progress),
34
+ - **items understood well** (they are easier to write about),
35
+ - **items that flatter** (a bug caught and fixed reads better than one not yet read).
36
+
37
+ The three omitted in the originating incident were: one not yet read, one only partially addressed and for an unrelated reason, and two dismissed internally as trivial formatting nits without ever saying so. Each omission was individually defensible. Together they produced a false picture.
38
+
39
+ ## Worked example
40
+
41
+ **Wrong** — true, and misleading:
42
+
43
+ > The review caught a real bug. `stopAnalytics` called `opt_out_capturing()` then `reset(true)`, and reset clears the opt-out flag… [400 words] …Second finding: the banner said "nothing is stored" while we persist the refusal. Fixed both.
44
+
45
+ **Right:**
46
+
47
+ > **6 review findings: 3 fixed, 3 open. Nothing needed from you unless you want the open ones handled now.**
48
+ >
49
+ > Fixed — no action:
50
+ > - 🔴 `posthog.ts` — withdrawal did not stick; reset wiped the opt-out. Order corrected, test now asserts order, mutation-proven.
51
+ > - 🟠 `site.ts` — banner overstated what a refusal stores. Copy, privacy page and fixtures corrected.
52
+ > - nitpick — test asserted call counts, now asserts order.
53
+ >
54
+ > Open:
55
+ > - 🟠 `lib/consent/index.ts` — uses `localStorage` directly instead of the storage abstraction; consent will not persist on native. **I had not read this one until now.**
56
+ > - 🟡 `audit.ignore.config.json` — obsolete advisory exclusion still present.
57
+ > - 🟡 `CHANGELOG.md` ×2 — formatting.
58
+
59
+ The second is shorter and answers "must I do anything?" in its first line.
60
+
61
+ ## Interaction with other rules
62
+
63
+ - **`automation-runbook-contract`** — requires a terminating flow to open with its run outcome and the operator action. That contract binds the FINAL message of a flow. This rule covers everything else: mid-run updates, review summaries, CI reports. The originating incident was a mid-run report, which is exactly why the existing contract did not catch it. Where both apply, the runbook contract's outcome vocabulary wins for the opening line and this rule governs the body.
64
+ - **`falsifiable-checks`** — that rule governs instruments that cannot fail. This one governs *accounts* that cannot be acted on. Both produce false confidence with no visible defect.
65
+ - **`stale-state-claims`** — a disposition recorded in a report expires exactly like a "not yet" comment. A finding reported OPEN and fixed an hour later must be re-reported, not left standing.
66
+ - **Corrections guidance** — reporting an error you made is required by this rule when it is one of the findings. Mark it fixed in the first sentence and move on; the rule demands completeness, never self-flagellation.
@@ -0,0 +1,28 @@
1
+ ---
2
+ description: "Report Actionability — Every Report Says What the Reader Must Do (load-bearing)"
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Report Actionability — Every Report Says What the Reader Must Do (load-bearing)
7
+
8
+ A report that describes real work accurately can still fail, because the reader cannot tell **which items need them and which are already handled**. Prose that mixes fixed and open items reads as a single undifferentiated pile of problems; the reader either acts on something already done, or assumes something open was handled. Both are caused by the report, not by the work.
9
+
10
+ The specific failure this rule exists to prevent, observed in a review cycle: six findings were returned, three were fixed, and the report described **two of them in detail without ever stating that six existed**. Every sentence in it was true. The reader still had to ask "did you fix them?" — and the answer was partly yes, partly no, and one finding had not even been read. A subset presented in the shape of a whole is worse than silence, because silence does not create false confidence.
11
+
12
+ ## Mandatory
13
+
14
+ 1. **State the denominator first.** Any report of findings, failures, checks, or review comments opens with the total — "6 findings: 3 fixed, 2 open, 1 needs your decision". A reader must never have to ask how many there were.
15
+ 2. **Account for every item.** Each one gets an explicit disposition. Nothing is omitted because it is minor, because it was fixed, or because it is embarrassing. An item you have not yet read is itself a disposition — say **"not read yet"** rather than leaving it out.
16
+ 3. **Label each item with who acts.** Exactly one of:
17
+ - **DONE** — handled; no action from the reader. Say so in the same breath as describing it.
18
+ - **OPEN** — needs work; state whether you are about to do it or waiting.
19
+ - **DECISION** — blocked on the reader; state the question and the options.
20
+ 4. **Never describe a fixed item as if it were live.** If you are reporting a defect you already fixed — which is often right, because the reader may need to know it existed — mark it fixed in the *first* sentence, not the last.
21
+ 5. **A subset must announce itself as one.** "Here are the two most serious" is fine. "Here is what the review said", when it was two of six, is not.
22
+ 6. **Lead the whole report with the action line**, per `automation-runbook-contract` — which already requires a terminating flow to open with its outcome and the operator action. This rule extends that requirement to reports that do **not** terminate a flow: a mid-run status update, a review summary, a "here is what CI said". The originating incident was one of those, which is how it slipped past a contract that only bound final messages.
23
+
24
+ ## Applies to
25
+
26
+ Code-review findings, CI failures, test results, audit output, security scans, deploy status, and any list of problems handed to a human. It applies equally to reports you are proud of and reports that expose your own mistake — the second kind is where the temptation to describe a flattering subset is strongest.
27
+
28
+ Detail, worked examples and the failure taxonomy: [reference/report-actionability.md](report-actionability-reference.mdc).
@@ -369,4 +369,13 @@ Do not paraphrase substrate output beyond JSON normalization.
369
369
 
370
370
  ## Headless behavior
371
371
 
372
- In a headless / non-interactive context (no TTY, `CI=true`, or `-p` mode), the MCP tier is unavailable (its OAuth flow needs a browser). The substrate ladder collapses to: acli (if pre-authenticated, e.g., a CI image baked with a service-account token) → curl + `ATLASSIAN_API_TOKEN`. Never block on interactive prompts. If both fail readiness checks, exit non-zero with a deterministic error.
372
+ In a headless / non-interactive context, the MCP tier is unavailable (its OAuth flow needs a browser). The substrate ladder collapses to: acli (if pre-authenticated, e.g., a CI image baked with a service-account token) → curl + `ATLASSIAN_API_TOKEN`. Never block on interactive prompts. If both fail readiness checks, exit non-zero with a deterministic error.
373
+
374
+ Treat all four of these as headless:
375
+
376
+ - no TTY
377
+ - `CI=true`
378
+ - `-p` mode
379
+ - **a subagent / teammate session** — measured (#2148): a subagent sees only the OAuth bootstrap stubs (`…__authenticate`, `…__complete_authentication`), never the data tools, and a direct call returns `No such tool available` rather than an auth error. The request never leaves the harness. This is not a general MCP block — other MCP servers work fine from a subagent — it is specific to servers whose OAuth completed in the lead. Crucially **acli works normally in a subagent**, so the ladder already has a working tier; it just has to skip MCP to reach it.
380
+
381
+ Detecting the subagent case: Lisa's Claude hooks already mark it — `SubagentStart` writes `"${STATE_DIR}/${SESSION_ID}.subagent"`, consumed by `enforce-verification-gate.sh` and `enforce-team-first.sh`. Where that flag is unavailable, probing the MCP tier and finding only `authenticate`-shaped tools is the same signal: treat it as unavailable and fall through rather than attempting a call that cannot succeed.
@@ -81,7 +81,7 @@ The dry-run mode never writes to the destination tracker. It also never modifies
81
81
 
82
82
  ## Hard Rule: All Writes Go Through `lisa-tracker-write`
83
83
 
84
- **Every ticket created by this skill — every Epic, Story, and Sub-task — MUST be created by invoking the `lisa-tracker-write` shim. Never call `lisa-jira-write-ticket`, `lisa-github-write-issue`, `mcp__atlassian__createJiraIssue`, or `gh issue create` directly from this skill or from any sub-agent it spawns.**
84
+ **Every ticket created by this skill — every Epic, Story, and Sub-task — MUST be created by invoking the `lisa-tracker-write` shim. Never call `lisa-jira-write-ticket`, `lisa-github-write-issue`, any vendor MCP tool, or `gh issue create` directly from this skill or from any sub-agent it spawns.**
85
85
 
86
86
  `lisa-tracker-write` enforces:
87
87
  - Vendor-agnostic dispatch (so a project's destination is one config edit away).
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lisa-intake
3
3
  description: "Vendor-agnostic scanner for Ready queues. Notion PRD database URL → first Ready PRD → lisa-plan. Confluence space or parent page URL → first prd-ready PRD → lisa-plan. Linear workspace URL or team key → first prd-ready project → lisa-plan. GitHub repo URL or `org/repo` token → first prd-ready issue → lisa-plan, or first `status:ready` issue → lisa-implement when `tracker = github`. JIRA project key or JQL filter → first Ready ticket → lisa-implement. On the PRD side it also closes the loop: each cycle rolls a ticketed PRD up to shipped and dispatches lisa-verify-prd for one shipped PRD (shipped → verified on pass; on fail, re-opened shipped → ticketed with build-ready fix tickets that auto-build and re-verify — never blocked). Designed as the cron target for /schedule — one eligible item per invocation, exits cleanly on empty. Symmetric counterpart to the single-item lisa-plan and lisa-implement skills."
4
- allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-search", "mcp__atlassian__getConfluencePage", "mcp__atlassian__getConfluenceSpaces", "mcp__atlassian__searchConfluenceUsingCql", "mcp__atlassian__getAccessibleAtlassianResources", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getJiraIssue"]
4
+ allowed-tools: ["Skill", "Bash"]
5
5
  ---
6
6
 
7
7
  # Intake: $ARGUMENTS