@codyswann/lisa 2.352.0 → 3.0.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 +70 -43
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/expo/copy-overwrite/scripts/bdd/discover.mjs +502 -0
- package/expo/copy-overwrite/scripts/bdd/envelope.mjs +10 -1
- package/expo/copy-overwrite/scripts/bdd/render.mjs +53 -0
- package/expo/copy-overwrite/scripts/bdd/report.mjs +46 -0
- package/expo/copy-overwrite/scripts/check-bdd-coverage.mjs +39 -4
- package/expo/create-only/.github/workflows/maestro-e2e.yml +10 -1
- package/expo/create-only/.github/workflows/nightly-e2e-health.yml +5 -0
- package/expo/create-only/bdd/coverage-map.json +16 -0
- 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-agent-ready/SKILL.md +5 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-confluence-to-tracker/SKILL.md +2 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-debrief-apply/SKILL.md +2 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-exploratory-qa/SKILL.md +7 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +5 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-github-create/SKILL.md +3 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-to-tracker/SKILL.md +2 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +7 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +16 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-improve-harness/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +5 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-create/SKILL.md +2 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +12 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-learnings-audit/SKILL.md +6 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +34 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +5 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-create/SKILL.md +3 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +2 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +13 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-notion-to-tracker/SKILL.md +2 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-prd-source-write/SKILL.md +4 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-fail/SKILL.md +3 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +28 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +2 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-build-intake/SKILL.md +1 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-create/SKILL.md +1 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-write/SKILL.md +1 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-validate-tracker-mapping/SKILL.md +33 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-verify/SKILL.md +1 -1
- package/plugins/lisa/rules/eager/bdd-e2e-coverage.md +3 -1
- package/plugins/lisa/rules/eager/claim-time-guards.md +30 -0
- package/plugins/lisa/rules/eager/ready-role-filing.md +22 -0
- package/plugins/lisa/rules/reference/automation-runbook-contract.md +8 -1
- package/plugins/lisa/rules/reference/bdd-e2e-coverage.md +42 -6
- package/plugins/lisa/rules/reference/claim-time-guards.md +69 -0
- package/plugins/lisa/rules/reference/config-resolution.md +7 -0
- package/plugins/lisa/rules/reference/ready-role-filing.md +66 -0
- package/plugins/lisa/scripts/queue-contract-resolution.mjs +50 -1
- package/plugins/lisa/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/lisa/skills/lisa-confluence-to-tracker/SKILL.md +2 -1
- package/plugins/lisa/skills/lisa-debrief-apply/SKILL.md +2 -2
- package/plugins/lisa/skills/lisa-exploratory-qa/SKILL.md +7 -1
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +5 -0
- package/plugins/lisa/skills/lisa-github-create/SKILL.md +3 -1
- package/plugins/lisa/skills/lisa-github-to-tracker/SKILL.md +2 -1
- package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +7 -3
- package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +16 -6
- package/plugins/lisa/skills/lisa-improve-harness/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +5 -0
- package/plugins/lisa/skills/lisa-jira-create/SKILL.md +2 -0
- package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +12 -2
- package/plugins/lisa/skills/lisa-learnings-audit/SKILL.md +6 -1
- package/plugins/lisa/skills/lisa-linear-access/SKILL.md +34 -0
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +5 -0
- package/plugins/lisa/skills/lisa-linear-create/SKILL.md +3 -1
- package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +2 -1
- package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +13 -4
- package/plugins/lisa/skills/lisa-notion-to-tracker/SKILL.md +2 -1
- package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-prd-source-write/SKILL.md +4 -2
- package/plugins/lisa/skills/lisa-qa-fail/SKILL.md +3 -1
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +28 -0
- package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +2 -2
- package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +1 -0
- package/plugins/lisa/skills/lisa-tracker-create/SKILL.md +1 -0
- package/plugins/lisa/skills/lisa-tracker-write/SKILL.md +1 -0
- package/plugins/lisa/skills/lisa-validate-tracker-mapping/SKILL.md +33 -4
- package/plugins/lisa/skills/lisa-verify/SKILL.md +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/scripts/queue-contract-resolution.mjs +50 -1
- package/plugins/lisa-agy/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/lisa-agy/skills/lisa-confluence-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-agy/skills/lisa-debrief-apply/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/lisa-exploratory-qa/SKILL.md +7 -1
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +5 -0
- package/plugins/lisa-agy/skills/lisa-github-create/SKILL.md +3 -1
- package/plugins/lisa-agy/skills/lisa-github-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +7 -3
- package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +16 -6
- package/plugins/lisa-agy/skills/lisa-improve-harness/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +5 -0
- package/plugins/lisa-agy/skills/lisa-jira-create/SKILL.md +2 -0
- package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +12 -2
- package/plugins/lisa-agy/skills/lisa-learnings-audit/SKILL.md +6 -1
- package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +34 -0
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +5 -0
- package/plugins/lisa-agy/skills/lisa-linear-create/SKILL.md +3 -1
- package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +13 -4
- package/plugins/lisa-agy/skills/lisa-notion-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-prd-source-write/SKILL.md +4 -2
- package/plugins/lisa-agy/skills/lisa-qa-fail/SKILL.md +3 -1
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +28 -0
- package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +1 -0
- package/plugins/lisa-agy/skills/lisa-tracker-create/SKILL.md +1 -0
- package/plugins/lisa-agy/skills/lisa-tracker-write/SKILL.md +1 -0
- package/plugins/lisa-agy/skills/lisa-validate-tracker-mapping/SKILL.md +33 -4
- package/plugins/lisa-agy/skills/lisa-verify/SKILL.md +1 -1
- 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/rules/eager/bdd-e2e-coverage.md +3 -1
- package/plugins/lisa-copilot/rules/eager/claim-time-guards.md +30 -0
- package/plugins/lisa-copilot/rules/eager/ready-role-filing.md +22 -0
- package/plugins/lisa-copilot/rules/reference/automation-runbook-contract.md +8 -1
- package/plugins/lisa-copilot/rules/reference/bdd-e2e-coverage.md +42 -6
- package/plugins/lisa-copilot/rules/reference/claim-time-guards.md +69 -0
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +7 -0
- package/plugins/lisa-copilot/rules/reference/ready-role-filing.md +66 -0
- package/plugins/lisa-copilot/scripts/queue-contract-resolution.mjs +50 -1
- package/plugins/lisa-copilot/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/lisa-copilot/skills/lisa-confluence-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-copilot/skills/lisa-debrief-apply/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-exploratory-qa/SKILL.md +7 -1
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +5 -0
- package/plugins/lisa-copilot/skills/lisa-github-create/SKILL.md +3 -1
- package/plugins/lisa-copilot/skills/lisa-github-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +7 -3
- package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +16 -6
- package/plugins/lisa-copilot/skills/lisa-improve-harness/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +5 -0
- package/plugins/lisa-copilot/skills/lisa-jira-create/SKILL.md +2 -0
- package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +12 -2
- package/plugins/lisa-copilot/skills/lisa-learnings-audit/SKILL.md +6 -1
- package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +34 -0
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +5 -0
- package/plugins/lisa-copilot/skills/lisa-linear-create/SKILL.md +3 -1
- package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +13 -4
- package/plugins/lisa-copilot/skills/lisa-notion-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-prd-source-write/SKILL.md +4 -2
- package/plugins/lisa-copilot/skills/lisa-qa-fail/SKILL.md +3 -1
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +28 -0
- package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +1 -0
- package/plugins/lisa-copilot/skills/lisa-tracker-create/SKILL.md +1 -0
- package/plugins/lisa-copilot/skills/lisa-tracker-write/SKILL.md +1 -0
- package/plugins/lisa-copilot/skills/lisa-validate-tracker-mapping/SKILL.md +33 -4
- package/plugins/lisa-copilot/skills/lisa-verify/SKILL.md +1 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/rules/automation-runbook-contract-reference.mdc +8 -1
- package/plugins/lisa-cursor/rules/bdd-e2e-coverage-reference.mdc +42 -6
- package/plugins/lisa-cursor/rules/bdd-e2e-coverage.mdc +3 -1
- package/plugins/lisa-cursor/rules/claim-time-guards-reference.mdc +74 -0
- package/plugins/lisa-cursor/rules/claim-time-guards.mdc +35 -0
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +7 -0
- package/plugins/lisa-cursor/rules/ready-role-filing-reference.mdc +71 -0
- package/plugins/lisa-cursor/rules/ready-role-filing.mdc +27 -0
- package/plugins/lisa-cursor/scripts/queue-contract-resolution.mjs +50 -1
- package/plugins/lisa-cursor/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/lisa-cursor/skills/lisa-confluence-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-cursor/skills/lisa-debrief-apply/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/lisa-exploratory-qa/SKILL.md +7 -1
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +5 -0
- package/plugins/lisa-cursor/skills/lisa-github-create/SKILL.md +3 -1
- package/plugins/lisa-cursor/skills/lisa-github-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +7 -3
- package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +16 -6
- package/plugins/lisa-cursor/skills/lisa-improve-harness/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +5 -0
- package/plugins/lisa-cursor/skills/lisa-jira-create/SKILL.md +2 -0
- package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +12 -2
- package/plugins/lisa-cursor/skills/lisa-learnings-audit/SKILL.md +6 -1
- package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +34 -0
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +5 -0
- package/plugins/lisa-cursor/skills/lisa-linear-create/SKILL.md +3 -1
- package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +13 -4
- package/plugins/lisa-cursor/skills/lisa-notion-to-tracker/SKILL.md +2 -1
- package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-prd-source-write/SKILL.md +4 -2
- package/plugins/lisa-cursor/skills/lisa-qa-fail/SKILL.md +3 -1
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +28 -0
- package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +1 -0
- package/plugins/lisa-cursor/skills/lisa-tracker-create/SKILL.md +1 -0
- package/plugins/lisa-cursor/skills/lisa-tracker-write/SKILL.md +1 -0
- package/plugins/lisa-cursor/skills/lisa-validate-tracker-mapping/SKILL.md +33 -4
- package/plugins/lisa-cursor/skills/lisa-verify/SKILL.md +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-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/rules/eager/bdd-e2e-coverage.md +3 -1
- package/plugins/src/base/rules/eager/claim-time-guards.md +30 -0
- package/plugins/src/base/rules/eager/ready-role-filing.md +22 -0
- package/plugins/src/base/rules/reference/automation-runbook-contract.md +8 -1
- package/plugins/src/base/rules/reference/bdd-e2e-coverage.md +42 -6
- package/plugins/src/base/rules/reference/claim-time-guards.md +69 -0
- package/plugins/src/base/rules/reference/config-resolution.md +7 -0
- package/plugins/src/base/rules/reference/ready-role-filing.md +66 -0
- package/plugins/src/base/scripts/queue-contract-resolution.mjs +50 -1
- package/plugins/src/base/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/src/base/skills/lisa-confluence-to-tracker/SKILL.md +2 -1
- package/plugins/src/base/skills/lisa-debrief-apply/SKILL.md +2 -2
- package/plugins/src/base/skills/lisa-exploratory-qa/SKILL.md +7 -1
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +5 -0
- package/plugins/src/base/skills/lisa-github-create/SKILL.md +3 -1
- package/plugins/src/base/skills/lisa-github-to-tracker/SKILL.md +2 -1
- package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +7 -3
- package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +16 -6
- package/plugins/src/base/skills/lisa-improve-harness/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +5 -0
- package/plugins/src/base/skills/lisa-jira-create/SKILL.md +2 -0
- package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +12 -2
- package/plugins/src/base/skills/lisa-learnings-audit/SKILL.md +6 -1
- package/plugins/src/base/skills/lisa-linear-access/SKILL.md +34 -0
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +5 -0
- package/plugins/src/base/skills/lisa-linear-create/SKILL.md +3 -1
- package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +2 -1
- package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +13 -4
- package/plugins/src/base/skills/lisa-notion-to-tracker/SKILL.md +2 -1
- package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-prd-source-write/SKILL.md +4 -2
- package/plugins/src/base/skills/lisa-qa-fail/SKILL.md +3 -1
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +28 -0
- package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +2 -2
- package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +1 -0
- package/plugins/src/base/skills/lisa-tracker-create/SKILL.md +1 -0
- package/plugins/src/base/skills/lisa-tracker-write/SKILL.md +1 -0
- package/plugins/src/base/skills/lisa-validate-tracker-mapping/SKILL.md +33 -4
- package/plugins/src/base/skills/lisa-verify/SKILL.md +1 -1
- package/typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs +76 -10
|
@@ -15,7 +15,7 @@ Default locations (a project that already has an equivalent contract keeps its o
|
|
|
15
15
|
| Artifact | Default path | What it is |
|
|
16
16
|
|---|---|---|
|
|
17
17
|
| Scenarios | `bdd/features/*.feature` | Gherkin, the product-level behavior contract |
|
|
18
|
-
| Coverage map | `bdd/coverage-map.json` | scenario → runner/platform/file/evidence mappings, plus waivers |
|
|
18
|
+
| Coverage map | `bdd/coverage-map.json` | scenario → runner/platform/file/evidence mappings, plus waivers, per-runner test-discovery roots, and exclusions |
|
|
19
19
|
| Generated matrix | `docs/bdd-scenario-matrix.md` | regenerated, never hand-edited |
|
|
20
20
|
| Burndown | `docs/e2e-bdd-coverage.md` | current coverage per platform |
|
|
21
21
|
|
|
@@ -36,6 +36,8 @@ The last three are out of the denominator. Deleting a committed capability to ma
|
|
|
36
36
|
|
|
37
37
|
Coverage is counted per **required scenario-platform obligation**, and an obligation is sealed only by **aligned e2e automation in the project's configured runner for that platform** — the runner→platform mapping is project configuration (e.g. a web runner covering `web`, a device runner covering `ios`/`android`), never named by this contract. A unit test, a route boot, a screenshot, a fixture, an API test, or a passing test on a *different* platform never seals an obligation: they prove something else. Each mapping names the runner, the platforms, the file, and the evidence string inside it, so the gate can prove the mapping still resolves.
|
|
38
38
|
|
|
39
|
+
**The gate reads in both directions.** It also walks the test roots the project declares per runner, so an e2e test that exists but that the contract never mentions is a violation — map it to a scenario, or record an exclusion stating why it aligns to no product behavior. Roots are configuration: a subflow or helper directory left undeclared is structurally invisible, which is the same failure as having no gate for it.
|
|
40
|
+
|
|
39
41
|
**Waivers are dated IOUs, never coverage.** An obligation whose runner genuinely cannot decide it today (no camera on the simulator, no request interception, no provisioned provider credential) is recorded with scenario, platforms, reason, and `recordedAt`. It leaves the denominator; it never counts as covered, and nothing about it asserts the behavior works. A waiver is invalid — and fails the gate — when it names a nonexistent scenario or an undeclared platform, covers an already-excluded scenario, or masks a scenario-platform that already has a mapping. Revisit a waiver when its reason dies.
|
|
40
42
|
|
|
41
43
|
## Definition of done
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Claim-Time Guards (load-bearing)
|
|
2
|
+
|
|
3
|
+
Two guards that run when build-intake claims a ready item, both from failures observed in the fleet: an item built twice because it had already shipped, and a loop burning cycles re-attempting an item that was never going to succeed.
|
|
4
|
+
|
|
5
|
+
**One vendor-neutral contract, cited by every build-intake arm** (the `leaf-only-lifecycle` / `repo-scope-split` / `rejection-detection` / `claim-archaeology` precedent: one shared slug, never three divergent implementations).
|
|
6
|
+
|
|
7
|
+
## When they run
|
|
8
|
+
|
|
9
|
+
Inside build-intake step `3b`, after `rejection-detection` and `claim-archaeology`, still before the `$READY → $CLAIMED` transition. The `two-failed-attempts` valve runs first — it is cheaper and it is the only pass that can stop the claim outright.
|
|
10
|
+
|
|
11
|
+
## `already-implemented` → `verify-and-close`
|
|
12
|
+
|
|
13
|
+
A ready item may already be implemented, because agents ship without transitioning. Before implementing, probe for the item's **own** key:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
git log --all --grep "<key>" --format='%H %aI %s' -n 10
|
|
17
|
+
gh pr list --repo <org>/<repo> --state all --search "<key>" --json number,state,mergedAt,url
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
On a hit, do not build it twice — switch `3c` to **verify-and-close**: verify what shipped against this item's acceptance criteria, post evidence naming the shipping PR/commit, then run the ordinary `3d` transition and rollup. If the shipped change only partially satisfies the criteria, implement the remaining gap instead of closing.
|
|
21
|
+
|
|
22
|
+
Distinct from `claim-archaeology` (finds a **different** ancestor issue) and from `DUPLICATE_ALREADY_FIXED` (a **different** canonical issue). Unreadable history degrades to "no hit"; the guard never blocks the claim.
|
|
23
|
+
|
|
24
|
+
## `two-failed-attempts` → blocked
|
|
25
|
+
|
|
26
|
+
Every non-success terminal outcome records a durable marker on the item — a visible line plus `<!-- [lisa-build-attempt] n=<N> outcome=<outcome> -->` (match on the marker, never the title). A cron holds no memory between cycles, so the item carries the count.
|
|
27
|
+
|
|
28
|
+
With **two or more** markers at claim time: do not claim. Move the item to the configured `blocked` role (resolved per `config-resolution`, never hardcoded), post an operator-readable comment naming both attempts and what a human must decide or supply, and **stop the loop** for this cycle. Recovery is deliberate — a human or a `lisa-repair-intake` cycle with the blocker provably cleared returns it to the queue.
|
|
29
|
+
|
|
30
|
+
Full contract (probe bounds, verify-and-close steps, partial-hit handling, marker mechanics): [reference/claim-time-guards.md](../reference/claim-time-guards.md).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Ready-Role Filing (load-bearing)
|
|
2
|
+
|
|
3
|
+
Filing a work item without the ready role is an **incomplete handoff** — build-intake scans the ready lane and nothing else, so the item is never picked up. A correct write plus a missing role still loses the work.
|
|
4
|
+
|
|
5
|
+
## Omitted means NOT ready — on every tracker
|
|
6
|
+
|
|
7
|
+
**An omitted `build_ready` is NOT build-ready on JIRA, GitHub, and Linear alike.** Ready is an explicit claim, never an accident of which tracker a project configured. This is a **breaking change** for GitHub and Linear callers, which previously treated omission as ready; `lisa-github-validate-issue` F4's compensating omitted → `true` normalization is removed with it.
|
|
8
|
+
|
|
9
|
+
## Every filing declares one of two things
|
|
10
|
+
|
|
11
|
+
- **`build_ready: true`** — complete enough to build; enters the ready lane for auto-pickup. Required for any complete defect found during other work, so it is claimable next cycle with no human flipping status.
|
|
12
|
+
- **`human_gate: "<why a human must judge this first>"`** — deliberately held outside the queue. The writer stamps a visible line plus `<!-- [lisa-human-gate] reason=<short-slug> -->` so the hold is auditable.
|
|
13
|
+
|
|
14
|
+
Filed, not ready, and no `human_gate` is the **incomplete handoff** case — writers reject it and name both ways to resolve it. `build_ready: false` with no reason is the same omission with a value attached. `build_ready` stays subordinate to `leaf-only-lifecycle`: a container is never build-ready and needs no gate.
|
|
15
|
+
|
|
16
|
+
## The named exception
|
|
17
|
+
|
|
18
|
+
`lisa-exploratory-qa` files findings not-ready **by design** — its findings are candidate defects whose product significance a human should judge. It is the named human-gate exception, not drift: it pairs `ready=false` with an explicit `human_gate` reason. The sibling `e2e-coverage-gaps` skills are the contrast (a missing test is not a product question, so they file build-ready).
|
|
19
|
+
|
|
20
|
+
`lisa-repair-intake` sweeps for open items that are neither in the ready role nor marked `[lisa-human-gate]`, and surfaces them rather than promoting them.
|
|
21
|
+
|
|
22
|
+
Full contract (the per-vendor before/after table, marker format, and recovery sweep): [reference/ready-role-filing.md](../reference/ready-role-filing.md).
|
|
@@ -159,7 +159,14 @@ fleet verdict.
|
|
|
159
159
|
|
|
160
160
|
A loop that cannot proceed escalates by filing a tracker item (through `lisa-tracker-write`, per
|
|
161
161
|
`tracked-work` and `integration-access-layer`) labeled **`status:blocked`** and **`human-needed`**,
|
|
162
|
-
containing exactly these fields
|
|
162
|
+
containing exactly these fields.
|
|
163
|
+
|
|
164
|
+
Every escalation is a **declared human gate** under `ready-role-filing`: it passes
|
|
165
|
+
`human_gate: "<the smallest unresolved choice>"` so the writer stamps the auditable
|
|
166
|
+
`[lisa-human-gate]` marker. An escalation is precisely a filing whose readiness a human owns, so
|
|
167
|
+
omitting the flag and relying on a tracker default would make a deliberate gate indistinguishable
|
|
168
|
+
from the accidental non-ready filing that rule exists to catch.
|
|
169
|
+
|
|
163
170
|
|
|
164
171
|
| Field | Content |
|
|
165
172
|
|---|---|
|
|
@@ -68,16 +68,43 @@ platforms it requires and that each named platform has a configured runner.
|
|
|
68
68
|
"level": "behavioral"
|
|
69
69
|
}
|
|
70
70
|
],
|
|
71
|
+
"testDiscovery": {
|
|
72
|
+
"<runner>": {
|
|
73
|
+
"roots": ["<repo-relative directory>", "..."],
|
|
74
|
+
"extensions": [".<suffix>", "..."],
|
|
75
|
+
"ignore": ["<optional repo-relative path prefix>"],
|
|
76
|
+
"evidence": { "kind": "call-title", "functions": ["test", "it"] }
|
|
77
|
+
}
|
|
78
|
+
},
|
|
71
79
|
"exclusions": [
|
|
72
|
-
{
|
|
80
|
+
{
|
|
81
|
+
"file": "<path>",
|
|
82
|
+
"evidence": "<optional exact title; omit to excuse the whole file>",
|
|
83
|
+
"reason": "why this test aligns to no product behavior"
|
|
84
|
+
}
|
|
73
85
|
]
|
|
74
86
|
}
|
|
75
87
|
```
|
|
76
88
|
|
|
77
89
|
`evidence` is what makes a mapping falsifiable: the gate reads the mapped file and confirms the
|
|
78
90
|
string is still there, so renaming or deleting a test breaks the map loudly instead of leaving a
|
|
79
|
-
scenario silently unguarded.
|
|
80
|
-
|
|
91
|
+
scenario silently unguarded.
|
|
92
|
+
|
|
93
|
+
`testDiscovery` closes the other direction. Validating only what the map DECLARES can never see a
|
|
94
|
+
test file nobody declared, so the gate walks the project's own roots and requires **every test it
|
|
95
|
+
finds to be named by a mapping or excused by an exclusion**. Roots and the evidence grammar are
|
|
96
|
+
per-runner configuration — list every directory, including subflow and helper directories, because
|
|
97
|
+
a directory omitted here is structurally invisible to the gate. Evidence grammars are an allowlist
|
|
98
|
+
of two (`call-title` reads `test("…")`-style declarations; `line-field` reads a leading `name:`
|
|
99
|
+
field), never a project-supplied regular expression, and a template-literal title is used verbatim
|
|
100
|
+
from the source rather than rewritten. A missing block is a defect in enforced mode
|
|
101
|
+
(`discovery-missing`); a malformed one is refused in **every** state (`discovery-invalid`), because
|
|
102
|
+
discovery that silently finds nothing looks exactly like a clean repo.
|
|
103
|
+
|
|
104
|
+
`exclusions` records tests that deliberately map to nothing — starter templates, source-level
|
|
105
|
+
corroboration — so "unmapped test" stays a meaningful signal. Each entry states a `reason`, and an
|
|
106
|
+
exclusion whose file is gone, whose title was renamed, or that no discovery root covers is
|
|
107
|
+
`exclusion-stale`: a standing claim about nothing, never a permanent excuse.
|
|
81
108
|
|
|
82
109
|
## The gate
|
|
83
110
|
|
|
@@ -94,8 +121,14 @@ Two commands, wired into the project's script surface and into CI:
|
|
|
94
121
|
- an invalid waiver (nonexistent scenario, undeclared platform, already-excluded scenario, a
|
|
95
122
|
`runner` that does not cover the waived platform under `runnerPlatforms`, or one that masks an
|
|
96
123
|
existing mapping);
|
|
124
|
+
- a discovered test named by no mapping and no exclusion, or an exclusion that no longer excuses
|
|
125
|
+
anything;
|
|
97
126
|
- a regression against the project's committed `coverageFloor` per platform.
|
|
98
127
|
|
|
128
|
+
Regeneration is never blocked by the check: `--write` rewrites the report and burndown whenever a
|
|
129
|
+
report can be built at all, so a stale evidence string can never hold hostage the paperwork that
|
|
130
|
+
documents it.
|
|
131
|
+
|
|
99
132
|
The percentage measures **aligned automation inventory, not the latest run result**. A mapped test
|
|
100
133
|
that currently fails is a red CI check, a separate signal; the map only asserts the automation
|
|
101
134
|
exists and still says what it claimed. Both facts are required — a green gate over a red suite is
|
|
@@ -157,9 +190,12 @@ A repo with no contract yet, taking its first frontend work item:
|
|
|
157
190
|
|
|
158
191
|
1. **Detect runners.** Find the e2e harnesses the project actually has, per the Tool Discovery
|
|
159
192
|
Process in `verification-lifecycle`. Record which platforms each covers.
|
|
160
|
-
2. **Scaffold the minimum** — `bdd/features/`, `bdd/coverage-map.json` (with `runnerPlatforms`
|
|
161
|
-
step 1
|
|
162
|
-
|
|
193
|
+
2. **Scaffold the minimum** — `bdd/features/`, `bdd/coverage-map.json` (with `runnerPlatforms` and
|
|
194
|
+
`testDiscovery` from step 1 — every root each runner's tests actually live in, subflow and helper
|
|
195
|
+
directories included — and a coverage floor of the current, honest number), the regenerate +
|
|
196
|
+
check scripts wired into the project's script surface, and the CI invocation of the check.
|
|
197
|
+
Pre-existing tests that align to no product behavior are recorded as `exclusions` with reasons
|
|
198
|
+
during this step, never left undisclosed.
|
|
163
199
|
3. **Write only this item's scenarios.** The first item is not a backfill project. Pre-existing
|
|
164
200
|
uncovered behavior becomes burndown in `docs/e2e-bdd-coverage.md`, and the floor starts where the
|
|
165
201
|
repo actually is.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Claim-Time Guards
|
|
2
|
+
|
|
3
|
+
Two guards that run when build-intake claims a ready item. Both come from geminisportsai's hand-rolled `sprint-loop` and both address failures actually observed there — an item built twice because it had already shipped, and a loop burning cycles re-attempting an item that was never going to succeed.
|
|
4
|
+
|
|
5
|
+
It is a **single vendor-neutral contract** consumed by all three build-intake skills (`lisa-github-build-intake`, `lisa-jira-build-intake`, `lisa-linear-build-intake`). Each arm cites this slug in its claim step rather than growing its own copy, exactly as the arms cite `leaf-only-lifecycle`, `repo-scope-split`, `rejection-detection`, and `claim-archaeology`. One slug is what keeps a guard that fires on GitHub from being absent on Linear.
|
|
6
|
+
|
|
7
|
+
## Sequencing
|
|
8
|
+
|
|
9
|
+
The shared claim phase is `3a.0` repo-scope gate → `3a` leaf-only claim gate → `3b` Claim → `3c` run lifecycle → `3d` transition to done. Inside `3b`, the pre-transition window now runs four passes in a fixed order:
|
|
10
|
+
|
|
11
|
+
1. **`rejection-detection`** — needs the current-lane signal the relabel destroys.
|
|
12
|
+
2. **`claim-archaeology`** — consumes the rejection classification.
|
|
13
|
+
3. **`two-failed-attempts` valve** (this rule) — may end the cycle before any claim happens.
|
|
14
|
+
4. **`already-implemented` check** (this rule) — decides whether `3c` implements or verifies.
|
|
15
|
+
|
|
16
|
+
The valve runs before the already-implemented probe because it is cheaper and it is the only one of the four that can stop the claim outright: there is no point spending git and PR queries on an item that is about to be blocked.
|
|
17
|
+
|
|
18
|
+
## Guard 1 — already-implemented → verify-and-close
|
|
19
|
+
|
|
20
|
+
**Why it exists.** A ready item may already be implemented. Agents ship without transitioning: the PR merges, the work is done, and the item sits in the ready lane looking untouched. Claiming it normally means building the same change a second time — at best a no-op PR, at worst a conflicting reimplementation of work that already landed.
|
|
21
|
+
|
|
22
|
+
**The probe.** Two deterministic searches for the item's **own** canonical key (the ref carried by the `Work-Item:` trailer), bounded and never interactive:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Commits anywhere in history — branches and merged work included — that carry the key.
|
|
26
|
+
git log --all --grep "<key>" --format='%H %aI %s' -n 10
|
|
27
|
+
|
|
28
|
+
# Open and merged PRs referencing the key (GitHub shown; JIRA and Linear use the
|
|
29
|
+
# equivalent search through their access layers, never a direct vendor API call).
|
|
30
|
+
gh pr list --repo <org>/<repo> --state all --search "<key>" --json number,state,mergedAt,url
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
A hit counts only when it names **this** key. Branch-name coincidence, a similar title, or a reference from an unrelated item is not a hit — that is `claim-archaeology`'s job, not this one.
|
|
34
|
+
|
|
35
|
+
**The outcome.** On a hit, do not implement. Switch `3c` to **verify-and-close**:
|
|
36
|
+
|
|
37
|
+
1. Read the referenced commits/PR and establish what actually shipped.
|
|
38
|
+
2. Verify the shipped change against this item's acceptance criteria — the ordinary verification path, not a fresh build.
|
|
39
|
+
3. On a pass: post evidence naming the shipping PR/commit, then run the normal `3d` transition (which still gates on the PR being merged) and the `3d.1` rollup.
|
|
40
|
+
4. On a fail — the shipped change does not satisfy the criteria — record that the item is only **partially** implemented, and proceed with the ordinary implement path for the remaining gap. A partial hit must never close an item whose criteria are unmet.
|
|
41
|
+
|
|
42
|
+
**What this is not.** Three nearby behaviors it must not be conflated with:
|
|
43
|
+
|
|
44
|
+
- **`claim-archaeology`** answers "is this item round 2 of a *different* past failure?" — it looks for an **ancestor** issue. This guard looks for **this same item** already having shipped. Different question, different key, different outcome.
|
|
45
|
+
- **`DUPLICATE_ALREADY_FIXED`** (from `lisa-ticket-triage`) is about a **different canonical issue** whose fix covers this one; it closes as a duplicate. This guard finds work done **under this item's own key** and closes it as completed, not as a duplicate.
|
|
46
|
+
- **Rejection reclaim** is about work that shipped and was pushed back. Verify-and-close applies to work that shipped and nobody noticed.
|
|
47
|
+
|
|
48
|
+
**Never block.** An unreadable history, an absent `gh`, or a failed search degrades to "no hit" and the ordinary implement path proceeds. A speculative probe must never strand a ready item.
|
|
49
|
+
|
|
50
|
+
## Guard 2 — two-failed-attempts → blocked
|
|
51
|
+
|
|
52
|
+
**Why it exists.** Without a valve, a scheduled loop re-claims the same failing item every cycle forever. Each attempt costs a full build flow, and the third attempt is not more likely to succeed than the second — what changed between them was nothing.
|
|
53
|
+
|
|
54
|
+
**The counter.** Attempts are counted from durable markers on the item itself, not from session memory (a cron process holds no state between cycles). On every **non-success terminal outcome** for a claimed item — errored, blocked by a gate, PR abandoned unmerged — the intake arm records a visible comment plus a marker:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
Build attempt <N> did not complete: <one-line operator-readable reason>.
|
|
58
|
+
<!-- [lisa-build-attempt] n=<N> outcome=<outcome> -->
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The marker line is verbatim; the count is the number of `[lisa-build-attempt]` markers on the item. Match on the **marker, never the title**. A successful build records no marker, so an item that shipped after one bad attempt starts clean if it is ever re-filed.
|
|
62
|
+
|
|
63
|
+
**The threshold is two.** At the top of the claim, count existing markers. With **two or more**, do not claim:
|
|
64
|
+
|
|
65
|
+
1. Move the item to the configured `blocked` role (`build.blocked` / `workflow.blocked`, resolved per `config-resolution` — never a hardcoded lane).
|
|
66
|
+
2. Post an operator-readable comment naming both prior attempts, what each one hit, and what a human would need to decide or supply. Written for a non-technical operator, per `report-actionability`.
|
|
67
|
+
3. **Stop the loop** — end the cycle without claiming anything else. Stopping is the point: the next scheduled invocation should not immediately pick up the next item as though nothing happened.
|
|
68
|
+
|
|
69
|
+
**Recovery is deliberate.** A blocked item returns to the queue only when a human (or `lisa-repair-intake`, once the named blocker is provably cleared) moves it back. The attempt markers stay on the item as history; re-entering the ready lane after a real fix is a fresh claim whose markers describe why it was hard, not a silent reset of the counter.
|
|
@@ -449,6 +449,13 @@ Every lifecycle skill operates on a fixed set of **roles** (`ready`, `claimed`,
|
|
|
449
449
|
|
|
450
450
|
**`ready` must never resolve to the team's DEFAULT state.** `Todo` is where Linear puts a brand-new issue, so using it for `ready` inverts the gate: the lane stops meaning "a human flipped this to build-ready" and starts meaning "nobody has touched this". Measured on the first team migrated: 20 issues in the lane, only 8 ever explicitly marked ready. JIRA avoids this because `jira.workflow.ready` is a dedicated `Ready` status while a fresh ticket lands in the project default.
|
|
451
451
|
|
|
452
|
+
**That rule is enforced, not merely stated — a correct default is only half the fix.** The default is `Ready`, but any project can override `linear.workflow.ready`, and an override reproduces the inversion exactly. Two arms catch it, deliberately split by what each can see:
|
|
453
|
+
|
|
454
|
+
- **Static, always-on.** The queue-contract resolver refuses a `ready` naming a stock default created state (`Todo`, `To Do`, `Backlog`, `Triage`) and throws rather than resolving. It needs no network, so it runs everywhere, including offline and in CI. It cannot see a team that renamed its default.
|
|
455
|
+
- **Live, authoritative.** `/lisa:validate-tracker-mapping` compares the configured `ready` against the team's real `defaultIssueState` (surfaced as `isTeamDefault` on `lisa-linear-access operation: list-workflow-states`) and classifies a match as `INVERTED` — never `VALID`, and never auto-repaired, because nothing records what lane the human meant instead.
|
|
456
|
+
|
|
457
|
+
`INVERTED` is not a name-resolution failure; it is the opposite. The name resolves perfectly, which is precisely why every existence check passes while the gate runs backwards.
|
|
458
|
+
|
|
452
459
|
**Linear state resolution is `type`-aware.** When a configured name is missing, a lifecycle skill may fall back to the team's states by `type` — `claimed`/`review` → the lowest-position `started`, `blocked` → `started` or `unstarted`, terminal `done` → `completed` — but only to *read*. **`ready` has no fallback on purpose:** every candidate would be the team's default unstarted state, which is exactly the inversion described above. A missing `ready` state is reported, never guessed; it must never invent a state to write into. Missing states are a setup defect, repaired by `/lisa:setup:linear`, not papered over at runtime.
|
|
453
460
|
|
|
454
461
|
`blocked` is what every vendor agent flips to when triage finds unresolved ambiguities or the build path is blocked by something the agent can't resolve. Different from `claimed` because it explicitly signals "human attention required."
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Ready-Role Filing
|
|
2
|
+
|
|
3
|
+
A work item that is filed but never given the ready role is an **incomplete handoff**. No other agent will ever pick it up: build-intake scans the ready lane and nothing else. The originating failure is small and entirely typical — an agent closed a ticket it could not reproduce, filed the real defect it found beside it, and left the new ticket sitting. The defect was correct, the write succeeded, and the work still died.
|
|
4
|
+
|
|
5
|
+
This rule makes the ready role an **explicit claim** at every filing site, and makes omission mean the same thing on every tracker.
|
|
6
|
+
|
|
7
|
+
## The one normalization
|
|
8
|
+
|
|
9
|
+
**An omitted `build_ready` means NOT build-ready — on JIRA, on GitHub, and on Linear alike.**
|
|
10
|
+
|
|
11
|
+
Before this rule the three writers disagreed, and the disagreement was invisible at the call site:
|
|
12
|
+
|
|
13
|
+
| Tracker | Omitted `build_ready` (before) | Omitted `build_ready` (now) |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| JIRA | project's default created status — **not ready** | unchanged — **not ready** |
|
|
16
|
+
| GitHub | `status:ready` applied — **ready** | **not ready** |
|
|
17
|
+
| Linear | created in the configured `ready` state — **ready** | **not ready** |
|
|
18
|
+
|
|
19
|
+
So the same vendor-neutral `lisa-tracker-write` call produced a different lifecycle outcome depending on which tracker a project had configured. That is a leak in the abstraction the shim exists to provide: switching trackers must not change behavior.
|
|
20
|
+
|
|
21
|
+
**This is a breaking change for GitHub and Linear callers.** Any caller that omitted `build_ready` and relied on implicit ready must now pass it explicitly. That is the point rather than a cost of it: the only paths affected are ones that were silently depending on a provider-specific default, which is exactly the class of bug this rule exists to eliminate. `lisa-github-validate-issue` F4's compensating normalization (omitted → `true`) is removed with it — a validator that re-introduces the old default would simply move the leak.
|
|
22
|
+
|
|
23
|
+
The safe direction is the implicit one. A ticket that reaches a build queue by accident is worse than one that waits, because the queue is what agents act on autonomously.
|
|
24
|
+
|
|
25
|
+
## Every filing declares one of two things
|
|
26
|
+
|
|
27
|
+
A writer accepts a filing only when it carries **one** of:
|
|
28
|
+
|
|
29
|
+
- **`build_ready: true`** — the item is complete enough to build and enters the ready lane for auto-pickup. This is the correct answer for a complete defect found during other work.
|
|
30
|
+
- **`human_gate: "<why a human must judge this first>"`** — the item is deliberately held outside the queue because a human product call is pending. The writer stamps a visible marker on the item so the hold is auditable rather than indistinguishable from an accident:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
Held for a human product call: <reason>.
|
|
34
|
+
<!-- [lisa-human-gate] reason=<short-slug> -->
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Filed, not ready, and no `human_gate` is the **incomplete handoff** case: the writer rejects it and names the two ways to resolve it. `build_ready: false` without a `human_gate` reason is the same failure spelled differently — it is not a gate, it is an omission with a value attached.
|
|
38
|
+
|
|
39
|
+
`build_ready` remains strictly subordinate to `leaf-only-lifecycle`: a container is never build-ready regardless of what a caller passes, and a container needs no `human_gate` because its state rolls up from its children rather than being claimed.
|
|
40
|
+
|
|
41
|
+
## Complete defects found during other work are filed build-ready
|
|
42
|
+
|
|
43
|
+
Any defect discovered while doing something else, which is complete enough to build, is filed through `lisa-track` / `lisa-tracker-write` with **explicit `build_ready: true`**. It must be claimable by build-intake on the next cycle with no human flipping status. "Complete enough to build" is the `work-item-definition-of-ready` bar — reproduction, observed-versus-expected, and Gherkin acceptance criteria — not a placeholder to be fleshed out later.
|
|
44
|
+
|
|
45
|
+
The same explicitness applies in the other direction. A filing that is genuinely a human product call declares `human_gate`; it does not simply omit the flag and hope the tracker default is the merciful one.
|
|
46
|
+
|
|
47
|
+
## The named exception: `lisa-exploratory-qa`
|
|
48
|
+
|
|
49
|
+
`lisa-exploratory-qa` files its findings **not** build-ready by default, and that is **correct** — it is the named human-gate exception under this rule, not drift to be repaired.
|
|
50
|
+
|
|
51
|
+
Exploratory QA is a first-time-user experience pass. Its findings are *candidate* defects and usability observations whose product significance a human should judge; auto-readying them would push judgment work into the build queue, which is precisely the failure the gate model exists to prevent. Its `ready=false` is therefore paired with an explicit `human_gate` reason and stamped with `[lisa-human-gate]` — an explicit human-gate marker, never a bare omission.
|
|
52
|
+
|
|
53
|
+
The sibling `e2e-coverage-gaps` skills are the contrast: a missing automated test is not a product question, so they file `build_ready: true` by default.
|
|
54
|
+
|
|
55
|
+
Other legitimate human-gate filings follow the same shape — `lisa-learnings-audit` promotion/demotion tickets, `lisa-improve-harness` intervention proposals, automation-retirement proposals, and provisioning tickets for access a human must grant. Each declares its `human_gate` reason rather than relying on a default.
|
|
56
|
+
|
|
57
|
+
## Recovery
|
|
58
|
+
|
|
59
|
+
`lisa-repair-intake` sweeps for the failure this rule prevents: recently filed items that are open, not in the configured ready role, and carrying **no** `[lisa-human-gate]` marker. Each is an incomplete handoff — surfaced with its filing context so an operator can promote it or gate it deliberately. The sweep reports rather than guesses: it never silently promotes an item into the queue, because a filing whose readiness nobody declared is exactly the input the gate model says a human should see.
|
|
60
|
+
|
|
61
|
+
## Related
|
|
62
|
+
|
|
63
|
+
- **`leaf-only-lifecycle`** — the prohibition `build_ready` is always subordinate to. Containers are never build-ready.
|
|
64
|
+
- **`work-item-definition-of-ready`** — what "complete enough to build" means.
|
|
65
|
+
- **`tracked-work`** — the filing entry point (`lisa-track`) this rule governs the readiness of.
|
|
66
|
+
- **`factory-model`** — why the ready flip is a gate standing outside the factory rather than a field inside it.
|
|
@@ -32,6 +32,24 @@ const DEFAULT_LINEAR_BUILD_DONE = {
|
|
|
32
32
|
production: "Done",
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
// The state names a stock Linear team creates brand-new Issues into. `ready`
|
|
36
|
+
// must name a lane a human moves an Issue INTO, so it may never be one of
|
|
37
|
+
// these: the claimable lane would stop meaning "a human flipped this to
|
|
38
|
+
// build-ready" and start meaning "nobody has touched this", and build-intake
|
|
39
|
+
// would dispatch work nobody approved.
|
|
40
|
+
//
|
|
41
|
+
// This list is a STATIC backstop for the stock names, which is the case that
|
|
42
|
+
// actually bit us. It cannot see a team that renamed its default — only the
|
|
43
|
+
// live `Team.defaultIssueState` can, which is why `/lisa:validate-tracker-mapping`
|
|
44
|
+
// carries the authoritative arm (`INVERTED`) and this one carries the arm that
|
|
45
|
+
// needs no network and therefore always runs.
|
|
46
|
+
const LINEAR_STOCK_DEFAULT_CREATED_STATES = [
|
|
47
|
+
"todo",
|
|
48
|
+
"to do",
|
|
49
|
+
"backlog",
|
|
50
|
+
"triage",
|
|
51
|
+
];
|
|
52
|
+
|
|
35
53
|
const DEFAULT_GITHUB_LINEAR_PRD_ROLES = {
|
|
36
54
|
draft: "prd-draft",
|
|
37
55
|
ready: "prd-ready",
|
|
@@ -272,6 +290,35 @@ export function resolvePrdLifecycleRoles(
|
|
|
272
290
|
}
|
|
273
291
|
}
|
|
274
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Reject a Linear `ready` override that names a state a stock team creates
|
|
295
|
+
* brand-new Issues into.
|
|
296
|
+
*
|
|
297
|
+
* Failing loudly is the safe direction. An operator staring at a hard error has
|
|
298
|
+
* a broken queue; an operator with a silently inverted gate has agents shipping
|
|
299
|
+
* work no human approved, which is the failure mode that produced this guard.
|
|
300
|
+
*
|
|
301
|
+
* @param {string} configured The resolved `linear.workflow.ready` name.
|
|
302
|
+
* @returns {string} The same name, once it is proven not to be a default lane.
|
|
303
|
+
* @throws {Error} When the name is a stock default created state.
|
|
304
|
+
*/
|
|
305
|
+
function assertLinearReadyIsNotDefaultState(configured) {
|
|
306
|
+
const normalized = configured.trim().toLowerCase();
|
|
307
|
+
|
|
308
|
+
if (!LINEAR_STOCK_DEFAULT_CREATED_STATES.includes(normalized)) {
|
|
309
|
+
return configured;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
throw new Error(
|
|
313
|
+
`linear.workflow.ready is set to "${configured.trim()}", which is where Linear puts a ` +
|
|
314
|
+
"brand-new Issue. That inverts the build-ready gate: the claimable lane would mean " +
|
|
315
|
+
'"nobody has touched this" instead of "a human marked this ready", so intake would ' +
|
|
316
|
+
"claim untouched backlog items. Point linear.workflow.ready at a dedicated state a " +
|
|
317
|
+
"human moves Issues into (the default is `Ready`), then re-run /lisa:setup:linear to " +
|
|
318
|
+
"create it if the team does not have one."
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
275
322
|
/**
|
|
276
323
|
* Resolve the build lifecycle roles for the configured tracker vendor.
|
|
277
324
|
*
|
|
@@ -307,7 +354,9 @@ export function resolveBuildLifecycleRoles(
|
|
|
307
354
|
vendor: "linear",
|
|
308
355
|
kind: "workflow",
|
|
309
356
|
roles: {
|
|
310
|
-
ready:
|
|
357
|
+
ready: assertLinearReadyIsNotDefaultState(
|
|
358
|
+
config.linear?.workflow?.ready || "Ready"
|
|
359
|
+
),
|
|
311
360
|
claimed: config.linear?.workflow?.claimed || "In Progress",
|
|
312
361
|
review: config.linear?.workflow?.review || "In Review",
|
|
313
362
|
blocked: config.linear?.workflow?.blocked || "Blocked",
|
|
@@ -217,9 +217,11 @@ vocabulary; it consumes it.
|
|
|
217
217
|
|
|
218
218
|
3. **File each standing blocker as a tracker work item — never an in-session question.** For every
|
|
219
219
|
standing ship blocker, create **one** Lisa work item through the vendor-neutral `lisa-tracker-write`
|
|
220
|
-
skill (never a vendor write skill directly), carrying the five finding fields in the body.
|
|
221
|
-
|
|
222
|
-
|
|
220
|
+
skill (never a vendor write skill directly), carrying the five finding fields in the body. Per the `ready-role-filing` rule each
|
|
221
|
+
create declares its readiness explicitly: pass **`build_ready: true`** when the correction is
|
|
222
|
+
mechanical (an omitted flag is NOT build-ready on any tracker, so the mechanical branch would
|
|
223
|
+
otherwise file work nothing ever claims), and pass **`human_gate: "<the decision only a human can
|
|
224
|
+
make>"`** plus the `human-needed` marker when it is a genuine human decision. This is the skill's **only tracker write**, and it creates Lisa's *own* work item —
|
|
223
225
|
it **never edits, comments on, transitions, or otherwise mutates any ingested source** (see the
|
|
224
226
|
connected-source safety boundary above). The shipped never-ask posture is preserved: a blocker
|
|
225
227
|
becomes a filed ticket, **never** a prompt, and the session **never pauses to ask a human anything**,
|
|
@@ -356,7 +356,7 @@ Each sub-task MUST:
|
|
|
356
356
|
2. **Include an Empirical Verification Plan** — real user-like verification, NOT unit tests, linting, or typechecking
|
|
357
357
|
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).
|
|
358
358
|
|
|
359
|
-
**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.
|
|
359
|
+
**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. **Pass `build_ready: true` explicitly on every Sub-task create** — per the `ready-role-filing` rule an omitted `build_ready` is NOT build-ready on any tracker, so a decomposition that relies on a vendor default silently produces a queue nothing ever claims. 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.
|
|
360
360
|
|
|
361
361
|
Sub-tasks inherit their parent story's artifacts by reference (the parent link). Do not pass the same artifact list to every sub-task.
|
|
362
362
|
|
|
@@ -425,6 +425,7 @@ tickets that downstream skills (triage, journey, evidence) cannot use.
|
|
|
425
425
|
|
|
426
426
|
For each sub-task, invoke `lisa-tracker-write` with:
|
|
427
427
|
- issue_type: "Sub-task"
|
|
428
|
+
- build_ready: true # explicit per `ready-role-filing`; omitted is NOT build-ready on any tracker
|
|
428
429
|
- prd_source: [the originating PRD URL — mandatory; arms the S16 traceability gate]
|
|
429
430
|
- parent: the parent story key
|
|
430
431
|
- project_key: [PROJECT]
|
|
@@ -29,11 +29,11 @@ For every row marked **Accept**:
|
|
|
29
29
|
| Edge case | Edge Case Brainstorm checklist in `intent-routing.md` | Append the new pattern + question to the matching group (Navigation, Data, Failure, Input, Auth, or a new group if none fit). Use the row's `Summary` and `Evidence` link as a citation comment. |
|
|
30
30
|
| Recurring gotcha | Committed learnings ledger (via contract) | Persist a ledger entry per [Ledger persistence](#ledger-persistence-knowledge-categories). The `rule` is the recurring gotcha and the guard against it; `why` is the causal claim. |
|
|
31
31
|
| Process friction | Committed learnings ledger (via contract) | Persist a ledger entry per [Ledger persistence](#ledger-persistence-knowledge-categories). The `rule` is the friction-avoiding guideline; `why` names the friction it prevents. |
|
|
32
|
-
| Tooling gap | Configured tracker — or upstream Lisa when harness-level | **Split by level.** Project-level (a missing project script, hook, or automation) → create a ticket via `lisa-tracker-write` with `issue_type: Task`, summary derived from the row's `Summary`, description citing the evidence and the originating debrief doc, labeled `type:tooling` / `lifecycle-improvement
|
|
32
|
+
| Tooling gap | Configured tracker — or upstream Lisa when harness-level | **Split by level.** Project-level (a missing project script, hook, or automation) → create a ticket via `lisa-tracker-write` with `issue_type: Task`, summary derived from the row's `Summary`, description citing the evidence and the originating debrief doc, labeled `type:tooling` / `lifecycle-improvement`, and explicit `build_ready: true` per `ready-role-filing` (a tooling gap the factory can close itself is queue work, and an omitted flag is NOT build-ready on any tracker). Harness-level (a Lisa skill/gate/agent that should have caught the issue but didn't) → file an upstream Lisa issue exactly per the "Filing upstream" procedure in `lisa-rework-triage` (dedupe search first, three-audience description, evidence chain, `self-hardening` label; repo from `.lisa.config.json` `hardening.upstreamRepo`, default `CodySwannGT/lisa`). |
|
|
33
33
|
| Convention drift | Committed learnings ledger (via contract) | Persist a ledger entry per [Ledger persistence](#ledger-persistence-knowledge-categories). The `rule` is the correct convention; `why` records the drift it corrects. |
|
|
34
34
|
| Decomposition infidelity | Upstream Lisa repo | File an upstream Lisa issue per the "Filing upstream" procedure in `lisa-rework-triage`, citing the PRD text vs. the distorted ticket AC and naming the gate that passed it. |
|
|
35
35
|
| PRD defect | Source PRD | Comment on the PRD via the `lisa-prd-backlink` lineage quoting the defective requirement and the failure it missed; flag for product review. Never silently edit the spec. |
|
|
36
|
-
| Missing tool access | Configured tracker | Create a provisioning ticket via `lisa-tracker-write` (`issue_type: Task`, `type:tooling`) describing the missing tool/credential/environment and which flow needs it. |
|
|
36
|
+
| Missing tool access | Configured tracker | Create a provisioning ticket via `lisa-tracker-write` (`issue_type: Task`, `type:tooling`) describing the missing tool/credential/environment and which flow needs it. Pass `human_gate: "a human must grant the missing access"` per `ready-role-filing` — the factory cannot provision its own credentials. |
|
|
37
37
|
| Uncategorized | **No route — requires reclassification** | `Uncategorized` records that the synthesizer could not fit the finding to a category; it is not itself a destination. Do NOT guess a route and do NOT silently skip the row. Leave the row unapplied, mark it `[!] Needs reclassification — <the synthesizer's "why no category fit" note>`, and list it under its own heading in the run summary so the human can retag it to one of the eight and re-run `apply`. A row that stays `Uncategorized` across runs is a signal the category set itself is missing a case — worth an upstream Lisa issue, not a forced fit. |
|
|
38
38
|
|
|
39
39
|
For every row marked **Reject** or **Defer**: no action. Defer is a no-op for `apply` but worth surfacing in the run summary — the human may want to revisit at the next debrief.
|
|
@@ -70,7 +70,13 @@ Kane never files the work item itself. Even when it marks a failure as a confirm
|
|
|
70
70
|
| User-visible **bug** (broken behavior) | `Bug` | the `ready` flag (default `false`) |
|
|
71
71
|
| **Usability / UX / clarity issue** | `Improvement` | the `ready` flag (default `false`) |
|
|
72
72
|
|
|
73
|
-
Each finding is a flat leaf, so `build_ready` applies directly — pass it explicitly on every create.
|
|
73
|
+
Each finding is a flat leaf, so `build_ready` applies directly — pass it explicitly on every create.
|
|
74
|
+
|
|
75
|
+
**This skill is the named human-gate exception under `ready-role-filing`.** Everywhere else in Lisa, a complete defect found during other work is filed with explicit `build_ready: true` so build-intake claims it next cycle. Exploratory QA is deliberately different, and that difference is ratified rather than drift: its findings are *candidate* defects and usability observations whose **product significance is a human call**, so auto-readying them would push judgment work into the build queue — precisely the failure the gate model exists to prevent. Its default `ready=false` is therefore an **explicit human-gate marker, never a bare omission**: every not-ready create passes `human_gate: "exploratory finding — product significance is a human product call"` alongside `build_ready: false`, and the writer stamps the auditable `[lisa-human-gate]` marker. An operator who wants a pass to feed the queue directly opts in with `ready=true`.
|
|
76
|
+
|
|
77
|
+
(The sibling `e2e-coverage-gaps` skills are the contrast: a missing automated test is not a product question, so they file `build_ready: true` by default.)
|
|
78
|
+
|
|
79
|
+
Each ticket MUST be a complete spec (the validator rejects thin tickets): a **three-audience description**; for a **bug**, exact reproduction steps, observed-vs-expected, the env / account / interface it occurred at, and evidence; for a **usability issue**, the observed friction, who it affects, **where**, and the proposed improvement; and **Gherkin acceptance criteria** for the fixed behavior.
|
|
74
80
|
|
|
75
81
|
### Idempotency — don't spam duplicates
|
|
76
82
|
|
|
@@ -258,6 +258,11 @@ A blocker is active if it is open and has no cleared status label. Treat `status
|
|
|
258
258
|
|
|
259
259
|
**Claim-time archaeology runs second — after rejection detection, still before the relabel below.** Classify this item per the vendor-neutral `claim-archaeology` rule, with the rejection classification above as its input. All shared semantics — ancestry signals, classification, learning-loop exclusion, cost budget, candidate derivation, marker dedupe, and the never-block degrade — live in that one slug; change them there, never here. GitHub wiring only: the typed relations and `closingIssuesReferences` are already in the read bundle; text-similarity searches use `gh search issues` over recently-closed issues; the fallback candidate comment is posted with `gh issue comment`.
|
|
260
260
|
|
|
261
|
+
**The two `claim-time-guards` run third and fourth — still before the relabel below.** Both semantics live in that one vendor-neutral slug; do not restate them here. GitHub wiring only:
|
|
262
|
+
|
|
263
|
+
1. **`two-failed-attempts` valve.** Count `[lisa-build-attempt]` markers on the issue from the read bundle's comments (match on the marker, never the title). With two or more, do **not** claim: relabel to the configured blocked role (`gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$BLOCKED"`, resolved from `github.labels.build.blocked` per `config-resolution`), post the operator-readable comment naming both attempts, and **stop the cycle** at Phase 3e. Every non-success terminal outcome recorded in 3c/3d also appends a fresh `<!-- [lisa-build-attempt] n=<N> outcome=<outcome> -->` marker so the next cycle can count it.
|
|
264
|
+
2. **`already-implemented` check.** Probe for this issue's own key — `git log --all --grep "<org>/<repo>#<number>"` and `gh pr list --repo <org>/<repo> --state all --search "<org>/<repo>#<number>" --json number,state,mergedAt,url`. On a hit, claim as normal but route 3c to **verify-and-close** instead of `lisa-implement`: verify what shipped against the issue's acceptance criteria, post evidence via `lisa-github-evidence` naming the shipping PR/commit, then run the ordinary 3d transition and 3d.1 rollup. A partial hit implements only the remaining gap. An unreadable history degrades to "no hit" and the ordinary path proceeds — the guard never blocks the claim. This is not `DUPLICATE_ALREADY_FIXED` (a *different* canonical issue) and not `claim-archaeology` (a *different* ancestor issue); it is this issue's own work already having shipped without a transition.
|
|
265
|
+
|
|
261
266
|
```bash
|
|
262
267
|
gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$CLAIMED"
|
|
263
268
|
# Assign to the authenticated user ONLY when the issue is currently unassigned (attributable claim;
|
|
@@ -80,7 +80,9 @@ Issues must be created in parent-before-child order:
|
|
|
80
80
|
|
|
81
81
|
1. Invoke `lisa-github-write-issue` for the Epic. Capture the returned issue number.
|
|
82
82
|
2. For each Story, invoke `lisa-github-write-issue` with the Epic ref as `parent_ref`. Capture each Story number.
|
|
83
|
-
3. For each Sub-task, invoke `lisa-github-write-issue` with the Story ref as `parent_ref`.
|
|
83
|
+
3. For each Sub-task, invoke `lisa-github-write-issue` with the Story ref as `parent_ref` and explicit `build_ready: true`.
|
|
84
|
+
|
|
85
|
+
- **Declare readiness on every leaf write.** Per the `ready-role-filing` rule an omitted `build_ready` is **not build-ready** on any tracker, so pass `build_ready: true` on each Sub-task (the leaf work units this skill plans) and never on the Epic or Stories, which are containers per `leaf-only-lifecycle`. A leaf that is deliberately held instead passes `human_gate: "<why a human must judge this first>"`. Filing a leaf with neither is an incomplete handoff and `lisa-github-write-issue` rejects it.
|
|
84
86
|
|
|
85
87
|
### What to pass to each invocation
|
|
86
88
|
|
|
@@ -343,7 +343,7 @@ Each sub-task MUST:
|
|
|
343
343
|
2. **Include an Empirical Verification Plan** — real user-like verification, NOT unit tests, linting, or typechecking.
|
|
344
344
|
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).
|
|
345
345
|
|
|
346
|
-
**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 label. `lisa-tracker-write` applies `status:ready` here so downstream build intake (`lisa-github-build-intake`) claims the leaves and never the Epic or Stories. Apply `status:ready` to each Sub-task; never to its parent Story or Epic (Phases 3–4). `lisa-github-write-issue` 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
|
+
**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 label. `lisa-tracker-write` applies `status:ready` here so downstream build intake (`lisa-github-build-intake`) claims the leaves and never the Epic or Stories. **Pass `build_ready: true` explicitly on every Sub-task create** — per the `ready-role-filing` rule an omitted `build_ready` is NOT build-ready on any tracker, so a decomposition that relies on a vendor default silently produces a queue nothing ever claims. Apply `status:ready` to each Sub-task; never to its parent Story or Epic (Phases 3–4). `lisa-github-write-issue` 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.
|
|
347
347
|
|
|
348
348
|
Sub-tasks inherit their parent Story's artifacts by reference (the parent link). Do not pass the same artifact list to every sub-task.
|
|
349
349
|
|
|
@@ -412,6 +412,7 @@ that downstream skills (triage, journey, evidence) cannot use.
|
|
|
412
412
|
|
|
413
413
|
For each sub-task, invoke `lisa-tracker-write` with:
|
|
414
414
|
- issue_type: "Sub-task"
|
|
415
|
+
- build_ready: true # explicit per `ready-role-filing`; omitted is NOT build-ready on any tracker
|
|
415
416
|
- prd_source: [the originating PRD URL — mandatory; arms the S16 traceability gate]
|
|
416
417
|
- parent_ref: the parent story ref
|
|
417
418
|
- summary: prefixed with the repo in brackets, e.g. "[backend-api] Add audit log table"
|
|
@@ -382,13 +382,17 @@ Per `Phase 5` of `lisa-github-write-issue`, every issue MUST carry
|
|
|
382
382
|
missing from the proposed spec or live issue, FAIL with the missing label name.
|
|
383
383
|
|
|
384
384
|
The `status:*` requirement uses this validator's S15 leaf/container classification while preserving
|
|
385
|
-
the writer's documented `build_ready` control-input defaults
|
|
385
|
+
the writer's documented `build_ready` control-input defaults, which the `ready-role-filing` rule
|
|
386
|
+
fixes at "omitted is NOT build-ready" for every vendor:
|
|
386
387
|
|
|
387
388
|
1. Classify the issue structurally using the S15 child-resolution rules. A container (any issue
|
|
388
389
|
with child work, plus a childless `Epic`) may omit `status:*`; its state rolls up rather than
|
|
389
390
|
being assigned directly.
|
|
390
|
-
2. For a proposed leaf spec, normalize omitted `build_ready` to `
|
|
391
|
-
|
|
391
|
+
2. For a proposed leaf spec, normalize omitted `build_ready` to `false`, per `ready-role-filing`:
|
|
392
|
+
ready is an explicit claim, so only `build_ready: true` asserts it. Explicit `build_ready: false`
|
|
393
|
+
means the same backlog mode. (This validator previously normalized omitted → `true` to mirror
|
|
394
|
+
GitHub's implicit-ready writer default; both were removed together, and re-introducing either
|
|
395
|
+
here would just move the leak.)
|
|
392
396
|
3. For a live issue ref, derive `build_ready` from the labels (`true` exactly when the S15-resolved
|
|
393
397
|
`READY_ROLE` from `github.labels.build.ready`, default `status:ready`, is present). A live backlog leaf without a status label
|
|
394
398
|
therefore validates as `build_ready: false`; live data cannot distinguish an explicit false from
|
|
@@ -253,12 +253,21 @@ For non-build-ready issues created fresh (Epics, Stories, and other containers),
|
|
|
253
253
|
|
|
254
254
|
### Build-ready control input (`build_ready`)
|
|
255
255
|
|
|
256
|
-
`build_ready` is
|
|
256
|
+
`build_ready` is a write-control input governed by the `ready-role-filing` rule — cite that slug for the full contract; do not restate its per-vendor normalization table here. It decides whether a **leaf** work unit is stamped with the build-ready role on create. It never overrides `leaf-only-lifecycle` — a container is never stamped build-ready regardless of `build_ready`. "Not build-ready" is not a special status: it simply means the issue is created in its natural default (a plain open issue with **no `status:ready` label**), which a human can promote later.
|
|
257
257
|
|
|
258
|
-
- **Omitted** →
|
|
258
|
+
- **Omitted** → **not build-ready**: the leaf is created without `status:ready`. Ready is an explicit claim, never a vendor default. **This is a breaking change** — GitHub previously applied `status:ready` on omission, so a caller that relied on that must now pass `build_ready: true`.
|
|
259
259
|
- **`build_ready: false`** → create the leaf **without** `status:ready`, so it sits in the backlog for a human to review and promote into the queue.
|
|
260
260
|
- **`build_ready: true`** → ensure the leaf carries `status:ready` so `lisa-intake` / `lisa-github-build-intake` auto-picks it up.
|
|
261
261
|
|
|
262
|
+
**A filing with neither is an incomplete handoff.** A leaf that is not build-ready must carry an explicit `human_gate: "<why a human must judge this first>"`; nothing in the ready lane means nothing ever claims it. When `human_gate` is supplied, stamp the hold on the issue so it is auditable — a visible line plus the verbatim marker:
|
|
263
|
+
|
|
264
|
+
```text
|
|
265
|
+
Held for a human product call: <reason>.
|
|
266
|
+
<!-- [lisa-human-gate] reason=<short-slug> -->
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
If a leaf arrives with `build_ready` omitted or `false` **and** no `human_gate`, do not create it: report the incomplete handoff and name both ways to resolve it (`build_ready: true`, or a `human_gate` reason). Containers are exempt — their state rolls up from children, so they need neither.
|
|
270
|
+
|
|
262
271
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
263
272
|
|
|
264
273
|
Before any write, invoke `lisa-github-validate-issue` with the full proposed spec assembled from Phases 2 / 3 / 4 / 5. Pass it as a YAML block per the `lisa-github-validate-issue` schema, including `runtime_behavior_change`, `authenticated_surface`, and `artifacts_attached` flags so the right gates run.
|
|
@@ -271,9 +280,9 @@ If the validator reports `FAIL`, do NOT proceed to Phase 6. Fix the spec and re-
|
|
|
271
280
|
|
|
272
281
|
### CREATE
|
|
273
282
|
|
|
274
|
-
1. Compose the body markdown from Phases 2/3/4 in a temp file (avoid quoting hell). Apply `status:ready` **only for a leaf work unit** per the Phase 5 leaf-only rule (`leaf-only-lifecycle`) — omit it for `Epic` / `Story` / `Spike` and any issue that has child work, **and** only when `build_ready` is
|
|
283
|
+
1. Compose the body markdown from Phases 2/3/4 in a temp file (avoid quoting hell). Apply `status:ready` **only for a leaf work unit** per the Phase 5 leaf-only rule (`leaf-only-lifecycle`) — omit it for `Epic` / `Story` / `Spike` and any issue that has child work, **and** only when `build_ready` is explicitly `true` (a leaf with `build_ready` omitted or `false` is created without `status:ready`; see the Build-ready control input):
|
|
275
284
|
```bash
|
|
276
|
-
# Leaf work unit (Bug / Task / Sub-task / Improvement with no children), build_ready
|
|
285
|
+
# Leaf work unit (Bug / Task / Sub-task / Improvement with no children), build_ready: true:
|
|
277
286
|
gh issue create \
|
|
278
287
|
--repo <org>/<repo> \
|
|
279
288
|
--title "<summary>" \
|
|
@@ -282,9 +291,10 @@ If the validator reports `FAIL`, do NOT proceed to Phase 6. Fix the spec and re-
|
|
|
282
291
|
[--label "component:<name>" ...] [--milestone "<milestone>"] \
|
|
283
292
|
[--assignee "<login>"]
|
|
284
293
|
|
|
285
|
-
# Container (Epic / Story / Spike / any issue with child work), OR a leaf
|
|
294
|
+
# Container (Epic / Story / Spike / any issue with child work), OR a leaf whose build_ready is
|
|
295
|
+
# omitted or false (and which therefore carries an explicit human_gate):
|
|
286
296
|
# identical, but WITHOUT --label "status:ready" — a container's state rolls up from children;
|
|
287
|
-
# a
|
|
297
|
+
# a human-gated leaf waits in the backlog for a human to promote it.
|
|
288
298
|
gh issue create \
|
|
289
299
|
--repo <org>/<repo> \
|
|
290
300
|
--title "<summary>" \
|