@codyswann/lisa 4.55.2 → 4.55.4
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-overwrite/scripts/check-orphaned-branches.mjs +49 -13
- package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +9 -1
- package/all/copy-overwrite/scripts/lisa-hooks/block-blind-automerge.sh +10 -5
- package/all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh +4 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh +73 -2
- package/all/copy-overwrite/scripts/lisa-hooks/guard-dedupe.bash +63 -29
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +2 -1
- package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.sh +2 -1
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +7 -2
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +50 -14
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +36 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +92 -80
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/block-managed-file-edits.sh +76 -2
- package/dist/opencode/plugin-templates/block-no-verify.sh +3 -0
- package/dist/opencode/plugin-templates/guard-dedupe.bash +66 -29
- package/dist/opencode/plugin-templates/parity-safety-net-heredoc.py +3 -0
- package/dist/opencode/plugin-templates/parity-safety-net.sh +5 -1
- package/dist/opencode/support-file-resolver.d.ts.map +1 -1
- package/dist/opencode/support-file-resolver.js +3 -1
- package/dist/opencode/support-file-resolver.js.map +1 -1
- package/expo/copy-overwrite/plugins/withAndroidSplashNoClientExit.js +23 -21
- package/expo/create-only/.github/required-checks.json +1 -1
- package/nestjs/create-only/.github/required-checks.json +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +38 -15
- package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +15 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +37 -13
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +15 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +56 -7
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +36 -11
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-prd-intake/SKILL.md +12 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +1 -18
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-verify/SKILL.md +0 -17
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +18 -35
- package/plugins/lisa/.codex-plugin/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +66 -12
- package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +2 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/providers.mjs +2 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +7 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +11 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/toolchain.mjs +17 -5
- package/plugins/lisa/.codex-plugin/skills/lisa-track/SKILL.md +32 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-build-intake/SKILL.md +15 -1
- package/plugins/lisa/hooks/block-blind-automerge.sh +13 -5
- package/plugins/lisa/hooks/block-direct-issue-create.sh +7 -0
- package/plugins/lisa/hooks/block-instruction-file-edits.sh +3 -0
- package/plugins/lisa/hooks/block-managed-file-edits.sh +76 -2
- package/plugins/lisa/hooks/block-no-verify.sh +3 -0
- package/plugins/lisa/hooks/block-shell-json-parsing.sh +3 -0
- package/plugins/lisa/hooks/guard-dedupe.bash +66 -29
- package/plugins/lisa/hooks/parity-safety-net-heredoc.py +3 -0
- package/plugins/lisa/hooks/parity-safety-net.sh +5 -1
- package/plugins/lisa/hooks/worktree-binding-guard.mjs +3 -0
- package/plugins/lisa/hooks/worktree-binding-guard.sh +5 -1
- package/plugins/lisa/rules/eager/00-rule-index.md +1 -0
- package/plugins/lisa/rules/eager/base-rules.md +3 -1
- package/plugins/lisa/rules/eager/withdrawn-rulings.md +14 -3
- package/plugins/lisa/rules/reference/automation-runbook-contract.md +1 -1
- package/plugins/lisa/rules/reference/bdd-e2e-coverage.md +1 -1
- package/plugins/lisa/rules/reference/blocker-containment.md +3 -3
- package/plugins/lisa/rules/reference/claim-archaeology.md +1 -1
- package/plugins/lisa/rules/reference/claim-evidence-mapping.md +1 -1
- package/plugins/lisa/rules/reference/claim-time-guards.md +1 -1
- package/plugins/lisa/rules/reference/control-reachability.md +1 -1
- package/plugins/lisa/rules/reference/convergent-review.md +1 -1
- package/plugins/lisa/rules/reference/credential-substrate-precedence.md +1 -1
- package/plugins/lisa/rules/reference/dependency-decision-records.md +1 -1
- package/plugins/lisa/rules/reference/dependency-internalization-kit.md +1 -1
- package/plugins/lisa/rules/reference/dependency-trust-classes.md +1 -1
- package/plugins/lisa/rules/reference/deployed-state-readback.md +1 -1
- package/plugins/lisa/rules/reference/derived-branch-plan.md +1 -1
- package/plugins/lisa/rules/reference/design-source-of-truth.md +1 -1
- package/plugins/lisa/rules/reference/design-value-binding.md +1 -1
- package/plugins/lisa/rules/reference/documentation-source-paths.md +1 -1
- package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa/rules/reference/observability-audit.md +1 -1
- package/plugins/lisa/rules/reference/prd-definition-of-ready.md +1 -1
- package/plugins/lisa/rules/reference/prd-lifecycle-rollup.md +1 -1
- package/plugins/lisa/rules/reference/pre-flight-autofill.md +1 -1
- package/plugins/lisa/rules/reference/promotion-contract.md +1 -1
- package/plugins/lisa/rules/reference/readiness-rubric.md +1 -1
- package/plugins/lisa/rules/reference/ready-role-filing.md +37 -1
- package/plugins/lisa/rules/reference/rejection-detection.md +1 -1
- package/plugins/lisa/rules/reference/repo-scope-split.md +9 -10
- package/plugins/lisa/rules/reference/reset-seed-coverage.md +1 -1
- package/plugins/lisa/rules/reference/usage-accounting.md +1 -1
- package/plugins/lisa/rules/reference/work-item-definition-of-ready.md +1 -1
- package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +85 -17
- package/plugins/lisa/scripts/qa-signal-lifecycle.mjs +5 -2
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +38 -15
- package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +15 -1
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +37 -13
- package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +15 -1
- package/plugins/lisa/skills/lisa-linear-access/SKILL.md +56 -7
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +36 -11
- package/plugins/lisa/skills/lisa-linear-prd-intake/SKILL.md +12 -2
- package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +1 -18
- package/plugins/lisa/skills/lisa-linear-verify/SKILL.md +0 -17
- package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +18 -35
- package/plugins/lisa/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +66 -12
- package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +2 -1
- package/plugins/lisa/skills/lisa-secrets-access/scripts/providers.mjs +2 -1
- package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +7 -2
- package/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +11 -4
- package/plugins/lisa/skills/lisa-setup-remote-env/scripts/toolchain.mjs +17 -5
- package/plugins/lisa/skills/lisa-track/SKILL.md +32 -4
- package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +15 -1
- package/plugins/lisa-agy/hooks/block-blind-automerge.sh +13 -5
- package/plugins/lisa-agy/hooks/block-direct-issue-create.sh +7 -0
- package/plugins/lisa-agy/hooks/block-instruction-file-edits.sh +3 -0
- package/plugins/lisa-agy/hooks/block-managed-file-edits.sh +76 -2
- package/plugins/lisa-agy/hooks/block-shell-json-parsing.sh +3 -0
- package/plugins/lisa-agy/hooks/guard-dedupe.bash +66 -29
- package/plugins/lisa-agy/hooks/parity-safety-net-heredoc.py +3 -0
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +5 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +85 -17
- package/plugins/lisa-agy/scripts/qa-signal-lifecycle.mjs +5 -2
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +38 -15
- package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +15 -1
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +37 -13
- package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +15 -1
- package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +56 -7
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +36 -11
- package/plugins/lisa-agy/skills/lisa-linear-prd-intake/SKILL.md +12 -2
- package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +1 -18
- package/plugins/lisa-agy/skills/lisa-linear-verify/SKILL.md +0 -17
- package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +18 -35
- package/plugins/lisa-agy/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +66 -12
- package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +2 -1
- package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/providers.mjs +2 -1
- package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +7 -2
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +11 -4
- package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/toolchain.mjs +17 -5
- package/plugins/lisa-agy/skills/lisa-track/SKILL.md +32 -4
- package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +15 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/block-blind-automerge.sh +13 -5
- package/plugins/lisa-copilot/hooks/block-direct-issue-create.sh +7 -0
- package/plugins/lisa-copilot/hooks/block-instruction-file-edits.sh +3 -0
- package/plugins/lisa-copilot/hooks/block-managed-file-edits.sh +76 -2
- package/plugins/lisa-copilot/hooks/block-no-verify.sh +3 -0
- package/plugins/lisa-copilot/hooks/block-shell-json-parsing.sh +3 -0
- package/plugins/lisa-copilot/hooks/guard-dedupe.bash +66 -29
- package/plugins/lisa-copilot/hooks/parity-safety-net-heredoc.py +3 -0
- package/plugins/lisa-copilot/hooks/parity-safety-net.sh +5 -1
- package/plugins/lisa-copilot/hooks/worktree-binding-guard.mjs +3 -0
- package/plugins/lisa-copilot/hooks/worktree-binding-guard.sh +5 -1
- package/plugins/lisa-copilot/rules/eager/00-rule-index.md +1 -0
- package/plugins/lisa-copilot/rules/eager/base-rules.md +3 -1
- package/plugins/lisa-copilot/rules/eager/withdrawn-rulings.md +14 -3
- package/plugins/lisa-copilot/rules/reference/automation-runbook-contract.md +1 -1
- package/plugins/lisa-copilot/rules/reference/bdd-e2e-coverage.md +1 -1
- package/plugins/lisa-copilot/rules/reference/blocker-containment.md +3 -3
- package/plugins/lisa-copilot/rules/reference/claim-archaeology.md +1 -1
- package/plugins/lisa-copilot/rules/reference/claim-evidence-mapping.md +1 -1
- package/plugins/lisa-copilot/rules/reference/claim-time-guards.md +1 -1
- package/plugins/lisa-copilot/rules/reference/control-reachability.md +1 -1
- package/plugins/lisa-copilot/rules/reference/convergent-review.md +1 -1
- package/plugins/lisa-copilot/rules/reference/credential-substrate-precedence.md +1 -1
- package/plugins/lisa-copilot/rules/reference/dependency-decision-records.md +1 -1
- package/plugins/lisa-copilot/rules/reference/dependency-internalization-kit.md +1 -1
- package/plugins/lisa-copilot/rules/reference/dependency-trust-classes.md +1 -1
- package/plugins/lisa-copilot/rules/reference/deployed-state-readback.md +1 -1
- package/plugins/lisa-copilot/rules/reference/derived-branch-plan.md +1 -1
- package/plugins/lisa-copilot/rules/reference/design-source-of-truth.md +1 -1
- package/plugins/lisa-copilot/rules/reference/design-value-binding.md +1 -1
- package/plugins/lisa-copilot/rules/reference/documentation-source-paths.md +1 -1
- package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa-copilot/rules/reference/observability-audit.md +1 -1
- package/plugins/lisa-copilot/rules/reference/prd-definition-of-ready.md +1 -1
- package/plugins/lisa-copilot/rules/reference/prd-lifecycle-rollup.md +1 -1
- package/plugins/lisa-copilot/rules/reference/pre-flight-autofill.md +1 -1
- package/plugins/lisa-copilot/rules/reference/promotion-contract.md +1 -1
- package/plugins/lisa-copilot/rules/reference/readiness-rubric.md +1 -1
- package/plugins/lisa-copilot/rules/reference/ready-role-filing.md +37 -1
- package/plugins/lisa-copilot/rules/reference/rejection-detection.md +1 -1
- package/plugins/lisa-copilot/rules/reference/repo-scope-split.md +9 -10
- package/plugins/lisa-copilot/rules/reference/reset-seed-coverage.md +1 -1
- package/plugins/lisa-copilot/rules/reference/usage-accounting.md +1 -1
- package/plugins/lisa-copilot/rules/reference/work-item-definition-of-ready.md +1 -1
- package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +85 -17
- package/plugins/lisa-copilot/scripts/qa-signal-lifecycle.mjs +5 -2
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +38 -15
- package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +15 -1
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +37 -13
- package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +15 -1
- package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +56 -7
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +36 -11
- package/plugins/lisa-copilot/skills/lisa-linear-prd-intake/SKILL.md +12 -2
- package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +1 -18
- package/plugins/lisa-copilot/skills/lisa-linear-verify/SKILL.md +0 -17
- package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +18 -35
- package/plugins/lisa-copilot/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +66 -12
- package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +2 -1
- package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/providers.mjs +2 -1
- package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +7 -2
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +11 -4
- package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/toolchain.mjs +17 -5
- package/plugins/lisa-copilot/skills/lisa-track/SKILL.md +32 -4
- package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +15 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-blind-automerge.sh +13 -5
- package/plugins/lisa-cursor/hooks/block-direct-issue-create.sh +7 -0
- package/plugins/lisa-cursor/hooks/block-instruction-file-edits.sh +3 -0
- package/plugins/lisa-cursor/hooks/block-managed-file-edits.sh +76 -2
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +3 -0
- package/plugins/lisa-cursor/hooks/block-shell-json-parsing.sh +3 -0
- package/plugins/lisa-cursor/hooks/guard-dedupe.bash +66 -29
- package/plugins/lisa-cursor/hooks/parity-safety-net-heredoc.py +3 -0
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +5 -1
- package/plugins/lisa-cursor/hooks/worktree-binding-guard.mjs +3 -0
- package/plugins/lisa-cursor/hooks/worktree-binding-guard.sh +5 -1
- package/plugins/lisa-cursor/rules/00-rule-index.mdc +1 -0
- package/plugins/lisa-cursor/rules/automation-runbook-contract-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/base-rules.mdc +3 -1
- package/plugins/lisa-cursor/rules/bdd-e2e-coverage-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/blocker-containment-reference.mdc +3 -3
- package/plugins/lisa-cursor/rules/claim-archaeology-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/claim-evidence-mapping-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/claim-time-guards-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/control-reachability-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/convergent-review-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/credential-substrate-precedence-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/dependency-decision-records-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/dependency-internalization-kit-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/dependency-trust-classes-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/deployed-state-readback-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/derived-branch-plan-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/design-source-of-truth-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/design-value-binding-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/documentation-source-paths-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/observability-audit-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/prd-definition-of-ready-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/prd-lifecycle-rollup-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/pre-flight-autofill-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/promotion-contract-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/readiness-rubric-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/ready-role-filing-reference.mdc +37 -1
- package/plugins/lisa-cursor/rules/rejection-detection-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/repo-scope-split-reference.mdc +9 -10
- package/plugins/lisa-cursor/rules/reset-seed-coverage-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/usage-accounting-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/withdrawn-rulings.mdc +14 -3
- package/plugins/lisa-cursor/rules/work-item-definition-of-ready-reference.mdc +1 -1
- package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +85 -17
- package/plugins/lisa-cursor/scripts/qa-signal-lifecycle.mjs +5 -2
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +38 -15
- package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +15 -1
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +37 -13
- package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +15 -1
- package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +56 -7
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +36 -11
- package/plugins/lisa-cursor/skills/lisa-linear-prd-intake/SKILL.md +12 -2
- package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +1 -18
- package/plugins/lisa-cursor/skills/lisa-linear-verify/SKILL.md +0 -17
- package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +18 -35
- package/plugins/lisa-cursor/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +66 -12
- package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +2 -1
- package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/providers.mjs +2 -1
- package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +7 -2
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +11 -4
- package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/toolchain.mjs +17 -5
- package/plugins/lisa-cursor/skills/lisa-track/SKILL.md +32 -4
- package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +15 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/materialized-artifacts.json +11 -0
- package/plugins/src/base/hooks/block-blind-automerge.sh +10 -5
- package/plugins/src/base/hooks/block-direct-issue-create.sh +4 -0
- package/plugins/src/base/hooks/block-managed-file-edits.sh +73 -2
- package/plugins/src/base/hooks/guard-dedupe.bash +63 -29
- package/plugins/src/base/hooks/parity-safety-net.sh +2 -1
- package/plugins/src/base/hooks/worktree-binding-guard.sh +2 -1
- package/plugins/src/base/rules/eager/00-rule-index.md +1 -0
- package/plugins/src/base/rules/eager/base-rules.md +3 -1
- package/plugins/src/base/rules/eager/withdrawn-rulings.md +14 -3
- package/plugins/src/base/rules/reference/automation-runbook-contract.md +1 -1
- package/plugins/src/base/rules/reference/bdd-e2e-coverage.md +1 -1
- package/plugins/src/base/rules/reference/blocker-containment.md +3 -3
- package/plugins/src/base/rules/reference/claim-archaeology.md +1 -1
- package/plugins/src/base/rules/reference/claim-evidence-mapping.md +1 -1
- package/plugins/src/base/rules/reference/claim-time-guards.md +1 -1
- package/plugins/src/base/rules/reference/control-reachability.md +1 -1
- package/plugins/src/base/rules/reference/convergent-review.md +1 -1
- package/plugins/src/base/rules/reference/credential-substrate-precedence.md +1 -1
- package/plugins/src/base/rules/reference/dependency-decision-records.md +1 -1
- package/plugins/src/base/rules/reference/dependency-internalization-kit.md +1 -1
- package/plugins/src/base/rules/reference/dependency-trust-classes.md +1 -1
- package/plugins/src/base/rules/reference/deployed-state-readback.md +1 -1
- package/plugins/src/base/rules/reference/derived-branch-plan.md +1 -1
- package/plugins/src/base/rules/reference/design-source-of-truth.md +1 -1
- package/plugins/src/base/rules/reference/design-value-binding.md +1 -1
- package/plugins/src/base/rules/reference/documentation-source-paths.md +1 -1
- package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/src/base/rules/reference/observability-audit.md +1 -1
- package/plugins/src/base/rules/reference/prd-definition-of-ready.md +1 -1
- package/plugins/src/base/rules/reference/prd-lifecycle-rollup.md +1 -1
- package/plugins/src/base/rules/reference/pre-flight-autofill.md +1 -1
- package/plugins/src/base/rules/reference/promotion-contract.md +1 -1
- package/plugins/src/base/rules/reference/readiness-rubric.md +1 -1
- package/plugins/src/base/rules/reference/ready-role-filing.md +37 -1
- package/plugins/src/base/rules/reference/rejection-detection.md +1 -1
- package/plugins/src/base/rules/reference/repo-scope-split.md +9 -10
- package/plugins/src/base/rules/reference/reset-seed-coverage.md +1 -1
- package/plugins/src/base/rules/reference/usage-accounting.md +1 -1
- package/plugins/src/base/rules/reference/work-item-definition-of-ready.md +1 -1
- package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +85 -17
- package/plugins/src/base/scripts/qa-signal-lifecycle.mjs +5 -2
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +38 -15
- package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +15 -1
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +37 -13
- package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +15 -1
- package/plugins/src/base/skills/lisa-linear-access/SKILL.md +56 -7
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +36 -11
- package/plugins/src/base/skills/lisa-linear-prd-intake/SKILL.md +12 -2
- package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +1 -18
- package/plugins/src/base/skills/lisa-linear-verify/SKILL.md +0 -17
- package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +18 -35
- package/plugins/src/base/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +66 -12
- package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +2 -1
- package/plugins/src/base/skills/lisa-secrets-access/scripts/providers.mjs +2 -1
- package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-setup-remote-env/scripts/preflight-tools.mjs +7 -2
- package/plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +11 -4
- package/plugins/src/base/skills/lisa-setup-remote-env/scripts/toolchain.mjs +17 -5
- package/plugins/src/base/skills/lisa-track/SKILL.md +32 -4
- package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +15 -1
- package/scripts/build-plugins.sh +4 -0
- package/scripts/copy-opencode-plugin-templates.mjs +5 -1
- package/scripts/lisa-enforcement-fallback.sh +9 -1
- package/scripts/two-channel-couplings.json +5 -33
- package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +551 -13
- package/typescript/create-only/.github/required-checks.json +1 -1
|
@@ -56,7 +56,7 @@ export function extractVersion(output) {
|
|
|
56
56
|
/**
|
|
57
57
|
* Classify one required tool against what the environment actually provides.
|
|
58
58
|
* @param {object} tool Manifest entry.
|
|
59
|
-
* @param {{version: string|null, present: boolean}} found Probe result.
|
|
59
|
+
* @param {{version: string|null, present: boolean, executable: boolean}} found Probe result.
|
|
60
60
|
* @returns {{name: string, action: string, reason: string}} The decision.
|
|
61
61
|
*/
|
|
62
62
|
function planRequired(tool, found) {
|
|
@@ -70,6 +70,13 @@ function planRequired(tool, found) {
|
|
|
70
70
|
`Either add an install entry or pin a different image.`,
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
|
+
if (found.executable !== true) {
|
|
74
|
+
return {
|
|
75
|
+
name: tool.name,
|
|
76
|
+
action: "missing",
|
|
77
|
+
reason: `${tool.name} was found but cannot be executed. Repair its permissions or replace the binary before using it.`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
73
80
|
if (
|
|
74
81
|
tool.minVersion &&
|
|
75
82
|
compareVersions(found.version ?? "0", tool.minVersion) < 0
|
|
@@ -97,7 +104,7 @@ function planRequired(tool, found) {
|
|
|
97
104
|
* and maintenance the same script, and it is the cheap path when a container
|
|
98
105
|
* resumes from cache rather than being built fresh.
|
|
99
106
|
* @param {object} tool Manifest entry.
|
|
100
|
-
* @param {{version: string|null, present: boolean}} found Probe result.
|
|
107
|
+
* @param {{version: string|null, present: boolean, executable: boolean}} found Probe result.
|
|
101
108
|
* @returns {{name: string, action: string, reason: string}} The decision.
|
|
102
109
|
*/
|
|
103
110
|
function planInstallable(tool, found, pinIsFloor = false) {
|
|
@@ -108,7 +115,11 @@ function planInstallable(tool, found, pinIsFloor = false) {
|
|
|
108
115
|
reason: `${tool.name} has no pinned version. An unpinned install is not reproducible.`,
|
|
109
116
|
};
|
|
110
117
|
}
|
|
111
|
-
if (
|
|
118
|
+
if (
|
|
119
|
+
found.present &&
|
|
120
|
+
found.executable === true &&
|
|
121
|
+
found.version === tool.version
|
|
122
|
+
) {
|
|
112
123
|
return {
|
|
113
124
|
name: tool.name,
|
|
114
125
|
action: "skip",
|
|
@@ -125,6 +136,7 @@ function planInstallable(tool, found, pinIsFloor = false) {
|
|
|
125
136
|
if (
|
|
126
137
|
pinIsFloor &&
|
|
127
138
|
found.present &&
|
|
139
|
+
found.executable === true &&
|
|
128
140
|
found.version &&
|
|
129
141
|
compareVersions(found.version, tool.version) > 0
|
|
130
142
|
) {
|
|
@@ -286,10 +298,10 @@ export function appliesToSurface(tool, surface) {
|
|
|
286
298
|
* asking about availability rather than provisioning has the answer instead of
|
|
287
299
|
* having to infer one from the other.
|
|
288
300
|
* @param {{require?: object[], install?: object[]}} tools Manifest.
|
|
289
|
-
* @param {(name: string) => {version: string|null, present: boolean}} probe Version probe.
|
|
301
|
+
* @param {(name: string) => {version: string|null, present: boolean, executable: boolean}} probe Version probe.
|
|
290
302
|
* @param {string} [surface] Surface being provisioned.
|
|
291
303
|
* @param {string} [platform] Platform key to resolve install entries against.
|
|
292
|
-
* @returns {Array<{name: string, action: string, reason: string, tool?: object, found?: {version: string|null, present: boolean}, unpinnedForPlatform?: boolean}>} Ordered decisions.
|
|
304
|
+
* @returns {Array<{name: string, action: string, reason: string, tool?: object, found?: {version: string|null, present: boolean, executable: boolean}, unpinnedForPlatform?: boolean}>} Ordered decisions.
|
|
293
305
|
*/
|
|
294
306
|
export function planToolchain(
|
|
295
307
|
tools,
|
|
@@ -6,6 +6,20 @@ allowed-tools: ["Skill", "Bash", "Read"]
|
|
|
6
6
|
|
|
7
7
|
# Track Work: $ARGUMENTS
|
|
8
8
|
|
|
9
|
+
## Human-gate release authorization
|
|
10
|
+
|
|
11
|
+
A release requires a trusted human author, not just matching comment text. Follow
|
|
12
|
+
`ready-role-filing` — **Human-gate release authorization**: preserve tracker-supplied comment
|
|
13
|
+
author IDs and bot metadata, resolve `trustedHumanActorIds` only from an explicit user instruction
|
|
14
|
+
or existing human-authored trusted project policy, and pass it with structured `comments` to every
|
|
15
|
+
hold classifier, reconciliation, normalization and release planner. Never derive trust from the
|
|
16
|
+
comment body, a display name, the actor's own assertion, or an automation posting on its own behalf.
|
|
17
|
+
Missing policy, missing/unreadable author identity, raw body strings, untrusted actors and known bots
|
|
18
|
+
cannot discharge a hold. Keep the item held and report the missing authorization; do not silently
|
|
19
|
+
replace these inputs with an empty history or an inferred allowlist. Authorized matching releases
|
|
20
|
+
continue through the existing path and never override an independently declared caller hold.
|
|
21
|
+
|
|
22
|
+
|
|
9
23
|
Establish the tracked-work invariant before any durable project mutation. Discussion and read-only orientation may proceed without this skill; code, configuration, documentation, research artifacts, plans, investigation findings, tests, commits, and pull requests may not.
|
|
10
24
|
|
|
11
25
|
This flow must return exactly one canonical `(tracker_provider, work_item_ref)` pair or fail closed. It never returns an unvalidated textual guess.
|
|
@@ -24,7 +38,7 @@ This flow must return exactly one canonical `(tracker_provider, work_item_ref)`
|
|
|
24
38
|
|
|
25
39
|
### Explicit reference
|
|
26
40
|
|
|
27
|
-
Invoke `lisa-tracker-read <ref>` and require a live result from the configured project. Reject nonexistent, inaccessible, closed/resolved/terminal, wrong-project, wrong-repository, or container items. Read the returned body
|
|
41
|
+
Invoke `lisa-tracker-read <ref>` and require a live result from the configured project. Reject nonexistent, inaccessible, closed/resolved/terminal, wrong-project, wrong-repository, or container items. Read the returned body, labels and all comments; Phase 3 uses the shared hold classifier so a historical `[lisa-human-gate]` marker with a matching release is not mistaken for an active hold. This live read is mandatory even if caller context already includes ticket text.
|
|
28
42
|
|
|
29
43
|
### File or plain text
|
|
30
44
|
|
|
@@ -44,9 +58,23 @@ This is intentionally conservative: ambiguity creates one explicit work item ins
|
|
|
44
58
|
|
|
45
59
|
## Phase 3 — Claim and bind
|
|
46
60
|
|
|
47
|
-
The work item is **held** when
|
|
61
|
+
The work item is **held** when the caller declared a `human_gate`, independently of any item history,
|
|
62
|
+
or `classifyReadyCandidate({ labels, body, comments, trustedHumanActorIds, humanNeededLabel })` from the shipped
|
|
63
|
+
`scripts/intake-blocker-reprobe.mjs` returns `claimable: false`. Pass the complete live comment
|
|
64
|
+
history so a matching `[lisa-human-gate-release]` discharges the historical body marker. Never
|
|
65
|
+
reimplement heldness as a substring test or as the negation of `planHumanGateRelease().released`:
|
|
66
|
+
that planner also returns `released: false` for an item that was never held. Missing comments fail
|
|
67
|
+
closed for a hold; never infer release from a missing label.
|
|
68
|
+
|
|
69
|
+
A held item stops the flow here, whatever roles or labels it carries. Do not invoke
|
|
70
|
+
`lisa-tracker-claim`, write the worktree binding, or begin durable project work. Return
|
|
71
|
+
`claim_outcome: held-by-gate` and `binding_outcome: skipped-human-gate`, name the signal in `held_by`
|
|
72
|
+
and carry its reason verbatim in `gate_reason` (null for a keyless hold), then stop.
|
|
48
73
|
|
|
49
|
-
|
|
74
|
+
For a discharged item, call
|
|
75
|
+
`planHumanGateRelease({ labels, body, comments, trustedHumanActorIds, humanNeededLabel, readyLabel, lifecycleLabels, alreadyNotified })`
|
|
76
|
+
and apply only the returned actions before claiming. Keep the body marker as history; a release
|
|
77
|
+
never overrides a new caller-declared hold or another eligibility check.
|
|
50
78
|
|
|
51
79
|
Otherwise:
|
|
52
80
|
|
|
@@ -78,5 +106,5 @@ Otherwise:
|
|
|
78
106
|
- Branch setup may call `node scripts/lisa-work-item.mjs attach-branch` after the feature branch exists.
|
|
79
107
|
- Keep the binding across ordinary interruptions and blocked outcomes so resumed work remains attributable.
|
|
80
108
|
- Clear it only after true terminal completion — merged, deployed/verified where required, tracker evidence/backlink complete, and the work item terminal — by running `node scripts/lisa-work-item.mjs clear` and verifying no current binding remains.
|
|
81
|
-
- A held filing writes no binding at all, so there is nothing to clear. The gate is released by a human decision, but not by a human edit: the person records the decision as a comment on the leaf beginning `[lisa-human-gate-release]` and
|
|
109
|
+
- A held filing writes no binding at all, so there is nothing to clear. The gate is released by a human decision, but not by a human edit: the person records the decision as a comment on the leaf beginning `[lisa-human-gate-release]` and, for a keyed hold, repeating its `reason=` verbatim. For a keyless hold, the comment begins `[lisa-human-gate-release]` without a `reason=` field. The next intake sweep takes the human-needed marker off and puts the leaf back in the build-ready role on its own (`planHumanGateRelease` in `scripts/intake-blocker-reprobe.mjs`). A later invocation then resolves it on the ordinary path. **Do not tell anyone to delete the marker from the description, and do not delete it here.** The only description write available is a whole-body replacement, so clearing one line means rewriting the entire record — which is why, before this, the rational move was always to leave a hold in place and answered holds only accumulated (CodySwannGT/lisa#3852). The hold stays in the body as history; the release is recorded beside it.
|
|
82
110
|
- A tracker outage, invalid item, failed claim, or failed binding blocks durable work. Never continue untracked and never ask a Git hook to create the item.
|
|
@@ -6,6 +6,20 @@ allowed-tools: ["Skill", "Bash", "Read"]
|
|
|
6
6
|
|
|
7
7
|
# Tracker Build Intake: $ARGUMENTS
|
|
8
8
|
|
|
9
|
+
## Human-gate release authorization
|
|
10
|
+
|
|
11
|
+
A release requires a trusted human author, not just matching comment text. Follow
|
|
12
|
+
`ready-role-filing` — **Human-gate release authorization**: preserve tracker-supplied comment
|
|
13
|
+
author IDs and bot metadata, resolve `trustedHumanActorIds` only from an explicit user instruction
|
|
14
|
+
or existing human-authored trusted project policy, and pass it with structured `comments` to every
|
|
15
|
+
hold classifier, reconciliation, normalization and release planner. Never derive trust from the
|
|
16
|
+
comment body, a display name, the actor's own assertion, or an automation posting on its own behalf.
|
|
17
|
+
Missing policy, missing/unreadable author identity, raw body strings, untrusted actors and known bots
|
|
18
|
+
cannot discharge a hold. Keep the item held and report the missing authorization; do not silently
|
|
19
|
+
replace these inputs with an empty history or an inferred allowlist. Authorized matching releases
|
|
20
|
+
continue through the existing path and never override an independently declared caller hold.
|
|
21
|
+
|
|
22
|
+
|
|
9
23
|
Thin dispatcher. Resolves the configured destination tracker and delegates to the matching vendor build-queue scanner.
|
|
10
24
|
|
|
11
25
|
See the `config-resolution` rule for configuration and dispatch table.
|
|
@@ -63,7 +77,7 @@ blocker re-probe carries an absolute human gate: an item carrying the configured
|
|
|
63
77
|
or a `[lisa-human-gate]` marker is never auto-selected, whatever a probe returns.
|
|
64
78
|
|
|
65
79
|
That gate has an inverse, and it is forwarded identically: a hold ends when a
|
|
66
|
-
`[lisa-human-gate-release]` comment naming the same `reason=` is recorded on the item. Every vendor
|
|
80
|
+
`[lisa-human-gate-release]` comment naming the same `reason=` is recorded on the item by an authorized human. Every vendor
|
|
67
81
|
scanner passes the item's `comments` into the gate helpers so the discharge is visible, and calls
|
|
68
82
|
`planHumanGateRelease(...)` to take the marker off and put the item back in the queue. **No vendor
|
|
69
83
|
scanner clears a hold by editing the description** — the only body write any of them has is a
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
3
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
4
|
+
|
|
2
5
|
# PreToolUse hook for Bash: refuse to ARM auto-merge on a pull request that
|
|
3
6
|
# GitHub already says is blocked on review.
|
|
4
7
|
#
|
|
@@ -280,7 +283,8 @@ NODE_ID_PATTERN = re.compile(r"^[A-Za-z0-9_=-]+$")
|
|
|
280
283
|
NODE_QUERY = (
|
|
281
284
|
"query($id:ID!){node(id:$id){... on PullRequest"
|
|
282
285
|
"{number url reviewDecision state baseRefName "
|
|
283
|
-
"commits(last:1){nodes{commit{statusCheckRollup{contexts(first:100){
|
|
286
|
+
"commits(last:1){nodes{commit{statusCheckRollup{contexts(first:100){"
|
|
287
|
+
"pageInfo{hasNextPage} nodes{"
|
|
284
288
|
"__typename ... on CheckRun{name conclusion} "
|
|
285
289
|
"... on StatusContext{context state}"
|
|
286
290
|
"}}}}}}}}}"
|
|
@@ -294,9 +298,13 @@ NODE_QUERY = (
|
|
|
294
298
|
# checks, which is genuinely not failing and gets an empty list. A node without
|
|
295
299
|
# the scaffolding is a probe that never asked, and it must leave the key absent
|
|
296
300
|
# so the re-target path can tell the two apart instead of reading both as green.
|
|
301
|
+
# A truncated page is equally unreadable: a failing check may be on the next
|
|
302
|
+
# page, so a green first page cannot authorize an uncovered-base re-target.
|
|
297
303
|
NODE_JQ = (
|
|
298
304
|
"if .data.node == null then null else .data.node as $n "
|
|
299
|
-
"| if ($n
|
|
305
|
+
"| if ($n.commits.nodes[0].commit.statusCheckRollup.contexts.pageInfo.hasNextPage == true) "
|
|
306
|
+
"then ($n | del(.commits)) "
|
|
307
|
+
"elif ($n | has(\"commits\")) then ($n | del(.commits)) "
|
|
300
308
|
"+ {statusCheckRollup: "
|
|
301
309
|
"((($n.commits.nodes[0].commit.statusCheckRollup.contexts.nodes)) // [])} "
|
|
302
310
|
"else $n end end"
|
|
@@ -1024,9 +1032,9 @@ not read the pull request's checks.
|
|
|
1024
1032
|
|
|
1025
1033
|
That ref has ZERO required status checks, so the one thing standing between the
|
|
1026
1034
|
move and a permission-free gate bypass is whether the PR is currently failing —
|
|
1027
|
-
and the probe returned no `statusCheckRollup
|
|
1028
|
-
empty one. Reporting the move as the sanctioned green-PR
|
|
1029
|
-
|
|
1035
|
+
and the probe returned no complete `statusCheckRollup`. An absent or truncated
|
|
1036
|
+
rollup is not an empty one. Reporting the move as the sanctioned green-PR
|
|
1037
|
+
batching case here would claim a result the probe did not establish.
|
|
1030
1038
|
|
|
1031
1039
|
Re-target through `gh pr edit --base` instead, which reads the checks, or fix
|
|
1032
1040
|
the probe. Do not report the PR as batched until something has actually looked.
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
3
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
4
|
+
|
|
2
5
|
# PreToolUse hook for Bash: refuse a direct tracker-creation command that
|
|
3
6
|
# declares no readiness.
|
|
4
7
|
#
|
|
@@ -2106,6 +2109,10 @@ def unparseable_reads_only(text):
|
|
|
2106
2109
|
Returns:
|
|
2107
2110
|
True when every segment's command word is a known reader.
|
|
2108
2111
|
"""
|
|
2112
|
+
# Unlexable operands cannot be certified as data when shell substitutions
|
|
2113
|
+
# may execute inside them. Preserve the plain apostrophe reader exemption.
|
|
2114
|
+
if any(operator in text for operator in ("$(", "`", "<(", ">(")):
|
|
2115
|
+
return False
|
|
2109
2116
|
words = raw_command_words(text)
|
|
2110
2117
|
return bool(words) and all(word in READ_ONLY_PROGRAMS for word in words)
|
|
2111
2118
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
3
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
4
|
+
|
|
2
5
|
# PreToolUse hook: refuse agent writes to the session-instruction files.
|
|
3
6
|
#
|
|
4
7
|
# `AGENTS.md`, `CLAUDE.md`, and `.github/copilot-instructions.md` are the files
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
3
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
4
|
+
|
|
2
5
|
# PreToolUse hook: refuse agent writes to files Lisa overwrites on every apply.
|
|
3
6
|
#
|
|
4
7
|
# Lisa ships templates in three modes, and only one of them is unsafe to edit:
|
|
@@ -566,6 +569,7 @@ EOF
|
|
|
566
569
|
import os
|
|
567
570
|
import re
|
|
568
571
|
import shlex
|
|
572
|
+
import sys
|
|
569
573
|
|
|
570
574
|
command = os.environ.get("MANAGED_EDIT_COMMAND", "")
|
|
571
575
|
project = os.environ.get("MANAGED_EDIT_PROJECT", "") or os.getcwd()
|
|
@@ -576,6 +580,7 @@ project = os.environ.get("MANAGED_EDIT_PROJECT", "") or os.getcwd()
|
|
|
576
580
|
FOLLOW_MAX_BYTES = 262144
|
|
577
581
|
FOLLOW_MAX_FILES = 8
|
|
578
582
|
FOLLOW_MAX_DEPTH = 3
|
|
583
|
+
ENV_SPLIT_UNRESOLVED = 42
|
|
579
584
|
|
|
580
585
|
# Spelled with chr() rather than backslash escapes on purpose. This source is
|
|
581
586
|
# embedded in a shell heredoc and copied verbatim through several generators
|
|
@@ -607,7 +612,7 @@ FOLLOW_WRAPPERS = {
|
|
|
607
612
|
# positional count: the walk below re-enters its assignment skip on the
|
|
608
613
|
# next iteration and steps over as many as are present.
|
|
609
614
|
"env": (
|
|
610
|
-
frozenset({"-C", "--chdir", "-P", "-
|
|
615
|
+
frozenset({"-C", "--chdir", "-P", "-u", "--unset"}),
|
|
611
616
|
0,
|
|
612
617
|
),
|
|
613
618
|
"exec": (frozenset({"-a"}), 0),
|
|
@@ -741,6 +746,31 @@ def statements(tokens):
|
|
|
741
746
|
return grouped
|
|
742
747
|
|
|
743
748
|
|
|
749
|
+
class UnresolvedEnvSplit(ValueError):
|
|
750
|
+
"""Split-string syntax whose executed arguments cannot be proven here."""
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
def parse_env_split(split_string):
|
|
754
|
+
"""Parse only the env -S subset shared with ordinary quoted arguments.
|
|
755
|
+
|
|
756
|
+
GNU env has its own escapes, comments and environment interpolation. Do
|
|
757
|
+
not pretend shlex implements those, or invent environment values in a
|
|
758
|
+
pre-execution guard. The operator can spell the resulting command directly.
|
|
759
|
+
|
|
760
|
+
Args:
|
|
761
|
+
split_string: The literal argument supplied to env's split option.
|
|
762
|
+
|
|
763
|
+
Returns:
|
|
764
|
+
Arguments for the supported subset; otherwise raises UnresolvedEnvSplit.
|
|
765
|
+
"""
|
|
766
|
+
if any(marker in split_string for marker in (BACKSLASH, "#", "$", chr(96), chr(11), chr(12))):
|
|
767
|
+
raise UnresolvedEnvSplit("escapes, comments, shell substitution, variable expansion or control whitespace")
|
|
768
|
+
try:
|
|
769
|
+
return shlex.split(split_string, comments=False, posix=True)
|
|
770
|
+
except ValueError as error:
|
|
771
|
+
raise UnresolvedEnvSplit("unbalanced quoting") from error
|
|
772
|
+
|
|
773
|
+
|
|
744
774
|
def command_word(statement):
|
|
745
775
|
"""The program a statement runs, and the tokens after it.
|
|
746
776
|
|
|
@@ -757,6 +787,7 @@ def command_word(statement):
|
|
|
757
787
|
its command word is itself the executed script.
|
|
758
788
|
"""
|
|
759
789
|
index = 0
|
|
790
|
+
split_expansions = 0
|
|
760
791
|
while index < len(statement):
|
|
761
792
|
token = statement[index]
|
|
762
793
|
if "=" in token and not token.startswith(("=", "-")):
|
|
@@ -772,6 +803,36 @@ def command_word(statement):
|
|
|
772
803
|
if option == "--":
|
|
773
804
|
index += 1
|
|
774
805
|
break
|
|
806
|
+
# env -S inserts the split string back into env's argument list;
|
|
807
|
+
# it is executable input, not an option value to discard. Keep
|
|
808
|
+
# shell -c's quoted operand intact while expanding the env layer.
|
|
809
|
+
# The known no-operand flags can be combined before S (-vS/-ivS).
|
|
810
|
+
# Stop at S: the rest belongs to its argument, not more flags.
|
|
811
|
+
short_split = re.match(r"^-[iv0]*S(.*)$", option)
|
|
812
|
+
if program == "env" and (
|
|
813
|
+
option == "--split-string"
|
|
814
|
+
or option.startswith("--split-string=")
|
|
815
|
+
or short_split is not None
|
|
816
|
+
):
|
|
817
|
+
consumed = 1
|
|
818
|
+
if option == "--split-string" or (
|
|
819
|
+
short_split is not None and not short_split.group(1)
|
|
820
|
+
):
|
|
821
|
+
if index + 1 >= len(statement):
|
|
822
|
+
raise UnresolvedEnvSplit("missing split-string operand")
|
|
823
|
+
split_string = statement[index + 1]
|
|
824
|
+
consumed = 2
|
|
825
|
+
elif option.startswith("--split-string="):
|
|
826
|
+
split_string = option.split("=", 1)[1]
|
|
827
|
+
else:
|
|
828
|
+
split_string = short_split.group(1)
|
|
829
|
+
if split_expansions >= 64:
|
|
830
|
+
raise UnresolvedEnvSplit("nested split-string limit")
|
|
831
|
+
expanded = parse_env_split(split_string)
|
|
832
|
+
statement = [token] + expanded + statement[index + consumed :]
|
|
833
|
+
split_expansions += 1
|
|
834
|
+
index = 0
|
|
835
|
+
break
|
|
775
836
|
index += 2 if option in separate else 1
|
|
776
837
|
index += positional
|
|
777
838
|
return (None, None, [])
|
|
@@ -985,7 +1046,11 @@ def collect(text, depth, seen, out):
|
|
|
985
1046
|
|
|
986
1047
|
|
|
987
1048
|
targets = []
|
|
988
|
-
|
|
1049
|
+
try:
|
|
1050
|
+
collect(command, 0, set(), targets)
|
|
1051
|
+
except UnresolvedEnvSplit as error:
|
|
1052
|
+
sys.stderr.write(str(error) + NEWLINE)
|
|
1053
|
+
sys.exit(ENV_SPLIT_UNRESOLVED)
|
|
989
1054
|
for target in targets:
|
|
990
1055
|
cleaned = target.strip().strip("'\"")
|
|
991
1056
|
if cleaned:
|
|
@@ -1003,6 +1068,15 @@ PY
|
|
|
1003
1068
|
else
|
|
1004
1069
|
analyzer_status=$?
|
|
1005
1070
|
fi
|
|
1071
|
+
if [ "$analyzer_status" -eq 42 ]; then
|
|
1072
|
+
printf 'Blocked: cannot resolve env --split-string for managed-file protection.\n' >&2
|
|
1073
|
+
printf 'Use an explicit command without split-string escapes, comments or variable expansion.\n' >&2
|
|
1074
|
+
while IFS= read -r analyzer_line; do
|
|
1075
|
+
[ -n "$analyzer_line" ] && printf ' %s\n' "$analyzer_line" >&2
|
|
1076
|
+
done <"$analyzer_stderr"
|
|
1077
|
+
rm -f "$analyzer_stderr"
|
|
1078
|
+
exit 2
|
|
1079
|
+
fi
|
|
1006
1080
|
if [ "$analyzer_status" -ne 0 ]; then
|
|
1007
1081
|
printf 'block-managed-file-edits: Bash analyzer failed (exit %s); Bash write protection is NOT active\n' "$analyzer_status" >&2
|
|
1008
1082
|
while IFS= read -r analyzer_line; do
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
3
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
4
|
+
|
|
2
5
|
# PreToolUse hook for Bash: blocks structural JSON parsing with text tools.
|
|
3
6
|
# Text tools (grep/sed/cut/awk) break on valid JSON — multiline values, escaped
|
|
4
7
|
# quotes, reordered keys, nested objects — producing silently wrong output
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
2
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
3
|
+
|
|
1
4
|
# shellcheck shell=bash
|
|
2
5
|
# Evaluate a dual-channel guard once per tool call, without de-registering it.
|
|
3
6
|
#
|
|
@@ -51,12 +54,9 @@
|
|
|
51
54
|
# refusal reaching the agent without the message that explains it. On a
|
|
52
55
|
# refusal every channel evaluates and speaks exactly as it does today.
|
|
53
56
|
#
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
# unless a second channel has actually been seen. The digest, and the one `stat`
|
|
58
|
-
# that feeds it the per-call discriminator, are reached only where a second
|
|
59
|
-
# channel is live, which is exactly where they are repaid.
|
|
57
|
+
# State ownership, modes and ancestry are verified before channel discovery.
|
|
58
|
+
# After that validation the channel check uses only builtins, and returns
|
|
59
|
+
# before digesting code or sizing the transcript unless another channel is live.
|
|
60
60
|
|
|
61
61
|
# Key this guard would memoise under, once computed. Empty means "record
|
|
62
62
|
# nothing on exit".
|
|
@@ -74,14 +74,25 @@ lisa_guard_memo_ready=0
|
|
|
74
74
|
# Digest tool for the memo key, resolved once. Empty disables the memo.
|
|
75
75
|
lisa_guard_memo_digest_tool=""
|
|
76
76
|
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
# Read ownership and all permission bits without accepting output from a
|
|
78
|
+
# failed platform-specific stat invocation.
|
|
79
|
+
# $1 - directory; sets lisa_guard_memo_owner and lisa_guard_memo_mode
|
|
80
|
+
lisa_guard_memo_stat() {
|
|
81
|
+
local facts=""
|
|
82
|
+
facts="$(stat -c '%u %a' "$1" 2>/dev/null)" ||
|
|
83
|
+
facts="$(stat -f '%u %p' "$1" 2>/dev/null)" || return 1
|
|
84
|
+
lisa_guard_memo_owner="${facts%% *}"
|
|
85
|
+
lisa_guard_memo_mode="${facts#* }"
|
|
86
|
+
case "$lisa_guard_memo_owner:$lisa_guard_memo_mode" in
|
|
87
|
+
*[!0-9:]* | :* | *:) return 1 ;;
|
|
88
|
+
esac
|
|
89
|
+
case "$lisa_guard_memo_mode" in *[!0-7]*) return 1 ;; esac
|
|
90
|
+
lisa_guard_memo_mode=$((8#$lisa_guard_memo_mode & 8#7777))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# Memo leaves must be private even when a sticky shared temp ancestor is safe.
|
|
94
|
+
# Ownership alone allows another local account to plant a session/allow file
|
|
95
|
+
# in an owned but group- or world-writable directory.
|
|
85
96
|
#
|
|
86
97
|
# $1 - candidate directory
|
|
87
98
|
lisa_guard_memo_dir_usable() {
|
|
@@ -89,23 +100,42 @@ lisa_guard_memo_dir_usable() {
|
|
|
89
100
|
[ -d "$1" ] || return 1
|
|
90
101
|
[ ! -L "$1" ] || return 1
|
|
91
102
|
[ -O "$1" ] || return 1
|
|
103
|
+
lisa_guard_memo_stat "$1" || return 1
|
|
104
|
+
[ $((lisa_guard_memo_mode & 8#0022)) -eq 0 ]
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
# Resolve parents physically and verify every ancestor. Plugin hooks do not
|
|
108
|
+
# inherit the dispatcher's trust walk, and exported paths are still inputs.
|
|
109
|
+
# $1 - candidate memo base; sets lisa_guard_memo_base only on success
|
|
110
|
+
lisa_guard_memo_trust_base() {
|
|
111
|
+
lisa_guard_memo_dir_usable "$1" || return 1
|
|
112
|
+
local physical=""
|
|
113
|
+
physical="$(cd "$1" 2>/dev/null && pwd -P)" || return 1
|
|
114
|
+
local current="$physical"
|
|
115
|
+
while :; do
|
|
116
|
+
lisa_guard_memo_stat "$current" || return 1
|
|
117
|
+
[ "$lisa_guard_memo_owner" = 0 ] || [ -O "$current" ] || return 1
|
|
118
|
+
if [ $((lisa_guard_memo_mode & 8#0022)) -ne 0 ] &&
|
|
119
|
+
[ $((lisa_guard_memo_mode & 8#1000)) -eq 0 ]; then
|
|
120
|
+
return 1
|
|
121
|
+
fi
|
|
122
|
+
[ "$current" != / ] || break
|
|
123
|
+
current="${current%/*}"
|
|
124
|
+
[ -n "$current" ] || current=/
|
|
125
|
+
done
|
|
126
|
+
lisa_guard_memo_base="$physical"
|
|
92
127
|
}
|
|
93
128
|
|
|
94
129
|
# Establish the memo base directory.
|
|
95
130
|
#
|
|
96
|
-
# Preferred source is `LISA_GUARD_MEMO_DIR`, exported by the dispatcher
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
# reached by the plugin channel has no such parent, so it creates the directory
|
|
100
|
-
# itself under `TMPDIR` — private by umask, and used only when this user owns
|
|
101
|
-
# it. If neither works the memo is unavailable and every guard evaluates, which
|
|
102
|
-
# is today's behaviour.
|
|
131
|
+
# Preferred source is `LISA_GUARD_MEMO_DIR`, exported by the dispatcher. Both
|
|
132
|
+
# this input and the plugin channel's TMPDIR fallback receive the same trust
|
|
133
|
+
# checks. Missing state is created privately; untrusted state disables memo use.
|
|
103
134
|
lisa_guard_memo_resolve_base() {
|
|
104
135
|
[ -z "$lisa_guard_memo_base" ] || return 0
|
|
105
136
|
|
|
106
137
|
local candidate="${LISA_GUARD_MEMO_DIR:-}"
|
|
107
|
-
if
|
|
108
|
-
lisa_guard_memo_base="$candidate"
|
|
138
|
+
if lisa_guard_memo_trust_base "$candidate"; then
|
|
109
139
|
return 0
|
|
110
140
|
fi
|
|
111
141
|
|
|
@@ -118,8 +148,7 @@ lisa_guard_memo_resolve_base() {
|
|
|
118
148
|
if [ ! -e "$candidate" ] && [ ! -L "$candidate" ]; then
|
|
119
149
|
(umask 077 && mkdir -p "$candidate") 2>/dev/null || true
|
|
120
150
|
fi
|
|
121
|
-
if
|
|
122
|
-
lisa_guard_memo_base="$candidate"
|
|
151
|
+
if lisa_guard_memo_trust_base "$candidate"; then
|
|
123
152
|
return 0
|
|
124
153
|
fi
|
|
125
154
|
return 1
|
|
@@ -165,6 +194,7 @@ lisa_guard_memo_sweep() {
|
|
|
165
194
|
#
|
|
166
195
|
# $1 - guard name, used only to name the memo file
|
|
167
196
|
# $2 - the raw tool payload this guard was handed on stdin
|
|
197
|
+
# Remaining arguments - files containing delegated verdict code
|
|
168
198
|
lisa_guard_dedupe() {
|
|
169
199
|
local guard_name="${1:-}"
|
|
170
200
|
local payload="${2:-}"
|
|
@@ -194,8 +224,7 @@ lisa_guard_dedupe() {
|
|
|
194
224
|
fresh_session=1
|
|
195
225
|
fi
|
|
196
226
|
fi
|
|
197
|
-
|
|
198
|
-
[ ! -L "$session_dir" ] || return 0
|
|
227
|
+
lisa_guard_memo_dir_usable "$session_dir" || return 0
|
|
199
228
|
|
|
200
229
|
# Swept once, by the process that created the session directory, so a
|
|
201
230
|
# long-lived machine does not accumulate memo state. Off the hot path by
|
|
@@ -278,11 +307,18 @@ lisa_guard_dedupe() {
|
|
|
278
307
|
case "$transcript_size" in "" | *[!0-9]*) return 0 ;; esac
|
|
279
308
|
|
|
280
309
|
# One command substitution, covering everything the verdict depends on: the
|
|
281
|
-
# guard's own bytes, this library
|
|
310
|
+
# guard's own bytes, this library, delegated code, payload, and call identity.
|
|
311
|
+
# Keep literal bytes (including trailing newlines), and propagate every read
|
|
312
|
+
# failure. A successful digest of a partial stream is not proof of identity.
|
|
282
313
|
local key=""
|
|
283
314
|
key="$(
|
|
315
|
+
set -o pipefail
|
|
284
316
|
{
|
|
285
|
-
|
|
317
|
+
local source_file=""
|
|
318
|
+
for source_file in "$self_script" "${BASH_SOURCE[0]}" "${@:3}"; do
|
|
319
|
+
cat "$source_file" 2>/dev/null || exit 1
|
|
320
|
+
printf '\0'
|
|
321
|
+
done
|
|
286
322
|
printf '\n%s\n' "$payload"
|
|
287
323
|
printf '%s\n' "$transcript_size"
|
|
288
324
|
} | if [ "$lisa_guard_memo_digest_tool" = "shasum" ]; then
|
|
@@ -293,6 +329,7 @@ lisa_guard_dedupe() {
|
|
|
293
329
|
)" || key=""
|
|
294
330
|
key="${key%% *}"
|
|
295
331
|
case "$key" in "" | *[!0-9a-f]*) return 0 ;; esac
|
|
332
|
+
[ "${#key}" -eq 64 ] || return 0
|
|
296
333
|
|
|
297
334
|
# One memo file per guard per session, rewritten as the call moves on, so the
|
|
298
335
|
# state directory stays a fixed size however long a session runs. A saturated
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
3
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
4
|
+
|
|
2
5
|
"""Classify the only heredoc forms whose payload is non-executable text.
|
|
3
6
|
|
|
4
7
|
SCOPE — read this before hardening anything here (issue #1993).
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# This file is managed by Lisa and IS replaced on each `lisa` run.
|
|
3
|
+
# Do not edit directly — durable changes belong upstream in Lisa.
|
|
4
|
+
|
|
2
5
|
# PreToolUse hook for Bash: a safety net that blocks destructive shell commands
|
|
3
6
|
# before they run. Lisa-native reimplementation of the upstream
|
|
4
7
|
# `safety-net@cc-marketplace` plugin's PreToolUse Bash-guard (parity work,
|
|
@@ -136,7 +139,8 @@ if [ -r "$lisa_guard_dedupe_lib" ]; then
|
|
|
136
139
|
# shellcheck source=guard-dedupe.bash
|
|
137
140
|
. "$lisa_guard_dedupe_lib"
|
|
138
141
|
trap 'lisa_guard_dedupe_record $?' EXIT
|
|
139
|
-
lisa_guard_dedupe parity-safety-net "$input"
|
|
142
|
+
lisa_guard_dedupe parity-safety-net "$input" \
|
|
143
|
+
"$lisa_guard_hook_dir/parity-safety-net-heredoc.py"
|
|
140
144
|
fi
|
|
141
145
|
|
|
142
146
|
tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')"
|