@codyswann/lisa 2.353.0 → 3.1.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 +83 -47
- 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/nightly-e2e-report.yml +71 -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-atlassian-access/SKILL.md +75 -64
- 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-jam-access/SKILL.md +13 -5
- 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 +30 -10
- 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-access/SKILL.md +36 -23
- 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-posthog-access/SKILL.md +16 -6
- 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-secrets-access/SKILL.md +8 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-sentry-access/SKILL.md +16 -6
- package/plugins/lisa/.codex-plugin/skills/lisa-sonarcloud-access/SKILL.md +7 -1
- 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-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/integration-access-layer.md +7 -3
- 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/credential-substrate-precedence.md +166 -0
- package/plugins/lisa/rules/reference/integration-access-layer.md +27 -15
- package/plugins/lisa/rules/reference/ready-role-filing.md +66 -0
- package/plugins/lisa/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/lisa/skills/lisa-atlassian-access/SKILL.md +76 -65
- 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-jam-access/SKILL.md +14 -6
- 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 +31 -11
- 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-access/SKILL.md +37 -24
- 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-posthog-access/SKILL.md +17 -7
- 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-secrets-access/SKILL.md +8 -0
- package/plugins/lisa/skills/lisa-sentry-access/SKILL.md +17 -7
- package/plugins/lisa/skills/lisa-sonarcloud-access/SKILL.md +7 -1
- 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-verify/SKILL.md +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/lisa-agy/skills/lisa-atlassian-access/SKILL.md +76 -65
- 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-jam-access/SKILL.md +14 -6
- 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 +31 -11
- 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-access/SKILL.md +37 -24
- 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-posthog-access/SKILL.md +17 -7
- 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-secrets-access/SKILL.md +8 -0
- package/plugins/lisa-agy/skills/lisa-sentry-access/SKILL.md +17 -7
- package/plugins/lisa-agy/skills/lisa-sonarcloud-access/SKILL.md +7 -1
- 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-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/integration-access-layer.md +7 -3
- 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/credential-substrate-precedence.md +166 -0
- package/plugins/lisa-copilot/rules/reference/integration-access-layer.md +27 -15
- package/plugins/lisa-copilot/rules/reference/ready-role-filing.md +66 -0
- package/plugins/lisa-copilot/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/lisa-copilot/skills/lisa-atlassian-access/SKILL.md +76 -65
- 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-jam-access/SKILL.md +14 -6
- 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 +31 -11
- 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-access/SKILL.md +37 -24
- 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-posthog-access/SKILL.md +17 -7
- 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-secrets-access/SKILL.md +8 -0
- package/plugins/lisa-copilot/skills/lisa-sentry-access/SKILL.md +17 -7
- package/plugins/lisa-copilot/skills/lisa-sonarcloud-access/SKILL.md +7 -1
- 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-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/credential-substrate-precedence-reference.mdc +171 -0
- package/plugins/lisa-cursor/rules/integration-access-layer-reference.mdc +27 -15
- package/plugins/lisa-cursor/rules/integration-access-layer.mdc +7 -3
- 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/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/lisa-cursor/skills/lisa-atlassian-access/SKILL.md +76 -65
- 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-jam-access/SKILL.md +14 -6
- 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 +31 -11
- 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-access/SKILL.md +37 -24
- 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-posthog-access/SKILL.md +17 -7
- 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-secrets-access/SKILL.md +8 -0
- package/plugins/lisa-cursor/skills/lisa-sentry-access/SKILL.md +17 -7
- package/plugins/lisa-cursor/skills/lisa-sonarcloud-access/SKILL.md +7 -1
- 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-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/integration-access-layer.md +7 -3
- 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/credential-substrate-precedence.md +166 -0
- package/plugins/src/base/rules/reference/integration-access-layer.md +27 -15
- package/plugins/src/base/rules/reference/ready-role-filing.md +66 -0
- package/plugins/src/base/skills/lisa-agent-ready/SKILL.md +5 -3
- package/plugins/src/base/skills/lisa-atlassian-access/SKILL.md +76 -65
- 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-jam-access/SKILL.md +14 -6
- 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 +31 -11
- 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-access/SKILL.md +37 -24
- 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-posthog-access/SKILL.md +17 -7
- 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-secrets-access/SKILL.md +8 -0
- package/plugins/src/base/skills/lisa-sentry-access/SKILL.md +17 -7
- package/plugins/src/base/skills/lisa-sonarcloud-access/SKILL.md +7 -1
- 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-verify/SKILL.md +1 -1
- package/typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs +631 -5
|
@@ -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.
|
|
@@ -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**,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lisa-atlassian-access
|
|
3
|
-
description: "Vendor-neutral access layer for Atlassian (JIRA + Confluence). Every jira-* and confluence-* skill MUST delegate through this skill rather than calling Atlassian directly.
|
|
3
|
+
description: "Vendor-neutral access layer for Atlassian (JIRA + Confluence). Every jira-* and confluence-* skill MUST delegate through this skill rather than calling Atlassian directly. Per the credential-substrate-precedence contract, resolves a substrate per operation with the ATLASSIAN_API_TOKEN curl path first for reads and writes alike whenever the token is present and identity-matched — binding JIRA writes to the configured cloudId — then acli, then the Atlassian MCP as fallbacks. acli is used when installed and switchable to a profile matching the configured site; mismatched active profiles are skipped only after switch plus re-verification fails, and acli writes are a guarded fallback with post-write tenant assertions."
|
|
4
4
|
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -35,46 +35,17 @@ EMAIL=$(jq -r '.atlassian.email // empty' .lisa.config.local.json 2>/dev/null)
|
|
|
35
35
|
[ -z "$CLOUDID" ] && { echo "Error: atlassian.cloudId not set. Run /lisa:setup:atlassian." >&2; exit 1; }
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Probe each tier in order; the first that's ready AND identity-matches is the substrate for this operation. Identity-match is verified before any operation; substrates authenticated as a different Atlassian account are switched to the configured profile when one exists, then skipped only if the switch fails or re-verification still mismatches.
|
|
38
|
+
Probe each tier in order; the first that's ready AND identity-matches is the substrate for this operation. The ordering is the shared `credential-substrate-precedence` contract — the configured-provider token substrate leads for **reads and writes alike**, with acli and the MCP as identity-matched fallbacks — not an Atlassian-local choice. Identity-match is verified before any operation; substrates authenticated as a different Atlassian account are switched to the configured profile when one exists, then skipped only if the switch fails or re-verification still mismatches.
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
41
|
substrate=""
|
|
42
42
|
|
|
43
|
-
# Tier 1:
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
if [ "$OP_KIND" != "jira-write" ] && command -v acli >/dev/null 2>&1 && acli auth status >/dev/null 2>&1; then
|
|
50
|
-
current_site=$(acli auth status 2>/dev/null | awk '/^ Site:/{print $2}')
|
|
51
|
-
if [ "$current_site" != "$SITE" ]; then
|
|
52
|
-
# acli installed but pointing at a different site. Try switching profiles.
|
|
53
|
-
acli auth switch --site "$SITE" ${EMAIL:+--email "$EMAIL"} >/dev/null 2>&1 || true
|
|
54
|
-
current_site=$(acli auth status 2>/dev/null | awk '/^ Site:/{print $2}')
|
|
55
|
-
fi
|
|
56
|
-
if [ "$current_site" = "$SITE" ]; then
|
|
57
|
-
substrate="acli"
|
|
58
|
-
fi
|
|
59
|
-
fi
|
|
60
|
-
|
|
61
|
-
# Tier 2: Atlassian MCP (if acli not ready OR the operation isn't acli-covered)
|
|
62
|
-
# $OP_REQUIRES is a conceptual variable set by the dispatch table to "non-acli" for
|
|
63
|
-
# operations that have no acli adapter (e.g. read-page-descendants). It is not a real
|
|
64
|
-
# shell variable initialized here — the condition is illustrative pseudo-code.
|
|
65
|
-
if [ -z "$substrate" ] || [ "$OP_REQUIRES" = "non-acli" ]; then
|
|
66
|
-
# Probe via mcp__plugin_atlassian_atlassian__getAccessibleAtlassianResources.
|
|
67
|
-
# (Pseudo-code; actual call is the MCP tool invocation, not a bash command.)
|
|
68
|
-
# If the MCP returns a list and $CLOUDID is in it, MCP is identity-matched.
|
|
69
|
-
# If the MCP is unauthenticated or $CLOUDID is NOT in the list, MCP is skipped.
|
|
70
|
-
if mcp_atlassian_authenticated_and_matches_cloudid "$CLOUDID"; then
|
|
71
|
-
: ${substrate:=mcp}
|
|
72
|
-
# Mark MCP as available even if acli already won tier 1 — used for ops acli can't do.
|
|
73
|
-
mcp_available=true
|
|
74
|
-
fi
|
|
75
|
-
fi
|
|
76
|
-
|
|
77
|
-
# Tier 3: curl + API token (headless / multi-account / scoped-token path)
|
|
43
|
+
# Tier 1: curl + API token — the configured-provider substrate, resolved through
|
|
44
|
+
# lisa-secrets-access. Leads for every operation because it is per-invocation-bound:
|
|
45
|
+
# the cloudId-scoped gateway URL and the token's own account carry the tenant inside
|
|
46
|
+
# the request, so no ambient machine-global state can redirect it. acli (one global
|
|
47
|
+
# active account) and the MCP (browser OAuth session) are ambient-bound and therefore
|
|
48
|
+
# TOCTOU-exposed — see credential-substrate-precedence, "tenant safety".
|
|
78
49
|
read_atlassian_token() {
|
|
79
50
|
local email="$1"
|
|
80
51
|
[ -n "$ATLASSIAN_API_TOKEN" ] && { echo "$ATLASSIAN_API_TOKEN"; return; }
|
|
@@ -136,13 +107,50 @@ public static class LisaCred {
|
|
|
136
107
|
esac
|
|
137
108
|
}
|
|
138
109
|
TOKEN=$(read_atlassian_token "$EMAIL")
|
|
139
|
-
[ -n "$TOKEN" ]
|
|
140
|
-
|
|
110
|
+
if [ -n "$TOKEN" ]; then
|
|
111
|
+
# Identity-match before use: /rest/api/3/myself must report the configured account
|
|
112
|
+
# (Step 2). A present-but-wrong token fails the gate loudly instead of quietly
|
|
113
|
+
# deferring to an acli profile or MCP session authenticated somewhere else — that
|
|
114
|
+
# silent success is the bug class the precedence contract exists to surface.
|
|
115
|
+
if atlassian_token_matches_config "$TOKEN" "$EMAIL" "$CLOUDID"; then
|
|
116
|
+
curl_available=true
|
|
141
117
|
substrate="curl"
|
|
142
118
|
else
|
|
143
|
-
:
|
|
119
|
+
echo "Warning: ATLASSIAN_API_TOKEN does not match the configured account/site. Skipping curl tier." >&2
|
|
144
120
|
fi
|
|
145
|
-
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
# Tier 2: acli — identity-matched fallback. Used when no token is available, or for
|
|
124
|
+
# operations with no curl adapter. Never the primary path for JIRA writes when token
|
|
125
|
+
# auth is available: acli stores one machine-global active account and workitem writes
|
|
126
|
+
# cannot pin a cloudId per invocation, so switch-then-write is a TOCTOU risk in
|
|
127
|
+
# multi-account or concurrent sessions. When a write does land here it is the *guarded*
|
|
128
|
+
# fallback documented in the dispatch table (assert, write, re-read, assert, roll back).
|
|
129
|
+
if command -v acli >/dev/null 2>&1 && acli auth status >/dev/null 2>&1; then
|
|
130
|
+
current_site=$(acli auth status 2>/dev/null | awk '/^ Site:/{print $2}')
|
|
131
|
+
if [ "$current_site" != "$SITE" ]; then
|
|
132
|
+
# acli installed but pointing at a different site. Try switching profiles.
|
|
133
|
+
acli auth switch --site "$SITE" ${EMAIL:+--email "$EMAIL"} >/dev/null 2>&1 || true
|
|
134
|
+
current_site=$(acli auth status 2>/dev/null | awk '/^ Site:/{print $2}')
|
|
135
|
+
fi
|
|
136
|
+
if [ "$current_site" = "$SITE" ]; then
|
|
137
|
+
acli_available=true
|
|
138
|
+
# Mark acli available even if curl already won tier 1 — used for ops curl can't do.
|
|
139
|
+
: ${substrate:=acli}
|
|
140
|
+
fi
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# Tier 3: Atlassian MCP — first-class interactive fallback, for when neither tier above
|
|
144
|
+
# is available or covers the operation (e.g. an op with no curl and no acli adapter).
|
|
145
|
+
# Probe via mcp__plugin_atlassian_atlassian__getAccessibleAtlassianResources.
|
|
146
|
+
# (Pseudo-code; actual call is the MCP tool invocation, not a bash command.)
|
|
147
|
+
# If the MCP returns a list and $CLOUDID is in it, MCP is identity-matched.
|
|
148
|
+
# If the MCP is unauthenticated or $CLOUDID is NOT in the list, MCP is skipped.
|
|
149
|
+
if mcp_atlassian_authenticated_and_matches_cloudid "$CLOUDID"; then
|
|
150
|
+
: ${substrate:=mcp}
|
|
151
|
+
# Mark MCP as available even if an earlier tier won — used for ops they can't do.
|
|
152
|
+
mcp_available=true
|
|
153
|
+
fi
|
|
146
154
|
|
|
147
155
|
# Fail loudly with actionable remediation if nothing works.
|
|
148
156
|
if [ -z "$substrate" ]; then
|
|
@@ -154,15 +162,25 @@ if [ -z "$substrate" ]; then
|
|
|
154
162
|
cat >&2 <<EOF
|
|
155
163
|
Error: no Atlassian access substrate available for site $SITE.
|
|
156
164
|
|
|
157
|
-
Attempted:
|
|
165
|
+
Attempted (in credential-substrate-precedence order):
|
|
166
|
+
curl — no ATLASSIAN_API_TOKEN found for $EMAIL (env, slug-suffixed env, or keychain) OR the token does not match the configured account/site
|
|
158
167
|
acli — $(command -v acli >/dev/null && echo "installed but identity mismatch or unauthenticated" || echo "not installed")
|
|
159
168
|
MCP — $([ "$plugin_enabled_global" = "true" ] || [ "$plugin_enabled_project" = "true" ] || [ "$plugin_enabled_local" = "true" ] && echo "plugin enabled but not authenticated or cloudId $CLOUDID not in accessible resources" || echo "plugin not enabled in any settings.json scope")
|
|
160
|
-
curl — no ATLASSIAN_API_TOKEN found for $EMAIL (env, slug-suffixed env, or keychain)
|
|
161
169
|
|
|
162
|
-
Remediation paths (
|
|
170
|
+
Remediation paths (the first is the contract's primary path):
|
|
171
|
+
|
|
172
|
+
1. Provision an API token — works headless, in CI, in subagents, and in
|
|
173
|
+
multi-account setups, and is the substrate this project resolves first.
|
|
174
|
+
|
|
175
|
+
Run /lisa:setup:atlassian — guided flow with clipboard-piped keychain store.
|
|
176
|
+
|
|
177
|
+
2. Install acli and authenticate (identity-matched fallback for multi-account developers).
|
|
163
178
|
|
|
164
|
-
|
|
165
|
-
|
|
179
|
+
brew tap atlassian/homebrew-acli && brew install acli
|
|
180
|
+
acli auth login # OAuth as the account matching $EMAIL
|
|
181
|
+
|
|
182
|
+
3. Install the Atlassian MCP plugin (local scope — per-developer, gitignored).
|
|
183
|
+
The supported fallback when no credentials provider is configured.
|
|
166
184
|
|
|
167
185
|
Run in your terminal:
|
|
168
186
|
|
|
@@ -174,25 +192,16 @@ Remediation paths (pick one):
|
|
|
174
192
|
Then restart Claude Code (or run /restart-mcp) to load the plugin, and
|
|
175
193
|
invoke 'mcp__plugin_atlassian_atlassian__authenticate' to complete OAuth.
|
|
176
194
|
|
|
177
|
-
2. Install acli and authenticate (best for multi-account developers).
|
|
178
|
-
|
|
179
|
-
brew tap atlassian/homebrew-acli && brew install acli
|
|
180
|
-
acli auth login # OAuth as the account matching $EMAIL
|
|
181
|
-
|
|
182
|
-
3. Provision an API token (headless / CI / scoped-token environments).
|
|
183
|
-
|
|
184
|
-
Run /lisa:setup:atlassian — guided flow with clipboard-piped keychain store.
|
|
185
|
-
|
|
186
195
|
EOF
|
|
187
196
|
exit 1
|
|
188
197
|
fi
|
|
189
198
|
```
|
|
190
199
|
|
|
191
|
-
Operation dispatch then uses `$substrate` for the primary route. If the operation has no
|
|
200
|
+
Operation dispatch then uses `$substrate` for the primary route. If the operation has no adapter for the selected substrate, fall through in contract order — `$curl_available`, then `$acli_available`, then `$mcp_available` — skipping the tier already tried. The fall-through stops at the first available tier that can perform the operation. A tier that failed identity-match is never in the fall-through set.
|
|
192
201
|
|
|
193
202
|
### Step 2 — Connection-match check
|
|
194
203
|
|
|
195
|
-
The active connection MUST point at the cloudId/site declared in `.lisa.config.json`. Step 1's substrate selection already tries to switch mismatched acli profiles
|
|
204
|
+
The active connection MUST point at the cloudId/site declared in `.lisa.config.json`. Identity-match is mandatory on **every** substrate, tier 1 included (`credential-substrate-precedence`); the "curl mode check" below *is* the tier-1 gate referenced as `atlassian_token_matches_config` in Step 1. Step 1's substrate selection already validates the token account and tries to switch mismatched acli profiles before selection. This step repeats the assertion before any operation runs — defensive in case the substrate state changed since selection.
|
|
196
205
|
|
|
197
206
|
Read configured site:
|
|
198
207
|
|
|
@@ -291,12 +300,12 @@ Rules:
|
|
|
291
300
|
|
|
292
301
|
### Step 3 — Operation dispatch
|
|
293
302
|
|
|
294
|
-
Substrate column meanings:
|
|
303
|
+
Substrate column meanings (ordering per `credential-substrate-precedence`):
|
|
295
304
|
|
|
296
|
-
- **`
|
|
297
|
-
- **`
|
|
298
|
-
- **`
|
|
299
|
-
- Multiple cells filled means tier ordering applies — try
|
|
305
|
+
- **`curl`**: routes through curl + Basic auth + `ATLASSIAN_API_TOKEN` — the configured-provider substrate. Preferred for every operation, read or write, whenever the token is present and identity-matched.
|
|
306
|
+
- **`acli`**: routes through `acli`. Identity-matched fallback — used when no token is available or the op has no curl adapter. For JIRA writes it is the *guarded* fallback (see the tenant-safety rule below).
|
|
307
|
+
- **`MCP`**: routes through the Atlassian MCP. First-class fallback for ops neither tier above covers, when identity-matched (cloudId in `getAccessibleAtlassianResources`).
|
|
308
|
+
- Multiple cells filled means tier ordering applies — try curl, then acli, then MCP, taking the first that has an adapter for the op AND is identity-matched.
|
|
300
309
|
- One cell means only that substrate can perform the op.
|
|
301
310
|
|
|
302
311
|
`<SITE>` = `.atlassian.site` (e.g. `acme.atlassian.net`). `<CLOUDID>` = `.atlassian.cloudId`. `<AUTH>` = `Basic $(printf '%s:%s' "$email" "$ATLASSIAN_API_TOKEN" | base64)`. JIRA curl writes use the cloudId-bound Atlassian gateway `https://api.atlassian.com/ex/jira/<CLOUDID>/rest/api/3/...`; JIRA curl reads may use either that gateway or `https://<SITE>/rest/api/3/...` after the token account check. Confluence uses `/wiki/rest/api/...` (v1) or `/api/v2/...` (v2).
|
|
@@ -334,7 +343,7 @@ Substrate column meanings:
|
|
|
334
343
|
|
|
335
344
|
**acli flag note:** acli's `--output` flag does not exist; the correct flag is `--json`. List commands require `--paginate` or `--limit` (no implicit fetch-all). `acli jira workitem view` defaults to a restricted field set (`key,issuetype,summary,status,assignee,description`), so `read-ticket` MUST pass `--fields '*all'` or an explicit equivalent that includes every downstream dependency: parent, subtasks, issue links, components, labels, priority, status, issue type, summary, description, fix versions, affected versions, attachments, comments, estimates, sprint/story-point fields, and project-required custom fields. Never rely on the default view fields; they hide parent/components/labels and corrupt leaf-only, relationship-search, build-ready, and required-custom-field gates. Several documented adapters are nominal — verify against `acli <subcmd> --help` before relying on them. When acli's adapter is broken or missing for a specific op, fall through to MCP (if identity-matched) then curl per the tier ordering.
|
|
336
345
|
|
|
337
|
-
**JIRA write tenant-safety rule
|
|
346
|
+
**JIRA write tenant-safety rule** — the Atlassian instance of the shared guarded-fallback protocol in `credential-substrate-precedence` (which states the general rule: prefer the per-invocation-bound substrate over the ambient-bound one, for reads and writes alike; the rationale is not restated here). Create, edit, transition, comment, and link are write operations. They MUST use the curl adapter whenever token auth is available because the URL includes `<CLOUDID>` and cannot be redirected by the user-global acli active account. If the flow must fall back to acli for a write, it is a guarded fallback, not the normal path:
|
|
338
347
|
|
|
339
348
|
1. Switch and assert the active `acli auth status` site/email matches config immediately before the write.
|
|
340
349
|
2. Execute the write.
|
|
@@ -378,15 +387,17 @@ Do not paraphrase substrate output beyond JSON normalization.
|
|
|
378
387
|
## Invariants
|
|
379
388
|
|
|
380
389
|
- Caller skills never invoke `acli` or `curl` against Atlassian directly. They only invoke this skill.
|
|
390
|
+
- Tier order is the shared `credential-substrate-precedence` contract — token curl first (reads **and** writes), then acli, then the Atlassian MCP. Do not restate or locally override the ordering here.
|
|
391
|
+
- acli and the Atlassian MCP remain first-class **fallbacks**, not removed tiers: every adapter stays in the dispatch table, and a project with no credentials provider is fully functional on them.
|
|
381
392
|
- Substrate is decided once per skill invocation and never switches mid-operation.
|
|
382
|
-
- Connection match is mandatory. Operations that bypass it (because "the user obviously meant the configured site") are forbidden.
|
|
393
|
+
- Connection match is mandatory on every tier, including the token tier. Operations that bypass it (because "the user obviously meant the configured site") are forbidden. A present-but-wrong token fails the gate rather than deferring to another substrate.
|
|
383
394
|
- Profile mutations (`acli auth switch`) are allowed when acli is the active substrate. The curl substrate never mutates the token — if `ATLASSIAN_API_TOKEN` doesn't match the configured account, fail loud rather than silently substituting.
|
|
384
395
|
- JIRA writes are cloudId-bound by default. `acli` write adapters are fallback-only and must perform post-write tenant assertions plus safe rollback on mismatch.
|
|
385
396
|
- `.lisa.config.local.json` overrides `.lisa.config.json` per-key — the same precedence rule as every other consumer of project config.
|
|
386
397
|
|
|
387
398
|
## Headless behavior
|
|
388
399
|
|
|
389
|
-
In a headless / non-interactive context, the MCP tier is unavailable (its OAuth flow needs a browser). The
|
|
400
|
+
In a headless / non-interactive context, the MCP tier is unavailable (its OAuth flow needs a browser). The ladder collapses to: curl + `ATLASSIAN_API_TOKEN` → acli (if pre-authenticated, e.g., a CI image baked with a service-account token). Because curl is already tier 1 interactively, headless and interactive sessions take the **same primary path** — that is the "headless parity" arm of `credential-substrate-precedence`, and it is why a credential problem reproduces on a laptop instead of only in cron. Never block on interactive prompts. If both fail readiness checks, exit non-zero with a deterministic error.
|
|
390
401
|
|
|
391
402
|
Treat all four of these as headless:
|
|
392
403
|
|
|
@@ -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>" \
|
|
@@ -191,7 +191,7 @@ authority — if any of these hold:
|
|
|
191
191
|
**On any of those: file a proposed-intervention ticket via `lisa-tracker-write` and STOP.** The
|
|
192
192
|
ticket carries the job contract, the earliest failed handoff, the gap classification with
|
|
193
193
|
evidence, and the proposed change with its expected mechanism; labels `type:harness`,
|
|
194
|
-
`status:blocked` (human-flipped to `status:ready` when approved). Post the result record with
|
|
194
|
+
`status:blocked` plus an explicit `human_gate: "a human approves the proposed harness intervention"` per `ready-role-filing` (human-flipped to `status:ready` when approved). Post the result record with
|
|
195
195
|
`Verdict: bounded-authority-stop`, `Decision: n/a (proposed-intervention, <url>)`, and
|
|
196
196
|
terminate. Implementing it anyway is the failure mode this phase exists to prevent.
|
|
197
197
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lisa-jam-access
|
|
3
|
-
description: "Vendor-neutral access layer for Jam. Jam triage rules and skills MUST delegate through this skill rather than calling Jam MCP tools directly.
|
|
3
|
+
description: "Vendor-neutral access layer for Jam. Jam triage rules and skills MUST delegate through this skill rather than calling Jam MCP tools directly. Per the credential-substrate-precedence contract, resolves the JAM_PAT-authenticated Jam CLI first when the PAT is present and identity-matched, then falls back to the Jam MCP."
|
|
4
4
|
allowed-tools: ["Bash", "Read", "Skill"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -21,13 +21,20 @@ Return parsed JSON or a concise structured summary in a `<result>` block.
|
|
|
21
21
|
|
|
22
22
|
## Substrate Selection
|
|
23
23
|
|
|
24
|
-
Probe in order
|
|
24
|
+
Probe in order — the ordering is the shared `credential-substrate-precedence`
|
|
25
|
+
contract, not a Jam-local choice. The first tier that is ready **and**
|
|
26
|
+
identity-matches the configured Jam account is used; one authenticated elsewhere
|
|
27
|
+
is skipped, never used.
|
|
25
28
|
|
|
26
|
-
1.
|
|
27
|
-
|
|
29
|
+
1. **Tier 1 — configured-provider substrate: Jam CLI authenticated with `JAM_PAT`**,
|
|
30
|
+
resolved through `lisa-secrets-access`.
|
|
31
|
+
2. **Tier 2 — interactive MCP fallback: Jam MCP**, if the tool is available and
|
|
32
|
+
authenticated. Used when tier 1 is genuinely unavailable: no `JAM_PAT`, no CLI
|
|
33
|
+
adapter for the operation, or a Jam outage.
|
|
28
34
|
|
|
29
35
|
Jam documents a PAT-authenticated CLI that is cleaner for remote routines than
|
|
30
|
-
editing `.mcp.json` headers
|
|
36
|
+
editing `.mcp.json` headers, and it is the same substrate interactively and
|
|
37
|
+
headlessly — which is why it leads. The CLI tier uses:
|
|
31
38
|
|
|
32
39
|
```bash
|
|
33
40
|
curl -fsSL https://native.jam.dev/install | bash
|
|
@@ -44,7 +51,8 @@ Error: no Jam access substrate available. Authenticate the Jam MCP or set JAM_PA
|
|
|
44
51
|
|
|
45
52
|
## Invariants
|
|
46
53
|
|
|
47
|
-
-
|
|
54
|
+
- Tier order is `credential-substrate-precedence`: `JAM_PAT` CLI first, Jam MCP as
|
|
55
|
+
a preserved first-class fallback. Do not retry a failed tier blindly.
|
|
48
56
|
- Never commit a Jam PAT into `.mcp.json` or any generated setup artifact.
|
|
49
57
|
- Headless Jam access requires `native.jam.dev` for the installer and
|
|
50
58
|
`api.jam.dev` for CLI/API calls in any custom remote network allowlist.
|
|
@@ -202,6 +202,11 @@ This gate never blocks a legitimate flat Task/Bug: those have no open children a
|
|
|
202
202
|
|
|
203
203
|
**Claim-time archaeology runs second — after rejection detection, still before the transition below.** Classify this ticket 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. JIRA wiring only: the typed relations are already in the read bundle; text-similarity searches run through `lisa-atlassian-access operation: search-issues jql:` over recently-closed tickets; the fallback candidate comment is posted via `lisa-atlassian-access operation: comment`.
|
|
204
204
|
|
|
205
|
+
**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. JIRA wiring only:
|
|
206
|
+
|
|
207
|
+
1. **`two-failed-attempts` valve.** Count `[lisa-build-attempt]` markers on the ticket from the read bundle's comments (match on the marker, never the summary). With two or more, do **not** claim: transition to the configured blocked status (`lisa-atlassian-access operation: transition to: "$BLOCKED"`, resolved from `jira.workflow.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.
|
|
208
|
+
2. **`already-implemented` check.** Probe for this ticket's own key — `git log --all --grep "<TICKET>"` and the merged/open PRs referencing `<TICKET>` (`gh pr list --state all --search "<TICKET>"` in the bound repo). On a hit, claim as normal but route 3c to **verify-and-close** instead of `lisa-implement`: verify what shipped against the ticket's acceptance criteria, post evidence via `lisa-jira-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 ticket) and not `claim-archaeology` (a *different* ancestor ticket); it is this ticket's own work already having shipped without a transition.
|
|
209
|
+
|
|
205
210
|
Transition the ticket from `$READY` to `$CLAIMED` by invoking `lisa-atlassian-access` `operation: transition key: <TICKET> to: "$CLAIMED"`.
|
|
206
211
|
- **Assign to the authenticated user when the ticket is unassigned.** A claim must be attributable. If the ticket has no assignee, assign it to the authenticated account — prefer acli `--assignee @me` (resolves server-side to the authenticated user, which avoids the federated-`accountId` mis-assignment), or `write-ticket` with the `accountId` from the `/rest/api/3/myself` identity probe the access skill already documents. Leave an already-assigned ticket's assignee untouched — never reassign work that already has an owner.
|
|
207
212
|
- Post a `[claude-build-intake]` comment via `lisa-atlassian-access` `operation: comment key: <TICKET> body: "Claimed by Claude. Starting build."`
|
|
@@ -125,6 +125,8 @@ Exclude unless requested: migration plans, performance tests
|
|
|
125
125
|
- Sign-in account and target environment recorded in description
|
|
126
126
|
- Post-create verification
|
|
127
127
|
|
|
128
|
+
**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-jira-write-ticket` rejects it.
|
|
129
|
+
|
|
128
130
|
### Invocation order
|
|
129
131
|
|
|
130
132
|
Tickets must be created in parent-before-child order so each child can be passed its parent key:
|