@codyswann/lisa 4.54.13 → 4.55.1
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/all/copy-contents/.gitattributes +8 -0
- package/all/copy-overwrite/scripts/check-orphaned-branches.mjs +78 -9
- package/all/copy-overwrite/scripts/check-third-party-action-pins.mjs +17 -1
- package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +194 -7
- package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +31 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-blind-automerge.sh +81 -2
- package/all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh +293 -8
- package/all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh +78 -15
- package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/guard-dedupe.bash +340 -0
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +29 -1
- package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.mjs +183 -1
- package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-postinstall.mjs +21 -1
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +100 -5
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +1085 -80
- package/all/create-only/.github/workflows/continuous-gates.yml +7 -0
- package/cdk/create-only/.github/workflows/ci.yml +7 -0
- package/cdk/create-only/.github/workflows/deploy.yml +21 -0
- package/dist/cli/apply.d.ts.map +1 -1
- package/dist/cli/apply.js +9 -1
- package/dist/cli/apply.js.map +1 -1
- package/dist/cli/doctor-apply-deletions.d.ts +61 -0
- package/dist/cli/doctor-apply-deletions.d.ts.map +1 -0
- package/dist/cli/doctor-apply-deletions.js +137 -0
- package/dist/cli/doctor-apply-deletions.js.map +1 -0
- package/dist/cli/doctor-cdk-preset-adoption.d.ts +15 -0
- package/dist/cli/doctor-cdk-preset-adoption.d.ts.map +1 -0
- package/dist/cli/doctor-cdk-preset-adoption.js +316 -0
- package/dist/cli/doctor-cdk-preset-adoption.js.map +1 -0
- package/dist/cli/doctor-config-shadowing.d.ts +22 -0
- package/dist/cli/doctor-config-shadowing.d.ts.map +1 -0
- package/dist/cli/doctor-config-shadowing.js +123 -0
- package/dist/cli/doctor-config-shadowing.js.map +1 -0
- package/dist/cli/doctor-rails-deploy-intent.d.ts +15 -0
- package/dist/cli/doctor-rails-deploy-intent.d.ts.map +1 -0
- package/dist/cli/doctor-rails-deploy-intent.js +197 -0
- package/dist/cli/doctor-rails-deploy-intent.js.map +1 -0
- package/dist/cli/doctor-seeded-artifacts.d.ts +12 -0
- package/dist/cli/doctor-seeded-artifacts.d.ts.map +1 -0
- package/dist/cli/doctor-seeded-artifacts.js +54 -0
- package/dist/cli/doctor-seeded-artifacts.js.map +1 -0
- package/dist/cli/doctor-stale-banner-scan.d.ts +44 -0
- package/dist/cli/doctor-stale-banner-scan.d.ts.map +1 -0
- package/dist/cli/doctor-stale-banner-scan.js +152 -0
- package/dist/cli/doctor-stale-banner-scan.js.map +1 -0
- package/dist/cli/doctor-stale-managed-banner.d.ts +19 -0
- package/dist/cli/doctor-stale-managed-banner.d.ts.map +1 -0
- package/dist/cli/doctor-stale-managed-banner.js +198 -0
- package/dist/cli/doctor-stale-managed-banner.js.map +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +16 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/ui-detected-stacks.d.ts.map +1 -1
- package/dist/cli/ui-detected-stacks.js +3 -2
- package/dist/cli/ui-detected-stacks.js.map +1 -1
- package/dist/cli/update-check.d.ts.map +1 -1
- package/dist/cli/update-check.js +14 -0
- package/dist/cli/update-check.js.map +1 -1
- package/dist/cli/worktree-liveness.d.ts +5 -0
- package/dist/cli/worktree-liveness.d.ts.map +1 -1
- package/dist/cli/worktree-liveness.js +7 -6
- package/dist/cli/worktree-liveness.js.map +1 -1
- package/dist/cli/worktree-ownership.d.ts +13 -0
- package/dist/cli/worktree-ownership.d.ts.map +1 -1
- package/dist/cli/worktree-ownership.js +14 -0
- package/dist/cli/worktree-ownership.js.map +1 -1
- package/dist/configs/eslint/base.d.ts +34 -0
- package/dist/configs/eslint/base.d.ts.map +1 -1
- package/dist/configs/eslint/base.js +34 -0
- package/dist/configs/eslint/base.js.map +1 -1
- package/dist/core/apply-receipt.d.ts +65 -0
- package/dist/core/apply-receipt.d.ts.map +1 -1
- package/dist/core/apply-receipt.js +62 -2
- package/dist/core/apply-receipt.js.map +1 -1
- package/dist/core/cdk-preset-adoption.d.ts +136 -0
- package/dist/core/cdk-preset-adoption.d.ts.map +1 -0
- package/dist/core/cdk-preset-adoption.js +135 -0
- package/dist/core/cdk-preset-adoption.js.map +1 -0
- package/dist/core/config-shadowing.d.ts +36 -0
- package/dist/core/config-shadowing.d.ts.map +1 -1
- package/dist/core/config-shadowing.js +38 -0
- package/dist/core/config-shadowing.js.map +1 -1
- package/dist/core/config.d.ts +11 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/learnings-merge-driver.d.ts +10 -0
- package/dist/core/learnings-merge-driver.d.ts.map +1 -1
- package/dist/core/learnings-merge-driver.js +18 -0
- package/dist/core/learnings-merge-driver.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +136 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +9 -1
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts +5 -5
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +7 -7
- package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
- package/dist/core/ownership-header.d.ts +74 -0
- package/dist/core/ownership-header.d.ts.map +1 -0
- package/dist/core/ownership-header.js +76 -0
- package/dist/core/ownership-header.js.map +1 -0
- package/dist/core/rails-deploy-production-intent.d.ts +36 -0
- package/dist/core/rails-deploy-production-intent.d.ts.map +1 -0
- package/dist/core/rails-deploy-production-intent.js +79 -0
- package/dist/core/rails-deploy-production-intent.js.map +1 -0
- package/dist/core/stale-managed-banner.d.ts +78 -0
- package/dist/core/stale-managed-banner.d.ts.map +1 -0
- package/dist/core/stale-managed-banner.js +118 -0
- package/dist/core/stale-managed-banner.js.map +1 -0
- package/dist/core/two-channel-delivery-scan.d.ts +33 -1
- package/dist/core/two-channel-delivery-scan.d.ts.map +1 -1
- package/dist/core/two-channel-delivery-scan.js +133 -6
- package/dist/core/two-channel-delivery-scan.js.map +1 -1
- package/dist/core/two-channel-delivery.d.ts +101 -4
- package/dist/core/two-channel-delivery.d.ts.map +1 -1
- package/dist/core/two-channel-delivery.js +121 -13
- package/dist/core/two-channel-delivery.js.map +1 -1
- package/dist/core/two-channel-staleness.d.ts +137 -0
- package/dist/core/two-channel-staleness.d.ts.map +1 -0
- package/dist/core/two-channel-staleness.js +268 -0
- package/dist/core/two-channel-staleness.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +276 -122
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/core/workflow-deletion-ownership.d.ts +6 -24
- package/dist/core/workflow-deletion-ownership.d.ts.map +1 -1
- package/dist/core/workflow-deletion-ownership.js +22 -42
- package/dist/core/workflow-deletion-ownership.js.map +1 -1
- package/dist/detection/detectors/cdk.d.ts.map +1 -1
- package/dist/detection/detectors/cdk.js +2 -1
- package/dist/detection/detectors/cdk.js.map +1 -1
- package/dist/health/template-inspection.d.ts.map +1 -1
- package/dist/health/template-inspection.js +2 -1
- package/dist/health/template-inspection.js.map +1 -1
- package/dist/migrations/ensure-lisa-postinstall.d.ts +16 -0
- package/dist/migrations/ensure-lisa-postinstall.d.ts.map +1 -1
- package/dist/migrations/ensure-lisa-postinstall.js +16 -0
- package/dist/migrations/ensure-lisa-postinstall.js.map +1 -1
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts +2 -2
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts.map +1 -1
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.js +98 -34
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.js.map +1 -1
- package/dist/migrations/ensure-playwright-dedicated-caller.d.ts.map +1 -1
- package/dist/migrations/ensure-playwright-dedicated-caller.js +1 -0
- package/dist/migrations/ensure-playwright-dedicated-caller.js.map +1 -1
- package/dist/opencode/hooks-installer.d.ts.map +1 -1
- package/dist/opencode/hooks-installer.js +1 -0
- package/dist/opencode/hooks-installer.js.map +1 -1
- package/dist/opencode/plugin-templates/block-managed-file-edits.sh +78 -15
- package/dist/opencode/plugin-templates/block-no-verify.sh +21 -0
- package/dist/opencode/plugin-templates/guard-dedupe.bash +337 -0
- package/dist/opencode/plugin-templates/lisa-block-direct-issue-create.ts +242 -55
- package/dist/opencode/plugin-templates/parity-safety-net.sh +29 -1
- package/dist/strategies/package-lisa.d.ts.map +1 -1
- package/dist/strategies/package-lisa.js +2 -1
- package/dist/strategies/package-lisa.js.map +1 -1
- package/dist/utils/path-utils.d.ts +29 -0
- package/dist/utils/path-utils.d.ts.map +1 -1
- package/dist/utils/path-utils.js +41 -0
- package/dist/utils/path-utils.js.map +1 -1
- package/expo/create-only/.github/workflows/ci.yml +21 -0
- package/expo/create-only/.github/workflows/deploy.yml +50 -6
- package/expo/create-only/.github/workflows/maestro-e2e.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml +124 -13
- package/expo/create-only/.github/workflows/nightly-e2e-health.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-report.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-tracking.yml +8 -0
- package/expo/create-only/.github/workflows/playwright-e2e.yml +7 -0
- package/harper-fabric/copy-overwrite/.github/workflows/ci.yml +7 -0
- package/harper-fabric/create-only/.github/workflows/deploy.yml +14 -0
- package/nestjs/create-only/.github/workflows/ci.yml +14 -0
- package/nestjs/create-only/.github/workflows/deploy.yml +28 -0
- package/package.json +15 -8
- package/phaser/copy-overwrite/.github/workflows/ci.yml +7 -0
- package/plugins/lisa/.claude-plugin/plugin.json +28 -1
- package/plugins/lisa/.codex-plugin/hooks.json +27 -0
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-prd-intake/SKILL.md +47 -30
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +4 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/lisa/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa/hooks/inject-rules.sh +13 -5
- package/plugins/lisa/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa/rules/eager/00-rule-index.md +1 -0
- package/plugins/lisa/rules/eager/operational-hazards.md +50 -0
- package/plugins/lisa/rules/eager/tracked-work.md +1 -1
- package/plugins/lisa/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa/rules/reference/operational-hazards.md +115 -0
- package/plugins/lisa/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-agy/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa-agy/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-agy/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/lisa-agy/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-agy/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-agy/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-agy/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-agy/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-agy/hooks.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-agy/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-agy/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-agy/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-agy/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-agy/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- 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 +19 -1
- package/plugins/lisa-copilot/agents/linear-prd-intake.agent.md +8 -8
- package/plugins/lisa-copilot/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-copilot/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-copilot/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-copilot/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-copilot/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa-copilot/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-copilot/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa-copilot/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-copilot/hooks/inject-rules.sh +13 -5
- package/plugins/lisa-copilot/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa-copilot/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa-copilot/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-copilot/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa-copilot/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa-copilot/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa-copilot/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa-copilot/rules/eager/00-rule-index.md +1 -0
- package/plugins/lisa-copilot/rules/eager/operational-hazards.md +50 -0
- package/plugins/lisa-copilot/rules/eager/tracked-work.md +1 -1
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa-copilot/rules/reference/operational-hazards.md +115 -0
- package/plugins/lisa-copilot/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-copilot/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-copilot/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-copilot/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-copilot/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-copilot/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa-cursor/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-cursor/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-cursor/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-cursor/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa-cursor/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-cursor/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa-cursor/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-cursor/hooks/hooks.json +10 -0
- package/plugins/lisa-cursor/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa-cursor/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-cursor/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa-cursor/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa-cursor/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa-cursor/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa-cursor/rules/00-rule-index.mdc +1 -0
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/operational-hazards-reference.mdc +120 -0
- package/plugins/lisa-cursor/rules/operational-hazards.mdc +55 -0
- package/plugins/lisa-cursor/rules/tracked-work.mdc +1 -1
- package/plugins/lisa-cursor/rules/work-item-trailer-definition-reference.mdc +134 -0
- package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-cursor/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-cursor/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-cursor/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-cursor/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-cursor/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- 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/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-harper-fabric/rules/eager/harper-fabric.md +31 -0
- 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-copilot/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-harper-fabric-copilot/rules/eager/harper-fabric.md +31 -0
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric-reference.mdc +57 -0
- package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric.mdc +32 -53
- 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/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-phaser/rules/eager/phaser.md +44 -0
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-phaser-copilot/rules/eager/phaser.md +44 -0
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/rules/phaser-reference.mdc +189 -0
- package/plugins/lisa-phaser-cursor/rules/phaser.mdc +45 -185
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/hooks/inject-rules.sh +14 -4
- package/plugins/lisa-rails/rules/eager/rails-conventions.md +23 -0
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/hooks/inject-rules.sh +14 -4
- package/plugins/lisa-rails-copilot/rules/eager/rails-conventions.md +23 -0
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/rules/rails-conventions-reference.mdc +181 -0
- package/plugins/lisa-rails-cursor/rules/rails-conventions.mdc +24 -177
- 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/materialized-artifacts.json +1 -0
- package/plugins/src/base/.claude-plugin/plugin.json +27 -0
- package/plugins/src/base/agents/linear-prd-intake.md +8 -8
- package/plugins/src/base/hooks/block-blind-automerge.sh +81 -2
- package/plugins/src/base/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/src/base/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/src/base/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/src/base/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/src/base/hooks/block-no-verify.sh +21 -0
- package/plugins/src/base/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/src/base/hooks/failure-signature-index.mjs +240 -5
- package/plugins/src/base/hooks/guard-dedupe.bash +337 -0
- package/plugins/src/base/hooks/inject-rules.sh +13 -5
- package/plugins/src/base/hooks/operational-hazards.mjs +736 -0
- package/plugins/src/base/hooks/operational-hazards.sh +28 -0
- package/plugins/src/base/hooks/parity-safety-net.sh +29 -1
- package/plugins/src/base/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/src/base/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/src/base/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/src/base/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/src/base/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/src/base/rules/eager/00-rule-index.md +1 -0
- package/plugins/src/base/rules/eager/operational-hazards.md +50 -0
- package/plugins/src/base/rules/eager/tracked-work.md +1 -1
- package/plugins/src/base/rules/reference/config-resolution.md +1 -1
- package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/src/base/rules/reference/operational-hazards.md +115 -0
- package/plugins/src/base/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/src/base/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/src/base/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/src/base/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/src/base/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/src/base/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/src/base/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/src/base/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/src/base/skills/lisa-track/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/src/harper-fabric/hooks/inject-rules.sh +14 -3
- package/plugins/src/harper-fabric/rules/eager/harper-fabric.md +31 -0
- package/plugins/src/phaser/hooks/inject-rules.sh +14 -3
- package/plugins/src/phaser/rules/eager/phaser.md +44 -0
- package/plugins/src/rails/hooks/inject-rules.sh +14 -4
- package/plugins/src/rails/rules/eager/rails-conventions.md +23 -0
- package/rails/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
- package/rails/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
- package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
- package/rails/create-only/.github/workflows/ci.yml +8 -0
- package/rails/create-only/.github/workflows/deploy.yml +22 -0
- package/scripts/build-plugins.sh +2 -1
- package/scripts/check-engine-floor.mjs +361 -0
- package/scripts/check-guard-parity-notes.mjs +709 -0
- package/scripts/check-template-workflow-refs.mjs +9 -0
- package/scripts/check-third-party-action-pins.mjs +17 -1
- package/scripts/check-workflow-contract-assertions.mjs +480 -0
- package/scripts/copy-opencode-plugin-templates.mjs +1 -0
- package/scripts/deployed-guard-advice.mjs +636 -0
- package/scripts/generate-agy-plugin-artifacts.mjs +35 -10
- package/scripts/generate-export-surface.mjs +105 -19
- package/scripts/generate-two-channel-couplings.ts +143 -212
- package/scripts/lisa-enforcement-fallback.sh +31 -0
- package/scripts/measure-scripts-profile-gap.mts +361 -0
- package/scripts/mutation-performance-measure.mjs +21 -5
- package/scripts/reconcile-release-tags.mjs +65 -84
- package/scripts/two-channel-couplings.json +302 -70
- package/scripts/workflow-contract-assertion.sh +47 -0
- package/typescript/copy-overwrite/.lintstagedrc.json +1 -0
- package/typescript/copy-overwrite/eslint.ignore.config.json +1 -0
- package/typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs +527 -53
- package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +301 -13
- package/typescript/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
- package/typescript/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
- package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
- package/typescript/create-only/.github/workflows/ci.yml +11 -0
- package/typescript/package-lisa/package.lisa.json +2 -2
- /package/plugins/lisa-harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/lisa-harper-fabric-copilot/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/lisa-phaser/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/lisa-phaser-copilot/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/lisa-rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
- /package/plugins/lisa-rails-copilot/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
- /package/plugins/src/harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/src/phaser/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/src/rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
|
@@ -299,7 +299,7 @@ If the item modifies an existing user-facing surface, a `lisa-product-walkthroug
|
|
|
299
299
|
Before create/update, verify each field is populated where applicable:
|
|
300
300
|
|
|
301
301
|
- **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.
|
|
302
|
-
- **Labels**: taxonomy only — `type:<Kind>`, `repo:<name>`, `component:<name
|
|
302
|
+
- **Labels**: taxonomy only — `type:<Kind>`, `repo:<name>`, `component:<name>`. Lifecycle is **not** a label on Linear; do not add `status:*` labels.
|
|
303
303
|
- **Native priority field**: 0–4 per Linear's scale; explicit, not "unset".
|
|
304
304
|
- **Native estimate**: per Linear's team-configured estimate scale (often 0–8 Fibonacci); skip for Epic / Spike.
|
|
305
305
|
- **ProjectMilestone**: when the team uses dated milestones, set the milestone on the Project (Epic) or on the Issue (when an Issue belongs to a milestone).
|
|
@@ -334,6 +334,17 @@ person scanning a board and to any path that has not yet been routed through the
|
|
|
334
334
|
If the label does not exist in the tracker, create it, or record that it could not be applied and
|
|
335
335
|
proceed — the marker still holds. Never file the label *instead of* the marker.
|
|
336
336
|
|
|
337
|
+
**Write a `reason=` the release can name.** The hold's reason is not decoration: a hold ends when a
|
|
338
|
+
`[lisa-human-gate-release]` comment repeating that same `reason=` is recorded on the item, and the
|
|
339
|
+
next intake sweep then takes the marker label off and puts the item back in the build-ready role on
|
|
340
|
+
its own. Matching is per-reason so that a hold declared *after* an earlier release is not born
|
|
341
|
+
discharged. A keyless hold is legal and is discharged by a keyless release; a hold whose reason is a
|
|
342
|
+
paragraph is legal and nobody will reproduce it. Prefer a short slug the person answering it can
|
|
343
|
+
retype. Do **not** instruct anyone to delete the marker from the description to lift the hold — the
|
|
344
|
+
only body write available is a whole-body replacement, so that asks them to rewrite the whole record
|
|
345
|
+
to clear one line, which is why answered holds accumulated instead of being lifted
|
|
346
|
+
(CodySwannGT/lisa#3852). The marker stays as history; the release is recorded beside it.
|
|
347
|
+
|
|
337
348
|
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.
|
|
338
349
|
|
|
339
350
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
@@ -360,7 +371,7 @@ If the validator reports `PASS`, continue to Phase 6.
|
|
|
360
371
|
|
|
361
372
|
### CREATE — Story / Task / Bug / Spike / Improvement (Issue with projectId)
|
|
362
373
|
|
|
363
|
-
1. Resolve any required Issue labels (`type:<Kind>`, `repo:<name>`, `component:<name
|
|
374
|
+
1. Resolve any required Issue labels (`type:<Kind>`, `repo:<name>`, `component:<name>`) via `lisa-linear-access operation: list-issue-labels` (create via `lisa-linear-access operation: create-issue-label` if missing). Separately, place a **leaf** work unit in the `ready` lane by passing `lifecycle_role: ready` on the create call below — and only on **explicit `build_ready: true`**, per the Build-ready control input below. Omit the role for a container, and for a leaf whose `build_ready` is `false` or omitted, which then waits in the team's default backlog state for a human to promote it. Ready is an explicit claim, never an omission's default. Never resolve a state ID here and pass it as `stateId`: the access layer resolves the configured `ready` state itself and refuses anything else.
|
|
364
375
|
2. Call `lisa-linear-access operation: save-issue` with: `team` (teamId), `title` (summary), `description` (markdown), `projectId` (the Epic Project), `priority` (0–4), `estimate`, `labelIds`, `assignee` if known.
|
|
365
376
|
3. Capture the returned identifier (e.g. `ENG-123`) — Phase 4 sub-tasks need it as `parentId`.
|
|
366
377
|
4. Add relationships from Phase 4b via `save_issue` (relations field) or paired relation calls.
|
|
@@ -384,7 +395,7 @@ Call the `lisa-linear-verify` skill on the resulting item. `lisa-linear-verify`
|
|
|
384
395
|
|
|
385
396
|
## Phase 8 — Announce
|
|
386
397
|
|
|
387
|
-
Post a creation comment via `lisa-linear-access operation: save-comment`
|
|
398
|
+
Post a creation comment via `lisa-linear-access operation: save-comment` — `issue_id:<ID>` for an Issue, `project_id:<ID>` for an Epic-level announcement, which goes on the Project itself. Never create an Issue to carry a Project's announcement. The comment contains:
|
|
388
399
|
|
|
389
400
|
- `[<repo>]` prefix if the item is repo-scoped
|
|
390
401
|
- Who the item is assigned to (if known)
|
|
@@ -393,6 +404,46 @@ Post a creation comment via `lisa-linear-access operation: save-comment` (on the
|
|
|
393
404
|
|
|
394
405
|
Skip this step only on UPDATE when no material change was made.
|
|
395
406
|
|
|
407
|
+
## Writing by a bespoke path (your own script, direct API or GraphQL)
|
|
408
|
+
|
|
409
|
+
Nothing here stops a consumer from writing to Linear through the Linear GraphQL API directly, a direct API call, or your own script, and nothing should
|
|
410
|
+
try to — a script that owns the credential plumbing is often the only practical transport.
|
|
411
|
+
**The transport is not the gate.** A bespoke write path still owes both halves of the quality
|
|
412
|
+
gate this skill runs, and owes them explicitly, because no phase of this flow will ever run
|
|
413
|
+
for it.
|
|
414
|
+
|
|
415
|
+
A bespoke script's own read-back does not discharge either obligation. Re-reading the work item
|
|
416
|
+
and confirming Linear stored what was sent **proves transport, not quality**: it shows the
|
|
417
|
+
fields round-tripped and says nothing about whether what was sent clears a single gate. An
|
|
418
|
+
agent that reads `VERIFIED` out of such a script has been told the work item was checked when it
|
|
419
|
+
was not. Measured once, on one work item, on 2026-09-03 (CodySwannGT/lisa#3663): a local
|
|
420
|
+
script's read-back was clean on every field, and the work item then failed gates S5, S9 and S18
|
|
421
|
+
when the validator was run against it by hand.
|
|
422
|
+
|
|
423
|
+
What a bespoke write path still owes — the same two checks, invoked by hand:
|
|
424
|
+
|
|
425
|
+
1. **Pre-write validate**, the obligation Phase 5.5 discharges here. Invoke `lisa-linear-validate-issue` via
|
|
426
|
+
the Skill tool with the proposed spec as a YAML block **before** writing. Never write on a
|
|
427
|
+
`FAIL` verdict.
|
|
428
|
+
2. **Post-write verify**, the obligation Phase 7 discharges here. Invoke `lisa-linear-verify` via the
|
|
429
|
+
Skill tool with the identifier of the work item you just wrote — or `lisa-linear-validate-issue` directly in
|
|
430
|
+
identifier mode, which fetches and validates the live state. Never report success on a
|
|
431
|
+
`FAIL` verdict.
|
|
432
|
+
|
|
433
|
+
Both run standalone against an existing live work item; `lisa-linear-validate-issue` documents the copy-pasteable
|
|
434
|
+
invocation under its standalone entry point.
|
|
435
|
+
|
|
436
|
+
**Three outcomes, never two.** `PASS`, `FAIL` and *could not validate* are distinct results.
|
|
437
|
+
If the validator did not run to a verdict — the skill was unavailable, a credential was
|
|
438
|
+
missing, the work item could not be fetched — that is **not** a pass. Report it as unvalidated and
|
|
439
|
+
say why. Collapsing "could not validate" into "validated" is the same misreading as trusting
|
|
440
|
+
a read-back.
|
|
441
|
+
|
|
442
|
+
**These are skills, not scripts.** `lisa-linear-validate-issue` and `lisa-linear-verify` are plugin-resident and invoked
|
|
443
|
+
through the Skill tool. They are **not** expected to appear in any repository's `scripts/`
|
|
444
|
+
directory, and their absence from one is not evidence that the capability is missing —
|
|
445
|
+
searching the repository you happen to be standing in is the wrong search.
|
|
446
|
+
|
|
396
447
|
## Rules
|
|
397
448
|
|
|
398
449
|
- Never create a non-Epic, non-top-level item without a parent context (Project for Stories, parentId for Sub-tasks).
|
|
@@ -50,7 +50,7 @@ Per-ticket gates (`lisa-jira-validate-ticket`) prove each created ticket is well
|
|
|
50
50
|
- **GitHub**: enumerate native sub-issues via `gh api graphql` (`subIssues` field), then `gh issue view <child-num> --json body,comments` per child. Recurse to depth 3.
|
|
51
51
|
The audit walks the full PRD tree.
|
|
52
52
|
4. If `tickets=[...]` not provided, locate the destination Epic by:
|
|
53
|
-
- Looking for a destination URL in the PRD body, comments, or the PRD's most recent "Ticketed by Claude" comment posted by `lisa-notion-prd-intake` / `lisa-confluence-prd-intake` / `lisa-linear-prd-intake` / `lisa-github-prd-intake` (for
|
|
53
|
+
- Looking for a destination URL in the PRD body, comments, or the PRD's most recent "Ticketed by Claude" comment posted by `lisa-notion-prd-intake` / `lisa-confluence-prd-intake` / `lisa-linear-prd-intake` / `lisa-github-prd-intake` (for every vendor, this comment lives on the PRD page / project / issue itself).
|
|
54
54
|
- Searching the destination tracker via `lisa-tracker-read` (or directly via `searchJiraIssuesUsingJql` / `gh issue list --search`) for an epic whose summary or description references the PRD title or project ID.
|
|
55
55
|
- If no epic found, return verdict `NO_TICKETS_FOUND` with a clear remediation — coverage cannot be assessed without the ticket set.
|
|
56
56
|
5. Once the epic is known, fetch all child stories and sub-tasks:
|
|
@@ -174,7 +174,7 @@ Atomic PRD items extracted: <n>
|
|
|
174
174
|
### Scope-creep count: <n>
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
`prd_anchor` and `prd_section` are built the same way as in `lisa-notion-to-tracker` / `lisa-confluence-to-tracker` / `lisa-linear-to-tracker` / `lisa-github-to-tracker`. For Notion, `prd_anchor` is the `selection_with_ellipsis` start/end snippet; for Confluence, it's the inline-comment selection text accepted by `createConfluenceInlineComment`; for Linear, it's a sub-issue identifier (e.g. `LIN-123`) when the gap maps to a specific issue, otherwise `null` (the caller posts unanchored Linear gaps
|
|
177
|
+
`prd_anchor` and `prd_section` are built the same way as in `lisa-notion-to-tracker` / `lisa-confluence-to-tracker` / `lisa-linear-to-tracker` / `lisa-github-to-tracker`. For Notion, `prd_anchor` is the `selection_with_ellipsis` start/end snippet; for Confluence, it's the inline-comment selection text accepted by `createConfluenceInlineComment`; for Linear, it's a sub-issue identifier (e.g. `LIN-123`) when the gap maps to a specific issue, otherwise `null` (the caller posts unanchored Linear gaps as a project-level comment); for GitHub, it's the section heading from the PRD issue body when the gap traces to a specific section, otherwise `null` (the caller approximates inline anchoring by quoting a body excerpt at the top of the comment). The downstream caller knows which vendor it's writing to and uses the right API; this skill just emits the anchor that vendor expects.
|
|
178
178
|
|
|
179
179
|
`category` is drawn from the same fixed taxonomy used by `lisa-jira-validate-ticket` so downstream callers can apply one consistent comment-formatting policy. Most coverage gaps map to `scope` (item not represented in any ticket) or `product-clarity` (item too vague to map). Use `acceptance-criteria` for missing pass/fail conditions and `design-ux` for missing visuals.
|
|
180
180
|
|
|
@@ -46,9 +46,20 @@ Read `.lisa.config.json`:
|
|
|
46
46
|
`[lisa-qa-clear] Certified without human QA: scope is <repo(s)>, not observable
|
|
47
47
|
with end-user access. Verified by the automated lifecycle pre-promotion.`
|
|
48
48
|
2. Then transition to the certified status.
|
|
49
|
-
3.
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
3. Then clear the QA-failure **signal**, because certifying is one of its two void
|
|
50
|
+
conditions and this is the second path that reaches it:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
RESOLVER="${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-plugins/lisa}}/scripts/qa-signal-lifecycle.mjs"
|
|
54
|
+
SIGNAL=$(node "$RESOLVER" --vendor "<jira|linear|github>" --print-label)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Remove `$SIGNAL` through the same tracker surface that applied it. Removing a label
|
|
58
|
+
the ticket does not carry is a no-op, so this runs unconditionally. The
|
|
59
|
+
`[lisa-qa-fail]` comments are never touched — the history stays, the signal goes.
|
|
60
|
+
4. Verify all three landed before counting the ticket as moved. A comment without
|
|
61
|
+
the transition, a transition without the comment, or a certified ticket still
|
|
62
|
+
wearing the signal is a **partial** — report it as such, never as completed.
|
|
52
63
|
5. Report the batch:
|
|
53
64
|
|
|
54
65
|
```text
|
|
@@ -68,7 +79,8 @@ marks exactly what was auto-cleared.
|
|
|
68
79
|
- Never bulk-move on an inferred repo list without explicit operator confirmation.
|
|
69
80
|
- Every cleared ticket carries the audit comment; a transition without the comment is a
|
|
70
81
|
bug in this procedure.
|
|
71
|
-
- Idempotent by repair, not by skip: a ticket is complete only when it has
|
|
72
|
-
`[lisa-qa-clear]` comment
|
|
73
|
-
present but not certified → transition it; certified but no
|
|
74
|
-
comment
|
|
82
|
+
- Idempotent by repair, not by skip: a ticket is complete only when it has the
|
|
83
|
+
`[lisa-qa-clear]` comment, the certified status, AND no QA-failure signal. Re-runs
|
|
84
|
+
finish partials — comment present but not certified → transition it; certified but no
|
|
85
|
+
comment → post the comment; certified but still signalled → clear the signal. Only
|
|
86
|
+
fully-complete tickets are skipped silently.
|
|
@@ -71,10 +71,32 @@ not smoothed over.
|
|
|
71
71
|
For `not-covered-by-ac`, do NOT transition the ticket — the spec question goes to the
|
|
72
72
|
human product gate. Flag it in the response and stop after posting.
|
|
73
73
|
|
|
74
|
-
## Phase 4 —
|
|
74
|
+
## Phase 4 — Signal and transition
|
|
75
75
|
|
|
76
|
-
1. Apply the
|
|
77
|
-
|
|
76
|
+
1. Apply the QA-failure **signal** label. Resolve its name — never hardcode one:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
SIGNAL=$(node "${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-plugins/lisa}}/scripts/qa-signal-lifecycle.mjs" \
|
|
80
|
+
--vendor "<jira|linear|github>" --print-label) # `qa.labels.fail`, default `qa-fail`
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
This is the deterministic rework signal `lisa-rework-triage` keys on at next claim, and
|
|
84
|
+
the gap classification above becomes its primary evidence.
|
|
85
|
+
|
|
86
|
+
The signal is **transient, and it says so.** Two void conditions lift it, both with an
|
|
87
|
+
executable predicate in `scripts/qa-signal-lifecycle.mjs`: a later QA pass verdict
|
|
88
|
+
(`qa-pass-recorded`), or the item reaching the certified or a terminal role
|
|
89
|
+
(`certified-role-reached`). `lisa-qa-queue` clears it on the pass path and `lisa-qa-clear`
|
|
90
|
+
clears it when it certifies without a human, so the clear path is as reachable as this
|
|
91
|
+
one. Record that in the comment so nobody has to infer it:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
Signal: <label> — voided by a later QA pass, or by reaching the certified/terminal role.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
What is durable is the **history**: this `[lisa-qa-fail]` comment is never rewritten or
|
|
98
|
+
removed, so "failed QA twice before shipping" stays readable after the label is gone.
|
|
99
|
+
The label is the machine-read signal; the comment is the record.
|
|
78
100
|
2. Transition the ticket to the build-ready status (`jira.workflow.ready`, or the
|
|
79
101
|
configured tracker's equivalent ready label/state when `tracker` is GitHub or
|
|
80
102
|
Linear). The rework loop takes it from here: intake claims it, `lisa-ticket-triage` Phase 2.5 runs
|
|
@@ -92,3 +114,6 @@ human product gate. Flag it in the response and stop after posting.
|
|
|
92
114
|
- The expectation gap must cite a specific evidence artifact or say `no-evidence-found` —
|
|
93
115
|
a gap classification without a citation is a guess, and guesses are worse than
|
|
94
116
|
`no-evidence-found`.
|
|
117
|
+
- Never apply a signal whose clear path you cannot name. A durable mark with no inverse is
|
|
118
|
+
a defect class of its own (`state-changes-without-inverses`): it stays correct at the
|
|
119
|
+
moment it fires and becomes wrong by outliving what it described.
|
|
@@ -45,9 +45,32 @@ Read `.lisa.config.json`:
|
|
|
45
45
|
|
|
46
46
|
## Recording the verdict
|
|
47
47
|
|
|
48
|
-
- **Pass** —
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
- **Pass** — three writes, in this order, and the pairing must be failure-safe exactly as
|
|
49
|
+
`lisa-qa-clear`'s is:
|
|
50
|
+
1. Post a brief `[lisa-qa-queue] QA pass` comment naming who verified and when. The
|
|
51
|
+
literal marker matters: it is the `qa-pass-recorded` void condition's evidence.
|
|
52
|
+
2. Transition the ticket to the certified status via the tracker access layer.
|
|
53
|
+
3. **Clear the QA-failure signal.** A pass is the inverse of a fail, and until this runs
|
|
54
|
+
an item that failed once reads as failing forever to `lisa-rework-triage`:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
RESOLVER="${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-plugins/lisa}}/scripts/qa-signal-lifecycle.mjs"
|
|
58
|
+
SIGNAL=$(node "$RESOLVER" --vendor "<jira|linear|github>" --print-label)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Remove `$SIGNAL` from the item through the same tracker surface that applied it —
|
|
62
|
+
`gh issue edit <n> --remove-label "$SIGNAL"` on GitHub, the label-update mutation on
|
|
63
|
+
Linear, the `update.labels[].remove` field on JIRA. Removing a label the item does not
|
|
64
|
+
carry is a no-op on every tracker, so this is safe to run unconditionally.
|
|
65
|
+
|
|
66
|
+
Verify all three landed before reporting the pass. A transition without the signal
|
|
67
|
+
cleared is a **partial** — report it as such and finish it, never count it as complete.
|
|
68
|
+
|
|
69
|
+
The failure **history** is untouched: the `[lisa-qa-fail]` comments stay exactly as
|
|
70
|
+
written. Only the machine-read signal is voided, so "this failed QA twice before
|
|
71
|
+
shipping" remains readable while "this is failing QA" stops being asserted.
|
|
72
|
+
|
|
73
|
+
Then offer the next item.
|
|
51
74
|
- **Fail** — invoke `lisa-qa-fail` with the ticket key and the tester's own words
|
|
52
75
|
(verbatim — do not paraphrase away detail; attach any screenshots they provided). That
|
|
53
76
|
skill owns the failure report, the expectation-gap diagnosis, the `qa-fail` label, and
|
|
@@ -63,6 +86,8 @@ Read `.lisa.config.json`:
|
|
|
63
86
|
- One ticket at a time — never dump the queue on the tester.
|
|
64
87
|
- The tester's verbatim description is evidence; preserve it exactly in whatever is posted.
|
|
65
88
|
- Never transition to certified without an explicit "pass" from the tester.
|
|
89
|
+
- Never certify without clearing the QA-failure signal. The clear path must stay as
|
|
90
|
+
reachable as the path that applied it (`state-changes-without-inverses`).
|
|
66
91
|
- All tracker writes go through the access layer / `lisa-qa-fail` — this skill never
|
|
67
92
|
hand-crafts tracker mutations beyond the pass transition and its comment.
|
|
68
93
|
- Session summary on request ("how did we do?"): counts of passed / failed / blocked /
|
|
@@ -188,6 +188,7 @@ In addition to the lifecycle roles above, the build lifecycle defines the **`hum
|
|
|
188
188
|
|
|
189
189
|
- The blocks repair-intake **itself writes** are the auto-recoverable kind — it files a build-ready fix ticket and moves the item `blocked` *blocked by that ticket*, expecting the next cycle to self-heal. Those are **not** `human_needed`; if such an item arrives carrying a `human_needed` marker **this skill applied on an earlier cycle**, repair-intake **clears** it (the block is no longer waiting on a human).
|
|
190
190
|
- **Never remove a `human_needed` marker this skill did not apply.** "Stale" is a judgment about the block's kind, not about who applied the marker or when — so without this rule an operator's deliberate hold, applied *after* correcting a wrong transition, is indistinguishable from a leftover the sweep is designed to clear, and gets swept. Establish provenance from the label event's actor (`rejection-detection` **Automation-reversal memory** reads the same surfaces); if provenance is not readable, **leave the marker in place**. Removing a human's hold is unrecoverable within the loop; leaving a stale one costs a cycle and is visible.
|
|
191
|
+
- **The one exception is a hold that has recorded its own discharge.** A `[lisa-human-gate-release]` comment naming the hold's `reason=` is not a guess about provenance — it is the hold's stated void condition, recorded on the item by the person who answered it. Clearing the marker there is not overriding a human's judgment; it is *enacting* it. That is the whole of the exception: no other reading of "this looks stale" reopens the question above, and an item whose release cannot be read stays held. See "Release the holds that have been answered" below (#3852).
|
|
191
192
|
- The marker is consulted **before **any** repair transition**, not only before Class C. Class C's hard stop is the strictest reading of it, but a marker that is honoured on one classification path and ignored on the other three is not a guard — and Class A, dependency clearing, is exactly the path an operator reverting a wrongly-cleared blocker is trying to protect. Match it robustly (hyphen/underscore, case-insensitive, label set and note prose) wherever it is read.
|
|
192
193
|
- The blocks the **vendor agent** writes when repair-intake re-dispatches it (its pre-flight gate) carry `human_needed` already — the agent owns that marker. repair-intake leaves it in place.
|
|
193
194
|
|
|
@@ -218,7 +219,7 @@ intakes use. Never call Atlassian MCP or `acli` directly — go through `lisa-at
|
|
|
218
219
|
| Linear (build) | Linear MCP `list_issues` / `get_issue` / `list_comments` | Linear MCP `save_issue` (labels) / `save_comment` | `lisa-linear-agent` |
|
|
219
220
|
| Notion (PRD) | `lisa-notion-access` (`query`, page comments) | `lisa-notion-access` `write-page` (status) / page comment | `lisa-notion-to-tracker` (dry-run) |
|
|
220
221
|
| GitHub (PRD) | `gh issue list/view` (PRD labels) / GraphQL sub-issues / generated-work section | `gh issue edit` / `gh issue comment` / `gh issue close --reason completed` | `lisa-github-to-tracker` (dry-run) |
|
|
221
|
-
| Linear (PRD) |
|
|
222
|
+
| Linear (PRD) | `lisa-linear-access` `list-projects` / `get-project` / `list-comments project_id` | `lisa-linear-access` `save-project` (labels) / `save-comment project_id` | `lisa-linear-to-tracker` (dry-run) |
|
|
222
223
|
| Confluence (PRD) | `lisa-atlassian-access` CQL | `lisa-atlassian-access` page `parentId` update / comment | `lisa-confluence-to-tracker` (dry-run) |
|
|
223
224
|
|
|
224
225
|
## Staleness model
|
|
@@ -267,8 +268,9 @@ exposes, and compare it to `now - stale_after`:
|
|
|
267
268
|
1. Provider-native status/label **transition** time into the in-progress role, when the provider
|
|
268
269
|
exposes it cleanly (JIRA changelog transition to `claimed` / In Progress, GitHub label event,
|
|
269
270
|
Linear state/label history, Notion/Confluence page move/status history).
|
|
270
|
-
2. Latest human lifecycle/progress **comment** or edit on the item (
|
|
271
|
-
|
|
271
|
+
2. Latest human lifecycle/progress **comment** or edit on the item (for Linear PRDs, the
|
|
272
|
+
project's own comments via `list-comments project_id`, plus any legacy sentinel feedback
|
|
273
|
+
issue for projects that predate project-level comments). Exclude automation self-comments and Lisa audit markers such as
|
|
272
274
|
`[claude-build-intake]`, `[codex-build-intake]`, `[lisa-build-intake]`, and
|
|
273
275
|
`[lisa-repair-intake]`.
|
|
274
276
|
3. For build items, latest **PR-side forward-progress activity** on the linked PR: newest commit,
|
|
@@ -466,25 +468,49 @@ branch — operate on it the same way.
|
|
|
466
468
|
|
|
467
469
|
**4. Classify as a blocker.** Treat any of these as a real external blocker:
|
|
468
470
|
|
|
469
|
-
- **True merge conflict** —
|
|
470
|
-
`
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
471
|
+
- **True merge conflict** — confirmed by a **merge trial**, never by a cached field.
|
|
472
|
+
`mergeable = CONFLICTING` and `mergeStateStatus = DIRTY` are hints that say *go look*: both are
|
|
473
|
+
computed asynchronously, and a stale one is served often enough that GitHub reported `DIRTY` for two
|
|
474
|
+
branches at the same moment while only one of them actually conflicted (#3694). Re-derive from
|
|
475
|
+
primary evidence at the moment of asking:
|
|
476
|
+
|
|
477
|
+
```sh
|
|
478
|
+
base=$(gh pr view <pr> --json baseRefName --jq .baseRefName)
|
|
479
|
+
head=$(gh pr view <pr> --json headRefOid --jq .headRefOid)
|
|
480
|
+
git fetch --quiet origin "$base" "pull/<pr>/head" || readable=no
|
|
481
|
+
git rev-parse --verify --quiet "origin/$base^{commit}" >/dev/null || readable=no
|
|
482
|
+
git rev-parse --verify --quiet "$head^{commit}" >/dev/null || readable=no
|
|
483
|
+
out=$(git merge-tree --write-tree "origin/$base" "$head" 2>/dev/null); code=$?
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
`merge-tree --write-tree` merges into the object store only — no working tree, no index and no
|
|
487
|
+
branch is touched — so it is safe inside an unattended scanner.
|
|
488
|
+
|
|
489
|
+
**Read the exit code together with stdout; the exit code alone cannot separate the three states.**
|
|
490
|
+
Measured on git 2.53.0: a trial naming a ref that does not exist exits `1`, the same code a genuine
|
|
491
|
+
conflict returns, printing nothing on stdout and `merge-tree: <ref> - not something we can merge`
|
|
492
|
+
on stderr. A trial that ran always prints the resulting tree OID on its first line; one that could
|
|
493
|
+
not run prints nothing. Three states, and the third is not optional:
|
|
494
|
+
|
|
495
|
+
- `code == 1` **and** `$out` non-empty → **CONFLICTED**. A real external blocker. Unlike the other
|
|
496
|
+
classes below, a conflict is **resolvable by re-running the build**, so step 5 gives it one
|
|
497
|
+
in-place re-dispatch before filing — see its conflict-first rule.
|
|
498
|
+
- `code == 0` → **CLEAN**. Not a blocker, whatever the API said. Write nothing, leave the item
|
|
499
|
+
`claimed`, and let a later cycle re-ask.
|
|
500
|
+
- `readable=no`, `$out` empty, or any other exit → **NOT DETERMINED**. The trial could not run — an
|
|
501
|
+
unresolvable ref, an unreachable remote, a git older than 2.38 — which is an absence of evidence,
|
|
502
|
+
not a verdict. Write nothing, file nothing, leave the item `claimed`, and record it as
|
|
503
|
+
`not_determined` in the run summary so a later cycle re-asks.
|
|
504
|
+
|
|
505
|
+
A `gh pr update-branch` (step 3) that reported a conflict it cannot apply also counts as
|
|
506
|
+
CONFLICTED — that is a merge actually attempted, not a cached answer. A merely `BEHIND` branch is
|
|
507
|
+
**not** here — it was re-synced in step 3.
|
|
508
|
+
|
|
509
|
+
**Filing on a cached field is the expensive direction here.** In a fix-mode loop a false
|
|
510
|
+
CONFLICTED wastes a resolve, which a human sees; in this scanner it files a
|
|
511
|
+
BLOCKER against a pull request that has nothing wrong with it, unattended — so the wrong answer
|
|
512
|
+
becomes durable tracker state that a later cycle reads as fact, and intake will keep doing that
|
|
513
|
+
without anyone noticing. Verify before filing, never after.
|
|
488
514
|
- **Failing required checks** — `statusCheckRollup` has a `FAILURE`/`ERROR`/`TIMED_OUT` conclusion,
|
|
489
515
|
or `mergeStateStatus = UNSTABLE`/`BLOCKED` due to checks.
|
|
490
516
|
- **Change requests outstanding** — `reviewDecision = CHANGES_REQUESTED`, or unresolved CodeRabbit
|
|
@@ -905,8 +931,8 @@ intake runs per item**, targeted at this single PRD and **skipping the claim** (
|
|
|
905
931
|
### PRD `blocked` → re-validate if new answers exist
|
|
906
932
|
|
|
907
933
|
1. Determine whether **new clarifying answers** exist: any comment/update on the PRD newer than
|
|
908
|
-
the last `[lisa-repair-intake]` note or the original `blocked` note. For Linear include the
|
|
909
|
-
|
|
934
|
+
the last `[lisa-repair-intake]` note or the original `blocked` note. For Linear include the project's own
|
|
935
|
+
comments, anchored sub-issue comments, and any legacy sentinel feedback issue; for Confluence include inline/footer
|
|
910
936
|
comments where the access layer exposes them; for Notion include page comments and
|
|
911
937
|
`last_edited_time`.
|
|
912
938
|
2. If new answers exist → run the `lisa:<source>-to-tracker` dry-run validate→route pipeline as
|
|
@@ -1023,6 +1049,50 @@ with labels like `build-ready`, or with no Lisa status label at all, that are in
|
|
|
1023
1049
|
substring match whose precision is a separate open defect (#3815). Refusing and reporting is
|
|
1024
1050
|
the safe failure direction without the latch. Count these under `held_for_person`, never under
|
|
1025
1051
|
`normalized_ready`.
|
|
1052
|
+
|
|
1053
|
+
**Pass the item's `comments`.** The planner reads a recorded `[lisa-human-gate-release]` comment
|
|
1054
|
+
as the discharge of the hold naming the same `reason=`, and an item read without its comments is
|
|
1055
|
+
an item whose discharge cannot be seen. That fails closed — it stays held — which is the safe
|
|
1056
|
+
direction and precisely why the omission is invisible.
|
|
1057
|
+
|
|
1058
|
+
2b. **Release the holds that have been answered.** This is step 2a's inverse and it is the reason
|
|
1059
|
+
this sweep is where it lives: applying a hold had a path and lifting one had none, so a person
|
|
1060
|
+
could supply exactly what a held item asked for, record the decision on the item, and the item
|
|
1061
|
+
stayed held forever (CodySwannGT/lisa#3852). The expensive part — getting a person's attention,
|
|
1062
|
+
framing the question, obtaining a judgment — was already paid for, and the system discarded the
|
|
1063
|
+
answer.
|
|
1064
|
+
|
|
1065
|
+
Enumerate items carrying the configured `human_needed` marker **or** a `[lisa-human-gate]` marker
|
|
1066
|
+
in the body, and for each call
|
|
1067
|
+
`planHumanGateRelease({ labels, body, comments, humanNeededLabel, readyLabel, lifecycleLabels, alreadyNotified })`
|
|
1068
|
+
from `scripts/intake-blocker-reprobe.mjs`. Apply exactly the actions it returns: remove the
|
|
1069
|
+
human-needed marker, add the configured build `ready` label back, and post
|
|
1070
|
+
`formatHumanGateReleaseNote()` once. Do **not** re-implement the discharge test, and do **not**
|
|
1071
|
+
decide it from labels alone — the hold and its release are body and comment surfaces.
|
|
1072
|
+
|
|
1073
|
+
Three refusals make this safe to run on every cycle, and each one is in the planner rather than
|
|
1074
|
+
in this prose so it cannot drift:
|
|
1075
|
+
|
|
1076
|
+
- **Still held plans nothing.** Every outstanding reason holds the whole item; an item whose
|
|
1077
|
+
second question is unanswered is not half-released.
|
|
1078
|
+
- **Never held plans nothing.** Without that this would be a path that adds the build-ready role
|
|
1079
|
+
to arbitrary items — a promotion mechanism wearing a release mechanism's name.
|
|
1080
|
+
- **An item that has moved on is not dragged back.** The ready role is restored only when the
|
|
1081
|
+
item carries no other configured lifecycle label.
|
|
1082
|
+
|
|
1083
|
+
This is a genuine exception to "never remove a `human_needed` marker this skill did not apply",
|
|
1084
|
+
and the exception is narrow enough to state exactly: provenance is the wrong question when the
|
|
1085
|
+
*hold itself* names the condition that voids it and that condition is recorded. The general rule
|
|
1086
|
+
stands because "stale" is otherwise a judgment about the block's kind; here nothing is being
|
|
1087
|
+
judged — a release naming the hold's own reason is on the item, or it is not.
|
|
1088
|
+
|
|
1089
|
+
**Never edit a description to clear a hold**, here or anywhere. The only body write this plugin
|
|
1090
|
+
has is a whole-body replacement, so deleting one line means rewriting the record and hoping
|
|
1091
|
+
nothing was dropped. That is why holds accumulated: each individual release was a small gamble
|
|
1092
|
+
with a large downside. The hold note stays in the body as history; the release is a comment
|
|
1093
|
+
beside it. Count these under `released_to_queue`, and name them in the cycle summary via
|
|
1094
|
+
`summarizeHumanGateReleases([...])` — printed even when it is zero, because a release path that
|
|
1095
|
+
has stopped working and a cycle with nothing to release read identically otherwise.
|
|
1026
1096
|
3. Classify the issue:
|
|
1027
1097
|
- **PRD** if it has PRD labels/markers (`prd`, `type:PRD`, `kind:prd`), PRD structure
|
|
1028
1098
|
(`## Problem`, `## Goals`, `## Validation Journey`, generated-work/backlink sections), or
|
|
@@ -41,8 +41,34 @@ first-attempt work.
|
|
|
41
41
|
comment posted by `lisa-tracker-evidence` (`[lisa-evidence]` / the vendor evidence
|
|
42
42
|
header). Only markers proving a prior *implementation* attempt qualify —
|
|
43
43
|
`[lisa-rework-triage]` comments and other unrelated `[lisa-*]` annotations never do.
|
|
44
|
-
4. **Explicit rework marker.** A `rework
|
|
45
|
-
|
|
44
|
+
4. **Explicit rework marker.** A `rework` or `regression` label applied by QA or the verify
|
|
45
|
+
lifecycle, or a **live** QA-failure signal.
|
|
46
|
+
|
|
47
|
+
The QA-failure signal is transient, so its bare presence is not the signal — its
|
|
48
|
+
liveness is. Ask the resolver, never the label list:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
RESOLVER="${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-plugins/lisa}}/scripts/qa-signal-lifecycle.mjs"
|
|
52
|
+
node "$RESOLVER" --vendor "<jira|linear|github>" --item bundle.json
|
|
53
|
+
# bundle.json: { "labels": [...], "comments": [<bodies, oldest first>], "role": "<current>" }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Branch on `action`, never on the label being there:
|
|
57
|
+
|
|
58
|
+
| `outcome` | Meaning | What triage does |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| `live` | the failure is unresolved | signal 4 fires — this is rework |
|
|
61
|
+
| `stale` | a later QA pass, or the certified/terminal role, voided it | signal 4 does **not** fire; **remove the label** (same tracker surface that applied it) and note the repair in the triage comment. Keep evaluating signals 1–3 |
|
|
62
|
+
| `absent` | no signal | signal 4 does not fire |
|
|
63
|
+
| `unchecked` | a declared void condition has no predicate | treat as `live` and surface it — a control nothing can evaluate is a defect to report, not an exemption |
|
|
64
|
+
|
|
65
|
+
Clearing a stale signal here is the repair path for items labelled before the signal had
|
|
66
|
+
an inverse; without it that backlog never drains. The `[lisa-qa-fail]` comments are the
|
|
67
|
+
history and are never touched — a stale signal removed still leaves the failure fully
|
|
68
|
+
readable, and signal 3 still reads those comments.
|
|
69
|
+
|
|
70
|
+
`rework` and `regression` are matched on presence as before. Whether they have the same
|
|
71
|
+
shape is **unverified** and not claimed here.
|
|
46
72
|
|
|
47
73
|
Record which signal fired — it is part of the evidence trail.
|
|
48
74
|
|
|
@@ -170,3 +196,7 @@ which blocks per the normal triage rules.
|
|
|
170
196
|
bypass the quality gates this loop exists to strengthen.
|
|
171
197
|
- Noise discipline: one triage comment per bounce (fingerprinted), no upstream issue without
|
|
172
198
|
the dedupe search, and upstream issues describe failure *classes*, not single incidents.
|
|
199
|
+
- Never key on a durable mark whose inverse you have not checked. A signal with no expiry
|
|
200
|
+
degrades toward meaning "this item has been around a while"
|
|
201
|
+
(`state-changes-without-inverses`), and a deterministic input that degrades is
|
|
202
|
+
deterministically wrong.
|
|
@@ -13,7 +13,7 @@ The two lifecycles run on different primitives, and conflating them is the most
|
|
|
13
13
|
- **Build queue → native workflow STATES**, read from `linear.workflow.*`. Not labels. See "Why Linear uses states, not labels" in `config-resolution`, and Step 3a below. `lisa-linear-build-intake` reads only these.
|
|
14
14
|
- **PRD lifecycle → PROJECT labels** (`prd-*`), because a PRD is a Linear Project.
|
|
15
15
|
|
|
16
|
-
Project labels and issue labels are distinct namespaces in Linear and are NOT interchangeable — creating an issue label named `prd-ready` will not work for the PRD flow.
|
|
16
|
+
Project labels and issue labels are distinct namespaces in Linear and are NOT interchangeable — creating an issue label named `prd-ready` will not work for the PRD flow. Every PRD-lifecycle label this skill creates is a **project** label; the PRD flow needs no issue label at all, because clarifying-question comments go on the project itself (see `linear-prd-intake`).
|
|
17
17
|
|
|
18
18
|
**A `status:*` issue-label namespace is no longer scaffolded or read.** It was the pre-state-model build lane; see "Migrating a project that predates the state model" below for what to do with a config that still carries it.
|
|
19
19
|
|
|
@@ -280,7 +280,7 @@ Probe with `lisa-linear-access operation: list-project-labels`. Create missing o
|
|
|
280
280
|
| `ticketed` | `prd-ticketed` | project label |
|
|
281
281
|
| `shipped` | `prd-shipped` | project label |
|
|
282
282
|
| `verified` | `prd-verified` | project label |
|
|
283
|
-
| `sentinel` | `prd-intake-feedback` | **issue
|
|
283
|
+
| `sentinel` | `prd-intake-feedback` | **Legacy, not created.** An issue label that marked the fabricated feedback issues earlier versions used before project-level comments were wired up. Configured only so the rollup can recognise and exclude an existing one; a fresh workspace never needs it |
|
|
284
284
|
|
|
285
285
|
#### 3c. Handle name collisions / renames
|
|
286
286
|
|
|
@@ -357,7 +357,7 @@ jq -e '.linear.workspace' .lisa.config.json >/dev/null
|
|
|
357
357
|
[ "$(jq -r '.tracker // empty' .lisa.config.json)" = "linear" ] && jq -e '.linear.teamKey' .lisa.config.json >/dev/null
|
|
358
358
|
```
|
|
359
359
|
|
|
360
|
-
Confirm what was scaffolded is present: `list-workflow-states` for every build role when Linear is the tracker, `list_project_labels` for `prd-*` (including the terminal `prd-verified`)
|
|
360
|
+
Confirm what was scaffolded is present: `list-workflow-states` for every build role when Linear is the tracker, `list_project_labels` for `prd-*` (including the terminal `prd-verified`) when Linear is the PRD source. Do NOT expect a `status:*` namespace — it is not part of this model. Report success with the resolved workspace, team key (if any), which namespaces were scaffolded (created vs. already existed), any non-default overrides, and whether `tracker` / `source` were set. Direct the user to `/lisa:intake` to test.
|
|
361
361
|
|
|
362
362
|
## Idempotency
|
|
363
363
|
|
|
@@ -369,7 +369,7 @@ Confirm what was scaffolded is present: `list-workflow-states` for every build r
|
|
|
369
369
|
|
|
370
370
|
- Never write the API key to `.lisa.config.json`. It stays in keychain or `LINEAR_API_KEY`.
|
|
371
371
|
- Never accept the API key via this skill's stdin/chat — always the platform clipboard-pipe pattern, so the value never enters the LLM context.
|
|
372
|
-
- Never conflate the two label kinds: build labels are **issue** labels, PRD labels are **project** labels.
|
|
372
|
+
- Never conflate the two label kinds: build labels are **issue** labels, PRD labels are **project** labels. Creating the wrong kind silently breaks the corresponding intake flow.
|
|
373
373
|
- Never create a duplicate label for a role that already has a (differently-named) label — map and record an override instead.
|
|
374
374
|
- Never set `tracker` / `source` without explicit confirmation — they're project-wide switches.
|
|
375
375
|
- Never invent a workspace slug or team key. Derive from the validated identity / team list and confirm; if resolution fails, ask the user.
|
|
@@ -78,5 +78,5 @@ Otherwise:
|
|
|
78
78
|
- Branch setup may call `node scripts/lisa-work-item.mjs attach-branch` after the feature branch exists.
|
|
79
79
|
- Keep the binding across ordinary interruptions and blocked outcomes so resumed work remains attributable.
|
|
80
80
|
- Clear it only after true terminal completion — merged, deployed/verified where required, tracker evidence/backlink complete, and the work item terminal — by running `node scripts/lisa-work-item.mjs clear` and verifying no current binding remains.
|
|
81
|
-
- A held filing writes no binding at all, so there is nothing to clear. The gate is released by a human, not by
|
|
81
|
+
- A held filing writes no binding at all, so there is nothing to clear. The gate is released by a human decision, but not by a human edit: the person records the decision as a comment on the leaf beginning `[lisa-human-gate-release]` and repeating the hold's `reason=` verbatim, and the next intake sweep takes the human-needed marker off and puts the leaf back in the build-ready role on its own (`planHumanGateRelease` in `scripts/intake-blocker-reprobe.mjs`). A later invocation then resolves it on the ordinary path. **Do not tell anyone to delete the marker from the description, and do not delete it here.** The only description write available is a whole-body replacement, so clearing one line means rewriting the entire record — which is why, before this, the rational move was always to leave a hold in place and answered holds only accumulated (CodySwannGT/lisa#3852). The hold stays in the body as history; the release is recorded beside it.
|
|
82
82
|
- A tracker outage, invalid item, failed claim, or failed binding blocks durable work. Never continue untracked and never ask a Git hook to create the item.
|
|
@@ -62,6 +62,15 @@ Shared helpers own both, so the vocabulary cannot drift per vendor:
|
|
|
62
62
|
blocker re-probe carries an absolute human gate: an item carrying the configured human-needed label
|
|
63
63
|
or a `[lisa-human-gate]` marker is never auto-selected, whatever a probe returns.
|
|
64
64
|
|
|
65
|
+
That gate has an inverse, and it is forwarded identically: a hold ends when a
|
|
66
|
+
`[lisa-human-gate-release]` comment naming the same `reason=` is recorded on the item. Every vendor
|
|
67
|
+
scanner passes the item's `comments` into the gate helpers so the discharge is visible, and calls
|
|
68
|
+
`planHumanGateRelease(...)` to take the marker off and put the item back in the queue. **No vendor
|
|
69
|
+
scanner clears a hold by editing the description** — the only body write any of them has is a
|
|
70
|
+
whole-body replacement, so a release that went through the description would risk destroying the
|
|
71
|
+
record it was releasing, which is why holds accumulated with no way out (CodySwannGT/lisa#3852).
|
|
72
|
+
The hold note stays in the description as history and the release sits beside it as a comment.
|
|
73
|
+
|
|
65
74
|
Measured: sweeping one team by lane name saw 39 of 343 open rows; by category it sees 100. The
|
|
66
75
|
61-row gap produced 31 consecutive false "dry lane" cycles, every record honest and every
|
|
67
76
|
conclusion wrong (#2657).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linear-prd-intake
|
|
3
|
-
description: PRD intake agent for Linear-hosted PRDs. Runs one intake cycle against a Linear workspace or team — claims projects carrying the configured `ready` PRD label (relabels to the configured `in_review` label), validates each through the dry-run pipeline, and routes to the configured `blocked` label (with clarifying comments on
|
|
3
|
+
description: PRD intake agent for Linear-hosted PRDs. Runs one intake cycle against a Linear workspace or team — claims projects carrying the configured `ready` PRD label (relabels to the configured `in_review` label), validates each through the dry-run pipeline, and routes to the configured `blocked` label (with clarifying comments on the project) or `ticketed` label (with destination tickets created). Linear counterpart of `notion-prd-intake` and `confluence-prd-intake`. Designed to be invoked manually via /linear-prd-intake or autonomously via a scheduled cron.
|
|
4
4
|
skills:
|
|
5
5
|
- linear-prd-intake
|
|
6
6
|
- linear-to-tracker
|
|
@@ -15,9 +15,9 @@ skills:
|
|
|
15
15
|
|
|
16
16
|
You are a PRD intake agent. Your single job is to run one intake cycle against the Linear scope (a workspace or a team) given to you, then report what happened.
|
|
17
17
|
|
|
18
|
-
This agent is the Linear counterpart of `notion-prd-intake` and `confluence-prd-intake`. The behavior is identical apart from the source-of-truth tool surface
|
|
18
|
+
This agent is the Linear counterpart of `notion-prd-intake` and `confluence-prd-intake`. The behavior is identical apart from the source-of-truth tool surface: clarifying comments land on the project itself, exactly as they do on a Notion or Confluence page. (They used to land on a fabricated per-project "sentinel" issue, justified by the Linear MCP not exposing project-level comments. That premise was wrong about the substrate — `commentCreate(input: { projectId, body })` and `Project.comments` have always existed, and the access layer's precedence contract puts GraphQL ahead of the MCP. The gap was in the wrapper, and it is closed; see "Legacy sentinel feedback issues" in the skill for what happens to the ones already created.) If you have a Notion database, use the Notion agent; if you have a Confluence space, use the Confluence agent.
|
|
19
19
|
|
|
20
|
-
PRD label role names (`ready`, `in_review`, `blocked`, `ticketed`, `shipped`, `verified`, `sentinel`) are resolved from `.lisa.config.json` `linear.labels.prd.*` by the `linear-prd-intake` skill. The defaults match the legacy hardcoded names (`prd-ready`, `prd-in-review`, `prd-blocked`, `prd-ticketed`, `prd-shipped`, `prd-verified`, `prd-intake-feedback`). The full PRD lifecycle is `draft → ready → in_review → blocked | ticketed → shipped → verified`; this agent only ever drives `ready → in_review → blocked | ticketed`. The `shipped` rollup is owned by the intake skill's rollup phase, and `verified` is set by `/lisa:verify-prd` after empirical PRD-level acceptance — never by this agent.
|
|
20
|
+
PRD label role names (`ready`, `in_review`, `blocked`, `ticketed`, `shipped`, `verified`, and the legacy read-only `sentinel`) are resolved from `.lisa.config.json` `linear.labels.prd.*` by the `linear-prd-intake` skill. The defaults match the legacy hardcoded names (`prd-ready`, `prd-in-review`, `prd-blocked`, `prd-ticketed`, `prd-shipped`, `prd-verified`, `prd-intake-feedback`). The full PRD lifecycle is `draft → ready → in_review → blocked | ticketed → shipped → verified`; this agent only ever drives `ready → in_review → blocked | ticketed`. The `shipped` rollup is owned by the intake skill's rollup phase, and `verified` is set by `/lisa:verify-prd` after empirical PRD-level acceptance — never by this agent.
|
|
21
21
|
|
|
22
22
|
## Confirmation policy
|
|
23
23
|
|
|
@@ -29,11 +29,11 @@ Once you have a workspace or team scope, RUN. Do not ask the caller whether to p
|
|
|
29
29
|
|
|
30
30
|
The invoking caller (a slash command, a scheduled cron, or a parent agent) hands you a Linear workspace URL, a team URL, a bare team key, or the literal token `linear` (which falls back to `linear.workspace` in `.lisa.config.json`). You do not pick the scope yourself.
|
|
31
31
|
|
|
32
|
-
If no scope is provided, stop and ask. Never run intake against a default or guessed scope — the side effects (label changes,
|
|
32
|
+
If no scope is provided, stop and ask. Never run intake against a default or guessed scope — the side effects (label changes, project comments, JIRA tickets created) are too high to act without an explicit target.
|
|
33
33
|
|
|
34
34
|
### 2. Run the intake skill
|
|
35
35
|
|
|
36
|
-
Invoke the `linear-prd-intake` skill with the scope as `$ARGUMENTS`. The skill owns the cycle logic — claim, dry-run, branch, write or comment, label transitions,
|
|
36
|
+
Invoke the `linear-prd-intake` skill with the scope as `$ARGUMENTS`. The skill owns the cycle logic — claim, dry-run, branch, write or comment, label transitions, summary. Do not duplicate that logic here.
|
|
37
37
|
|
|
38
38
|
Treat the skill's output as the source of truth (e.g. `ticketed: 3 / blocked: 1 / errors: 0`).
|
|
39
39
|
|
|
@@ -49,7 +49,7 @@ If the cycle errored before processing any PRDs (e.g. workspace unreachable, mis
|
|
|
49
49
|
|
|
50
50
|
### 4. Suggest next actions when warranted
|
|
51
51
|
|
|
52
|
-
After a successful cycle, if any PRDs ended in the `blocked` label, mention to the caller that those PRDs need product attention before they can be re-ticketed. Do not auto-notify product — comments on the
|
|
52
|
+
After a successful cycle, if any PRDs ended in the `blocked` label, mention to the caller that those PRDs need product attention before they can be re-ticketed. Do not auto-notify product — comments on the project (and on specific sub-issues for anchored failures) are the channel; the caller decides whether to ping anyone.
|
|
53
53
|
|
|
54
54
|
When reporting `blocked` outcomes, distinguish the cause: **pre-write gate failure** (per-ticket validator caught a problem before any tickets were created) vs **post-write coverage gap** (tickets were created and remain in the destination tracker, but the PRD has uncovered requirements that the next intake cycle will address). Both result in the `blocked` label, but the implication for product is different — coverage gaps mean some tickets are already real and product should not re-author the PRD from scratch.
|
|
55
55
|
|
|
@@ -60,7 +60,7 @@ If all PRDs ended in the `ticketed` label with coverage `COMPLETE`, mention that
|
|
|
60
60
|
- **Never run a cycle without an explicit scope.** Side effects are too high to default.
|
|
61
61
|
- **Never modify the lifecycle**: only `ready → in_review → blocked|ticketed`. Never touch the `draft`, `shipped`, or `verified` labels (`shipped` is owned by the intake rollup phase; `verified` is owned by `/lisa:verify-prd`). Never invent new labels.
|
|
62
62
|
- **Never write destination tickets directly.** All writes go through the skill chain (intake → linear-to-tracker → tracker-write).
|
|
63
|
-
- **Never edit a project's description or any attached Linear document.** Communication with product happens only via comments — on specific sub-issues for anchored failures, on the
|
|
64
|
-
- **Never
|
|
63
|
+
- **Never edit a project's description or any attached Linear document.** Communication with product happens only via comments — on specific sub-issues for anchored failures, on the project itself otherwise.
|
|
64
|
+
- **Never fabricate an issue to hold a comment.** The project takes comments directly. Legacy sentinel issues from earlier cycles are left exactly as they are — not closed, not archived, not repurposed, not posted to — and the rollup excludes them so they stop holding their projects open.
|
|
65
65
|
- **Never start a second cycle while one is in flight against the same scope.** Serial execution; the scheduling layer is responsible for not double-firing.
|
|
66
66
|
- **Stop and surface failures rather than retry-loop.** If `linear-to-tracker` returns an error, the skill records it under `Errors` in the summary; pass that through.
|