@codyswann/lisa 2.41.1 → 2.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  "lodash": ">=4.18.1"
83
83
  },
84
84
  "name": "@codyswann/lisa",
85
- "version": "2.41.1",
85
+ "version": "2.42.0",
86
86
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
87
87
  "main": "dist/index.js",
88
88
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -39,7 +39,8 @@ Pass `$ARGUMENTS` as a single JSON-style block:
39
39
  - `linear` → Linear MCP update
40
40
  - `github` → `gh issue edit --body`
41
41
  - `file` → `Edit` (preferred) or `Write` (full rewrite if needed)
42
- 5. **Return** the rendered section (so the caller can include it in its own report) and the source URL of the updated PRD.
42
+ 5. **Record the PRD→child relationship in the source tool's native hierarchy** where the source supports it and the destination tracker is the same system. For a `github` source whose repo is the same repo as the created tickets, link each generated top-level work item as a native GitHub **sub-issue** of the PRD issue — see [Native parent linking (GitHub)](#native-parent-linking-github). The documented `## Tickets` section from step 3 is always written regardless; native linking is **in addition to** it, not a replacement (the documented section is the cross-vendor and older-host fallback per the `prd-lifecycle-rollup` rule). Sources without native issue hierarchy (Notion, Confluence, file) rely on the documented section alone.
43
+ 6. **Return** the rendered section (so the caller can include it in its own report) and the source URL of the updated PRD.
43
44
 
44
45
  ## Format
45
46
 
@@ -75,6 +76,54 @@ Rendering rules:
75
76
  - Sort epics by key (lexical). Sort stories within an epic by key. Sort sub-tasks within a story by key. Sort the unparented list by `(type, key)`.
76
77
  - The line `_Generated by ..._` is fixed text — does not include a timestamp. A timestamp would defeat the diff-equality check Debrief relies on.
77
78
 
79
+ ## Native parent linking (GitHub)
80
+
81
+ When `source_type: github` **and** the PRD issue lives in the same repository as the created tickets, make the PRD the structural parent of the work it generated by linking each generated top-level work item as a native GitHub **sub-issue** of the PRD issue. This is the GitHub leg of the PRD→child native-hierarchy requirement in the `prd-lifecycle-rollup` rule (cite it by slug; do not restate its taxonomy here). The documented `## Tickets` section is still written either way — native linking is the first-class relationship; the documented section is the durable fallback for cross-vendor and older hosts.
82
+
83
+ This section is GitHub-only. Linear/JIRA native parents and the documented-section-only fallback are governed elsewhere and are out of scope for this section.
84
+
85
+ ### What gets linked — generated top-level work only
86
+
87
+ Per the `prd-lifecycle-rollup` "generated top-level work" contract, the PRD owns **only** its generated top-level work as direct children:
88
+
89
+ - A ticket is **top-level** when its `parent_key` is null/empty — these are the created Epic(s) and any top-level Story created directly under the PRD. Link these as sub-issues of the PRD.
90
+ - A ticket with a non-null `parent_key` is a **descendant** (a Story under an Epic, or a leaf Sub-task) — it is owned by its own top-level parent, **never** linked directly to the PRD. Leaf Sub-tasks are explicitly NOT direct PRD children (PRD #525 non-goal).
91
+
92
+ So if the PRD generated `Epic E1 → Story S1 → Sub-task T1`, only `E1` becomes a sub-issue of the PRD; `S1` is a sub-issue of `E1` and `T1` of `S1` (those links were already made by the write path), and neither `S1` nor `T1` is a direct child of the PRD.
93
+
94
+ ### Same-repo guard
95
+
96
+ Native sub-issue linking only applies when the PRD and the work item are in the same repository. Parse `owner/repo` from `source_ref` (the PRD URL or `<org>/<repo>#<n>` token) and from each top-level ticket's `key`/`url`. Skip native linking for any ticket whose repo differs from the PRD's repo (cross-repo or cross-vendor) — record those in the documented section only. The cross-vendor case (e.g. a GitHub PRD with a JIRA/Linear tracker) never reaches this path because the ticket is not a GitHub issue.
97
+
98
+ ### Idempotency — dedupe by child-ref
99
+
100
+ The dedupe key is **child-ref identity** (`owner/repo#number`), per the `prd-lifecycle-rollup` idempotency rule. Before adding any link, read the PRD's current sub-issues and skip any child already linked, so re-running `prd-backlink` never creates duplicate sub-issue links and is a no-op when everything is already linked.
101
+
102
+ 1. **Read the PRD's existing sub-issues** (same GraphQL `subIssues` query `lisa:github-read-issue` Phase 3 uses), and build the set of already-linked child refs:
103
+
104
+ ```bash
105
+ gh api graphql -f query='query($org:String!,$repo:String!,$number:Int!){repository(owner:$org,name:$repo){issue(number:$number){subIssues(first:100){nodes{number repository{nameWithOwner}}}}}}' \
106
+ -F org=<prd_org> -F repo=<prd_repo> -F number=<prd_number> \
107
+ --jq '.data.repository.issue.subIssues.nodes[] | "\(.repository.nameWithOwner)#\(.number)"'
108
+ ```
109
+
110
+ The resulting `owner/repo#number` strings are the existing child-ref set.
111
+
112
+ 2. **For each generated top-level ticket** in the same repo whose child-ref is **not** already in that set, resolve node IDs and call `addSubIssue` (the same mutation `lisa:github-write-issue` Phase 6 step 3 uses):
113
+
114
+ ```bash
115
+ prd_id=$(gh api graphql -f query='query($org:String!,$repo:String!,$number:Int!){repository(owner:$org,name:$repo){issue(number:$number){id}}}' -F org=<prd_org> -F repo=<prd_repo> -F number=<prd_number> --jq '.data.repository.issue.id')
116
+ child_id=$(gh api graphql -f query='query($org:String!,$repo:String!,$number:Int!){repository(owner:$org,name:$repo){issue(number:$number){id}}}' -F org=<org> -F repo=<repo> -F number=<child_number> --jq '.data.repository.issue.id')
117
+ gh api graphql -f query='mutation($parentId:ID!,$childId:ID!){addSubIssue(input:{issueId:$parentId,subIssueId:$childId}){issue{number}subIssue{number}}}' -F parentId="$prd_id" -F childId="$child_id"
118
+ ```
119
+
120
+ A child already in the existing-sub-issue set is a no-op — do not call the mutation for it.
121
+
122
+ ### Graceful degradation
123
+
124
+ - **Already linked.** Covered by the dedupe read above (no mutation issued). If a concurrent run linked it between the read and the mutation, GitHub rejects the duplicate — treat that rejection as success (the desired end state already holds), not a failure.
125
+ - **Mutation unavailable** (older GHES, sub-issues feature off, or the `addSubIssue`/`subIssues` fields are missing). Fall back to the documented `## Tickets` section only and surface a warning to the caller (`native sub-issue linking unavailable — documented section written`). Never silently drop the relationship and never abort the run — the documented section is the contract that always lands.
126
+
78
127
  ## Failures
79
128
 
80
129
  - **Source unreachable / permission denied.** Stop and report. Do not silently swallow.
@@ -86,4 +135,11 @@ Rendering rules:
86
135
  ```text
87
136
  PRD back-link updated: <source_url>
88
137
  Section: ## Tickets — <n> epics, <n> stories, <n> sub-tasks, <n> unparented (<bugs/spikes>)
138
+ Native sub-issues: <n> linked, <n> already linked (GitHub same-repo only; documented section is the fallback)
89
139
  ```
140
+
141
+ Omit the `Native sub-issues` line when the source is not a same-repo GitHub PRD (no native linking applies). If native linking was attempted but the mutation was unavailable, replace the counts with the degradation warning from [Graceful degradation](#graceful-degradation).
142
+
143
+ ## Related rules
144
+
145
+ - `prd-lifecycle-rollup` — the vendor-neutral source of truth for PRD→generated-top-level-work ownership, the per-vendor terminal predicate, PRD `shipped` rollup, and the child-ref idempotency dedupe key. This skill implements the GitHub native-linking leg of that rule; it cites the rule by slug rather than restating its taxonomy.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
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.41.1",
3
+ "version": "2.42.0",
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-expo",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.41.1",
3
+ "version": "2.42.0",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -39,7 +39,8 @@ Pass `$ARGUMENTS` as a single JSON-style block:
39
39
  - `linear` → Linear MCP update
40
40
  - `github` → `gh issue edit --body`
41
41
  - `file` → `Edit` (preferred) or `Write` (full rewrite if needed)
42
- 5. **Return** the rendered section (so the caller can include it in its own report) and the source URL of the updated PRD.
42
+ 5. **Record the PRD→child relationship in the source tool's native hierarchy** where the source supports it and the destination tracker is the same system. For a `github` source whose repo is the same repo as the created tickets, link each generated top-level work item as a native GitHub **sub-issue** of the PRD issue — see [Native parent linking (GitHub)](#native-parent-linking-github). The documented `## Tickets` section from step 3 is always written regardless; native linking is **in addition to** it, not a replacement (the documented section is the cross-vendor and older-host fallback per the `prd-lifecycle-rollup` rule). Sources without native issue hierarchy (Notion, Confluence, file) rely on the documented section alone.
43
+ 6. **Return** the rendered section (so the caller can include it in its own report) and the source URL of the updated PRD.
43
44
 
44
45
  ## Format
45
46
 
@@ -75,6 +76,54 @@ Rendering rules:
75
76
  - Sort epics by key (lexical). Sort stories within an epic by key. Sort sub-tasks within a story by key. Sort the unparented list by `(type, key)`.
76
77
  - The line `_Generated by ..._` is fixed text — does not include a timestamp. A timestamp would defeat the diff-equality check Debrief relies on.
77
78
 
79
+ ## Native parent linking (GitHub)
80
+
81
+ When `source_type: github` **and** the PRD issue lives in the same repository as the created tickets, make the PRD the structural parent of the work it generated by linking each generated top-level work item as a native GitHub **sub-issue** of the PRD issue. This is the GitHub leg of the PRD→child native-hierarchy requirement in the `prd-lifecycle-rollup` rule (cite it by slug; do not restate its taxonomy here). The documented `## Tickets` section is still written either way — native linking is the first-class relationship; the documented section is the durable fallback for cross-vendor and older hosts.
82
+
83
+ This section is GitHub-only. Linear/JIRA native parents and the documented-section-only fallback are governed elsewhere and are out of scope for this section.
84
+
85
+ ### What gets linked — generated top-level work only
86
+
87
+ Per the `prd-lifecycle-rollup` "generated top-level work" contract, the PRD owns **only** its generated top-level work as direct children:
88
+
89
+ - A ticket is **top-level** when its `parent_key` is null/empty — these are the created Epic(s) and any top-level Story created directly under the PRD. Link these as sub-issues of the PRD.
90
+ - A ticket with a non-null `parent_key` is a **descendant** (a Story under an Epic, or a leaf Sub-task) — it is owned by its own top-level parent, **never** linked directly to the PRD. Leaf Sub-tasks are explicitly NOT direct PRD children (PRD #525 non-goal).
91
+
92
+ So if the PRD generated `Epic E1 → Story S1 → Sub-task T1`, only `E1` becomes a sub-issue of the PRD; `S1` is a sub-issue of `E1` and `T1` of `S1` (those links were already made by the write path), and neither `S1` nor `T1` is a direct child of the PRD.
93
+
94
+ ### Same-repo guard
95
+
96
+ Native sub-issue linking only applies when the PRD and the work item are in the same repository. Parse `owner/repo` from `source_ref` (the PRD URL or `<org>/<repo>#<n>` token) and from each top-level ticket's `key`/`url`. Skip native linking for any ticket whose repo differs from the PRD's repo (cross-repo or cross-vendor) — record those in the documented section only. The cross-vendor case (e.g. a GitHub PRD with a JIRA/Linear tracker) never reaches this path because the ticket is not a GitHub issue.
97
+
98
+ ### Idempotency — dedupe by child-ref
99
+
100
+ The dedupe key is **child-ref identity** (`owner/repo#number`), per the `prd-lifecycle-rollup` idempotency rule. Before adding any link, read the PRD's current sub-issues and skip any child already linked, so re-running `prd-backlink` never creates duplicate sub-issue links and is a no-op when everything is already linked.
101
+
102
+ 1. **Read the PRD's existing sub-issues** (same GraphQL `subIssues` query `lisa:github-read-issue` Phase 3 uses), and build the set of already-linked child refs:
103
+
104
+ ```bash
105
+ gh api graphql -f query='query($org:String!,$repo:String!,$number:Int!){repository(owner:$org,name:$repo){issue(number:$number){subIssues(first:100){nodes{number repository{nameWithOwner}}}}}}' \
106
+ -F org=<prd_org> -F repo=<prd_repo> -F number=<prd_number> \
107
+ --jq '.data.repository.issue.subIssues.nodes[] | "\(.repository.nameWithOwner)#\(.number)"'
108
+ ```
109
+
110
+ The resulting `owner/repo#number` strings are the existing child-ref set.
111
+
112
+ 2. **For each generated top-level ticket** in the same repo whose child-ref is **not** already in that set, resolve node IDs and call `addSubIssue` (the same mutation `lisa:github-write-issue` Phase 6 step 3 uses):
113
+
114
+ ```bash
115
+ prd_id=$(gh api graphql -f query='query($org:String!,$repo:String!,$number:Int!){repository(owner:$org,name:$repo){issue(number:$number){id}}}' -F org=<prd_org> -F repo=<prd_repo> -F number=<prd_number> --jq '.data.repository.issue.id')
116
+ child_id=$(gh api graphql -f query='query($org:String!,$repo:String!,$number:Int!){repository(owner:$org,name:$repo){issue(number:$number){id}}}' -F org=<org> -F repo=<repo> -F number=<child_number> --jq '.data.repository.issue.id')
117
+ gh api graphql -f query='mutation($parentId:ID!,$childId:ID!){addSubIssue(input:{issueId:$parentId,subIssueId:$childId}){issue{number}subIssue{number}}}' -F parentId="$prd_id" -F childId="$child_id"
118
+ ```
119
+
120
+ A child already in the existing-sub-issue set is a no-op — do not call the mutation for it.
121
+
122
+ ### Graceful degradation
123
+
124
+ - **Already linked.** Covered by the dedupe read above (no mutation issued). If a concurrent run linked it between the read and the mutation, GitHub rejects the duplicate — treat that rejection as success (the desired end state already holds), not a failure.
125
+ - **Mutation unavailable** (older GHES, sub-issues feature off, or the `addSubIssue`/`subIssues` fields are missing). Fall back to the documented `## Tickets` section only and surface a warning to the caller (`native sub-issue linking unavailable — documented section written`). Never silently drop the relationship and never abort the run — the documented section is the contract that always lands.
126
+
78
127
  ## Failures
79
128
 
80
129
  - **Source unreachable / permission denied.** Stop and report. Do not silently swallow.
@@ -86,4 +135,11 @@ Rendering rules:
86
135
  ```text
87
136
  PRD back-link updated: <source_url>
88
137
  Section: ## Tickets — <n> epics, <n> stories, <n> sub-tasks, <n> unparented (<bugs/spikes>)
138
+ Native sub-issues: <n> linked, <n> already linked (GitHub same-repo only; documented section is the fallback)
89
139
  ```
140
+
141
+ Omit the `Native sub-issues` line when the source is not a same-repo GitHub PRD (no native linking applies). If native linking was attempted but the mutation was unavailable, replace the counts with the degradation warning from [Graceful degradation](#graceful-degradation).
142
+
143
+ ## Related rules
144
+
145
+ - `prd-lifecycle-rollup` — the vendor-neutral source of truth for PRD→generated-top-level-work ownership, the per-vendor terminal predicate, PRD `shipped` rollup, and the child-ref idempotency dedupe key. This skill implements the GitHub native-linking leg of that rule; it cites the rule by slug rather than restating its taxonomy.