@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
|
@@ -1,181 +1,28 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Rails Coding Conventions"
|
|
2
|
+
description: "Rails Coding Conventions (load-bearing)"
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Rails Coding Conventions
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@order.apply_discount(current_user.discount_rate)
|
|
30
|
-
@order.save!
|
|
31
|
-
OrderMailer.confirmation(@order).deliver_later
|
|
32
|
-
redirect_to @order
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Service Objects
|
|
38
|
-
|
|
39
|
-
Extract complex business logic into service objects when a model method would be too large or spans multiple models.
|
|
40
|
-
|
|
41
|
-
```ruby
|
|
42
|
-
# app/services/order_placement_service.rb
|
|
43
|
-
class OrderPlacementService
|
|
44
|
-
def initialize(user:, params:)
|
|
45
|
-
@user = user
|
|
46
|
-
@params = params
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def call
|
|
50
|
-
order = Order.new(@params)
|
|
51
|
-
order.user = @user
|
|
52
|
-
order.calculate_total
|
|
53
|
-
order.save!
|
|
54
|
-
OrderMailer.confirmation(order).deliver_later
|
|
55
|
-
order
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Concerns
|
|
61
|
-
|
|
62
|
-
Use concerns to share behavior across models or controllers. Keep concerns focused on a single responsibility.
|
|
63
|
-
|
|
64
|
-
```ruby
|
|
65
|
-
# app/models/concerns/searchable.rb
|
|
66
|
-
module Searchable
|
|
67
|
-
extend ActiveSupport::Concern
|
|
68
|
-
|
|
69
|
-
included do
|
|
70
|
-
scope :search, ->(query) { where("name ILIKE ?", "%#{query}%") }
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## ActiveRecord Patterns
|
|
76
|
-
|
|
77
|
-
### Scopes over class methods for chainable queries
|
|
78
|
-
|
|
79
|
-
```ruby
|
|
80
|
-
# Correct — scope
|
|
81
|
-
scope :active, -> { where(active: true) }
|
|
82
|
-
scope :recent, -> { order(created_at: :desc) }
|
|
83
|
-
|
|
84
|
-
# Wrong — class method for simple query
|
|
85
|
-
def self.active
|
|
86
|
-
where(active: true)
|
|
87
|
-
end
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Validations
|
|
91
|
-
|
|
92
|
-
```ruby
|
|
93
|
-
# Use built-in validators
|
|
94
|
-
validates :email, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
|
|
95
|
-
validates :age, numericality: { greater_than: 0 }
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### Callbacks — use sparingly
|
|
99
|
-
|
|
100
|
-
Prefer explicit service objects over callbacks for complex side effects. Callbacks are acceptable for simple data normalization.
|
|
101
|
-
|
|
102
|
-
```ruby
|
|
103
|
-
# Acceptable — simple normalization
|
|
104
|
-
before_validation :normalize_email
|
|
105
|
-
|
|
106
|
-
private
|
|
107
|
-
|
|
108
|
-
def normalize_email
|
|
109
|
-
self.email = email&.downcase&.strip
|
|
110
|
-
end
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## N+1 Query Prevention
|
|
114
|
-
|
|
115
|
-
Always use `includes`, `preload`, or `eager_load` to prevent N+1 queries. The Bullet gem is included to detect these in development.
|
|
116
|
-
|
|
117
|
-
```ruby
|
|
118
|
-
# Correct — eager loading
|
|
119
|
-
@posts = Post.includes(:author, :comments).where(published: true)
|
|
120
|
-
|
|
121
|
-
# Wrong — N+1 query
|
|
122
|
-
@posts = Post.where(published: true)
|
|
123
|
-
@posts.each { |post| post.author.name } # N+1!
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## Strong Parameters
|
|
127
|
-
|
|
128
|
-
Always use strong parameters in controllers. Never use `permit!`.
|
|
129
|
-
|
|
130
|
-
```ruby
|
|
131
|
-
# Correct
|
|
132
|
-
def order_params
|
|
133
|
-
params.require(:order).permit(:product_id, :quantity, :notes)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Wrong — permits everything
|
|
137
|
-
def order_params
|
|
138
|
-
params.require(:order).permit!
|
|
139
|
-
end
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Database Migrations
|
|
143
|
-
|
|
144
|
-
- Use `strong_migrations` gem constraints (included via Gemfile.lisa)
|
|
145
|
-
- Never modify `db/schema.rb` directly
|
|
146
|
-
- Always add indexes for foreign keys and commonly queried columns
|
|
147
|
-
- Use `change` method when the migration is reversible; use `up`/`down` when it is not
|
|
148
|
-
|
|
149
|
-
```ruby
|
|
150
|
-
class AddIndexToOrdersUserId < ActiveRecord::Migration[7.2]
|
|
151
|
-
def change
|
|
152
|
-
add_index :orders, :user_id
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Testing with RSpec
|
|
158
|
-
|
|
159
|
-
- Use `let` and `let!` for test setup
|
|
160
|
-
- Use `described_class` instead of repeating the class name
|
|
161
|
-
- Use `factory_bot` for test data, not fixtures
|
|
162
|
-
- Use `shoulda-matchers` for model validation tests
|
|
163
|
-
- Keep tests focused — one assertion concept per example
|
|
164
|
-
|
|
165
|
-
```ruby
|
|
166
|
-
RSpec.describe Order, type: :model do
|
|
167
|
-
describe "validations" do
|
|
168
|
-
it { is_expected.to validate_presence_of(:user) }
|
|
169
|
-
it { is_expected.to validate_numericality_of(:total).is_greater_than(0) }
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
describe ".recent" do
|
|
173
|
-
it "returns orders in descending creation order" do
|
|
174
|
-
old_order = create(:order, created_at: 1.day.ago)
|
|
175
|
-
new_order = create(:order, created_at: 1.hour.ago)
|
|
176
|
-
|
|
177
|
-
expect(described_class.recent).to eq([new_order, old_order])
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
```
|
|
6
|
+
# Rails Coding Conventions (load-bearing)
|
|
7
|
+
|
|
8
|
+
Rails-specific standards for this project. The head below is what changes
|
|
9
|
+
behaviour in a session that never asks for it; the worked examples for every
|
|
10
|
+
point live in the reference body.
|
|
11
|
+
|
|
12
|
+
## Mandatory
|
|
13
|
+
|
|
14
|
+
1. **Fat models, skinny controllers.** Controllers handle HTTP concerns only.
|
|
15
|
+
Business logic belongs in a model or a service object under `app/services/`.
|
|
16
|
+
2. **Strong parameters always, `permit!` never.** Enumerate the permitted keys.
|
|
17
|
+
3. **No N+1 queries.** Use `includes` / `preload` / `eager_load` on any
|
|
18
|
+
association you iterate. Bullet is installed to catch the ones you miss.
|
|
19
|
+
4. **Never edit `db/schema.rb` by hand.** Change it through a migration, honour
|
|
20
|
+
the `strong_migrations` constraints, and index every foreign key and
|
|
21
|
+
commonly-queried column.
|
|
22
|
+
5. **Scopes, not class methods,** for chainable queries. Prefer built-in
|
|
23
|
+
validators; keep callbacks to simple normalization and push complex side
|
|
24
|
+
effects into a service object.
|
|
25
|
+
6. **RSpec with `factory_bot` and `shoulda-matchers`,** not fixtures. Use
|
|
26
|
+
`described_class` and keep one assertion concept per example.
|
|
27
|
+
|
|
28
|
+
Full prose and Ruby examples: [reference/rails-conventions.md](rails-conventions-reference.mdc).
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh",
|
|
9
9
|
"all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh",
|
|
10
10
|
"all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh",
|
|
11
|
+
"all/copy-overwrite/scripts/lisa-hooks/guard-dedupe.bash",
|
|
11
12
|
"all/copy-overwrite/scripts/lisa-hooks/parity-safety-net-heredoc.py",
|
|
12
13
|
"all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh",
|
|
13
14
|
"all/copy-overwrite/scripts/lisa-hooks/sonar-secrets.sh",
|
|
@@ -108,6 +108,15 @@
|
|
|
108
108
|
}
|
|
109
109
|
]
|
|
110
110
|
},
|
|
111
|
+
{
|
|
112
|
+
"matcher": "Bash|Edit|Write|Read|Task|Grep|Glob",
|
|
113
|
+
"hooks": [
|
|
114
|
+
{
|
|
115
|
+
"type": "command",
|
|
116
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/operational-hazards.sh --hook"
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
},
|
|
111
120
|
{
|
|
112
121
|
"matcher": "EnterWorktree",
|
|
113
122
|
"hooks": [
|
|
@@ -258,6 +267,15 @@
|
|
|
258
267
|
}
|
|
259
268
|
]
|
|
260
269
|
},
|
|
270
|
+
{
|
|
271
|
+
"matcher": "",
|
|
272
|
+
"hooks": [
|
|
273
|
+
{
|
|
274
|
+
"type": "command",
|
|
275
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/operational-hazards.sh --session-start"
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
},
|
|
261
279
|
{
|
|
262
280
|
"matcher": "",
|
|
263
281
|
"hooks": [
|
|
@@ -331,6 +349,15 @@
|
|
|
331
349
|
}
|
|
332
350
|
]
|
|
333
351
|
},
|
|
352
|
+
{
|
|
353
|
+
"matcher": "",
|
|
354
|
+
"hooks": [
|
|
355
|
+
{
|
|
356
|
+
"type": "command",
|
|
357
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/operational-hazards.sh --session-start"
|
|
358
|
+
}
|
|
359
|
+
]
|
|
360
|
+
},
|
|
334
361
|
{
|
|
335
362
|
"matcher": "",
|
|
336
363
|
"hooks": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linear-prd-intake
|
|
3
|
-
description: PRD intake agent for Linear-hosted PRDs. Runs one intake cycle against a Linear workspace or team — claims projects carrying the configured `ready` PRD label (relabels to the configured `in_review` label), validates each through the dry-run pipeline, and routes to the configured `blocked` label (with clarifying comments on
|
|
3
|
+
description: PRD intake agent for Linear-hosted PRDs. Runs one intake cycle against a Linear workspace or team — claims projects carrying the configured `ready` PRD label (relabels to the configured `in_review` label), validates each through the dry-run pipeline, and routes to the configured `blocked` label (with clarifying comments on the project) or `ticketed` label (with destination tickets created). Linear counterpart of `notion-prd-intake` and `confluence-prd-intake`. Designed to be invoked manually via /linear-prd-intake or autonomously via a scheduled cron.
|
|
4
4
|
skills:
|
|
5
5
|
- linear-prd-intake
|
|
6
6
|
- linear-to-tracker
|
|
@@ -15,9 +15,9 @@ skills:
|
|
|
15
15
|
|
|
16
16
|
You are a PRD intake agent. Your single job is to run one intake cycle against the Linear scope (a workspace or a team) given to you, then report what happened.
|
|
17
17
|
|
|
18
|
-
This agent is the Linear counterpart of `notion-prd-intake` and `confluence-prd-intake`. The behavior is identical apart from the source-of-truth tool surface
|
|
18
|
+
This agent is the Linear counterpart of `notion-prd-intake` and `confluence-prd-intake`. The behavior is identical apart from the source-of-truth tool surface: clarifying comments land on the project itself, exactly as they do on a Notion or Confluence page. (They used to land on a fabricated per-project "sentinel" issue, justified by the Linear MCP not exposing project-level comments. That premise was wrong about the substrate — `commentCreate(input: { projectId, body })` and `Project.comments` have always existed, and the access layer's precedence contract puts GraphQL ahead of the MCP. The gap was in the wrapper, and it is closed; see "Legacy sentinel feedback issues" in the skill for what happens to the ones already created.) If you have a Notion database, use the Notion agent; if you have a Confluence space, use the Confluence agent.
|
|
19
19
|
|
|
20
|
-
PRD label role names (`ready`, `in_review`, `blocked`, `ticketed`, `shipped`, `verified`, `sentinel`) are resolved from `.lisa.config.json` `linear.labels.prd.*` by the `linear-prd-intake` skill. The defaults match the legacy hardcoded names (`prd-ready`, `prd-in-review`, `prd-blocked`, `prd-ticketed`, `prd-shipped`, `prd-verified`, `prd-intake-feedback`). The full PRD lifecycle is `draft → ready → in_review → blocked | ticketed → shipped → verified`; this agent only ever drives `ready → in_review → blocked | ticketed`. The `shipped` rollup is owned by the intake skill's rollup phase, and `verified` is set by `/lisa:verify-prd` after empirical PRD-level acceptance — never by this agent.
|
|
20
|
+
PRD label role names (`ready`, `in_review`, `blocked`, `ticketed`, `shipped`, `verified`, and the legacy read-only `sentinel`) are resolved from `.lisa.config.json` `linear.labels.prd.*` by the `linear-prd-intake` skill. The defaults match the legacy hardcoded names (`prd-ready`, `prd-in-review`, `prd-blocked`, `prd-ticketed`, `prd-shipped`, `prd-verified`, `prd-intake-feedback`). The full PRD lifecycle is `draft → ready → in_review → blocked | ticketed → shipped → verified`; this agent only ever drives `ready → in_review → blocked | ticketed`. The `shipped` rollup is owned by the intake skill's rollup phase, and `verified` is set by `/lisa:verify-prd` after empirical PRD-level acceptance — never by this agent.
|
|
21
21
|
|
|
22
22
|
## Confirmation policy
|
|
23
23
|
|
|
@@ -29,11 +29,11 @@ Once you have a workspace or team scope, RUN. Do not ask the caller whether to p
|
|
|
29
29
|
|
|
30
30
|
The invoking caller (a slash command, a scheduled cron, or a parent agent) hands you a Linear workspace URL, a team URL, a bare team key, or the literal token `linear` (which falls back to `linear.workspace` in `.lisa.config.json`). You do not pick the scope yourself.
|
|
31
31
|
|
|
32
|
-
If no scope is provided, stop and ask. Never run intake against a default or guessed scope — the side effects (label changes,
|
|
32
|
+
If no scope is provided, stop and ask. Never run intake against a default or guessed scope — the side effects (label changes, project comments, JIRA tickets created) are too high to act without an explicit target.
|
|
33
33
|
|
|
34
34
|
### 2. Run the intake skill
|
|
35
35
|
|
|
36
|
-
Invoke the `linear-prd-intake` skill with the scope as `$ARGUMENTS`. The skill owns the cycle logic — claim, dry-run, branch, write or comment, label transitions,
|
|
36
|
+
Invoke the `linear-prd-intake` skill with the scope as `$ARGUMENTS`. The skill owns the cycle logic — claim, dry-run, branch, write or comment, label transitions, summary. Do not duplicate that logic here.
|
|
37
37
|
|
|
38
38
|
Treat the skill's output as the source of truth (e.g. `ticketed: 3 / blocked: 1 / errors: 0`).
|
|
39
39
|
|
|
@@ -49,7 +49,7 @@ If the cycle errored before processing any PRDs (e.g. workspace unreachable, mis
|
|
|
49
49
|
|
|
50
50
|
### 4. Suggest next actions when warranted
|
|
51
51
|
|
|
52
|
-
After a successful cycle, if any PRDs ended in the `blocked` label, mention to the caller that those PRDs need product attention before they can be re-ticketed. Do not auto-notify product — comments on the
|
|
52
|
+
After a successful cycle, if any PRDs ended in the `blocked` label, mention to the caller that those PRDs need product attention before they can be re-ticketed. Do not auto-notify product — comments on the project (and on specific sub-issues for anchored failures) are the channel; the caller decides whether to ping anyone.
|
|
53
53
|
|
|
54
54
|
When reporting `blocked` outcomes, distinguish the cause: **pre-write gate failure** (per-ticket validator caught a problem before any tickets were created) vs **post-write coverage gap** (tickets were created and remain in the destination tracker, but the PRD has uncovered requirements that the next intake cycle will address). Both result in the `blocked` label, but the implication for product is different — coverage gaps mean some tickets are already real and product should not re-author the PRD from scratch.
|
|
55
55
|
|
|
@@ -60,7 +60,7 @@ If all PRDs ended in the `ticketed` label with coverage `COMPLETE`, mention that
|
|
|
60
60
|
- **Never run a cycle without an explicit scope.** Side effects are too high to default.
|
|
61
61
|
- **Never modify the lifecycle**: only `ready → in_review → blocked|ticketed`. Never touch the `draft`, `shipped`, or `verified` labels (`shipped` is owned by the intake rollup phase; `verified` is owned by `/lisa:verify-prd`). Never invent new labels.
|
|
62
62
|
- **Never write destination tickets directly.** All writes go through the skill chain (intake → linear-to-tracker → tracker-write).
|
|
63
|
-
- **Never edit a project's description or any attached Linear document.** Communication with product happens only via comments — on specific sub-issues for anchored failures, on the
|
|
64
|
-
- **Never
|
|
63
|
+
- **Never edit a project's description or any attached Linear document.** Communication with product happens only via comments — on specific sub-issues for anchored failures, on the project itself otherwise.
|
|
64
|
+
- **Never fabricate an issue to hold a comment.** The project takes comments directly. Legacy sentinel issues from earlier cycles are left exactly as they are — not closed, not archived, not repurposed, not posted to — and the rollup excludes them so they stop holding their projects open.
|
|
65
65
|
- **Never start a second cycle while one is in flight against the same scope.** Serial execution; the scheduling layer is responsible for not double-firing.
|
|
66
66
|
- **Stop and surface failures rather than retry-loop.** If `linear-to-tracker` returns an error, the skill records it under `Errors` in the summary; pass that through.
|
|
@@ -162,6 +162,27 @@ set -euo pipefail
|
|
|
162
162
|
|
|
163
163
|
input="$(cat)"
|
|
164
164
|
|
|
165
|
+
# Evaluate once per tool call when this guard is registered on both channels.
|
|
166
|
+
#
|
|
167
|
+
# Lisa reaches an agent through the repository dispatcher AND the plugin
|
|
168
|
+
# manifest, and where both are live the harness runs this guard twice for one
|
|
169
|
+
# tool call. `guard-dedupe.bash` short-circuits the second run ONLY when a
|
|
170
|
+
# byte-identical copy already ALLOWED this exact payload on this exact tool
|
|
171
|
+
# call; a differing vintage, a refusal, and a host with one channel all
|
|
172
|
+
# evaluate exactly as before. Nothing is de-registered by it
|
|
173
|
+
# (CodySwannGT/lisa#3814).
|
|
174
|
+
#
|
|
175
|
+
# Absent library means no dedupe, which is the pre-existing behaviour, so an
|
|
176
|
+
# older channel copy that predates it is unaffected.
|
|
177
|
+
lisa_guard_hook_dir="${BASH_SOURCE[0]%/*}"
|
|
178
|
+
lisa_guard_dedupe_lib="$lisa_guard_hook_dir/guard-dedupe.bash"
|
|
179
|
+
if [ -r "$lisa_guard_dedupe_lib" ]; then
|
|
180
|
+
# shellcheck source=guard-dedupe.bash
|
|
181
|
+
. "$lisa_guard_dedupe_lib"
|
|
182
|
+
trap 'lisa_guard_dedupe_record $?' EXIT
|
|
183
|
+
lisa_guard_dedupe block-blind-automerge "$input"
|
|
184
|
+
fi
|
|
185
|
+
|
|
165
186
|
# Both interpreters are probed BEFORE use, and a missing one is ANNOUNCED
|
|
166
187
|
# rather than swallowed. Under `set -e` an absent jq would abort with 127, and
|
|
167
188
|
# Claude Code treats any non-2 exit as a non-blocking hook error — so the guard
|
|
@@ -244,9 +265,41 @@ PULL_REQUEST_ID_PATTERN = re.compile(
|
|
|
244
265
|
NODE_ID_PATTERN = re.compile(r"^[A-Za-z0-9_=-]+$")
|
|
245
266
|
|
|
246
267
|
# The probe that resolves a node id to the same fields `gh pr view` returns.
|
|
268
|
+
#
|
|
269
|
+
# `statusCheckRollup` is in here because the RE-TARGET path needs it and this
|
|
270
|
+
# is the only probe a GraphQL `updatePullRequest` can use. Without it
|
|
271
|
+
# `failing_check_names` read an absent key, found no failing check, and the
|
|
272
|
+
# guard announced the re-target as the sanctioned green-PR batching case —
|
|
273
|
+
# for a pull request that might be failing every check it has. The porcelain
|
|
274
|
+
# path asked the right question and the API path could not, so the identical
|
|
275
|
+
# act was guarded through `gh pr edit --base` and waved through as GraphQL:
|
|
276
|
+
# a bypass that needs no permission, only a different spelling.
|
|
277
|
+
#
|
|
278
|
+
# The nodes are reshaped by `--jq` below into the flat list `gh pr view
|
|
279
|
+
# --json statusCheckRollup` returns, so one reader serves both probes.
|
|
247
280
|
NODE_QUERY = (
|
|
248
281
|
"query($id:ID!){node(id:$id){... on PullRequest"
|
|
249
|
-
"{number url reviewDecision state baseRefName
|
|
282
|
+
"{number url reviewDecision state baseRefName "
|
|
283
|
+
"commits(last:1){nodes{commit{statusCheckRollup{contexts(first:100){nodes{"
|
|
284
|
+
"__typename ... on CheckRun{name conclusion} "
|
|
285
|
+
"... on StatusContext{context state}"
|
|
286
|
+
"}}}}}}}}}"
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
# Reshape the envelope into the porcelain's shape: unwrap `.data.node`, hoist
|
|
290
|
+
# the last commit's rollup contexts to a top-level `statusCheckRollup` list,
|
|
291
|
+
# and drop the `commits` scaffolding that carried it.
|
|
292
|
+
# `has("commits")` rather than an unconditional default, and the distinction is
|
|
293
|
+
# the point: a node that CARRIES the scaffolding and no contexts is a PR with no
|
|
294
|
+
# checks, which is genuinely not failing and gets an empty list. A node without
|
|
295
|
+
# the scaffolding is a probe that never asked, and it must leave the key absent
|
|
296
|
+
# so the re-target path can tell the two apart instead of reading both as green.
|
|
297
|
+
NODE_JQ = (
|
|
298
|
+
"if .data.node == null then null else .data.node as $n "
|
|
299
|
+
"| if ($n | has(\"commits\")) then ($n | del(.commits)) "
|
|
300
|
+
"+ {statusCheckRollup: "
|
|
301
|
+
"((($n.commits.nodes[0].commit.statusCheckRollup.contexts.nodes)) // [])} "
|
|
302
|
+
"else $n end end"
|
|
250
303
|
)
|
|
251
304
|
|
|
252
305
|
# What a probe spec asks for. `view` and `node` differ only in how the PR is
|
|
@@ -725,7 +778,7 @@ def probe_args(kind, subject, repo_args, fields):
|
|
|
725
778
|
"gh", "api", "graphql",
|
|
726
779
|
"-f", "query=" + NODE_QUERY,
|
|
727
780
|
"-f", "id=" + subject,
|
|
728
|
-
"--jq",
|
|
781
|
+
"--jq", NODE_JQ,
|
|
729
782
|
]
|
|
730
783
|
args = ["gh", "pr", "view"]
|
|
731
784
|
if subject is not None:
|
|
@@ -966,6 +1019,20 @@ Do one of these instead:
|
|
|
966
1019
|
- leave the PR on its covered base and merge it there.
|
|
967
1020
|
"""
|
|
968
1021
|
|
|
1022
|
+
RETARGET_CHECKS_UNREADABLE = """Blocked: re-targeting %s onto "%s" cannot be judged, because this guard could
|
|
1023
|
+
not read the pull request's checks.
|
|
1024
|
+
|
|
1025
|
+
That ref has ZERO required status checks, so the one thing standing between the
|
|
1026
|
+
move and a permission-free gate bypass is whether the PR is currently failing —
|
|
1027
|
+
and the probe returned no `statusCheckRollup` at all. An absent rollup is not an
|
|
1028
|
+
empty one. Reporting the move as the sanctioned green-PR batching case here
|
|
1029
|
+
would be a verdict about a question that was never asked.
|
|
1030
|
+
|
|
1031
|
+
Re-target through `gh pr edit --base` instead, which reads the checks, or fix
|
|
1032
|
+
the probe. Do not report the PR as batched until something has actually looked.
|
|
1033
|
+
"""
|
|
1034
|
+
|
|
1035
|
+
|
|
969
1036
|
UNCOVERED_RETARGET_NOTICE = (
|
|
970
1037
|
"block-blind-automerge: %s is being re-targeted onto \"%s\", a ref with ZERO "
|
|
971
1038
|
"required status checks; its gates will run but cannot block a merge\n"
|
|
@@ -1036,6 +1103,18 @@ for act, kind, subject, repo_args, target_ref in acts:
|
|
|
1036
1103
|
# nothing can block it", which holds whatever base it came from.
|
|
1037
1104
|
if not base_is_uncovered(payload, repo_args, target_ref):
|
|
1038
1105
|
continue
|
|
1106
|
+
# Fails CLOSED, and only here. Everywhere else in this file an
|
|
1107
|
+
# unanswerable question degrades and continues, because the guard being
|
|
1108
|
+
# unable to run must not become the reason a command is refused. This
|
|
1109
|
+
# branch is different: the base has already been confirmed to have zero
|
|
1110
|
+
# required checks, so an empty `failing` list is the whole basis for
|
|
1111
|
+
# allowing the move, and an ABSENT rollup produces the identical empty
|
|
1112
|
+
# list. Passing on it would be a measurement that could not fail.
|
|
1113
|
+
if not isinstance(payload.get("statusCheckRollup"), list):
|
|
1114
|
+
sys.stderr.write(
|
|
1115
|
+
RETARGET_CHECKS_UNREADABLE % (pr_name(payload), target_ref)
|
|
1116
|
+
)
|
|
1117
|
+
sys.exit(1)
|
|
1039
1118
|
failing = failing_check_names(payload)
|
|
1040
1119
|
if not failing:
|
|
1041
1120
|
# A green PR moving onto a stack base is the sanctioned batching
|
|
@@ -8,19 +8,44 @@
|
|
|
8
8
|
# block-direct-issue-create.sh beside it (same delegation pattern as
|
|
9
9
|
# block-instruction-file-edits.agy.sh).
|
|
10
10
|
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# unenforced on every tool call beside it.
|
|
11
|
+
# THE SECOND SUBSTRATE (CodySwannGT/lisa#3785). CodySwannGT/lisa#3753 taught the
|
|
12
|
+
# canonical guard that a creation also arrives as NAMED FIELDS rather than as a
|
|
13
|
+
# command line. This adapter used to forward `run_command` and nothing else, and
|
|
14
|
+
# the registration matched `run_command` only, so on agy that substrate was
|
|
15
|
+
# unenforced — refused entry twice over, exactly as it was on Claude before
|
|
16
|
+
# CodySwannGT/lisa#3753. Widening one without the other changes nothing.
|
|
18
17
|
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
18
|
+
# agy's envelope was CAPTURED, not guessed — a probe plugin registered with an
|
|
19
|
+
# empty matcher, driven through `agy --dangerously-skip-permissions -p`, on
|
|
20
|
+
# agy 1.1.3:
|
|
21
|
+
#
|
|
22
|
+
# {"toolCall":{"name":"call_mcp_tool","args":{
|
|
23
|
+
# "ServerName":"probe-tracker","ToolName":"create_issue",
|
|
24
|
+
# "Arguments":{"title":"envelope probe","body":"capture"},
|
|
25
|
+
# "toolAction":"...","toolSummary":"..."}}}
|
|
26
|
+
#
|
|
27
|
+
# Two things about it decide the translation below, and both would have been got
|
|
28
|
+
# wrong by a plausible guess:
|
|
29
|
+
#
|
|
30
|
+
# - EVERY MCP call arrives under the single tool name `call_mcp_tool`. The
|
|
31
|
+
# server and tool the model actually asked for live in `ServerName` /
|
|
32
|
+
# `ToolName`, so forwarding agy's outer name verbatim hands the canonical
|
|
33
|
+
# guard a name carrying no tracker noun, and its shape gate ALLOWS the lot.
|
|
34
|
+
# Measured before this change: forwarding `call_mcp_tool` raw ALLOWED an
|
|
35
|
+
# undeclared `create_issue`. So the adapter reassembles the name into the
|
|
36
|
+
# `mcp__<server>__<tool>` spelling the canonical guard already classifies on
|
|
37
|
+
# Claude — one vocabulary, one classifier.
|
|
38
|
+
# - The arguments land under `Arguments`, not inline beside the metadata, so
|
|
39
|
+
# `toolAction` / `toolSummary` — agy's own prose about the call — stay OUT
|
|
40
|
+
# of the payload the declaration is read from. Passing them would let a
|
|
41
|
+
# summary sentence mentioning the ready role answer for the filing.
|
|
42
|
+
#
|
|
43
|
+
# Every other tool is forwarded generically (`{tool_name, tool_input}`) rather
|
|
44
|
+
# than allowed here. The canonical guard owns the question of what counts as a
|
|
45
|
+
# creation; an adapter that pre-filtered would be a second copy of that policy,
|
|
46
|
+
# and the first native creation tool agy adds would arrive on the wrong side of
|
|
47
|
+
# it. The cost is one extra `bash` + `jq` per non-shell tool call, which is what
|
|
48
|
+
# the canonical guard's subprocess-free shape gate exists to keep cheap.
|
|
24
49
|
#
|
|
25
50
|
# Fail-open on missing runtimes: a missed refusal costs one under-declared
|
|
26
51
|
# ticket, and `lisa-repair-intake` already sweeps for exactly that. Failing
|
|
@@ -47,15 +72,38 @@ input="$(cat 2>/dev/null || true)"
|
|
|
47
72
|
command -v jq >/dev/null 2>&1 || allow
|
|
48
73
|
|
|
49
74
|
tool_name="$(printf '%s' "$input" | jq -r '.toolCall.name // empty' 2>/dev/null || true)"
|
|
50
|
-
[ "$tool_name"
|
|
51
|
-
|
|
52
|
-
|
|
75
|
+
[ -z "$tool_name" ] && allow
|
|
76
|
+
|
|
77
|
+
canonical_input=""
|
|
78
|
+
if [ "$tool_name" = "run_command" ]; then
|
|
79
|
+
# The shell substrate, byte-identical to what it was before the second
|
|
80
|
+
# substrate arrived. Its verdicts are the control for this change.
|
|
81
|
+
command_str="$(printf '%s' "$input" | jq -r '.toolCall.args.CommandLine // empty' 2>/dev/null || true)"
|
|
82
|
+
[ -z "$command_str" ] && allow
|
|
83
|
+
canonical_input="$(jq -cn --arg command "$command_str" '{tool_name:"Bash",tool_input:{command:$command}}')"
|
|
84
|
+
elif [ "$tool_name" = "call_mcp_tool" ]; then
|
|
85
|
+
# A missing ServerName or ToolName is a payload this adapter cannot name, and
|
|
86
|
+
# naming is the whole of its job here. It hands the canonical guard the
|
|
87
|
+
# unspellable name rather than inventing a plausible one, so the guard's own
|
|
88
|
+
# fail-closed arm decides — never this adapter.
|
|
89
|
+
canonical_input="$(
|
|
90
|
+
printf '%s' "$input" |
|
|
91
|
+
jq -c '(.toolCall.args // {}) as $a
|
|
92
|
+
| {tool_name: ("mcp__" + ($a.ServerName // "?") + "__" + ($a.ToolName // "?")),
|
|
93
|
+
tool_input: ($a.Arguments // {})}' 2>/dev/null || true
|
|
94
|
+
)"
|
|
95
|
+
else
|
|
96
|
+
canonical_input="$(
|
|
97
|
+
printf '%s' "$input" |
|
|
98
|
+
jq -c '{tool_name: .toolCall.name, tool_input: (.toolCall.args // {})}' 2>/dev/null || true
|
|
99
|
+
)"
|
|
100
|
+
fi
|
|
101
|
+
[ -z "$canonical_input" ] && allow
|
|
53
102
|
|
|
54
103
|
hook_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
55
104
|
canonical_hook="$hook_dir/block-direct-issue-create.sh"
|
|
56
105
|
[ -r "$canonical_hook" ] || allow
|
|
57
106
|
|
|
58
|
-
canonical_input="$(jq -cn --arg command "$command_str" '{tool_name:"Bash",tool_input:{command:$command}}')"
|
|
59
107
|
canonical_output=""
|
|
60
108
|
canonical_status=0
|
|
61
109
|
if canonical_output="$(printf '%s' "$canonical_input" | /bin/bash "$canonical_hook" 2>&1)"; then
|