@codyswann/lisa 4.54.13 → 4.55.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/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 +265 -121
- 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 +28 -0
- 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 +10 -5
- 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 +7 -0
- /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
|
@@ -307,6 +307,17 @@ person scanning a board and to any path that has not yet been routed through the
|
|
|
307
307
|
If the label does not exist in the tracker, create it, or record that it could not be applied and
|
|
308
308
|
proceed — the marker still holds. Never file the label *instead of* the marker.
|
|
309
309
|
|
|
310
|
+
**Write a `reason=` the release can name.** The hold's reason is not decoration: a hold ends when a
|
|
311
|
+
`[lisa-human-gate-release]` comment repeating that same `reason=` is recorded on the item, and the
|
|
312
|
+
next intake sweep then takes the marker label off and puts the item back in the build-ready role on
|
|
313
|
+
its own. Matching is per-reason so that a hold declared *after* an earlier release is not born
|
|
314
|
+
discharged. A keyless hold is legal and is discharged by a keyless release; a hold whose reason is a
|
|
315
|
+
paragraph is legal and nobody will reproduce it. Prefer a short slug the person answering it can
|
|
316
|
+
retype. Do **not** instruct anyone to delete the marker from the description to lift the hold — the
|
|
317
|
+
only body write available is a whole-body replacement, so that asks them to rewrite the whole record
|
|
318
|
+
to clear one line, which is why answered holds accumulated instead of being lifted
|
|
319
|
+
(CodySwannGT/lisa#3852). The marker stays as history; the release is recorded beside it.
|
|
320
|
+
|
|
310
321
|
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 status rolls up from children, so they need neither.
|
|
311
322
|
|
|
312
323
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
@@ -355,6 +366,46 @@ Post a creation comment via `lisa-atlassian-access` `operation: comment key: <K>
|
|
|
355
366
|
|
|
356
367
|
Skip this step only on UPDATE when no material change was made.
|
|
357
368
|
|
|
369
|
+
## Writing by a bespoke path (your own script, direct API or GraphQL)
|
|
370
|
+
|
|
371
|
+
Nothing here stops a consumer from writing to JIRA through the JIRA REST API directly, `acli`, or your own script, and nothing should
|
|
372
|
+
try to — a script that owns the credential plumbing is often the only practical transport.
|
|
373
|
+
**The transport is not the gate.** A bespoke write path still owes both halves of the quality
|
|
374
|
+
gate this skill runs, and owes them explicitly, because no phase of this flow will ever run
|
|
375
|
+
for it.
|
|
376
|
+
|
|
377
|
+
A bespoke script's own read-back does not discharge either obligation. Re-reading the ticket
|
|
378
|
+
and confirming JIRA stored what was sent **proves transport, not quality**: it shows the
|
|
379
|
+
fields round-tripped and says nothing about whether what was sent clears a single gate. An
|
|
380
|
+
agent that reads `VERIFIED` out of such a script has been told the ticket was checked when it
|
|
381
|
+
was not. Measured once, on one ticket, on 2026-09-03 (CodySwannGT/lisa#3663): a local
|
|
382
|
+
script's read-back was clean on every field, and the ticket then failed gates S5, S9 and S18
|
|
383
|
+
when the validator was run against it by hand.
|
|
384
|
+
|
|
385
|
+
What a bespoke write path still owes — the same two checks, invoked by hand:
|
|
386
|
+
|
|
387
|
+
1. **Pre-write validate**, the obligation Phase 5.5 discharges here. Invoke `lisa-jira-validate-ticket` via
|
|
388
|
+
the Skill tool with the proposed spec as a YAML block **before** writing. Never write on a
|
|
389
|
+
`FAIL` verdict.
|
|
390
|
+
2. **Post-write verify**, the obligation Phase 7 discharges here. Invoke `lisa-jira-verify` via the
|
|
391
|
+
Skill tool with the identifier of the ticket you just wrote — or `lisa-jira-validate-ticket` directly in
|
|
392
|
+
identifier mode, which fetches and validates the live state. Never report success on a
|
|
393
|
+
`FAIL` verdict.
|
|
394
|
+
|
|
395
|
+
Both run standalone against an existing live ticket; `lisa-jira-validate-ticket` documents the copy-pasteable
|
|
396
|
+
invocation under its standalone entry point.
|
|
397
|
+
|
|
398
|
+
**Three outcomes, never two.** `PASS`, `FAIL` and *could not validate* are distinct results.
|
|
399
|
+
If the validator did not run to a verdict — the skill was unavailable, a credential was
|
|
400
|
+
missing, the ticket could not be fetched — that is **not** a pass. Report it as unvalidated and
|
|
401
|
+
say why. Collapsing "could not validate" into "validated" is the same misreading as trusting
|
|
402
|
+
a read-back.
|
|
403
|
+
|
|
404
|
+
**These are skills, not scripts.** `lisa-jira-validate-ticket` and `lisa-jira-verify` are plugin-resident and invoked
|
|
405
|
+
through the Skill tool. They are **not** expected to appear in any repository's `scripts/`
|
|
406
|
+
directory, and their absence from one is not evidence that the capability is missing —
|
|
407
|
+
searching the repository you happen to be standing in is the wrong search.
|
|
408
|
+
|
|
358
409
|
## Rules
|
|
359
410
|
|
|
360
411
|
- Never create a non-bug ticket without an epic parent.
|
|
@@ -23,8 +23,8 @@ operation: get-issue id:<ID>
|
|
|
23
23
|
operation: save-issue payload:{...} [lifecycle_role:<ROLE>] [env:<KEY>]
|
|
24
24
|
operation: list-workflow-states team:<ID>
|
|
25
25
|
operation: create-workflow-state payload:{...}
|
|
26
|
-
operation: list-comments issue_id:<ID>
|
|
27
|
-
operation: save-comment issue_id:<ID> body:"..."
|
|
26
|
+
operation: list-comments (issue_id:<ID> | project_id:<ID>)
|
|
27
|
+
operation: save-comment (issue_id:<ID> | project_id:<ID>) body:"..."
|
|
28
28
|
operation: history id:<ID>
|
|
29
29
|
operation: list-issue-labels [team:<ID>]
|
|
30
30
|
operation: create-issue-label payload:{...}
|
|
@@ -294,6 +294,55 @@ Set `isTeamDefault` per node by comparing `node.id` against
|
|
|
294
294
|
the team's default, resolve the default through the team record and join on `id`
|
|
295
295
|
the same way.
|
|
296
296
|
|
|
297
|
+
## `save-comment` / `list-comments` — an Issue **or** a Project
|
|
298
|
+
|
|
299
|
+
Both comment operations take **either** `issue_id:` or `project_id:`. Exactly one
|
|
300
|
+
is required; passing both, or neither, is refused naming the operation.
|
|
301
|
+
|
|
302
|
+
Linear treats a comment's target as one field on the same input type, so the
|
|
303
|
+
project form is not a second mechanism — it is the same mutation with a
|
|
304
|
+
different anchor. Direct introspection of `https://api.linear.app/graphql`:
|
|
305
|
+
`CommentCreateInput` accepts `issueId`, `projectId`, `projectUpdateId`,
|
|
306
|
+
`documentContentId`, and `parentId`, and the `Project` type exposes
|
|
307
|
+
`Project.comments`. Neither is beta and neither needs a special scope.
|
|
308
|
+
|
|
309
|
+
```graphql
|
|
310
|
+
# save-comment — the anchor field is chosen by which id the caller passed.
|
|
311
|
+
mutation($input:CommentCreateInput!){
|
|
312
|
+
commentCreate(input:$input){ success comment{ id url createdAt } }
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Build `$input` as `{ issueId: <id>, body: <body> }` for the Issue form and
|
|
317
|
+
`{ projectId: <id>, body: <body> }` for the Project form. Nothing else differs —
|
|
318
|
+
same mutation, same result shape, same error handling.
|
|
319
|
+
|
|
320
|
+
```graphql
|
|
321
|
+
# list-comments project_id:<ID> — page via pageInfo so a long-lived PRD's
|
|
322
|
+
# feedback history never silently truncates.
|
|
323
|
+
query($id:String!){
|
|
324
|
+
project(id:$id){
|
|
325
|
+
comments(first:100){
|
|
326
|
+
pageInfo{ hasNextPage endCursor }
|
|
327
|
+
nodes{ id body createdAt url user{ name } }
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
The Issue form reads through `issue(id:$id){ comments{...} }` with the identical
|
|
334
|
+
node shape, so a caller consumes one result format for either anchor.
|
|
335
|
+
|
|
336
|
+
**Substrate.** The Linear MCP exposes comments on Issues only, so the
|
|
337
|
+
`project_id` form resolves solely through the tier-1 `LINEAR_API_KEY` + GraphQL
|
|
338
|
+
substrate — the same restriction `history` carries, and for the same reason.
|
|
339
|
+
That is not a gap in Linear: the precedence contract already puts GraphQL ahead
|
|
340
|
+
of the MCP, so the preferred substrate has always been able to do this. Only
|
|
341
|
+
this wrapper could not, which is what made callers fabricate an Issue to hold a
|
|
342
|
+
Project's comments. If tier 1 is unavailable, fail with the layer's standard
|
|
343
|
+
`Error:` result naming `save-comment project_id` — do **not** silently degrade
|
|
344
|
+
into creating an Issue to comment on.
|
|
345
|
+
|
|
297
346
|
## `history` — transition history (read-only)
|
|
298
347
|
|
|
299
348
|
`history id:<ID>` returns an Issue's ordered past state changes — the raw
|
|
@@ -371,6 +420,10 @@ query($id:String!){
|
|
|
371
420
|
- Missing token plus missing MCP is a hard failure naming `LINEAR_API_KEY`.
|
|
372
421
|
- Mutations send only the fields being changed, matching existing Linear skill
|
|
373
422
|
guidance that `save_*` style updates should not clobber unrelated fields.
|
|
423
|
+
- A comment anchors to exactly one target. `save-comment` and `list-comments`
|
|
424
|
+
take `issue_id` **or** `project_id`, never both and never neither. A caller
|
|
425
|
+
that wants to comment on a Project passes `project_id` — it never creates an
|
|
426
|
+
Issue to hold the comment, and this layer never creates one on its behalf.
|
|
374
427
|
- Every workflow-state write is resolved by
|
|
375
428
|
`scripts/linear-state-write-target.mjs` from a declared `lifecycle_role`,
|
|
376
429
|
before either transport. The ID dispatched is the ID that script returned —
|
|
@@ -216,7 +216,12 @@ other gate's verdict — however conclusive — may promote an item a person par
|
|
|
216
216
|
drift, and a drifted gate fails *silently*, by quietly ceasing to match. Do **not** re-implement
|
|
217
217
|
the test here, and do **not** key it on `reason=`: markers in the wild carry no `reason=` key at
|
|
218
218
|
all and sit anywhere in the body, so a structured parse would miss them while appearing to work
|
|
219
|
-
on every item that happens to have one.
|
|
219
|
+
on every item that happens to have one. **Pass the item's `comments` alongside its labels and
|
|
220
|
+
body.** A hold is ended by a release recorded in a comment, so a reader handed no comments cannot
|
|
221
|
+
see the discharge — it goes on holding an item whose question was answered weeks ago, which is
|
|
222
|
+
the defect this gate carried from the day it was written (CodySwannGT/lisa#3852). Omitting them
|
|
223
|
+
fails closed, and that is exactly why it is easy to miss: nothing breaks, the item simply never
|
|
224
|
+
comes back.
|
|
220
225
|
2. **On `claimable: false` with reason `human-gate`, do not claim and do not dispatch.**
|
|
221
226
|
3. **Reconcile the lane; do not merely skip.** Skipping alone leaves the item in `$READY`, re-judged
|
|
222
227
|
and re-rejected every cycle forever and seen by nothing — `lisa-repair-intake` sweeps items that
|
|
@@ -228,14 +233,32 @@ other gate's verdict — however conclusive — may promote an item a person par
|
|
|
228
233
|
already out of the lane and already marked yields no second mutation and no second comment. This
|
|
229
234
|
is the same repair the leaf-only gate already performs for a ready item that must not be
|
|
230
235
|
dispatched.
|
|
231
|
-
4. **
|
|
236
|
+
4. **On `claimable: true` for an item that still carries a hold, RELEASE it — do not just proceed.**
|
|
237
|
+
The hold left durable state behind: the item is out of the queue and flagged as needing a person,
|
|
238
|
+
and answering the question does not undo either. Call
|
|
239
|
+
`planHumanGateRelease({ labels, body, comments, humanNeededLabel, readyLabel, lifecycleLabels, alreadyNotified })`
|
|
240
|
+
and apply exactly the actions it returns: remove the configured human-needed marker, add the
|
|
241
|
+
configured ready role back, and post `formatHumanGateReleaseNote()` once. It is the exact inverse
|
|
242
|
+
of step 3's planner and it refuses in both directions — an item still held plans nothing, and an
|
|
243
|
+
item never held plans nothing, so it can only ever un-do a hold and can never promote something on
|
|
244
|
+
its own. It is idempotent by state, so a second cycle over a released item yields no second
|
|
245
|
+
mutation and no second comment.
|
|
246
|
+
|
|
247
|
+
**Never edit the description to clear a hold.** The only body write available is a whole-body
|
|
248
|
+
replacement, so deleting one line means rewriting the whole record and hoping nothing was
|
|
249
|
+
dropped — the reason holds accumulated instead of being lifted. The hold note stays in the
|
|
250
|
+
description as history; the release is a comment beside it.
|
|
251
|
+
5. **Name it in the cycle summary** via `summarizeHumanGateHolds([...])`, so the record
|
|
232
252
|
distinguishes "nothing was eligible" from "something eligible was held for a person". A lane
|
|
233
253
|
mutation nobody can see afterwards is the same class of problem this gate exists to fix.
|
|
234
254
|
Report alongside it what the precision rule SKIPPED, via `summarizeHumanGateMentions(n)`
|
|
235
255
|
— the marker occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815).
|
|
236
256
|
A rule that quietly declines to honour half the occurrences it sees reads exactly like a
|
|
237
|
-
rule that saw none, so the count is printed even when it is zero.
|
|
238
|
-
|
|
257
|
+
rule that saw none, so the count is printed even when it is zero. Report what was RELEASED
|
|
258
|
+
beside it via `summarizeHumanGateReleases([...])`, printed even when it is zero: a release path
|
|
259
|
+
that has stopped working and a cycle with nothing to release read identically otherwise, which
|
|
260
|
+
is how a missing inverse stays missing.
|
|
261
|
+
6. **Continue to the next candidate.** A held item does not end the cycle.
|
|
239
262
|
|
|
240
263
|
|
|
241
264
|
#### 3a.0 Repo-scope gate (claim only current-repo Issues)
|
|
@@ -12,7 +12,7 @@ allowed-tools: ["Skill", "Bash"]
|
|
|
12
12
|
- A Linear **team** URL or team key — scans every project on the team whose labels include the configured `ready` label. Example: `https://linear.app/acme/team/ENG/projects` or bare `ENG`.
|
|
13
13
|
- The literal token `linear` — equivalent to "the default Linear workspace"; only valid if `linear.workspace` is configured in `.lisa.config.json`.
|
|
14
14
|
|
|
15
|
-
Run one intake cycle against that scope. The first eligible project with the `ready` label is claimed, validated, routed to either the `blocked` label (with clarifying comments on
|
|
15
|
+
Run one intake cycle against that scope. The first eligible project with the `ready` label is claimed, validated, routed to either the `blocked` label (with clarifying comments on the project) or the `ticketed` label (with destination tickets created), then the cycle exits. Remaining ready projects stay queued for later scheduler invocations.
|
|
16
16
|
|
|
17
17
|
## Workflow resolution
|
|
18
18
|
|
|
@@ -37,9 +37,15 @@ SHIPPED=$(read_role shipped "prd-shipped")
|
|
|
37
37
|
SENTINEL=$(read_role sentinel "prd-intake-feedback")
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
`$SENTINEL` is **legacy-read-only**. This skill no longer creates a sentinel
|
|
41
|
+
feedback issue — unanchored comments go on the project. The role is still
|
|
42
|
+
resolved because projects intake ran against before this change already carry
|
|
43
|
+
one, and the rollup phase must recognise it to keep it out of the denominator
|
|
44
|
+
(see "Legacy sentinel feedback issues").
|
|
45
|
+
|
|
40
46
|
In prose below, the role names refer to the resolved labels: e.g. "the `ready` label" means whatever `linear.labels.prd.ready` resolves to (default: `prd-ready`).
|
|
41
47
|
|
|
42
|
-
This skill is the Linear counterpart of `lisa-notion-prd-intake` and `lisa-confluence-prd-intake`, and shares its PRD shipped rollup phase (3f) with `lisa-github-prd-intake`. The phases, gates, comment templates, and rules are identical — the only differences are (1) the lifecycle is encoded as **project labels** instead of a status property, (2) the fetch / update
|
|
48
|
+
This skill is the Linear counterpart of `lisa-notion-prd-intake` and `lisa-confluence-prd-intake`, and shares its PRD shipped rollup phase (3f) with `lisa-github-prd-intake`. The phases, gates, comment templates, and rules are identical — the only differences are (1) the lifecycle is encoded as **project labels** instead of a status property, and (2) the fetch / update surface is `lisa-linear-access`. Unanchored clarifying-question comments land on the **project itself**, exactly as they do on a Notion or Confluence page — `lisa-linear-access operation: save-comment project_id:<ID>` maps to `commentCreate(input: { projectId, body })`, which Linear has always supported. Keep all four intake skills behaviorally aligned: when changing intake logic — including the rollup phase — change them together.
|
|
43
49
|
|
|
44
50
|
The **PRD shipped rollup phase (3f)** transitions a `$TICKETED` PRD project to `$SHIPPED` once all its generated top-level work is terminal, per the `prd-lifecycle-rollup` rule. This is the Linear leg of the same vendor-neutral rollup that `lisa-github-prd-intake` implements for GitHub (LPC-1.3 #584); only the vendor surface (Linear workflow states + project labels) differs.
|
|
45
51
|
|
|
@@ -146,7 +152,7 @@ This call also indirectly invokes `lisa-tracker-source-artifacts` (artifact extr
|
|
|
146
152
|
|
|
147
153
|
1. Re-invoke `lisa-linear-to-tracker` with `dry_run: false` to actually write the tickets. This re-runs Phases 1-5 and runs the preservation gate (Phase 5.5).
|
|
148
154
|
2. Capture the created ticket keys from the skill's output.
|
|
149
|
-
3.
|
|
155
|
+
3. Post a comment on the project via `lisa-linear-access operation: save-comment project_id:<id>` listing the created tickets (epic, stories, sub-tasks) with their JIRA URLs. Lead with: `"Ticketed by Claude. Created N JIRA issues — see below. Add the $SHIPPED label to the Linear project after the work is delivered."`
|
|
150
156
|
4. Transition labels: remove `$IN_REVIEW`, add `$TICKETED` via `save_project`.
|
|
151
157
|
5. **Run Phase 3e (coverage audit)** before considering this PRD done.
|
|
152
158
|
|
|
@@ -157,13 +163,13 @@ The audience for these comments is the **product team**, not engineers. They are
|
|
|
157
163
|
##### 3c.1 Partition failures
|
|
158
164
|
|
|
159
165
|
1. Drop every failure where `product_relevant = false`. Those are internal data-quality problems — the agent should fix its own spec rather than ask product to clarify a missing core field. Record the dropped failures under `Errors` in the cycle summary so engineers can see them; never surface them on the PRD.
|
|
160
|
-
2. Group the remaining product-relevant failures by `prd_anchor` (which, for Linear, is a sub-issue identifier when the failure traces to a specific issue, or `null` otherwise). Failures that share an anchor become one comment thread on that issue. Failures with `prd_anchor: null` are batched into one comment on the
|
|
166
|
+
2. Group the remaining product-relevant failures by `prd_anchor` (which, for Linear, is a sub-issue identifier when the failure traces to a specific issue, or `null` otherwise). Failures that share an anchor become one comment thread on that issue. Failures with `prd_anchor: null` are batched into one comment on the **project itself**, since they have no source sub-issue to attach to.
|
|
161
167
|
|
|
162
168
|
##### 3c.2 Render each comment
|
|
163
169
|
|
|
164
|
-
|
|
170
|
+
For each anchored group (`prd_anchor` is a sub-issue identifier), post a comment on THAT sub-issue via `lisa-linear-access operation: save-comment issue_id:<prd_anchor> body:<template>`. For the unanchored group, post a single comment on the **project** via `lisa-linear-access operation: save-comment project_id:<id> body:<template>`, using the same template, prefixed with `Issues without a specific sub-issue anchor:` and one block per failure.
|
|
165
171
|
|
|
166
|
-
If `
|
|
172
|
+
If `save-comment` fails for a specific anchored sub-issue (the issue was deleted between fetch and post, or the agent lacks comment permission), fall back to the **project** comment for that group. Do not silently drop the failure, and do not create an issue to hold it.
|
|
167
173
|
|
|
168
174
|
##### 3c.3 Comment template
|
|
169
175
|
|
|
@@ -207,7 +213,7 @@ Use these exact badge labels — they are the validator's category values transl
|
|
|
207
213
|
|
|
208
214
|
##### 3c.6 Label transition
|
|
209
215
|
|
|
210
|
-
After all comments are posted (anchored groups + the optional
|
|
216
|
+
After all comments are posted (anchored groups + the optional project-level summary), transition labels: remove `$IN_REVIEW`, add `$BLOCKED` via `save_project`. Do NOT write any destination tickets.
|
|
211
217
|
|
|
212
218
|
#### 3d. Stop
|
|
213
219
|
|
|
@@ -223,8 +229,8 @@ Per-ticket gates prove each ticket is well-formed; they do NOT prove the *set* o
|
|
|
223
229
|
| Verdict | Action |
|
|
224
230
|
|---------|--------|
|
|
225
231
|
| `COMPLETE` | Done. Leave label as `$TICKETED`. End the cycle. |
|
|
226
|
-
| `COMPLETE_WITH_SCOPE_CREEP` | Post an advisory comment on the
|
|
227
|
-
| `GAPS_FOUND` | The created ticket set is incomplete. (a) For each gap, post a comment using the same product-facing template as Phase 3c.3 — anchored on the relevant sub-issue when `prd_anchor` is non-null, on the
|
|
232
|
+
| `COMPLETE_WITH_SCOPE_CREEP` | Post an advisory comment on the project naming the scope-creep tickets (so product can decide whether to close them as out-of-scope). Leave label as `$TICKETED`. |
|
|
233
|
+
| `GAPS_FOUND` | The created ticket set is incomplete. (a) For each gap, post a comment using the same product-facing template as Phase 3c.3 — anchored on the relevant sub-issue when `prd_anchor` is non-null, on the project otherwise; category badge from the gap's `category` field; `What's unclear` and `Recommendation` from the audit report's `what` and `recommendation` fields. Apply the same forbidden-language rules from Phase 3c.5. (b) Post one summary comment on the project listing the tickets that *were* successfully created (so product knows what to keep vs. what to extend). (c) Transition labels from `$TICKETED` back to `$BLOCKED` via `save_project`. |
|
|
228
234
|
| `NO_TICKETS_FOUND` | Should not happen if step 2 succeeded. If it does, log it as an Error in the cycle summary and leave label as `$TICKETED` with a comment flagging the audit failure for human review. |
|
|
229
235
|
|
|
230
236
|
3. The created tickets remain in the destination tracker regardless of the verdict — they are valid in their own right. The audit only tells us whether *more* are needed.
|
|
@@ -251,6 +257,8 @@ Read the PRD's **generated top-level work** — its created Epics and any top-le
|
|
|
251
257
|
|
|
252
258
|
2. **Documented `## Tickets` section (fallback).** When the native relationship is unavailable (the destination tracker is a *different* system — e.g. Linear PRD → JIRA tracker — so the children were never linked as Linear issues), parse the machine-readable generated-work section `lisa-prd-backlink` writes to the PRD (`## Tickets`, alias `## Generated Work`; see #582). Top-level children are the `### <Epic key>: <title>` group headers' first line (`- [<ref>](<url>) — Epic`) plus any top-level Story listed directly under `### Unparented items`. Lines nested deeper (` - ... — Story:` under an Epic, ` - ... — Sub-task:`) are descendants, NOT top-level children — skip them.
|
|
253
259
|
|
|
260
|
+
**Exclude any Issue carrying the `$SENTINEL` label from the child set entirely — before the dedupe, before the predicate.** A legacy sentinel is an artifact of this skill, not generated work, and it can never be terminal: closing it was forbidden precisely so its comment history stayed intact. Counting it kept the PRD out of `$SHIPPED` forever — a project whose real children were all terminal still sat at `$TICKETED` because the one non-terminal child was the reporting mechanism itself. It is excluded regardless of its state, so projects that already have a sentinel unjam without anyone touching the sentinel. Record it in the cycle summary as `excluded: legacy sentinel <ref>` so the exclusion is visible rather than silent.
|
|
261
|
+
|
|
254
262
|
Dedupe the resulting child set by **child-ref identity** (the Linear issue/project identifier, e.g. `TEAM-123` or its UUID) so a child that appears both as a native relationship and in the documented section is counted once (`prd-lifecycle-rollup` idempotency dedupe key). If neither source yields any child (the PRD generated nothing, or the relationship was never recorded), record `no generated top-level children — rollup skipped` and leave the PRD as `$TICKETED`; do not ship an empty PRD.
|
|
255
263
|
|
|
256
264
|
##### 3f.3 Apply the terminal-state predicate
|
|
@@ -261,7 +269,7 @@ For each top-level child, fetch its workflow state and classify per the `prd-lif
|
|
|
261
269
|
- **Terminal-but-dropped.** The child is in a **canceled** workflow state (the `canceled`-category state). Like a not-planned leaf, it does not hold the PRD open and is excluded from the shipped set.
|
|
262
270
|
- **Incomplete / blocked.** Anything else: any backlog / unstarted / started / triage workflow state. Holds the PRD open.
|
|
263
271
|
|
|
264
|
-
The set of **required** children for the all-terminal check is the top-level children minus the canceled (terminal-but-dropped) ones.
|
|
272
|
+
The set of **required** children for the all-terminal check is the top-level children minus the canceled (terminal-but-dropped) ones. Legacy `$SENTINEL`-labelled Issues never reach this predicate at all — 3f.2 drops them from the child set, so they are absent from both the numerator and the denominator.
|
|
265
273
|
|
|
266
274
|
##### 3f.4 Branch on the rollup verdict
|
|
267
275
|
|
|
@@ -269,12 +277,12 @@ The set of **required** children for the all-terminal check is the top-level chi
|
|
|
269
277
|
|
|
270
278
|
1. Transition labels: remove `$TICKETED`, add `$SHIPPED` via `lisa-linear-access operation: save-project({id, labels})`. Verify exactly one lifecycle label remains (the single-label invariant).
|
|
271
279
|
2. Leave the PRD active for `/lisa:verify-prd`; do not archive at the shipped hop.
|
|
272
|
-
3. Post a short rollup comment on the
|
|
280
|
+
3. Post a short rollup comment on the project naming the terminal child set and (when dropped children exist) the dropped set, so the audit trail records *why* the PRD shipped. Lead with `"Shipped by Claude — all generated top-level work is complete."`
|
|
273
281
|
|
|
274
282
|
**Any required child incomplete / blocked**:
|
|
275
283
|
|
|
276
284
|
1. Leave the PRD label as `$TICKETED` and leave the project **active**. Do NOT add `$SHIPPED`. Do NOT archive.
|
|
277
|
-
2. Report the incomplete child set — both in the cycle summary and, when at least one cycle has previously ticketed this PRD, as a single advisory comment on the
|
|
285
|
+
2. Report the incomplete child set — both in the cycle summary and, when at least one cycle has previously ticketed this PRD, as a single advisory comment on the project listing the still-open children (`- <ref> "<title>" — <state>`), so product can see what's blocking the rollup. Keep it idempotent: regenerate the advisory rather than appending a fresh one each cycle.
|
|
278
286
|
|
|
279
287
|
##### 3f.5 Rollup cites the rule
|
|
280
288
|
|
|
@@ -315,28 +323,37 @@ Coverage audit summary: <n> COMPLETE / <n> COMPLETE_WITH_SCOPE_CREEP / <n> GAPS_
|
|
|
315
323
|
|
|
316
324
|
Print to the agent's output. Do not write this summary to Linear or the destination tracker — it's an operational record for the human.
|
|
317
325
|
|
|
318
|
-
##
|
|
319
|
-
|
|
320
|
-
Linear's MCP does not expose project-level comments. To preserve the comment-based feedback channel that Notion and Confluence intake have natively, this skill maintains a single sentinel **feedback Issue** under each project. All clarifying-question comments that don't anchor to a specific sub-issue land here.
|
|
326
|
+
## Legacy sentinel feedback issues
|
|
321
327
|
|
|
322
|
-
|
|
328
|
+
Earlier versions of this skill find-or-created one Issue per project — titled
|
|
329
|
+
`"PRD intake: clarifying questions"`, labelled `$SENTINEL` — to hold the
|
|
330
|
+
unanchored clarifying-question comments, on the belief that Linear had no
|
|
331
|
+
project-level comment channel. It does: `commentCreate(input: { projectId, body })`
|
|
332
|
+
and `Project.comments` are first-class operations, now exposed by
|
|
333
|
+
`lisa-linear-access` as the `project_id` forms of `save-comment` and
|
|
334
|
+
`list-comments`. The constraint was this wrapper, never the substrate.
|
|
323
335
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
- Membership in the project being processed
|
|
336
|
+
**This skill no longer creates a sentinel.** There is no find-or-create step;
|
|
337
|
+
unanchored comments go on the project. New projects never get one.
|
|
327
338
|
|
|
328
|
-
|
|
339
|
+
Projects processed before this change still carry theirs, so:
|
|
329
340
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
341
|
+
- **Do not close, archive, delete, or repurpose an existing sentinel.** Its
|
|
342
|
+
comment history is a real audit trail, and it has nowhere else to live yet.
|
|
343
|
+
Retiring them is deliberately out of scope here.
|
|
344
|
+
- **Do not post to it either.** New unanchored comments go on the project, so the
|
|
345
|
+
two channels do not interleave.
|
|
346
|
+
- **The rollup ignores it** (Phase 3f.2). That is what stops an existing sentinel
|
|
347
|
+
from holding its project out of `$SHIPPED` forever.
|
|
333
348
|
|
|
334
|
-
|
|
349
|
+
`$SENTINEL` therefore survives in config as a **read-only recognizer** — the
|
|
350
|
+
label name the rollup matches on to exclude these issues. It is no longer a
|
|
351
|
+
label this skill writes.
|
|
335
352
|
|
|
336
353
|
## Idempotency & safety
|
|
337
354
|
|
|
338
355
|
- **One item per cycle**: this skill processes the first eligible ready project from Phase 2, then exits. New or remaining `$READY` projects are picked up by later scheduler invocations.
|
|
339
|
-
- **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa-linear-to-tracker` (which delegates to `lisa-tracker-write`), only ever changes Linear project labels among `$IN_REVIEW`, `$BLOCKED`, `$TICKETED`, and `$SHIPPED` (the last via the rollup phase 3f only), only ever
|
|
356
|
+
- **No writes outside the lifecycle**: this skill only ever writes to the destination tracker via `lisa-linear-to-tracker` (which delegates to `lisa-tracker-write`), only ever changes Linear project labels among `$IN_REVIEW`, `$BLOCKED`, `$TICKETED`, and `$SHIPPED` (the last via the rollup phase 3f only), only ever comments on the PRD project itself and on the sub-issues a failure anchors to (never on any other Linear issue, and it creates no Linear issue of its own). It never edits project descriptions, never edits Linear documents, never touches the `draft` label, never archives projects at the shipped hop, and never deletes projects.
|
|
340
357
|
- **Claim-first ordering**: the label flip to `$IN_REVIEW` happens BEFORE validation runs, so a re-entrant call won't double-process.
|
|
341
358
|
- **Failure handling**: an exception processing the selected project is caught and recorded under "Errors" in the summary, then the cycle exits. The project that errored is left labelled `$IN_REVIEW` — the human investigates from there.
|
|
342
359
|
- **Single-label invariant**: after every transition, verify exactly one lifecycle label is present on the project. If two are present (rare race), surface as an Error and skip — do NOT auto-resolve, the human decides.
|
|
@@ -358,18 +375,18 @@ Destination tracker config (jira / github / linear) is consumed by `lisa-tracker
|
|
|
358
375
|
| `.lisa.config.json` `linear.labels.prd.blocked` | `prd-blocked` | Project label set on validation failure |
|
|
359
376
|
| `.lisa.config.json` `linear.labels.prd.ticketed` | `prd-ticketed` | Project label set on success |
|
|
360
377
|
| `.lisa.config.json` `linear.labels.prd.shipped` | `prd-shipped` | Project label set by the rollup phase (3f) when all generated top-level work is terminal; product may also set it by hand |
|
|
361
|
-
| `.lisa.config.json` `linear.labels.prd.sentinel` | `prd-intake-feedback` | Issue-level label marking
|
|
378
|
+
| `.lisa.config.json` `linear.labels.prd.sentinel` | `prd-intake-feedback` | Issue-level label marking a **legacy** sentinel feedback issue. Read-only: matched so the rollup can exclude it (Phase 3f.2); never written by this skill |
|
|
362
379
|
|
|
363
380
|
## Rules
|
|
364
381
|
|
|
365
382
|
- Never write to the destination tracker outside of `lisa-linear-to-tracker` → `lisa-tracker-write`. The validator's verdict gates progress; bypassing it produces broken tickets.
|
|
366
|
-
- Never add or remove a label this skill doesn't own (`$IN_REVIEW`, `$BLOCKED`, `$TICKETED`, and `$SHIPPED` via the rollup phase only). Product owns the `draft` and `ready` labels; product and the rollup phase (3f) both set `shipped`. The issue-level `$SENTINEL` label is
|
|
383
|
+
- Never add or remove a label this skill doesn't own (`$IN_REVIEW`, `$BLOCKED`, `$TICKETED`, and `$SHIPPED` via the rollup phase only). Product owns the `draft` and `ready` labels; product and the rollup phase (3f) both set `shipped`. The issue-level `$SENTINEL` label is read-only here — matched to recognise legacy sentinel issues, never applied.
|
|
367
384
|
- Set `$SHIPPED` only from the rollup phase, and only when all generated top-level children are terminal per the `prd-lifecycle-rollup` rule. Never ship on partial completion and never archive at shipped.
|
|
368
|
-
- Never edit a project's description or any attached Linear document. Communication with product happens only through comments on
|
|
369
|
-
- Never post a single dump of all gate failures on one comment. One comment per `prd_anchor` group on the relevant sub-issue (or one comment on the
|
|
385
|
+
- Never edit a project's description or any attached Linear document. Communication with product happens only through comments — on the project itself, or on the sub-issue a failure anchors to.
|
|
386
|
+
- Never post a single dump of all gate failures on one comment. One comment per `prd_anchor` group on the relevant sub-issue (or one comment on the project for unanchored failures only). Comments must be sub-issue-anchored where possible, categorized, plain-language, and contain a concrete recommendation.
|
|
370
387
|
- Never include a gate ID, internal skill name, or engineering shorthand in a comment body.
|
|
371
388
|
- Never run more than one intake cycle concurrently against the same scope. This skill assumes serial execution.
|
|
372
|
-
- Never close, archive, or
|
|
389
|
+
- Never create a Linear issue to hold a comment. Unanchored feedback belongs on the project. Never close, archive, repurpose, or post to a legacy sentinel issue either — its existing history is an audit trail, and retiring those issues is a separate, deliberate follow-up.
|
|
373
390
|
- If `lisa-linear-to-tracker` returns errors, treat them as gate failures: comment + `$BLOCKED`. Don't silently fail.
|
|
374
391
|
|
|
375
392
|
## Adoption (one-time per project)
|
|
@@ -27,7 +27,7 @@ This skill supports two modes, controlled by a `dry_run` flag in `$ARGUMENTS`:
|
|
|
27
27
|
- **`dry_run: false`** (default — full mode): run all phases, write tickets via `lisa-tracker-write`, run the preservation gate, report.
|
|
28
28
|
- **`dry_run: true`** (planning + validation only — no writes): run Phases 1, 1.5, 1.6, 2, 3, 4 to plan the hierarchy and draft each ticket spec, then call `lisa-tracker-validate` (with `--spec-only`) on every drafted ticket. Aggregate the per-ticket validator reports into a single dry-run report. **Skip Phase 5 (sub-task creation), Phase 5.5 (preservation gate), and Phase 6 (results report)** — none of those make sense without writes. Return the dry-run report so the caller (e.g. `lisa-linear-prd-intake`) can decide whether to proceed.
|
|
29
29
|
|
|
30
|
-
Dry-run output format is identical to `lisa-notion-to-tracker`'s and `lisa-confluence-to-tracker`'s. Reuse the same fields, including `prd_anchor` and `prd_section`, the `### Requirement register` section, and the per-node `requirements:` lists. The only difference: Linear has no inline-comment selection-anchor primitive at the project level — `prd_anchor` is the anchor a downstream caller would use to *post a comment on the related sub-issue* (typically the issue identifier, e.g. `LIN-123`, scoped to a section heading). When the failure does not map to any single sub-issue, set `prd_anchor: null` and the caller
|
|
30
|
+
Dry-run output format is identical to `lisa-notion-to-tracker`'s and `lisa-confluence-to-tracker`'s. Reuse the same fields, including `prd_anchor` and `prd_section`, the `### Requirement register` section, and the per-node `requirements:` lists. The only difference: Linear has no inline-comment selection-anchor primitive at the project level — `prd_anchor` is the anchor a downstream caller would use to *post a comment on the related sub-issue* (typically the issue identifier, e.g. `LIN-123`, scoped to a section heading). When the failure does not map to any single sub-issue, set `prd_anchor: null` and the caller posts it on the project itself.
|
|
31
31
|
|
|
32
32
|
```text
|
|
33
33
|
## linear-to-tracker dry-run: <PRD title>
|
|
@@ -270,7 +270,7 @@ Skip the *walkthrough* only when the work has no user-visible surface, or affect
|
|
|
270
270
|
**Git ancestry, a merge check and `cdk synth` are never deployment evidence** — a discarded pipeline execution leaves a commit merged and unshipped, and all three still report "present". **An unanswerable probe is not a "no"**: when the state cannot be read back, record that the check could not be performed rather than defaulting to absent.
|
|
271
271
|
|
|
272
272
|
|
|
273
|
-
Walkthrough findings are surfaced back to product via the orchestrating intake skill (`lisa-linear-prd-intake`), which posts them on the project
|
|
273
|
+
Walkthrough findings are surfaced back to product via the orchestrating intake skill (`lisa-linear-prd-intake`), which posts them on the project itself. This skill itself does NOT post to Linear — it only reads. The walkthrough section is also inherited onto the resulting epic / stories under a `## Current Product` subsection in the JIRA description.
|
|
274
274
|
|
|
275
275
|
### Phase 3: Create Epics
|
|
276
276
|
|
|
@@ -445,5 +445,5 @@ Track tickets that are shared across PRDs to avoid duplication. When a sub-task
|
|
|
445
445
|
- **Project description format**: Linear project descriptions are markdown. Treat headings (`#`, `##`, `###`) as section markers for `prd_section`.
|
|
446
446
|
- **Document parents**: Linear documents are attached to either a Project or an Issue (exactly one). For PRD intake, only documents attached to the project being processed are in scope. Documents attached to a child Issue are picked up via that issue's content surface.
|
|
447
447
|
- **Comment threading**: Linear comments are threaded via a `parentId` field on each comment. When fetching comments via `list_comments`, capture the full reply tree — replies often hold the actual decision while the root comment was the question.
|
|
448
|
-
- **No
|
|
448
|
+
- **No inline selection anchors on a project**: Linear has no equivalent of a Notion selection snippet or a Confluence inline comment, so an unanchored failure has no in-text location to attach to. It still lands on the project — `lisa-linear-access operation: save-comment project_id:<ID>` posts a project-level comment — just as a whole-page comment rather than an inline one. This skill does not write to Linear at all; it only reads.
|
|
449
449
|
- **Issue identifiers** (`LIN-123`, `ENG-456`, etc.) are the closest analog to a Confluence inline-comment anchor. When dry-run output sets `prd_anchor` to an issue identifier, the caller knows it can post a clarifying-question comment on that specific issue if it wants block-level anchoring.
|
|
@@ -19,6 +19,28 @@ Reads `linear.workspace`, `linear.teamKey` from `.lisa.config.json` (with `.loca
|
|
|
19
19
|
1. **An existing Linear identifier** (e.g. `ENG-123` for an Issue, or `<workspace>/project/<slug>-<id>` for a Project): fetch and validate the live state.
|
|
20
20
|
2. **A proposed item spec** (YAML block, see schema below): validate as-is without touching Linear.
|
|
21
21
|
|
|
22
|
+
### Standalone entry point — validating an item written by another path
|
|
23
|
+
|
|
24
|
+
Input form 1 is a **supported entry point in its own right**, not only an internal step of a
|
|
25
|
+
caller flow. Point this skill at any existing item — however it was written, including by a
|
|
26
|
+
bespoke script, a direct API or GraphQL call, or the vendor's own web UI — and it fetches the
|
|
27
|
+
live state and runs the full gate set against it.
|
|
28
|
+
|
|
29
|
+
Copy-pasteable, via the Skill tool:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
Skill(skill: "lisa-linear-validate-issue", args: "ENG-123")
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
where the argument is an Issue identifier such as `ENG-123`, or a Project URL. The report it returns is the same structured PASS/FAIL
|
|
36
|
+
report the write path consumes, so a bespoke write path can discharge both the pre-write
|
|
37
|
+
validate and the post-write verify obligation with it (see the bespoke-path section of
|
|
38
|
+
`lisa-linear-write-issue`).
|
|
39
|
+
|
|
40
|
+
This skill is plugin-resident. It is invoked through the Skill tool and is **not** expected to
|
|
41
|
+
appear in any repository's `scripts/` directory; not finding a shell script by this name is
|
|
42
|
+
not evidence that the capability is absent.
|
|
43
|
+
|
|
22
44
|
### Spec schema
|
|
23
45
|
|
|
24
46
|
```yaml
|
|
@@ -44,6 +44,20 @@ Return the validator's report verbatim — same structured format as `lisa-linea
|
|
|
44
44
|
|
|
45
45
|
If the verdict is `FAIL`, the caller should fix the item and re-run verify. Never declare success on a `FAIL` verdict.
|
|
46
46
|
|
|
47
|
+
## Comparison semantics — semantic, never byte-exact
|
|
48
|
+
|
|
49
|
+
Verification here re-runs `lisa-linear-validate-issue` against the live work item. It does **not** compare the
|
|
50
|
+
stored body against the sent body byte for byte, and it must never drift to doing so.
|
|
51
|
+
|
|
52
|
+
Linear normalizes markdown on write. Observed normalizations include rewriting `-` bullets
|
|
53
|
+
as `*`, wrapping a bare URL as an explicit link, and re-segmenting bold emphasis around
|
|
54
|
+
inline code spans — all lossless, all rendering-identical. **A byte-exact comparator cannot
|
|
55
|
+
distinguish vendor markdown normalization from corruption**, so it reports failure on
|
|
56
|
+
perfectly healthy writes and trains its reader to ignore it (CodySwannGT/lisa#3663).
|
|
57
|
+
|
|
58
|
+
Any comparison of tracker-normalized rich text is therefore semantic, or
|
|
59
|
+
normalize-then-compare. Byte-exact comparison of such text is forbidden.
|
|
60
|
+
|
|
47
61
|
## Rules
|
|
48
62
|
|
|
49
63
|
- Never write to Linear. Read-only.
|
|
@@ -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
|
|