@codyswann/lisa 2.326.2 → 2.327.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/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +25 -23
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/sync/lifecycle-defaults.d.ts +61 -0
- package/dist/sync/lifecycle-defaults.d.ts.map +1 -0
- package/dist/sync/lifecycle-defaults.js +75 -0
- package/dist/sync/lifecycle-defaults.js.map +1 -0
- package/dist/sync/registry.d.ts.map +1 -1
- package/dist/sync/registry.js +15 -23
- package/dist/sync/registry.js.map +1 -1
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +20 -9
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +76 -66
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-claim/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-evidence/SKILL.md +7 -7
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-journey/SKILL.md +2 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-sync/SKILL.md +34 -30
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +6 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +8 -7
- package/plugins/lisa/.codex-plugin/skills/lisa-notion-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +59 -12
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-sync/SKILL.md +2 -2
- package/plugins/lisa/agents/linear-agent.md +6 -6
- package/plugins/lisa/agents/linear-build-intake.md +3 -3
- package/plugins/lisa/rules/eager/rejection-detection.md +2 -2
- package/plugins/lisa/rules/reference/config-resolution.md +37 -9
- package/plugins/lisa/rules/reference/rejection-detection.md +2 -2
- package/plugins/lisa/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-linear-access/SKILL.md +20 -9
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +77 -67
- package/plugins/lisa/skills/lisa-linear-claim/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-linear-evidence/SKILL.md +7 -7
- package/plugins/lisa/skills/lisa-linear-journey/SKILL.md +2 -2
- package/plugins/lisa/skills/lisa-linear-sync/SKILL.md +34 -30
- package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +6 -6
- package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +8 -7
- package/plugins/lisa/skills/lisa-notion-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +59 -12
- package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-tracker-sync/SKILL.md +2 -2
- package/plugins/lisa-agy/agents/linear-agent.md +6 -6
- package/plugins/lisa-agy/agents/linear-build-intake.md +3 -3
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +20 -9
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +77 -67
- package/plugins/lisa-agy/skills/lisa-linear-claim/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-linear-evidence/SKILL.md +7 -7
- package/plugins/lisa-agy/skills/lisa-linear-journey/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/lisa-linear-sync/SKILL.md +34 -30
- package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +6 -6
- package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +8 -7
- package/plugins/lisa-agy/skills/lisa-notion-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +59 -12
- package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-tracker-sync/SKILL.md +2 -2
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/agents/linear-agent.agent.md +6 -6
- package/plugins/lisa-copilot/agents/linear-build-intake.agent.md +3 -3
- package/plugins/lisa-copilot/rules/eager/rejection-detection.md +2 -2
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +37 -9
- package/plugins/lisa-copilot/rules/reference/rejection-detection.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +20 -9
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +77 -67
- package/plugins/lisa-copilot/skills/lisa-linear-claim/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-linear-evidence/SKILL.md +7 -7
- package/plugins/lisa-copilot/skills/lisa-linear-journey/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-linear-sync/SKILL.md +34 -30
- package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +6 -6
- package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +8 -7
- package/plugins/lisa-copilot/skills/lisa-notion-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +59 -12
- package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-tracker-sync/SKILL.md +2 -2
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/linear-agent.md +6 -6
- package/plugins/lisa-cursor/agents/linear-build-intake.md +3 -3
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +37 -9
- package/plugins/lisa-cursor/rules/rejection-detection-reference.mdc +2 -2
- package/plugins/lisa-cursor/rules/rejection-detection.mdc +2 -2
- package/plugins/lisa-cursor/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +20 -9
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +77 -67
- package/plugins/lisa-cursor/skills/lisa-linear-claim/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-linear-evidence/SKILL.md +7 -7
- package/plugins/lisa-cursor/skills/lisa-linear-journey/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/lisa-linear-sync/SKILL.md +34 -30
- package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +6 -6
- package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +8 -7
- package/plugins/lisa-cursor/skills/lisa-notion-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +59 -12
- package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-tracker-sync/SKILL.md +2 -2
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +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-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-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-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-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/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/agents/linear-agent.md +6 -6
- package/plugins/src/base/agents/linear-build-intake.md +3 -3
- package/plugins/src/base/rules/eager/rejection-detection.md +2 -2
- package/plugins/src/base/rules/reference/config-resolution.md +37 -9
- package/plugins/src/base/rules/reference/rejection-detection.md +2 -2
- package/plugins/src/base/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
- package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-linear-access/SKILL.md +20 -9
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +77 -67
- package/plugins/src/base/skills/lisa-linear-claim/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-linear-evidence/SKILL.md +7 -7
- package/plugins/src/base/skills/lisa-linear-journey/SKILL.md +2 -2
- package/plugins/src/base/skills/lisa-linear-sync/SKILL.md +34 -30
- package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +6 -6
- package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +8 -7
- package/plugins/src/base/skills/lisa-notion-to-tracker/SKILL.md +3 -3
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +59 -12
- package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-tracker-sync/SKILL.md +2 -2
|
@@ -292,7 +292,7 @@ For each epic identified in Phase 1, **invoke the `lisa-tracker-write` skill** (
|
|
|
292
292
|
- `artifacts`: the full Phase 1.5 artifact list — every artifact, regardless of domain. The epic is the canonical hub. No filtering at the epic level.
|
|
293
293
|
- `priority`, `labels`, `components`, `fix_version`: as appropriate
|
|
294
294
|
|
|
295
|
-
**Leaf-only build-ready (`leaf-only-lifecycle`)**: an Epic is a container, not a leaf work unit. Do NOT mark it build-ready — `lisa-tracker-write` must not be passed
|
|
295
|
+
**Leaf-only build-ready (`leaf-only-lifecycle`)**: an Epic is a container, not a leaf work unit. Do NOT mark it build-ready — `lisa-tracker-write` must not be passed the build-ready role for an Epic, and the Epic's lifecycle state rolls up from its children. The build-ready role is applied only in Phase 5.
|
|
296
296
|
|
|
297
297
|
Capture the returned epic key — Phase 4 needs it as the parent for stories.
|
|
298
298
|
|
|
@@ -323,7 +323,7 @@ For each story, **invoke `lisa-tracker-write`** with:
|
|
|
323
323
|
| Infrastructure | `ops`, `reference` |
|
|
324
324
|
| Mixed / setup ("X.0") | All domains |
|
|
325
325
|
|
|
326
|
-
**Leaf-only build-ready (`leaf-only-lifecycle`)**: a Story is a container (it has child Sub-tasks), not a leaf work unit. Do NOT mark it build-ready — never pass
|
|
326
|
+
**Leaf-only build-ready (`leaf-only-lifecycle`)**: a Story is a container (it has child Sub-tasks), not a leaf work unit. Do NOT mark it build-ready — never pass the build-ready role to `lisa-tracker-write` for a Story. Its lifecycle state rolls up from its Sub-tasks. The build-ready role is applied only in Phase 5.
|
|
327
327
|
|
|
328
328
|
Capture each returned story key — Phase 5 needs it as the parent for sub-tasks.
|
|
329
329
|
|
|
@@ -340,7 +340,7 @@ Each sub-task MUST:
|
|
|
340
340
|
2. **Include an Empirical Verification Plan** — real user-like verification, NOT unit tests, linting, or typechecking
|
|
341
341
|
3. **Carry its own `## Source Requirement` section** (shared format above) with the full verbatim quote(s) from the Phase 1.4 register — a leaf claimed by build-intake in isolation must be self-explanatory. When a sub-task is split per-repo, every split child inherits the same requirement quote(s).
|
|
342
342
|
|
|
343
|
-
**Leaf-only build-ready (`leaf-only-lifecycle`)**: Sub-tasks are the **leaf work units** of the decomposition — they are the ONLY items in the hierarchy that receive the build-ready
|
|
343
|
+
**Leaf-only build-ready (`leaf-only-lifecycle`)**: Sub-tasks are the **leaf work units** of the decomposition — they are the ONLY items in the hierarchy that receive the build-ready role. `lisa-tracker-write` applies the build-ready role here so downstream build intake (`lisa-tracker-build-intake`) claims the leaves and never the Epic or Stories. Apply the build-ready role to each Sub-task; never to its parent Story or Epic (Phases 3–4). `lisa-tracker-write` enforces the same invariant on the write side, so a Sub-task split into per-repo children (the cross-repo case above) carries build-ready on the children, not on any intermediate parent that gains child work.
|
|
344
344
|
|
|
345
345
|
Sub-tasks inherit their parent story's artifacts by reference (the parent link). Do not pass the same artifact list to every sub-task.
|
|
346
346
|
|
|
@@ -61,12 +61,12 @@ authenticated_surface: true # → requires Sign-in Required
|
|
|
61
61
|
artifacts_attached: true # → requires Source Precedence section
|
|
62
62
|
relations: [{ id: "ENG-99", type: "blocked_by" }] # known issue relations (may be empty)
|
|
63
63
|
remote_links: [{ url: "https://github.com/...", title: "PR #42" }]
|
|
64
|
-
build_ready: true # caller asserts the build-ready role (
|
|
64
|
+
build_ready: true # caller asserts the build-ready role (the `Todo` state) is/would be set — see S15
|
|
65
65
|
child_refs: ["ENG-601", "ENG-602"] # known child work (sub-issues / project-member issues / blocked_by parentage) — see S15
|
|
66
66
|
prd_source: "https://notion.so/..." # set when the Issue was generated from a PRD — requires the Source Requirement section, see S16
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
If the caller passes only an identifier, fetch the item via `lisa-linear-access operation: get-issue` (Issue) or `lisa-linear-access operation: get-project` (Project), derive the same fields from the fetched data — including `build_ready` (label set contains `
|
|
69
|
+
If the caller passes only an identifier, fetch the item via `lisa-linear-access operation: get-issue` (Issue) or `lisa-linear-access operation: get-project` (Project), derive the same fields from the fetched data — including `build_ready` (label set contains `Todo`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa-linear-read-issue`) so S15 can classify the item — then run gates.
|
|
70
70
|
|
|
71
71
|
## Gates
|
|
72
72
|
|
|
@@ -235,9 +235,9 @@ This gate depends on S11. It is `N/A` for containers — a **Project** (the Epic
|
|
|
235
235
|
|
|
236
236
|
#### S15 — Leaf-only build-ready
|
|
237
237
|
|
|
238
|
-
Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only a leaf work unit may carry the build-ready role.** This is the symmetric write-side guard for the Linear validator — a stale or hand-applied `
|
|
238
|
+
Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only a leaf work unit may carry the build-ready role.** This is the symmetric write-side guard for the Linear validator — a stale or hand-applied `Todo` label on a container is a lifecycle error and must FAIL here, regardless of how the item was produced. (Mirrors the "Build-ready label is leaf-only" rule that `lisa-linear-write-issue` applies at write time.)
|
|
239
239
|
|
|
240
|
-
**When the gate applies.** Run S15 whenever the item is build-ready — i.e. `build_ready = true`, or the spec/live labels include `
|
|
240
|
+
**When the gate applies.** Run S15 whenever the item is build-ready — i.e. `build_ready = true`, or the spec/live labels include `Todo`. If the item is not build-ready, S15 is `N/A` (nothing claims a non-ready item, so the invariant is vacuous).
|
|
241
241
|
|
|
242
242
|
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an item is a **container** if it has child work, whatever its declared type; otherwise the **issue type** decides. Determine child work from (in order) `child_refs`, native sub-issues, project-member issues (an Epic is modeled as a Linear Project), and `blocked_by` / parent references — the same hierarchy resolution `lisa-linear-read-issue` uses. When validating a live identifier, query sub-issues / project members alongside the item fetch.
|
|
243
243
|
|
|
@@ -255,7 +255,7 @@ PASS (the childless-parent exception) when the item is build-ready and is a **le
|
|
|
255
255
|
| Epic (Project) | no | yes | **FAIL** (childless Epic/Project — pure rollup container, exception does not apply) |
|
|
256
256
|
| any | any | no | **N/A** (not build-ready) |
|
|
257
257
|
|
|
258
|
-
Remediation: `"Build-ready
|
|
258
|
+
Remediation: `"Build-ready is leaf-only per leaf-only-lifecycle. Move the build-ready role off this container onto its leaf children (or, for a childless Epic, decompose it into leaf children or reclassify it to a leaf type); a parent's lifecycle state rolls up from its children and is never set to ready directly."`
|
|
259
259
|
|
|
260
260
|
`product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
|
|
261
261
|
|
|
@@ -362,7 +362,7 @@ system, and never invent or ask for credentials inline.
|
|
|
362
362
|
|
|
363
363
|
## Execution
|
|
364
364
|
|
|
365
|
-
1. Parse `$ARGUMENTS`. If it's an identifier, fetch the item and derive the spec from the fetched fields — including `build_ready` (label set contains `
|
|
365
|
+
1. Parse `$ARGUMENTS`. If it's an identifier, fetch the item and derive the spec from the fetched fields — including `build_ready` (label set contains `Todo`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa-linear-read-issue`) so S15 can classify the item. Otherwise parse the YAML spec.
|
|
366
366
|
2. Resolve team ID via `lisa-linear-access operation: list-teams({query: <teamKey>})` if any feasibility gate will run.
|
|
367
367
|
3. Run every Specification gate in order. Collect PASS / FAIL / N/A with a one-line reason.
|
|
368
368
|
4. Unless the caller passed `--spec-only` (dry-run), run every Feasibility gate. Collect results.
|
|
@@ -31,7 +31,7 @@ Linear's data model maps Epic / Story / Sub-task to **different entity types**.
|
|
|
31
31
|
| `Bug` | **Issue** | `lisa-linear-access operation: save-issue` | `projectId` if part of an Epic; else top-level |
|
|
32
32
|
| `Spike` | **Issue** | `lisa-linear-access operation: save-issue` | `projectId` if part of an Epic; else top-level |
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
The build lifecycle uses native **workflow states** (`Todo`, `In Progress`, `In Review`, `Blocked`, `On Dev`, `On Stg`, `Done`), resolved per role from `linear.workflow` — see "Why Linear uses states, not labels" in `config-resolution`. A new Issue is created in the team's default backlog/unstarted state unless `build_ready` promotes it (below).
|
|
35
35
|
|
|
36
36
|
## Phase 1 — Resolve Intent
|
|
37
37
|
|
|
@@ -227,7 +227,8 @@ If the item modifies an existing user-facing surface, a `lisa-product-walkthroug
|
|
|
227
227
|
|
|
228
228
|
Before create/update, verify each field is populated where applicable:
|
|
229
229
|
|
|
230
|
-
- **
|
|
230
|
+
- **Workflow state**: set the resolved `ready` state (`linear.workflow.ready`, default `Todo`) on a new **leaf** work unit (Bug / Task / Sub-task / Improvement with no child work) per `leaf-only-lifecycle`, **unless `build_ready: false`** (see the Build-ready control input below). A container (Epic Project / Story with sub-issues / Spike) is never put in the build-ready state.
|
|
231
|
+
- **Labels**: taxonomy only — `type:<Kind>`, `repo:<name>`, `component:<name>`, and the `prd-intake-feedback` sentinel. Lifecycle is **not** a label on Linear; do not add `status:*` labels.
|
|
231
232
|
- **Native priority field**: 0–4 per Linear's scale; explicit, not "unset".
|
|
232
233
|
- **Native estimate**: per Linear's team-configured estimate scale (often 0–8 Fibonacci); skip for Epic / Spike.
|
|
233
234
|
- **ProjectMilestone**: when the team uses dated milestones, set the milestone on the Project (Epic) or on the Issue (when an Issue belongs to a milestone).
|
|
@@ -238,11 +239,11 @@ For Bug / Task / Sub-task, ensure the summary is prefixed with `[<repo-name>]`.
|
|
|
238
239
|
|
|
239
240
|
### Build-ready control input (`build_ready`)
|
|
240
241
|
|
|
241
|
-
`build_ready` is an optional write-control input (default: **omitted**). It governs whether a **leaf** work unit
|
|
242
|
+
`build_ready` is an optional write-control input (default: **omitted**). It governs whether a **leaf** work unit is created **in the resolved `ready` workflow state**. It never overrides `leaf-only-lifecycle` — a container is never stamped build-ready regardless of `build_ready`. "Not build-ready" is not a special state: the Issue is simply left in the team's default backlog/unstarted state, which a human can promote later. This mirrors `lisa-jira-write-ticket`, because Linear is a state-driven tracker like JIRA, not a label-driven one like GitHub.
|
|
242
243
|
|
|
243
|
-
- **Omitted** → current behavior: a leaf work unit
|
|
244
|
-
- **`build_ready: false`** → create the leaf **without** the `
|
|
245
|
-
- **`build_ready: true`** →
|
|
244
|
+
- **Omitted** → current behavior: a leaf work unit is created in the resolved `ready` state. Preserves what every existing caller (`lisa-plan`, the `*-to-tracker` skills) relies on.
|
|
245
|
+
- **`build_ready: false`** → create the leaf **without** the `ready` state, leaving it in the team's default backlog state so it waits for a human to review and promote it into the queue.
|
|
246
|
+
- **`build_ready: true`** → transition the **leaf** to the resolved `ready` state (`.linear.workflow.ready`) so `lisa-intake` / `lisa-linear-build-intake` auto-picks it up. Best-effort: if the state cannot be resolved or the transition is rejected, do not fail the write — leave the Issue in its default state and record the reason.
|
|
246
247
|
|
|
247
248
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
248
249
|
|
|
@@ -268,7 +269,7 @@ If the validator reports `PASS`, continue to Phase 6.
|
|
|
268
269
|
|
|
269
270
|
### CREATE — Story / Task / Bug / Spike / Improvement (Issue with projectId)
|
|
270
271
|
|
|
271
|
-
1. Resolve any required Issue labels (`component:<name>`, `prd-intake-feedback` only if this is a sentinel issue
|
|
272
|
+
1. Resolve any required Issue labels (`type:<Kind>`, `repo:<name>`, `component:<name>`, `prd-intake-feedback` only if this is a sentinel issue) via `lisa-linear-access operation: list-issue-labels` (create via `lisa-linear-access operation: create-issue-label` if missing). Separately resolve the `ready` **state** id via `lisa-linear-access operation: list-workflow-states`, and set it as `stateId` only for a **leaf** work unit and only when `build_ready` is not `false` — omit it for a container, and for a `build_ready: false` leaf which then waits in the default backlog state for a human to promote it.
|
|
272
273
|
2. Call `lisa-linear-access operation: save-issue` with: `team` (teamId), `title` (summary), `description` (markdown), `projectId` (the Epic Project), `priority` (0–4), `estimate`, `labelIds`, `assignee` if known.
|
|
273
274
|
3. Capture the returned identifier (e.g. `ENG-123`) — Phase 4 sub-tasks need it as `parentId`.
|
|
274
275
|
4. Add relationships from Phase 4b via `save_issue` (relations field) or paired relation calls.
|
|
@@ -280,7 +280,7 @@ For each PRD epic, **invoke the `lisa-tracker-write` skill** (do not call `creat
|
|
|
280
280
|
- `artifacts`: the full Phase 1.5 artifact list — every artifact, regardless of domain. The epic is the canonical hub, and anyone working on the epic or its descendants must be able to reach the full set from one place. No filtering at the epic level. `lisa-tracker-write` Phase 4c attaches them as remote links.
|
|
281
281
|
- `priority`, `labels`, `components`, `fix_version`: as appropriate
|
|
282
282
|
|
|
283
|
-
**Leaf-only build-ready (`leaf-only-lifecycle`)**: an Epic is a container, not a leaf work unit. Do NOT mark it build-ready — `lisa-tracker-write` must not be passed
|
|
283
|
+
**Leaf-only build-ready (`leaf-only-lifecycle`)**: an Epic is a container, not a leaf work unit. Do NOT mark it build-ready — `lisa-tracker-write` must not be passed the build-ready role for an Epic, and the Epic's lifecycle state rolls up from its children. The build-ready role is applied only in Phase 5.
|
|
284
284
|
|
|
285
285
|
Capture the returned epic key — Phase 4 needs it as the parent for stories.
|
|
286
286
|
|
|
@@ -314,7 +314,7 @@ For each story, **invoke `lisa-tracker-write`** with:
|
|
|
314
314
|
- `artifacts`: the Phase 1.5 artifacts filtered by domain per the inheritance table below — `lisa-tracker-write` Phase 4c attaches them as remote links
|
|
315
315
|
- `priority`, `labels`, `components`, `fix_version`: as appropriate
|
|
316
316
|
|
|
317
|
-
**Leaf-only build-ready (`leaf-only-lifecycle`)**: a Story is a container (it has child Sub-tasks), not a leaf work unit. Do NOT mark it build-ready — never pass
|
|
317
|
+
**Leaf-only build-ready (`leaf-only-lifecycle`)**: a Story is a container (it has child Sub-tasks), not a leaf work unit. Do NOT mark it build-ready — never pass the build-ready role to `lisa-tracker-write` for a Story. Its lifecycle state rolls up from its Sub-tasks. The build-ready role is applied only in Phase 5.
|
|
318
318
|
|
|
319
319
|
Capture each returned story key — Phase 5 needs it as the parent for sub-tasks.
|
|
320
320
|
|
|
@@ -342,7 +342,7 @@ Each sub-task MUST:
|
|
|
342
342
|
2. **Include an Empirical Verification Plan** — real user-like verification, NOT unit tests, linting, or typechecking
|
|
343
343
|
3. **Carry its own `## Source Requirement` section** (shared format above) with the full verbatim quote(s) from the Phase 1.4 register — a leaf claimed by build-intake in isolation must be self-explanatory. When a sub-task is split per-repo, every split child inherits the same requirement quote(s).
|
|
344
344
|
|
|
345
|
-
**Leaf-only build-ready (`leaf-only-lifecycle`)**: Sub-tasks are the **leaf work units** of the decomposition — they are the ONLY items in the hierarchy that receive the build-ready
|
|
345
|
+
**Leaf-only build-ready (`leaf-only-lifecycle`)**: Sub-tasks are the **leaf work units** of the decomposition — they are the ONLY items in the hierarchy that receive the build-ready role. `lisa-tracker-write` applies the build-ready role here so downstream build intake (`lisa-tracker-build-intake`) claims the leaves and never the Epic or Stories. Apply the build-ready role to each Sub-task; never to its parent Story or Epic (Phases 3–4). `lisa-tracker-write` enforces the same invariant on the write side, so a Sub-task split into per-repo children (the cross-repo case above) carries build-ready on the children, not on any intermediate parent that gains child work.
|
|
346
346
|
|
|
347
347
|
**Verification plan examples by stack:**
|
|
348
348
|
- **Backend APIs**: curl GraphQL/REST calls with auth token, database queries, checking audit entries
|
|
@@ -178,7 +178,7 @@ rule — never hardcode status/label strings. The relevant repair roles:
|
|
|
178
178
|
|-----------|--------|----------------------|------------------|----------------------------|
|
|
179
179
|
| Build | JIRA | `jira.workflow.claimed` (`In Progress`) | `jira.workflow.blocked` (`Blocked`) | env-resolved `jira.workflow.done` |
|
|
180
180
|
| Build | GitHub | `github.labels.build.claimed` (`status:in-progress`) | `github.labels.build.blocked` (`status:blocked`) | env-resolved `github.labels.build.done` (`status:done`) |
|
|
181
|
-
| Build | Linear | `linear.
|
|
181
|
+
| Build | Linear | `linear.workflow.claimed` (`In Progress`) | `linear.workflow.blocked` (`Blocked`) | env-resolved `linear.workflow.done` (`Done`) |
|
|
182
182
|
| PRD | Notion | `notion.values.in_review` (`In Review`) | `notion.values.blocked` (`Blocked`) | `notion.values.shipped` (`Shipped`) |
|
|
183
183
|
| PRD | GitHub | `github.labels.prd.in_review` (`prd-in-review`) | `github.labels.prd.blocked` (`prd-blocked`) | `github.labels.prd.shipped` (`prd-shipped`) |
|
|
184
184
|
| PRD | Linear | `linear.labels.prd.in_review` (`prd-in-review`) | `linear.labels.prd.blocked` (`prd-blocked`) | `linear.labels.prd.shipped` (`prd-shipped`) |
|
|
@@ -152,19 +152,41 @@ read_role() { # $1=namespace (build|prd) $2=role $3=default
|
|
|
152
152
|
}
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
-
#### 3a. Build-queue
|
|
155
|
+
#### 3a. Build-queue lifecycle — WORKFLOW STATES (only if Linear is the tracker)
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
The build lane resolves to native workflow **states**, not labels — see "Why Linear uses states, not labels" in `config-resolution`. Read role → state name with the same ladder, against `linear.workflow`:
|
|
158
158
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
159
|
+
```bash
|
|
160
|
+
read_state() { # $1=role path (e.g. ready, done.dev) $2=default
|
|
161
|
+
local role="$1" default="$2" local_v global_v
|
|
162
|
+
local_v=$(jq -r ".linear.workflow.${role} // empty" .lisa.config.local.json 2>/dev/null)
|
|
163
|
+
global_v=$(jq -r ".linear.workflow.${role} // empty" .lisa.config.json 2>/dev/null)
|
|
164
|
+
echo "${local_v:-${global_v:-$default}}"
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Enumerate the team's states with `lisa-linear-access operation: list-workflow-states` (each carries `id`, `name`, `type`, `position`). For each role, resolve in this order — the same cascade `lisa-setup-jira` uses, with one extra rung Linear affords that JIRA does not:
|
|
169
|
+
|
|
170
|
+
1. **Exact name match** → resolved, nothing to do.
|
|
171
|
+
2. **A plausible existing state of the right `type`** (`ready` → `unstarted`, `claimed`/`review` → `started`, `blocked` → `started` or `unstarted`, terminal `done` → `completed`) → present the team's state list via `AskUserQuestion` and let the user pick which state means this role. Record the choice as a config override in Step 4.
|
|
172
|
+
3. **Nothing plausible** → offer to **create** the state via `lisa-linear-access operation: create-workflow-state` (name, `type`, `position`, colour), showing the exact name and type first. Linear's API permits this where JIRA's workflow editing is admin-gated — which is why this rung exists here and not there.
|
|
173
|
+
4. **User declines creation** → stop and say which role is unresolvable and that the lifecycle cannot run without it. Never silently fall back to a state whose meaning differs, and never invent a name in config that does not exist in the team.
|
|
174
|
+
|
|
175
|
+
| Role | Default state | `type` | Ships with a stock team? |
|
|
176
|
+
|------|---------------|--------|--------------------------|
|
|
177
|
+
| `ready` | `Todo` | `unstarted` | yes |
|
|
178
|
+
| `claimed` | `In Progress` | `started` | yes |
|
|
179
|
+
| `review` | `In Review` | `started` | yes |
|
|
180
|
+
| `blocked` | `Blocked` | `unstarted` | **no — must be created or mapped** |
|
|
181
|
+
| `done.dev` | `On Dev` | `started` | **no — must be created or mapped** |
|
|
182
|
+
| `done.staging` | `On Stg` | `started` | **no — must be created or mapped** |
|
|
183
|
+
| `done.production` | `Done` | `completed` | yes |
|
|
184
|
+
|
|
185
|
+
**The env rungs are deliberately `started`, not `completed`.** `On Dev` and `On Stg` mean "merged and deployed *that far*" — work that is emphatically not finished. Typing them `completed` would make Linear treat them as closed: they would leave the active board, stop counting in cycles, and re-create the exact premature-closure problem this model exists to fix. Only `done.production` is `completed`.
|
|
186
|
+
|
|
187
|
+
**Position them between `In Review` and `Done`** so the board reads left-to-right in real lifecycle order. A team that orders its board differently can pass its own `position`.
|
|
188
|
+
|
|
189
|
+
**Turn off the team's `merge → Done` git automation.** Linear's per-team git automations (Settings → Team → Workflow, or the `gitAutomationStates` API) auto-complete an Issue on merge to **any** branch. With this model that automation is an unwanted second writer: it jumps an Issue straight to `Done` at a `dev` merge, skipping `On Dev` / `On Stg` and asserting production-done. Lisa itself moves the state at each rung, so the automation is redundant as well as wrong. Detect it and offer to delete it; leave `start` and `review` alone — those assert non-terminal states and are harmless.
|
|
168
190
|
|
|
169
191
|
#### 3b. PRD-lifecycle labels — PROJECT labels (only if Linear is the PRD source)
|
|
170
192
|
|
|
@@ -205,14 +227,39 @@ if [ -n "$TEAM_KEY" ]; then
|
|
|
205
227
|
.lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
|
|
206
228
|
fi
|
|
207
229
|
|
|
208
|
-
# Conditionally write label overrides (only
|
|
230
|
+
# Conditionally write label overrides (markers + PRD lane only — the build lane
|
|
231
|
+
# is states now, and lives under .linear.workflow below).
|
|
209
232
|
if [ -n "$LABEL_OVERRIDES_JSON" ] && [ "$LABEL_OVERRIDES_JSON" != "{}" ]; then
|
|
210
233
|
jq --argjson o "$LABEL_OVERRIDES_JSON" \
|
|
211
234
|
'.linear.labels = ((.linear.labels // {}) * $o)' \
|
|
212
235
|
.lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
|
|
213
236
|
fi
|
|
237
|
+
|
|
238
|
+
# Workflow-state overrides: only roles whose resolved state name differs from
|
|
239
|
+
# the default, INCLUDING any the user mapped onto an existing state in 3a.
|
|
240
|
+
if [ -n "$WORKFLOW_OVERRIDES_JSON" ] && [ "$WORKFLOW_OVERRIDES_JSON" != "{}" ]; then
|
|
241
|
+
jq --argjson w "$WORKFLOW_OVERRIDES_JSON" \
|
|
242
|
+
'.linear.workflow = ((.linear.workflow // {}) * $w)' \
|
|
243
|
+
.lisa.config.json > .lisa.config.json.tmp && mv .lisa.config.json.tmp .lisa.config.json
|
|
244
|
+
fi
|
|
214
245
|
```
|
|
215
246
|
|
|
247
|
+
**Migrating a project that predates the state model.** A config carrying
|
|
248
|
+
`linear.labels.build.{ready,claimed,review,blocked,done}` was written against the
|
|
249
|
+
old label-driven lane. Those keys are inert now — nothing reads them — but
|
|
250
|
+
leaving them in place reads as configuration and will mislead the next person.
|
|
251
|
+
Migrate in one pass, and do it before the first intake cycle runs, or that cycle
|
|
252
|
+
sees an empty queue:
|
|
253
|
+
|
|
254
|
+
1. Resolve each build role to a state per 3a, writing `linear.workflow`.
|
|
255
|
+
2. **Backfill live Issues**: for every Issue carrying a `status:*` label, set its
|
|
256
|
+
workflow state to the role that label encoded. Do this before deleting
|
|
257
|
+
anything — the labels are the only record of where each Issue sits.
|
|
258
|
+
3. Drop `build.{ready,claimed,review,blocked,done}` from `linear.labels`, keeping
|
|
259
|
+
`build.human_needed` and the whole `prd` map.
|
|
260
|
+
4. Leave the `status:*` labels themselves in the workspace, unapplied, until the
|
|
261
|
+
first intake cycle after the migration has run green. They are the rollback.
|
|
262
|
+
|
|
216
263
|
No secrets in config — the API key stays in keychain / `LINEAR_API_KEY`, the MCP session in its own store.
|
|
217
264
|
|
|
218
265
|
### Step 5 — Offer to set top-level `tracker` / `source`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lisa-tracker-build-intake
|
|
3
|
-
description: "Vendor-neutral wrapper for the build-queue scanner. Reads the required `tracker` from .lisa.config.json and dispatches to lisa-jira-build-intake (JQL/project-key queue), lisa-github-build-intake (GitHub repo queue keyed off the `status:ready` label), or lisa-linear-build-intake (Linear team queue keyed off the `
|
|
3
|
+
description: "Vendor-neutral wrapper for the build-queue scanner. Reads the required `tracker` from .lisa.config.json and dispatches to lisa-jira-build-intake (JQL/project-key queue), lisa-github-build-intake (GitHub repo queue keyed off the `status:ready` label), or lisa-linear-build-intake (Linear team queue keyed off the configured `ready` workflow state). Every vendor scanner processes at most one eligible item per cycle and enforces the claim-time arm of the `leaf-only-lifecycle` rule — dispatch leaf work units only; move or safe-block a container with open child work (or a childless Epic) that carries a stale build-ready role according to the vendor's lifecycle semantics. Counterpart to lisa-intake's PRD-side dispatchers."
|
|
4
4
|
allowed-tools: ["Skill", "Bash", "Read"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -21,7 +21,7 @@ See the `config-resolution` rule for configuration and dispatch table.
|
|
|
21
21
|
- Anything else → stop and report `"Unknown tracker '<value>' in .lisa.config.json. Expected 'jira', 'github', or 'linear'."`
|
|
22
22
|
3. Pass through the output.
|
|
23
23
|
|
|
24
|
-
`$ARGUMENTS` is forwarded verbatim, including the optional `--rollup` flag (see "Parent status rollup" below), `--update-label
|
|
24
|
+
`$ARGUMENTS` is forwarded verbatim, including the optional `--rollup` flag (see "Parent status rollup" below), the vendor lane-write flag (`--update-label` on GitHub, `--update-state` on Linear), `pr_url=<url>`, and `merge_sha=<sha>`. The shim never interprets these — the vendor skill does.
|
|
25
25
|
|
|
26
26
|
If `$ARGUMENTS` is empty, all vendor skills auto-detect a ticket reference from the active plan file (most recently modified `.md` in `plans/`).
|
|
27
27
|
|
|
@@ -60,6 +60,6 @@ This is the reverse half of `lisa-git-submit-pr`'s PR body linkage. A PR that me
|
|
|
60
60
|
## Rules
|
|
61
61
|
|
|
62
62
|
- Idempotent updates — running sync at the same milestone twice should not produce duplicate comments. Vendor skills enforce this.
|
|
63
|
-
- Never auto-transition the
|
|
63
|
+
- Never auto-transition a lane the caller did not ask for. On GitHub the canonical signal is the `status:*` label, written only with `--update-label`; on Linear it is the native workflow state, written only with `--update-state`. Without the flag, every vendor arm only suggests.
|
|
64
64
|
- Parent rollup derives state from children per the `leaf-only-lifecycle` rule; it never sets a parent to `ready` and never resolves a dev/staging `done` in this single-environment repo.
|
|
65
65
|
- Pull request backlinks are mandatory when `pr_url=<url>` is present: native first, managed-comment fallback, never silently dropped.
|