@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
|
@@ -106,6 +106,40 @@ linear_graphql() {
|
|
|
106
106
|
Map operation names to Linear GraphQL queries/mutations in this access skill.
|
|
107
107
|
Consumers pass business-shaped arguments only; they do not embed GraphQL.
|
|
108
108
|
|
|
109
|
+
## `list-workflow-states` — the team's states, and which one it creates into
|
|
110
|
+
|
|
111
|
+
`list-workflow-states team:<ID>` returns one node per state with `id`, `name`,
|
|
112
|
+
`type`, `position`, and **`isTeamDefault`**.
|
|
113
|
+
|
|
114
|
+
`isTeamDefault` is `true` for the single state named by the team's
|
|
115
|
+
`defaultIssueState` — where Linear puts every brand-new Issue. Callers need it to
|
|
116
|
+
enforce the rule that `linear.workflow.ready` must be a lane a human moves an
|
|
117
|
+
Issue **into**: pointing `ready` at the default inverts the gate, so the
|
|
118
|
+
claimable lane means "nobody has touched this" rather than "a human marked this
|
|
119
|
+
ready", and build-intake dispatches unapproved work. `/lisa:setup:linear` refuses
|
|
120
|
+
to resolve `ready` onto it, and `/lisa:validate-tracker-mapping` classifies a
|
|
121
|
+
config that already does as `INVERTED`.
|
|
122
|
+
|
|
123
|
+
It belongs on this operation rather than in a separate `get-team` call because
|
|
124
|
+
every caller that needs it is already enumerating states, and a second round trip
|
|
125
|
+
is a second chance for the two answers to disagree. A team with no
|
|
126
|
+
`defaultIssueState` set yields `isTeamDefault: false` on every node — report that
|
|
127
|
+
honestly; do not fall back to guessing by name or position.
|
|
128
|
+
|
|
129
|
+
```graphql
|
|
130
|
+
query($teamId:String!){
|
|
131
|
+
team(id:$teamId){
|
|
132
|
+
defaultIssueState{ id }
|
|
133
|
+
states(first:100){ nodes{ id name type position } }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Set `isTeamDefault` per node by comparing `node.id` against
|
|
139
|
+
`team.defaultIssueState.id`. On the MCP substrate, which exposes states without
|
|
140
|
+
the team's default, resolve the default through the team record and join on `id`
|
|
141
|
+
the same way.
|
|
142
|
+
|
|
109
143
|
## `history` — transition history (read-only)
|
|
110
144
|
|
|
111
145
|
`history id:<ID>` returns an Issue's ordered past state changes — the raw
|
|
@@ -203,6 +203,11 @@ This gate never blocks a legitimate flat Task/Bug: those have no open children a
|
|
|
203
203
|
|
|
204
204
|
**Claim-time archaeology runs second — after rejection detection, still before the transition below.** Classify this Issue 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. Linear wiring only: the native relations are already in the read bundle; text-similarity searches run through `lisa-linear-access operation: list-issues` filtered to recently-closed Issues; the fallback candidate comment is posted via `lisa-linear-access operation: save-comment`.
|
|
205
205
|
|
|
206
|
+
**The two `claim-time-guards` run third and fourth — still before the transition below.** Both semantics live in that one vendor-neutral slug; do not restate them here. Linear wiring only:
|
|
207
|
+
|
|
208
|
+
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: set `stateId` to the configured blocked state via `lisa-linear-access operation: save-issue` (resolved from `linear.workflow.blocked` per `config-resolution`), post the operator-readable comment naming both attempts via `save-comment`, 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.
|
|
209
|
+
2. **`already-implemented` check.** Probe for this Issue's own key — `git log --all --grep "<IDENTIFIER>"` and the merged/open PRs referencing `<IDENTIFIER>` (`gh pr list --state all --search "<IDENTIFIER>"` in the bound repo; Linear's own GitHub attachments in the read bundle are the cheaper first look). 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-linear-evidence` naming the shipping PR/commit, then run the ordinary 3d transition and 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.
|
|
210
|
+
|
|
206
211
|
Transition the Issue via `lisa-linear-access operation: save-issue` by setting `stateId` to the `$CLAIMED` state. Resolve state IDs via `list-workflow-states`; a missing `$CLAIMED` state is a setup defect (see the pre-flight check) — never create one here.
|
|
207
212
|
|
|
208
213
|
**Assign to the authenticated user when the Issue is unassigned.** A claim must be attributable. If the Issue has no assignee, set its `assigneeId` to the authenticated viewer (resolve the viewer's id via the Linear MCP identity — e.g. `get_user` for the current actor) through `lisa-linear-access operation: save-issue`. Leave an already-assigned Issue's assignee untouched — never reassign work that already has an owner.
|
|
@@ -124,7 +124,9 @@ Items must be created in parent-before-child order so each child can be passed i
|
|
|
124
124
|
|
|
125
125
|
1. Invoke `lisa-linear-write-issue` for the Epic (Project). Capture the returned Project ID.
|
|
126
126
|
2. For each Story, invoke `lisa-linear-write-issue` with the Project ID as `parent_project_id`. Capture each Issue identifier.
|
|
127
|
-
3. For each Sub-task, invoke `lisa-linear-write-issue` with the Story Issue ID as `parent_issue_id`.
|
|
127
|
+
3. For each Sub-task, invoke `lisa-linear-write-issue` with the Story Issue ID as `parent_issue_id` and explicit `build_ready: true`.
|
|
128
|
+
|
|
129
|
+
- **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-linear-write-issue` rejects it.
|
|
128
130
|
|
|
129
131
|
### What to pass to each invocation
|
|
130
132
|
|
|
@@ -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 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.
|
|
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. **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.
|
|
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
|
|
|
@@ -408,6 +408,7 @@ produces broken tickets that downstream skills (triage, journey, evidence) canno
|
|
|
408
408
|
|
|
409
409
|
For each sub-task, invoke `lisa-tracker-write` with:
|
|
410
410
|
- issue_type: "Sub-task"
|
|
411
|
+
- build_ready: true # explicit per `ready-role-filing`; omitted is NOT build-ready on any tracker
|
|
411
412
|
- prd_source: [the originating PRD URL — mandatory; arms the S16 traceability gate]
|
|
412
413
|
- parent: the parent story key
|
|
413
414
|
- project_key: [PROJECT]
|
|
@@ -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
|
-
The build lifecycle uses native **workflow states** (`Ready`, `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 **leaf** work unit is created in the configured `ready` state
|
|
34
|
+
The build lifecycle uses native **workflow states** (`Ready`, `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 **leaf** work unit is created in the configured `ready` state only on explicit `build_ready: true`; omitted or `false` leaves it in the team's default backlog state, and a container is never put in `ready` at all (see the Build-ready control input below).
|
|
35
35
|
|
|
36
36
|
## Phase 1 — Resolve Intent
|
|
37
37
|
|
|
@@ -242,7 +242,7 @@ If the item modifies an existing user-facing surface, a `lisa-product-walkthroug
|
|
|
242
242
|
|
|
243
243
|
Before create/update, verify each field is populated where applicable:
|
|
244
244
|
|
|
245
|
-
- **Workflow state**: set the resolved `ready` state (`linear.workflow.ready`, default `Ready`) on a new **leaf** work unit (Bug / Task / Sub-task / Improvement with no child work) per `leaf-only-lifecycle`, **
|
|
245
|
+
- **Workflow state**: set the resolved `ready` state (`linear.workflow.ready`, default `Ready`) on a new **leaf** work unit (Bug / Task / Sub-task / Improvement with no child work) per `leaf-only-lifecycle`, **only on explicit `build_ready: true`** (see the Build-ready control input below). A container (Epic Project / Story with sub-issues / Spike) is never put in the build-ready state.
|
|
246
246
|
- **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.
|
|
247
247
|
- **Native priority field**: 0–4 per Linear's scale; explicit, not "unset".
|
|
248
248
|
- **Native estimate**: per Linear's team-configured estimate scale (often 0–8 Fibonacci); skip for Epic / Spike.
|
|
@@ -254,12 +254,21 @@ For Bug / Task / Sub-task, ensure the summary is prefixed with `[<repo-name>]`.
|
|
|
254
254
|
|
|
255
255
|
### Build-ready control input (`build_ready`)
|
|
256
256
|
|
|
257
|
-
`build_ready` is
|
|
257
|
+
`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 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.
|
|
258
258
|
|
|
259
|
-
- **Omitted** →
|
|
259
|
+
- **Omitted** → **not build-ready**: the leaf is left in the team's default backlog state. Ready is an explicit claim, never a vendor default. **This is a breaking change** — Linear previously created a leaf directly in the `ready` state on omission, so a caller that relied on that must now pass `build_ready: true`.
|
|
260
260
|
- **`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.
|
|
261
261
|
- **`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.
|
|
262
262
|
|
|
263
|
+
**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:
|
|
264
|
+
|
|
265
|
+
```text
|
|
266
|
+
Held for a human product call: <reason>.
|
|
267
|
+
<!-- [lisa-human-gate] reason=<short-slug> -->
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
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.
|
|
271
|
+
|
|
263
272
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
264
273
|
|
|
265
274
|
Before any write, invoke `lisa-linear-validate-issue` with the full proposed spec assembled from Phases 2 / 3 / 4 / 5. Pass it as a YAML block per the `lisa-linear-validate-issue` schema, including `runtime_behavior_change`, `authenticated_surface`, and `artifacts_attached` flags so the right gates run.
|
|
@@ -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 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.
|
|
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. **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.
|
|
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
|
|
@@ -426,6 +426,7 @@ produces broken tickets that downstream skills (triage, journey, evidence) canno
|
|
|
426
426
|
|
|
427
427
|
For each sub-task, invoke `lisa-tracker-write` with:
|
|
428
428
|
- issue_type: "Sub-task"
|
|
429
|
+
- build_ready: true # explicit per `ready-role-filing`; omitted is NOT build-ready on any tracker
|
|
429
430
|
- parent: the parent story key
|
|
430
431
|
- project_key: [PROJECT]
|
|
431
432
|
- prd_source: [the originating PRD URL — mandatory; arms the S16 traceability gate]
|
|
@@ -112,7 +112,7 @@ This disposition completes the SLL-5 loop (#1583): on a Lisa-attributed failure
|
|
|
112
112
|
|
|
113
113
|
Resolve the upstream repo from `.lisa.config.json` `hardening.upstreamRepo` (default `CodySwannGT/lisa`). Search **all issue states** for an existing issue carrying the marker — a closed marker-bearing ticket still owns this root cause, and searching only open issues would mint a duplicate the moment the original closes. Match on the **MARKER, never the title** — with the same eventual-consistency guard as above (`gh issue list -R <upstream> --state all --search '"<marker>" in:body' --json number,state,url`, and when the search index returns nothing, also `gh issue list -R <upstream> --state all --json number,state,body` and grep the bodies for the marker before concluding no ticket exists).
|
|
114
114
|
|
|
115
|
-
- **No existing ticket** → compose the body EXCLUSIVELY through the executable builder, then file its stdout verbatim via `lisa-github-write-issue` targeting the upstream repo with the `self-hardening` label:
|
|
115
|
+
- **No existing ticket** → compose the body EXCLUSIVELY through the executable builder, then file its stdout verbatim via `lisa-github-write-issue` targeting the upstream repo with the `self-hardening` label and explicit `build_ready: true` (per `ready-role-filing`; the upstream repo runs its own build queue off the ready role, and an omitted flag would strand the hardening ticket there):
|
|
116
116
|
|
|
117
117
|
```bash
|
|
118
118
|
bunx @codyswann/lisa file-upstream --input filing-event.json # or pipe the JSON on stdin
|
|
@@ -48,8 +48,10 @@ ideation_ledger_payload: # optional; forwarded unchanged to the ven
|
|
|
48
48
|
- **`ready`** → the PRD is created in the source's `ready` PRD role (`prd-ready`), so the PRD-side of
|
|
49
49
|
`lisa-intake` / the `*-prd-intake` scanner auto-claims it on the next cycle.
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
Omitted means `draft` — the not-ready default. This matches the ticket-side `build_ready` contract
|
|
52
|
+
in `ready-role-filing`: on both sides of the pipeline, entering a queue is an **explicit claim** and
|
|
53
|
+
omission is the safe direction. (The ticket side reached that position by removing a per-vendor
|
|
54
|
+
legacy default; the PRD side never had one to remove.)
|
|
53
55
|
|
|
54
56
|
## Workflow
|
|
55
57
|
|
|
@@ -20,7 +20,9 @@ plus any screenshots).
|
|
|
20
20
|
recently-closed tickets in the affected area, and the current QA-queue set. If an existing ticket
|
|
21
21
|
covers it, that ticket is the target — update it, never file a twin. Only when the
|
|
22
22
|
search documents no match, create a new Bug via `lisa-tracker-write` (which enforces
|
|
23
|
-
the full quality gates)
|
|
23
|
+
the full quality gates) with explicit `build_ready: true` per the `ready-role-filing`
|
|
24
|
+
rule — omitted is NOT build-ready on any tracker, and a rework Bug nothing claims is
|
|
25
|
+
an incomplete handoff — and treat it as the target. Report which path was taken.
|
|
24
26
|
|
|
25
27
|
## Phase 2 — Structured failure report
|
|
26
28
|
|
|
@@ -752,6 +752,34 @@ with labels like `build-ready`, or with no Lisa status label at all, that are in
|
|
|
752
752
|
applied. Include the normalization result in the loop-prevention fingerprint so repeated repair
|
|
753
753
|
cycles do not spam comments.
|
|
754
754
|
|
|
755
|
+
### Ungated non-ready filing → surface as an incomplete handoff (read-only)
|
|
756
|
+
|
|
757
|
+
The recovery net for the failure `ready-role-filing` prevents: an agent files a real defect it found
|
|
758
|
+
during other work, never gives it the ready role, and the ticket sits forever because build-intake
|
|
759
|
+
scans the ready lane and nothing else. Under that rule every filing declares either
|
|
760
|
+
`build_ready: true` or a `human_gate` reason; an item carrying neither is an **incomplete handoff**.
|
|
761
|
+
|
|
762
|
+
1. Enumerate open items filed recently (within the configured staleness window — same resolution as
|
|
763
|
+
every other candidate class) that are **not** in the configured `ready` role for their lifecycle
|
|
764
|
+
and are not in a claimed / blocked / terminal role either. On GitHub that is the absence of the
|
|
765
|
+
configured build `ready` label; on JIRA and Linear it is a status/state outside the configured
|
|
766
|
+
`ready` role. Items whose role is simply "the tracker's default created lane" are the target.
|
|
767
|
+
2. Exclude anything carrying the `[lisa-human-gate]` marker — those are deliberate holds and the rule
|
|
768
|
+
ratifies them. Exclude containers (their state rolls up per `leaf-only-lifecycle`), and exclude
|
|
769
|
+
`[lisa-exploratory-qa]`-marked findings, which are the rule's **named** human-gate exception even
|
|
770
|
+
on an older item written before the marker existed.
|
|
771
|
+
3. **Report each survivor read-only; never promote it.** Name the item, when it was filed, and what
|
|
772
|
+
filed it, and state the two ways to resolve it — flip it to the configured `ready` role, or mark
|
|
773
|
+
it as a deliberate human gate. A filing whose readiness nobody declared is exactly the input the
|
|
774
|
+
gate model says a human should see, so guessing "it was probably meant to be ready" would
|
|
775
|
+
re-introduce the accidental-queue-entry failure this rule exists to eliminate.
|
|
776
|
+
4. Post at most one idempotent `[lisa-repair-intake]` note per item and include the finding in the
|
|
777
|
+
loop-prevention fingerprint so repeated cycles do not spam.
|
|
778
|
+
|
|
779
|
+
This is distinct from the GitHub label-normalization repair above, which targets items carrying **no
|
|
780
|
+
Lisa lifecycle label at all** (created by older tools or by hand) and does normalize them. This sweep
|
|
781
|
+
targets items inside the Lisa lifecycle whose readiness was never declared.
|
|
782
|
+
|
|
755
783
|
## Blocker classification & clearing (conservative, vendor-specific extraction)
|
|
756
784
|
|
|
757
785
|
A `blocked` build item is held by one or more of three blocker classes. Identify which are present
|
|
@@ -96,8 +96,8 @@ Lisa work item.
|
|
|
96
96
|
|---------------|-------------|--------|
|
|
97
97
|
| `decomposition-infidelity` | **Upstream Lisa issue** | The decomposition pipeline produced an unfaithful ticket and every gate passed it — that is a harness defect. File per "Filing upstream" below, citing the PRD text, the distorted ticket AC, and which gate should have caught it. |
|
|
98
98
|
| `verification-gap` | **Upstream Lisa issue** | The verification lifecycle passed work it should have failed. File per "Filing upstream", citing the missed failure class and the weak/missing codified test. |
|
|
99
|
-
| `missing-tool-access` | Project tracker | Create a provisioning ticket via `lisa-tracker-write` (`issue_type: Task`, labeled `type:tooling`) describing the missing tool/credential/environment and which flow needs it. Link it `blocks` the rework ticket. |
|
|
100
|
-
| `environment-data` | Project tracker | Create an environment-hardening ticket via `lisa-tracker-write` citing the drift/fixture/shared-state evidence. Link `relates to` the rework ticket. |
|
|
99
|
+
| `missing-tool-access` | Project tracker | Create a provisioning ticket via `lisa-tracker-write` (`issue_type: Task`, labeled `type:tooling`) describing the missing tool/credential/environment and which flow needs it. Link it `blocks` the rework ticket. Pass `human_gate: "a human must grant the missing access"` per `ready-role-filing` — the factory cannot provision its own credentials, so this is a declared gate rather than an unclaimed filing. |
|
|
100
|
+
| `environment-data` | Project tracker | Create an environment-hardening ticket via `lisa-tracker-write` citing the drift/fixture/shared-state evidence. Link `relates to` the rework ticket. Pass `build_ready: true` when the hardening is a code/fixture change the factory can make, or `human_gate: "<the shared-environment decision a human owns>"` when it is not — per `ready-role-filing`, never neither. |
|
|
101
101
|
| `prd-defect` | Source PRD | Comment on the PRD (via the `lisa-prd-backlink` lineage) quoting the defective requirement and the QA failure; flag for product review. Do NOT silently edit the PRD — spec changes are a human gate. |
|
|
102
102
|
| `implementation-defect` (no secondary) | None | Normal fix path; the classification comment is the record. Pass the pattern to the `learner` phase — repeated implementation defects of the same shape escalate to `verification-gap`. |
|
|
103
103
|
|
|
@@ -83,4 +83,5 @@ If the canonical fix is merged but not yet on the production branch, the close c
|
|
|
83
83
|
- **Leaf-only dispatch, every vendor.** Per the `leaf-only-lifecycle` rule, each vendor scanner dispatches leaf work units only and moves or safe-blocks a container (open child work, or a childless Epic) carrying a stale build-ready role according to its lifecycle semantics. This shim does not re-implement the gate — it relies on the vendor scanner's Phase 3a — but the contract is uniform across `jira`, `github`, and `linear` so behavior never drifts by tracker.
|
|
84
84
|
- **Terminal native closure, every capable vendor.** Per the same rule, each vendor scanner finalizes native open/closed state only at the true terminal `done` value. This shim never performs native closure itself, but callers can rely on the dispatched vendor scanner to apply the contract.
|
|
85
85
|
- **Duplicate already fixed, every vendor.** Auto-close without a PR is allowed only for `DUPLICATE_ALREADY_FIXED` with canonical reference and empirical base-branch evidence. Do not conflate this with `BLOCKED`.
|
|
86
|
+
- **Claim-time guards, every vendor.** Per the `claim-time-guards` rule, each vendor scanner runs both guards inside its Phase 3b before the claim transition: an item whose own key already appears in git history or an open/merged PR routes to **verify-and-close** rather than being built twice, and the **`two-failed-attempts`** valve moves an item with two `[lisa-build-attempt]` markers to the configured blocked role and stops the cycle. This shim does not re-implement either guard; it forwards the contract so behavior never drifts by tracker.
|
|
86
87
|
- Never run two intake cycles concurrently against overlapping queues — the scheduling layer is responsible for serialization.
|
|
@@ -24,4 +24,5 @@ See the `config-resolution` rule for configuration and dispatch table.
|
|
|
24
24
|
## Rules
|
|
25
25
|
|
|
26
26
|
- All vendor skills delegate every individual ticket write through `lisa-tracker-write`. They never call vendor-specific write tools directly.
|
|
27
|
+
- **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-tracker-write` rejects it.
|
|
27
28
|
- This shim is for ad-hoc creation from code files / descriptions. PRD-driven creation goes through the `*-to-tracker` skills (notion / confluence / linear / github).
|
|
@@ -52,3 +52,4 @@ See the `config-resolution` rule for the full configuration schema and skill-map
|
|
|
52
52
|
- Never accept a tracker value outside `{jira, github, linear}`.
|
|
53
53
|
- Never mutate `$ARGUMENTS` between layers. The vendor skills define their own input contract.
|
|
54
54
|
- Never inline gate logic here. All validation rules live in the vendor skills (`lisa-jira-validate-ticket` / `lisa-github-validate-issue` / `lisa-linear-validate-issue`); this skill only routes.
|
|
55
|
+
- **Readiness is the caller's explicit claim, not this shim's default.** Per the `ready-role-filing` rule, an omitted `build_ready` is **not build-ready** on every vendor, so a caller filing work it expects build-intake to pick up must pass `build_ready: true`, and a caller deliberately holding work outside the queue must pass a `human_gate` reason. This shim normalizes nothing — it forwards `$ARGUMENTS` verbatim and the vendor writers enforce the contract — which is exactly why the caller cannot rely on a vendor default here.
|
|
@@ -71,7 +71,8 @@ Resolve the **effective** role → name mapping using the same defaults `/lisa:i
|
|
|
71
71
|
- **Missing / empty tracker**: report `UNRESOLVABLE` with setup guidance (`/lisa:setup:jira`, `/lisa:setup:github`, or `/lisa:setup:linear`). Do not default to JIRA.
|
|
72
72
|
- **JIRA build workflow** (`jira.workflow`): `ready`, `claimed`, optional `review`, `blocked`, and each `done.<env>` (`dev` / `staging` / `production`). Defaults: `Ready`, `In Progress`, `Code Review`, `Blocked`, `{dev: "On Dev", staging: "On Stg", production: "Done"}`.
|
|
73
73
|
- **GitHub build/prd labels** (`github.labels.build`, `github.labels.prd`): each configured label string.
|
|
74
|
-
- **Linear build
|
|
74
|
+
- **Linear build workflow** (`linear.workflow`): `ready`, `claimed`, `review`, `blocked`, and each `done.<env>` — native workflow **states**, the Linear analogue of `jira.workflow`, not of `github.labels`. Defaults: `Ready`, `In Progress`, `In Review`, `Blocked`, `{dev: "On Dev", staging: "On Stg", production: "Done"}`.
|
|
75
|
+
- **Linear labels** (`linear.labels`): the `prd.*` map plus the one surviving build-lane key, the `human_needed` marker (`linear.labels.build.human_needed`). A config that predates the state model may still carry `ready` / `claimed` / `blocked` / `done` under `linear.labels.build`; those are **inert** — nothing reads them. Do not audit them against the live label set, and do not report them as drift. Report them once as a migration note pointing at `/lisa:setup:linear`, which removes them.
|
|
75
76
|
- **Notion PRD values** (`notion.values`): each configured select-option value, validated against the `notion.statusProperty` property's options.
|
|
76
77
|
- **Confluence PRD parents** (`confluence.parents`): each configured parent page id, validated by existence.
|
|
77
78
|
|
|
@@ -103,7 +104,9 @@ gh label list --repo "$REPO" --limit 200 --json name -q '.[].name'
|
|
|
103
104
|
|
|
104
105
|
### Linear / Notion / Confluence
|
|
105
106
|
|
|
106
|
-
Enumerate via the corresponding access surface (
|
|
107
|
+
Enumerate via the corresponding access surface (`lisa-linear-access` workflow states + labels; Notion data-source select options for `notion.statusProperty`; Confluence page-exists check per parent id). Same compare-exact-case contract as JIRA.
|
|
108
|
+
|
|
109
|
+
For Linear, `lisa-linear-access operation: list-workflow-states` returns each state's `name`, `type`, `position` and `isTeamDefault` (the access layer sets it from the team's `defaultIssueState`). **Keep `isTeamDefault`** — Step 4 needs it, and it is the only authoritative answer to "which state does this team create Issues into". Do not approximate it with a name guess: `Todo` is merely the stock name, and a team that renamed its `defaultIssueState` is exactly the case a name guess misses.
|
|
107
110
|
|
|
108
111
|
## Step 4 — Compare (exact case)
|
|
109
112
|
|
|
@@ -113,10 +116,14 @@ For each `(role, configured-name)` pair, classify against the live name set:
|
|
|
113
116
|
- **CASE_DRIFT** — a case-insensitive match exists but no exact-case match (e.g. config `"On Stg"` vs live `"ON STG"`). Canonical = the live exact name.
|
|
114
117
|
- **MISSING** — no case-insensitive match exists. The name was renamed beyond recognition or deleted.
|
|
115
118
|
|
|
119
|
+
One role carries a further check that name-existence cannot express:
|
|
120
|
+
|
|
121
|
+
- **INVERTED** — Linear only, `ready` only: the configured state exists, but it is the team's **default created state** (`isTeamDefault`). This is worse than a name that does not resolve. The name resolves perfectly, so every existence check passes while the gate runs backwards: `ready` is supposed to mean "a human moved this Issue here", and the team's default means "nobody has touched this". Build-intake claims from that lane, so an INVERTED mapping dispatches work no human ever approved. Measured on the first team it hit: 20 Issues in the claimable lane, 12 never marked ready — including decision tickets shaped like leaves, which the leaf-only gate cannot catch either. Report it even when every other role is VALID.
|
|
122
|
+
|
|
116
123
|
A project's verdict:
|
|
117
124
|
|
|
118
125
|
- **VALID** — every role is VALID.
|
|
119
|
-
- **DRIFTED** — at least one CASE_DRIFT or
|
|
126
|
+
- **DRIFTED** — at least one CASE_DRIFT, MISSING, or INVERTED role, none of which is UNRESOLVABLE. An INVERTED `ready` is never VALID, no matter how cleanly it resolves.
|
|
120
127
|
- **UNRESOLVABLE** — the live set couldn't be enumerated (auth mismatch, missing tracker config, access failure). Distinguish this loudly from VALID — an unresolved audit is not a passing audit.
|
|
121
128
|
|
|
122
129
|
## Step 5 — Report
|
|
@@ -134,7 +141,17 @@ Per project, print a terminal-first section:
|
|
|
134
141
|
done.production Done Done VALID
|
|
135
142
|
```
|
|
136
143
|
|
|
137
|
-
|
|
144
|
+
An INVERTED `ready` gets a full line rather than a one-word status, because the operator reading it is not necessarily an engineer and the word alone does not convey the stakes:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
ready Todo Todo INVERTED
|
|
148
|
+
"Todo" is the state this Linear team puts every NEW issue into, so the
|
|
149
|
+
build queue is currently claiming issues nobody marked ready. Pick or
|
|
150
|
+
create a state a person moves an issue into (Lisa's default is "Ready")
|
|
151
|
+
via /lisa:setup:linear, then set linear.workflow.ready to it.
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
End with a roll-up: counts of VALID / DRIFTED / UNRESOLVABLE projects and the exact next command (`… repair=true` when drift is auto-repairable; an admin note when a status is genuinely MISSING; `/lisa:setup:linear` when a `ready` is INVERTED).
|
|
138
155
|
|
|
139
156
|
## Step 6 — Repair (only when `repair=true`)
|
|
140
157
|
|
|
@@ -166,6 +183,18 @@ Compute the closest live candidates (case-insensitive token/substring overlap, t
|
|
|
166
183
|
|
|
167
184
|
Only write on an explicit pick. Never auto-select. If the user leaves it unchanged, keep the project `DRIFTED` and surface the admin remediation (add the status back, or fix it in the tracker).
|
|
168
185
|
|
|
186
|
+
### INVERTED — never auto-repair
|
|
187
|
+
|
|
188
|
+
**Never auto-repair an INVERTED `ready`, even with `repair=true`.** Every other classification has one correct answer that the live tracker already knows: CASE_DRIFT has the canonical casing, MISSING has a shortlist of near-matches. INVERTED has neither. The configured name is live and correctly cased; what is wrong is which lane the project chose to mean "build-ready", and nothing in the config or the tracker records what the human intended instead. Guessing would silently repoint the queue at a lane that may hold nothing, or worse, at another lane the team fills automatically — swapping one wrong answer for a quieter one.
|
|
189
|
+
|
|
190
|
+
The team may also genuinely not have a dedicated ready lane yet, in which case the repair is to **create a state**, not to rewrite a string — `/lisa:validate-tracker-mapping` audits config, it does not mutate the tracker.
|
|
191
|
+
|
|
192
|
+
So: present the team's non-default states via `AskUserQuestion`, and write `linear.workflow.ready` only on an explicit pick. If none fits, or the user declines, leave the config untouched, keep the project `DRIFTED`, and hand off:
|
|
193
|
+
|
|
194
|
+
> Linear has no dedicated build-ready state on this team. Run `/lisa:setup:linear` — it offers to create `Ready` and records the mapping.
|
|
195
|
+
|
|
196
|
+
Until then, say plainly that the build queue is claiming unapproved work and that pausing build intake is the safe interim.
|
|
197
|
+
|
|
169
198
|
### Invalidate the verification cache
|
|
170
199
|
|
|
171
200
|
After any JIRA repair, clear the `setup-jira` reachability cache so it re-verifies the new mapping:
|
|
@@ -35,7 +35,7 @@ Treat the first successful lead-spawn request (or, on the Codex fallback, the fi
|
|
|
35
35
|
|
|
36
36
|
Execute the **Verify** flow as defined in the `intent-routing` rule (loaded via the lisa plugin). The flow includes:
|
|
37
37
|
|
|
38
|
-
1. **Pre-flight: codification gate** — confirm that every passing local empirical verification on this branch was codified as a regression test (the Implement flow's codify step). If any verification has no committed test and no allowed skip reason (PR / Documentation / Deploy / Investigate-Only), invoke `codify-verification` now and amend the PR before shipping. For frontend work the gate additionally enforces the `bdd-e2e-coverage` rule: the shipped behavior exists as a Gherkin scenario with a stable ID, every required scenario-platform obligation has aligned automation in the project's configured runner for that platform or a dated waiver, and the project's coverage gate passes with the matrix regenerated. A missing runner is never a bare recorded absence — it needs a dated `platformWaivers` entry (per the rule) and, where the runner could reasonably be added, a linked build-ready follow-up ticket referenced from it; never a silent skip. Missing BDD coverage is a verification failure that blocks the ship, not a warning. A change cannot ship until its verifications are guarded. For work that adds or changes persistent state the gate additionally enforces the `reset-seed-coverage` rule: every entity the work introduces or changes is classified in the project's state contract, anything `fixture-owned` has an ownership predicate and a sweep, and the state-classification check passes — an unclassified entity fails closed and blocks the ship exactly as missing BDD coverage does.
|
|
38
|
+
1. **Pre-flight: codification gate** — confirm that every passing local empirical verification on this branch was codified as a regression test (the Implement flow's codify step). If any verification has no committed test and no allowed skip reason (PR / Documentation / Deploy / Investigate-Only), invoke `codify-verification` now and amend the PR before shipping. For frontend work the gate additionally enforces the `bdd-e2e-coverage` rule: the shipped behavior exists as a Gherkin scenario with a stable ID, every required scenario-platform obligation has aligned automation in the project's configured runner for that platform or a dated waiver, and the project's coverage gate passes with the matrix regenerated. A missing runner is never a bare recorded absence — it needs a dated `platformWaivers` entry (per the rule) and, where the runner could reasonably be added, a linked build-ready follow-up ticket referenced from it — filed through `lisa-tracker-write` with explicit `build_ready: true` per `ready-role-filing`, since an omitted flag is NOT build-ready on any tracker and the waiver would then point at work nothing claims; never a silent skip. Missing BDD coverage is a verification failure that blocks the ship, not a warning. A change cannot ship until its verifications are guarded. For work that adds or changes persistent state the gate additionally enforces the `reset-seed-coverage` rule: every entity the work introduces or changes is classified in the project's state contract, anything `fixture-owned` has an ownership predicate and a sweep, and the state-classification check passes — an unclassified entity fails closed and blocks the ship exactly as missing BDD coverage does.
|
|
39
39
|
2. **Commit** any pending changes via `lisa-git-commit`
|
|
40
40
|
3. **Push and PR** via `lisa-git-submit-pr`
|
|
41
41
|
4. **PR Watch Loop** — drive the PR to MERGED via `lisa-drive-pr-to-merge`, the single source of truth for clearing every blocker: auto-merge with direct-merge fallback, `BEHIND` re-sync, conflict resolution, failing-check fixes, human + bot review-comment handling with thread resolution (it invokes `lisa-pull-request-review` itself), stale `CHANGES_REQUESTED` dismissal, and post-merge ancestry verification. Do not re-implement the loop or its terminal conditions.
|
|
@@ -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.
|