@codyswann/lisa 4.49.0 → 4.50.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/all/copy-overwrite/scripts/check-conflict-markers.mjs +4 -1
- package/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +163 -0
- package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +178 -1
- package/all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh +89 -10
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +44 -0
- package/all/copy-overwrite/scripts/lisa-lint-staged-preflight.mjs +1 -1
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +24 -24
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +490 -81
- package/cdk/package-lisa/package.lisa.json +45 -15
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +76 -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 +121 -227
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/opencode/plugin-templates/lisa-block-direct-issue-create.ts +45 -1
- package/dist/opencode/plugin-templates/parity-safety-net.sh +44 -0
- package/expo/package-lisa/package.lisa.json +110 -53
- package/harper-fabric/package-lisa/package.lisa.json +62 -32
- package/nestjs/package-lisa/package.lisa.json +57 -27
- package/npm-package/package-lisa/package.lisa.json +43 -7
- package/package.json +11 -7
- package/phaser/copy-overwrite/ast-grep/rules/no-day-truncating-file-age-predicate.yml +50 -0
- package/phaser/package-lisa/package.lisa.json +62 -32
- 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-drive-pr-to-merge/SKILL.md +17 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +4 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +4 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +4 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +4 -1
- package/plugins/lisa/hooks/block-direct-issue-create.sh +89 -10
- package/plugins/lisa/hooks/discharge-work-item-gates.sh +7 -1
- package/plugins/lisa/hooks/parity-safety-net.sh +44 -0
- package/plugins/lisa/hooks/threshold-ratchet-families.mjs +12 -0
- package/plugins/lisa/rules/eager/00-rule-index.md +79 -0
- package/plugins/lisa/rules/eager/base-rules.md +10 -0
- package/plugins/lisa/rules/eager/config-resolution.md +1 -88
- package/plugins/lisa/rules/reference/automation-runbook-contract.md +97 -0
- package/plugins/lisa/rules/reference/bdd-e2e-coverage.md +56 -0
- package/plugins/lisa/rules/reference/blocker-containment.md +58 -0
- package/plugins/lisa/rules/reference/claim-archaeology.md +42 -0
- package/plugins/lisa/rules/reference/claim-evidence-mapping.md +83 -0
- package/plugins/lisa/rules/reference/claim-time-guards.md +37 -0
- package/plugins/lisa/rules/reference/config-resolution.md +97 -0
- package/plugins/lisa/rules/reference/control-reachability.md +44 -0
- package/plugins/lisa/rules/reference/convergent-review.md +31 -0
- package/plugins/lisa/rules/reference/credential-substrate-precedence.md +57 -0
- package/plugins/lisa/rules/reference/dependency-decision-records.md +37 -0
- package/plugins/lisa/rules/reference/dependency-internalization-kit.md +47 -0
- package/plugins/lisa/rules/reference/dependency-trust-classes.md +48 -0
- package/plugins/lisa/rules/reference/deployed-state-readback.md +52 -0
- package/plugins/lisa/rules/reference/derived-branch-plan.md +52 -0
- package/plugins/lisa/rules/reference/design-source-of-truth.md +43 -0
- package/plugins/lisa/rules/reference/design-value-binding.md +103 -0
- package/plugins/lisa/rules/reference/documentation-source-paths.md +18 -0
- package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +75 -0
- package/plugins/lisa/rules/reference/observability-audit.md +20 -0
- package/plugins/lisa/rules/reference/prd-definition-of-ready.md +37 -0
- package/plugins/lisa/rules/reference/prd-lifecycle-rollup.md +36 -0
- package/plugins/lisa/rules/reference/pre-flight-autofill.md +88 -0
- package/plugins/lisa/rules/reference/promotion-contract.md +21 -0
- package/plugins/lisa/rules/reference/readiness-rubric.md +63 -0
- package/plugins/lisa/rules/reference/ready-role-filing.md +34 -0
- package/plugins/lisa/rules/reference/rejection-detection.md +69 -0
- package/plugins/lisa/rules/reference/repo-scope-split.md +48 -0
- package/plugins/lisa/rules/reference/reset-seed-coverage.md +55 -0
- package/plugins/lisa/rules/reference/usage-accounting.md +38 -0
- package/plugins/lisa/rules/reference/work-item-definition-of-ready.md +32 -0
- package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +158 -1
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +4 -0
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +4 -0
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +4 -0
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +4 -1
- package/plugins/lisa-agy/hooks/block-direct-issue-create.sh +89 -10
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +44 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +158 -1
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +4 -0
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +4 -0
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +4 -0
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +4 -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-direct-issue-create.sh +89 -10
- package/plugins/lisa-copilot/hooks/discharge-work-item-gates.sh +7 -1
- package/plugins/lisa-copilot/hooks/parity-safety-net.sh +44 -0
- package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +12 -0
- package/plugins/lisa-copilot/rules/eager/00-rule-index.md +79 -0
- package/plugins/lisa-copilot/rules/eager/base-rules.md +10 -0
- package/plugins/lisa-copilot/rules/eager/config-resolution.md +1 -88
- package/plugins/lisa-copilot/rules/reference/automation-runbook-contract.md +97 -0
- package/plugins/lisa-copilot/rules/reference/bdd-e2e-coverage.md +56 -0
- package/plugins/lisa-copilot/rules/reference/blocker-containment.md +58 -0
- package/plugins/lisa-copilot/rules/reference/claim-archaeology.md +42 -0
- package/plugins/lisa-copilot/rules/reference/claim-evidence-mapping.md +83 -0
- package/plugins/lisa-copilot/rules/reference/claim-time-guards.md +37 -0
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +97 -0
- package/plugins/lisa-copilot/rules/reference/control-reachability.md +44 -0
- package/plugins/lisa-copilot/rules/reference/convergent-review.md +31 -0
- package/plugins/lisa-copilot/rules/reference/credential-substrate-precedence.md +57 -0
- package/plugins/lisa-copilot/rules/reference/dependency-decision-records.md +37 -0
- package/plugins/lisa-copilot/rules/reference/dependency-internalization-kit.md +47 -0
- package/plugins/lisa-copilot/rules/reference/dependency-trust-classes.md +48 -0
- package/plugins/lisa-copilot/rules/reference/deployed-state-readback.md +52 -0
- package/plugins/lisa-copilot/rules/reference/derived-branch-plan.md +52 -0
- package/plugins/lisa-copilot/rules/reference/design-source-of-truth.md +43 -0
- package/plugins/lisa-copilot/rules/reference/design-value-binding.md +103 -0
- package/plugins/lisa-copilot/rules/reference/documentation-source-paths.md +18 -0
- package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +75 -0
- package/plugins/lisa-copilot/rules/reference/observability-audit.md +20 -0
- package/plugins/lisa-copilot/rules/reference/prd-definition-of-ready.md +37 -0
- package/plugins/lisa-copilot/rules/reference/prd-lifecycle-rollup.md +36 -0
- package/plugins/lisa-copilot/rules/reference/pre-flight-autofill.md +88 -0
- package/plugins/lisa-copilot/rules/reference/promotion-contract.md +21 -0
- package/plugins/lisa-copilot/rules/reference/readiness-rubric.md +63 -0
- package/plugins/lisa-copilot/rules/reference/ready-role-filing.md +34 -0
- package/plugins/lisa-copilot/rules/reference/rejection-detection.md +69 -0
- package/plugins/lisa-copilot/rules/reference/repo-scope-split.md +48 -0
- package/plugins/lisa-copilot/rules/reference/reset-seed-coverage.md +55 -0
- package/plugins/lisa-copilot/rules/reference/usage-accounting.md +38 -0
- package/plugins/lisa-copilot/rules/reference/work-item-definition-of-ready.md +32 -0
- package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +158 -1
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +4 -0
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +4 -0
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +4 -0
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +4 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-direct-issue-create.sh +89 -10
- package/plugins/lisa-cursor/hooks/discharge-work-item-gates.sh +7 -1
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +44 -0
- package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +12 -0
- package/plugins/lisa-cursor/rules/00-rule-index.mdc +84 -0
- package/plugins/lisa-cursor/rules/automation-runbook-contract-reference.mdc +97 -0
- package/plugins/lisa-cursor/rules/base-rules.mdc +10 -0
- package/plugins/lisa-cursor/rules/bdd-e2e-coverage-reference.mdc +56 -0
- package/plugins/lisa-cursor/rules/blocker-containment-reference.mdc +58 -0
- package/plugins/lisa-cursor/rules/claim-archaeology-reference.mdc +42 -0
- package/plugins/lisa-cursor/rules/claim-evidence-mapping-reference.mdc +83 -0
- package/plugins/lisa-cursor/rules/claim-time-guards-reference.mdc +37 -0
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +97 -0
- package/plugins/lisa-cursor/rules/config-resolution.mdc +1 -88
- package/plugins/lisa-cursor/rules/control-reachability-reference.mdc +44 -0
- package/plugins/lisa-cursor/rules/convergent-review-reference.mdc +31 -0
- package/plugins/lisa-cursor/rules/credential-substrate-precedence-reference.mdc +57 -0
- package/plugins/lisa-cursor/rules/dependency-decision-records-reference.mdc +37 -0
- package/plugins/lisa-cursor/rules/dependency-internalization-kit-reference.mdc +47 -0
- package/plugins/lisa-cursor/rules/dependency-trust-classes-reference.mdc +48 -0
- package/plugins/lisa-cursor/rules/deployed-state-readback-reference.mdc +52 -0
- package/plugins/lisa-cursor/rules/derived-branch-plan-reference.mdc +52 -0
- package/plugins/lisa-cursor/rules/design-source-of-truth-reference.mdc +43 -0
- package/plugins/lisa-cursor/rules/design-value-binding-reference.mdc +103 -0
- package/plugins/lisa-cursor/rules/documentation-source-paths-reference.mdc +18 -0
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +75 -0
- package/plugins/lisa-cursor/rules/observability-audit-reference.mdc +20 -0
- package/plugins/lisa-cursor/rules/prd-definition-of-ready-reference.mdc +37 -0
- package/plugins/lisa-cursor/rules/prd-lifecycle-rollup-reference.mdc +36 -0
- package/plugins/lisa-cursor/rules/pre-flight-autofill-reference.mdc +88 -0
- package/plugins/lisa-cursor/rules/promotion-contract-reference.mdc +21 -0
- package/plugins/lisa-cursor/rules/readiness-rubric-reference.mdc +63 -0
- package/plugins/lisa-cursor/rules/ready-role-filing-reference.mdc +34 -0
- package/plugins/lisa-cursor/rules/rejection-detection-reference.mdc +69 -0
- package/plugins/lisa-cursor/rules/repo-scope-split-reference.mdc +48 -0
- package/plugins/lisa-cursor/rules/reset-seed-coverage-reference.mdc +55 -0
- package/plugins/lisa-cursor/rules/usage-accounting-reference.mdc +38 -0
- package/plugins/lisa-cursor/rules/work-item-definition-of-ready-reference.mdc +32 -0
- package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +158 -1
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +4 -0
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +4 -0
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +4 -0
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +4 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/block-direct-issue-create.sh +89 -10
- package/plugins/src/base/hooks/discharge-work-item-gates.sh +7 -1
- package/plugins/src/base/hooks/parity-safety-net.sh +44 -0
- package/plugins/src/base/hooks/threshold-ratchet-families.mjs +12 -0
- package/plugins/src/base/rules/eager/00-rule-index.md +79 -0
- package/plugins/src/base/rules/eager/base-rules.md +10 -0
- package/plugins/src/base/rules/eager/config-resolution.md +1 -88
- package/plugins/src/base/rules/reference/automation-runbook-contract.md +97 -0
- package/plugins/src/base/rules/reference/bdd-e2e-coverage.md +56 -0
- package/plugins/src/base/rules/reference/blocker-containment.md +58 -0
- package/plugins/src/base/rules/reference/claim-archaeology.md +42 -0
- package/plugins/src/base/rules/reference/claim-evidence-mapping.md +83 -0
- package/plugins/src/base/rules/reference/claim-time-guards.md +37 -0
- package/plugins/src/base/rules/reference/config-resolution.md +97 -0
- package/plugins/src/base/rules/reference/control-reachability.md +44 -0
- package/plugins/src/base/rules/reference/convergent-review.md +31 -0
- package/plugins/src/base/rules/reference/credential-substrate-precedence.md +57 -0
- package/plugins/src/base/rules/reference/dependency-decision-records.md +37 -0
- package/plugins/src/base/rules/reference/dependency-internalization-kit.md +47 -0
- package/plugins/src/base/rules/reference/dependency-trust-classes.md +48 -0
- package/plugins/src/base/rules/reference/deployed-state-readback.md +52 -0
- package/plugins/src/base/rules/reference/derived-branch-plan.md +52 -0
- package/plugins/src/base/rules/reference/design-source-of-truth.md +43 -0
- package/plugins/src/base/rules/reference/design-value-binding.md +103 -0
- package/plugins/src/base/rules/reference/documentation-source-paths.md +18 -0
- package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +75 -0
- package/plugins/src/base/rules/reference/observability-audit.md +20 -0
- package/plugins/src/base/rules/reference/prd-definition-of-ready.md +37 -0
- package/plugins/src/base/rules/reference/prd-lifecycle-rollup.md +36 -0
- package/plugins/src/base/rules/reference/pre-flight-autofill.md +88 -0
- package/plugins/src/base/rules/reference/promotion-contract.md +21 -0
- package/plugins/src/base/rules/reference/readiness-rubric.md +63 -0
- package/plugins/src/base/rules/reference/ready-role-filing.md +34 -0
- package/plugins/src/base/rules/reference/rejection-detection.md +69 -0
- package/plugins/src/base/rules/reference/repo-scope-split.md +48 -0
- package/plugins/src/base/rules/reference/reset-seed-coverage.md +55 -0
- package/plugins/src/base/rules/reference/usage-accounting.md +38 -0
- package/plugins/src/base/rules/reference/work-item-definition-of-ready.md +32 -0
- package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +158 -1
- package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +4 -0
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +4 -0
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +4 -0
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +4 -1
- package/rails/copy-overwrite/ast-grep/rules/no-day-truncating-file-age-predicate.yml +50 -0
- package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +12 -0
- package/scripts/check-eager-rule-budget.mjs +176 -0
- package/scripts/check-generated-artifact-merge-coverage.mjs +7 -0
- package/scripts/check-rules-pairing.sh +45 -14
- package/scripts/check-shipped-surface-removals.mjs +851 -0
- package/scripts/generate-export-surface.mjs +318 -0
- package/scripts/lib/shipped-surface.mjs +212 -0
- package/scripts/lisa-enforcement-fallback.sh +178 -1
- package/scripts/remedy-conformance.mjs +435 -0
- package/scripts/two-channel-couplings.json +2 -2
- package/typescript/copy-contents/.husky/pre-push +147 -2
- package/typescript/copy-overwrite/ast-grep/rules/no-day-truncating-file-age-predicate.yml +50 -0
- package/typescript/copy-overwrite/audit.ignore.config.json +0 -10
- package/typescript/copy-overwrite/scripts/lisa-mutation.mjs +180 -29
- package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +12 -0
- package/typescript/package-lisa/package.lisa.json +72 -42
- package/plugins/lisa/rules/eager/automation-runbook-contract.md +0 -92
- package/plugins/lisa/rules/eager/bdd-e2e-coverage.md +0 -51
- package/plugins/lisa/rules/eager/blocker-containment.md +0 -53
- package/plugins/lisa/rules/eager/claim-archaeology.md +0 -37
- package/plugins/lisa/rules/eager/claim-evidence-mapping.md +0 -78
- package/plugins/lisa/rules/eager/claim-time-guards.md +0 -32
- package/plugins/lisa/rules/eager/control-reachability.md +0 -39
- package/plugins/lisa/rules/eager/convergent-review.md +0 -24
- package/plugins/lisa/rules/eager/credential-substrate-precedence.md +0 -54
- package/plugins/lisa/rules/eager/dependency-decision-records.md +0 -32
- package/plugins/lisa/rules/eager/dependency-internalization-kit.md +0 -42
- package/plugins/lisa/rules/eager/dependency-trust-classes.md +0 -43
- package/plugins/lisa/rules/eager/deployed-state-readback.md +0 -47
- package/plugins/lisa/rules/eager/derived-branch-plan.md +0 -47
- package/plugins/lisa/rules/eager/design-source-of-truth.md +0 -38
- package/plugins/lisa/rules/eager/design-value-binding.md +0 -98
- package/plugins/lisa/rules/eager/documentation-source-paths.md +0 -13
- package/plugins/lisa/rules/eager/factory-model.md +0 -41
- package/plugins/lisa/rules/eager/leaf-only-lifecycle.md +0 -70
- package/plugins/lisa/rules/eager/observability-audit.md +0 -15
- package/plugins/lisa/rules/eager/prd-definition-of-ready.md +0 -32
- package/plugins/lisa/rules/eager/prd-lifecycle-rollup.md +0 -31
- package/plugins/lisa/rules/eager/pre-flight-autofill.md +0 -84
- package/plugins/lisa/rules/eager/project-learnings.md +0 -22
- package/plugins/lisa/rules/eager/promotion-contract.md +0 -18
- package/plugins/lisa/rules/eager/readiness-rubric.md +0 -58
- package/plugins/lisa/rules/eager/ready-role-filing.md +0 -29
- package/plugins/lisa/rules/eager/rejection-detection.md +0 -64
- package/plugins/lisa/rules/eager/repo-scope-split.md +0 -43
- package/plugins/lisa/rules/eager/reset-seed-coverage.md +0 -50
- package/plugins/lisa/rules/eager/usage-accounting.md +0 -33
- package/plugins/lisa/rules/eager/work-item-definition-of-ready.md +0 -27
- package/plugins/lisa-copilot/rules/eager/automation-runbook-contract.md +0 -92
- package/plugins/lisa-copilot/rules/eager/bdd-e2e-coverage.md +0 -51
- package/plugins/lisa-copilot/rules/eager/blocker-containment.md +0 -53
- package/plugins/lisa-copilot/rules/eager/claim-archaeology.md +0 -37
- package/plugins/lisa-copilot/rules/eager/claim-evidence-mapping.md +0 -78
- package/plugins/lisa-copilot/rules/eager/claim-time-guards.md +0 -32
- package/plugins/lisa-copilot/rules/eager/control-reachability.md +0 -39
- package/plugins/lisa-copilot/rules/eager/convergent-review.md +0 -24
- package/plugins/lisa-copilot/rules/eager/credential-substrate-precedence.md +0 -54
- package/plugins/lisa-copilot/rules/eager/dependency-decision-records.md +0 -32
- package/plugins/lisa-copilot/rules/eager/dependency-internalization-kit.md +0 -42
- package/plugins/lisa-copilot/rules/eager/dependency-trust-classes.md +0 -43
- package/plugins/lisa-copilot/rules/eager/deployed-state-readback.md +0 -47
- package/plugins/lisa-copilot/rules/eager/derived-branch-plan.md +0 -47
- package/plugins/lisa-copilot/rules/eager/design-source-of-truth.md +0 -38
- package/plugins/lisa-copilot/rules/eager/design-value-binding.md +0 -98
- package/plugins/lisa-copilot/rules/eager/documentation-source-paths.md +0 -13
- package/plugins/lisa-copilot/rules/eager/factory-model.md +0 -41
- package/plugins/lisa-copilot/rules/eager/leaf-only-lifecycle.md +0 -70
- package/plugins/lisa-copilot/rules/eager/observability-audit.md +0 -15
- package/plugins/lisa-copilot/rules/eager/prd-definition-of-ready.md +0 -32
- package/plugins/lisa-copilot/rules/eager/prd-lifecycle-rollup.md +0 -31
- package/plugins/lisa-copilot/rules/eager/pre-flight-autofill.md +0 -84
- package/plugins/lisa-copilot/rules/eager/project-learnings.md +0 -22
- package/plugins/lisa-copilot/rules/eager/promotion-contract.md +0 -18
- package/plugins/lisa-copilot/rules/eager/readiness-rubric.md +0 -58
- package/plugins/lisa-copilot/rules/eager/ready-role-filing.md +0 -29
- package/plugins/lisa-copilot/rules/eager/rejection-detection.md +0 -64
- package/plugins/lisa-copilot/rules/eager/repo-scope-split.md +0 -43
- package/plugins/lisa-copilot/rules/eager/reset-seed-coverage.md +0 -50
- package/plugins/lisa-copilot/rules/eager/usage-accounting.md +0 -33
- package/plugins/lisa-copilot/rules/eager/work-item-definition-of-ready.md +0 -27
- package/plugins/lisa-cursor/rules/automation-runbook-contract.mdc +0 -97
- package/plugins/lisa-cursor/rules/bdd-e2e-coverage.mdc +0 -56
- package/plugins/lisa-cursor/rules/blocker-containment.mdc +0 -58
- package/plugins/lisa-cursor/rules/claim-archaeology.mdc +0 -42
- package/plugins/lisa-cursor/rules/claim-evidence-mapping.mdc +0 -83
- package/plugins/lisa-cursor/rules/claim-time-guards.mdc +0 -37
- package/plugins/lisa-cursor/rules/control-reachability.mdc +0 -44
- package/plugins/lisa-cursor/rules/convergent-review.mdc +0 -29
- package/plugins/lisa-cursor/rules/credential-substrate-precedence.mdc +0 -59
- package/plugins/lisa-cursor/rules/dependency-decision-records.mdc +0 -37
- package/plugins/lisa-cursor/rules/dependency-internalization-kit.mdc +0 -47
- package/plugins/lisa-cursor/rules/dependency-trust-classes.mdc +0 -48
- package/plugins/lisa-cursor/rules/deployed-state-readback.mdc +0 -52
- package/plugins/lisa-cursor/rules/derived-branch-plan.mdc +0 -52
- package/plugins/lisa-cursor/rules/design-source-of-truth.mdc +0 -43
- package/plugins/lisa-cursor/rules/design-value-binding.mdc +0 -103
- package/plugins/lisa-cursor/rules/documentation-source-paths.mdc +0 -18
- package/plugins/lisa-cursor/rules/factory-model.mdc +0 -46
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle.mdc +0 -75
- package/plugins/lisa-cursor/rules/observability-audit.mdc +0 -20
- package/plugins/lisa-cursor/rules/prd-definition-of-ready.mdc +0 -37
- package/plugins/lisa-cursor/rules/prd-lifecycle-rollup.mdc +0 -36
- package/plugins/lisa-cursor/rules/pre-flight-autofill.mdc +0 -89
- package/plugins/lisa-cursor/rules/project-learnings.mdc +0 -27
- package/plugins/lisa-cursor/rules/promotion-contract.mdc +0 -23
- package/plugins/lisa-cursor/rules/readiness-rubric.mdc +0 -63
- package/plugins/lisa-cursor/rules/ready-role-filing.mdc +0 -34
- package/plugins/lisa-cursor/rules/rejection-detection.mdc +0 -69
- package/plugins/lisa-cursor/rules/repo-scope-split.mdc +0 -48
- package/plugins/lisa-cursor/rules/reset-seed-coverage.mdc +0 -55
- package/plugins/lisa-cursor/rules/usage-accounting.mdc +0 -38
- package/plugins/lisa-cursor/rules/work-item-definition-of-ready.mdc +0 -32
- package/plugins/src/base/rules/eager/automation-runbook-contract.md +0 -92
- package/plugins/src/base/rules/eager/bdd-e2e-coverage.md +0 -51
- package/plugins/src/base/rules/eager/blocker-containment.md +0 -53
- package/plugins/src/base/rules/eager/claim-archaeology.md +0 -37
- package/plugins/src/base/rules/eager/claim-evidence-mapping.md +0 -78
- package/plugins/src/base/rules/eager/claim-time-guards.md +0 -32
- package/plugins/src/base/rules/eager/control-reachability.md +0 -39
- package/plugins/src/base/rules/eager/convergent-review.md +0 -24
- package/plugins/src/base/rules/eager/credential-substrate-precedence.md +0 -54
- package/plugins/src/base/rules/eager/dependency-decision-records.md +0 -32
- package/plugins/src/base/rules/eager/dependency-internalization-kit.md +0 -42
- package/plugins/src/base/rules/eager/dependency-trust-classes.md +0 -43
- package/plugins/src/base/rules/eager/deployed-state-readback.md +0 -47
- package/plugins/src/base/rules/eager/derived-branch-plan.md +0 -47
- package/plugins/src/base/rules/eager/design-source-of-truth.md +0 -38
- package/plugins/src/base/rules/eager/design-value-binding.md +0 -98
- package/plugins/src/base/rules/eager/documentation-source-paths.md +0 -13
- package/plugins/src/base/rules/eager/factory-model.md +0 -41
- package/plugins/src/base/rules/eager/leaf-only-lifecycle.md +0 -70
- package/plugins/src/base/rules/eager/observability-audit.md +0 -15
- package/plugins/src/base/rules/eager/prd-definition-of-ready.md +0 -32
- package/plugins/src/base/rules/eager/prd-lifecycle-rollup.md +0 -31
- package/plugins/src/base/rules/eager/pre-flight-autofill.md +0 -84
- package/plugins/src/base/rules/eager/project-learnings.md +0 -22
- package/plugins/src/base/rules/eager/promotion-contract.md +0 -18
- package/plugins/src/base/rules/eager/readiness-rubric.md +0 -58
- package/plugins/src/base/rules/eager/ready-role-filing.md +0 -29
- package/plugins/src/base/rules/eager/rejection-detection.md +0 -64
- package/plugins/src/base/rules/eager/repo-scope-split.md +0 -43
- package/plugins/src/base/rules/eager/reset-seed-coverage.md +0 -50
- package/plugins/src/base/rules/eager/usage-accounting.md +0 -33
- package/plugins/src/base/rules/eager/work-item-definition-of-ready.md +0 -27
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"force": {
|
|
3
3
|
"scripts": {
|
|
4
|
+
"prepare": "$npm_execpath run build && husky install || true",
|
|
4
5
|
"prepublishOnly": "$npm_execpath run build",
|
|
5
6
|
"setup:deploy-key": "setup-deploy-key",
|
|
6
|
-
"test": "lisa-test-run --profile npm-package --adapter vitest -- vitest run",
|
|
7
|
-
"test:unit": "lisa-test-run --profile npm-package --adapter vitest -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
7
|
+
"test:cov:lisa": "lisa-test-run --profile npm-package --adapter vitest -- vitest run --coverage",
|
|
8
|
+
"test:cov:unit:lisa": "LISA_COVERAGE_SCOPE=unit lisa-test-run --profile npm-package --adapter vitest -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
8
9
|
"test:integration:lisa": "lisa-test-run --profile npm-package --adapter vitest -- vitest run '.integration.' 'integration/'",
|
|
9
|
-
"test:
|
|
10
|
-
"test:cov:unit": "LISA_COVERAGE_SCOPE=unit lisa-test-run --profile npm-package --adapter vitest -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
10
|
+
"test:lisa": "lisa-test-run --profile npm-package --adapter vitest -- vitest run",
|
|
11
11
|
"test:mutation": "LISA_TEST_SCRATCH_PREFIXES='[\"lisa-mutation-\",\"worker-\"]' lisa-test-run --profile npm-package --adapter direct -- node scripts/lisa-mutation.mjs",
|
|
12
|
-
"test:watch": "lisa-test-run --profile npm-package --adapter vitest -- vitest",
|
|
13
12
|
"test:node": "LISA_TEST_SCRATCH_PREFIXES='[\"node-\"]' lisa-test-run --profile npm-package --adapter direct -- node scripts/lisa-test-node.mjs",
|
|
14
|
-
"
|
|
13
|
+
"test:unit:lisa": "lisa-test-run --profile npm-package --adapter vitest -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
14
|
+
"test:watch:lisa": "lisa-test-run --profile npm-package --adapter vitest -- vitest"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"vite": "^8.0.16",
|
|
@@ -29,6 +29,42 @@
|
|
|
29
29
|
"files": [
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
|
-
"types": "./dist/index.d.ts"
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"scripts": {
|
|
34
|
+
"test": "$npm_execpath run test:lisa",
|
|
35
|
+
"test:cov": "$npm_execpath run test:cov:lisa",
|
|
36
|
+
"test:cov:unit": "$npm_execpath run test:cov:unit:lisa",
|
|
37
|
+
"test:unit": "$npm_execpath run test:unit:lisa",
|
|
38
|
+
"test:watch": "$npm_execpath run test:watch:lisa"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"adopt": {
|
|
42
|
+
"scripts": {
|
|
43
|
+
"test": [
|
|
44
|
+
"lisa-test-run --profile npm-package --adapter vitest -- vitest run",
|
|
45
|
+
"lisa-test-run --profile npm-package -- vitest run",
|
|
46
|
+
"lisa-test-run -- vitest run"
|
|
47
|
+
],
|
|
48
|
+
"test:cov": [
|
|
49
|
+
"lisa-test-run --profile npm-package --adapter vitest -- vitest run --coverage",
|
|
50
|
+
"lisa-test-run --profile npm-package -- vitest run --coverage",
|
|
51
|
+
"lisa-test-run -- vitest run --coverage"
|
|
52
|
+
],
|
|
53
|
+
"test:cov:unit": [
|
|
54
|
+
"LISA_COVERAGE_SCOPE=unit lisa-test-run --profile npm-package --adapter vitest -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
55
|
+
"LISA_COVERAGE_SCOPE=unit lisa-test-run --profile npm-package -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
56
|
+
"LISA_COVERAGE_SCOPE=unit lisa-test-run -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'"
|
|
57
|
+
],
|
|
58
|
+
"test:unit": [
|
|
59
|
+
"lisa-test-run --profile npm-package --adapter vitest -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
60
|
+
"lisa-test-run --profile npm-package -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
61
|
+
"lisa-test-run -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'"
|
|
62
|
+
],
|
|
63
|
+
"test:watch": [
|
|
64
|
+
"lisa-test-run --profile npm-package --adapter vitest -- vitest",
|
|
65
|
+
"lisa-test-run --profile npm-package -- vitest",
|
|
66
|
+
"lisa-test-run -- vitest"
|
|
67
|
+
]
|
|
68
|
+
}
|
|
33
69
|
}
|
|
34
70
|
}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"lisa-test-run": "bun run build && node dist/cli/lisa-test-run.js --profile lisa",
|
|
7
7
|
"test:integration": "$npm_execpath run lisa-test-run -- --adapter vitest -- vitest run tests/integration",
|
|
8
8
|
"test:integration:push": "$npm_execpath run lisa-test-run -- --adapter vitest -- vitest run tests/integration --exclude='**/mutation-gate-bite.test.ts' --exclude='**/mutation-gate-diff-bite.test.ts' --exclude='**/mutation-sigterm-control.test.ts' --exclude='**/mutation-performance-fixture.test.ts' --exclude='**/mutation-performance-packed-apply.test.ts'",
|
|
9
|
-
"postinstall": "bash ./scripts/install-claude-plugins.sh || true; node ./scripts/install-generated-artifact-merge-driver.mjs || true; tsc || true",
|
|
9
|
+
"postinstall": "bash ./scripts/install-claude-plugins.sh || true; node ./scripts/install-generated-artifact-merge-driver.mjs || true; [ ! -f tsconfig.json ] || tsc -p tsconfig.json || true",
|
|
10
10
|
"pretest": "bun run build",
|
|
11
11
|
"test": "$npm_execpath run lisa-test-run -- --adapter vitest -- vitest run",
|
|
12
12
|
"test:unit": "$npm_execpath run lisa-test-run -- --adapter vitest -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
@@ -52,12 +52,14 @@
|
|
|
52
52
|
"check:upstream-evidence-manifest": "node scripts/generate-upstream-evidence-manifest.mjs --check",
|
|
53
53
|
"build:lisa-owned-hash-ledger": "node scripts/generate-lisa-owned-hash-ledger.mjs",
|
|
54
54
|
"check:lisa-owned-hash-ledger": "node scripts/generate-lisa-owned-hash-ledger.mjs --check",
|
|
55
|
+
"build:export-surface": "node scripts/generate-export-surface.mjs",
|
|
56
|
+
"check:export-surface": "node scripts/generate-export-surface.mjs --check",
|
|
55
57
|
"build:nightly-guard-certificate": "node scripts/generate-nightly-e2e-guard-certificate.mjs",
|
|
56
58
|
"check:nightly-guard-certificate": "node scripts/generate-nightly-e2e-guard-certificate.mjs --check",
|
|
57
59
|
"generate:two-channel-couplings": "bun scripts/generate-two-channel-couplings.ts",
|
|
58
60
|
"check:two-channel-couplings": "bun scripts/generate-two-channel-couplings.ts --check",
|
|
59
61
|
"check:deletion-basis": "node scripts/check-deletion-basis.mjs",
|
|
60
|
-
"check:artifacts": "node scripts/run-artifact-checks.mjs check:upstream-evidence-manifest check:lisa-owned-hash-ledger check:nightly-guard-certificate check:two-channel-couplings check:deletion-basis check:merge-coverage",
|
|
62
|
+
"check:artifacts": "node scripts/run-artifact-checks.mjs check:upstream-evidence-manifest check:lisa-owned-hash-ledger check:nightly-guard-certificate check:two-channel-couplings check:deletion-basis check:export-surface check:merge-coverage",
|
|
61
63
|
"refresh:upstream-public-commits": "node scripts/generate-upstream-evidence-manifest.mjs --refresh-public-commits",
|
|
62
64
|
"check:rules-pairing": "bash scripts/check-rules-pairing.sh",
|
|
63
65
|
"check:pipeline-status-reads": "node scripts/check-pipeline-status-reads.mjs",
|
|
@@ -77,6 +79,7 @@
|
|
|
77
79
|
"check:third-party-action-pins": "node scripts/check-third-party-action-pins.mjs",
|
|
78
80
|
"check:workflow-package-paths": "node scripts/check-workflow-package-paths.mjs",
|
|
79
81
|
"check:delivery-deletion-conflicts": "node scripts/check-delivery-deletion-conflicts.mjs",
|
|
82
|
+
"check:shipped-surface-removals": "node scripts/check-shipped-surface-removals.mjs",
|
|
80
83
|
"check:duplicate-versions": "node scripts/check-duplicate-versions.mjs",
|
|
81
84
|
"check:required-check-promotions": "node scripts/check-required-check-promotions.mjs",
|
|
82
85
|
"check:self-pin": "node scripts/check-self-dependency-pin.mjs",
|
|
@@ -92,7 +95,8 @@
|
|
|
92
95
|
"verify:health-consumer": "bun run build:dist && node scripts/verify-health-consumer-built.mjs",
|
|
93
96
|
"measure:tmpdir-growth": "node scripts/measure-tmpdir-growth.mjs",
|
|
94
97
|
"lint:staged": "lint-staged --config .lintstagedrc.json",
|
|
95
|
-
"check:merge-coverage": "node scripts/check-generated-artifact-merge-coverage.mjs"
|
|
98
|
+
"check:merge-coverage": "node scripts/check-generated-artifact-merge-coverage.mjs",
|
|
99
|
+
"check:eager-rule-budget": "node scripts/check-eager-rule-budget.mjs"
|
|
96
100
|
},
|
|
97
101
|
"engines": {
|
|
98
102
|
"npm": "please-use-bun",
|
|
@@ -176,7 +180,7 @@
|
|
|
176
180
|
"zod-validation-error": "^4.0.0"
|
|
177
181
|
},
|
|
178
182
|
"name": "@codyswann/lisa",
|
|
179
|
-
"version": "4.
|
|
183
|
+
"version": "4.50.1",
|
|
180
184
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
181
185
|
"main": "dist/index.js",
|
|
182
186
|
"exports": {
|
|
@@ -324,7 +328,7 @@
|
|
|
324
328
|
"test": "tests"
|
|
325
329
|
},
|
|
326
330
|
"types": "./dist/index.d.ts",
|
|
327
|
-
"lisaReleaseCommit": "
|
|
328
|
-
"gitHead": "
|
|
329
|
-
"lisaReleaseTag": "v4.
|
|
331
|
+
"lisaReleaseCommit": "41dfd4ab241a37ba5bb16442205e808f8375e232",
|
|
332
|
+
"gitHead": "41dfd4ab241a37ba5bb16442205e808f8375e232",
|
|
333
|
+
"lisaReleaseTag": "v4.50.1"
|
|
330
334
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
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
|
+
|
|
4
|
+
id: no-day-truncating-file-age-predicate
|
|
5
|
+
language: bash
|
|
6
|
+
severity: error
|
|
7
|
+
message: |
|
|
8
|
+
`-mtime`, `-atime` and `-ctime` do NOT mean "older than N days".
|
|
9
|
+
|
|
10
|
+
`find` divides the file's age by 86400 and DISCARDS the remainder, so
|
|
11
|
+
`-mtime +N` matches only files older than N+1 days. Measured on this
|
|
12
|
+
repository's own platform with fixtures stamped at known ages:
|
|
13
|
+
|
|
14
|
+
age -mtime +2 -mmin +2880
|
|
15
|
+
47h no no
|
|
16
|
+
49h NO yes <- the whole disagreement
|
|
17
|
+
71h NO yes
|
|
18
|
+
73h yes yes
|
|
19
|
+
|
|
20
|
+
The 49h-71h band is silently dropped. The failure direction is what makes
|
|
21
|
+
this worth a rule: the under-selection reports "nothing to do", and nobody
|
|
22
|
+
questions an empty result from a cleanup predicate, so it prevents needed
|
|
23
|
+
work instead of causing visible harm. Reported once as a broken `find`; it
|
|
24
|
+
is not. `find` is answering a different question than the flag appears to
|
|
25
|
+
ask, which is exactly why it survives review.
|
|
26
|
+
|
|
27
|
+
Write the question you mean:
|
|
28
|
+
|
|
29
|
+
older than N days -> -mmin +$((N * 1440))
|
|
30
|
+
older than N days -> ! -newermt "<an ISO timestamp N days back>"
|
|
31
|
+
older than N hours -> -mmin +$((N * 60))
|
|
32
|
+
|
|
33
|
+
`-mmin` is minute-granularity and is not truncated to days, so it means
|
|
34
|
+
what it reads. `-newermt` is exact but needs a timestamp, and the two
|
|
35
|
+
`date` implementations disagree on how to produce one: `date -v-2d` is
|
|
36
|
+
BSD/macOS and `date -d '2 days ago'` is GNU/Linux. Prefer `-mmin` in any
|
|
37
|
+
script that runs on both.
|
|
38
|
+
note: |
|
|
39
|
+
This rule matches the flag itself rather than a `find` invocation, so it
|
|
40
|
+
still fires through `/usr/bin/find`, `$FIND`, and `xargs find`. There are
|
|
41
|
+
no legitimate uses in this repository: every shipped age predicate already
|
|
42
|
+
uses `-mmin`, and this rule exists to keep it that way, because `-mtime` is
|
|
43
|
+
the form a maintainer reaches for by reflex and the shell hooks that carry
|
|
44
|
+
these predicates are copied across five per-agent plugin variants, so one
|
|
45
|
+
wrong edit lands in eight files at once.
|
|
46
|
+
|
|
47
|
+
See CodySwannGT/lisa#3905.
|
|
48
|
+
rule:
|
|
49
|
+
kind: word
|
|
50
|
+
regex: ^-(mtime|atime|ctime)$
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"force": {
|
|
3
3
|
"scripts": {
|
|
4
|
-
"setup:deploy-key": "setup-deploy-key",
|
|
5
|
-
"typecheck:lisa": "tsc --noEmit",
|
|
6
|
-
"test": "lisa-test-run --profile phaser --adapter vitest -- vitest run",
|
|
7
|
-
"test:unit": "lisa-test-run --profile phaser --adapter vitest -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
8
|
-
"test:integration:lisa": "lisa-test-run --profile phaser --adapter vitest -- vitest run '.integration.' 'integration/'",
|
|
9
|
-
"test:cov": "lisa-test-run --profile phaser --adapter vitest -- vitest run --coverage",
|
|
10
|
-
"test:cov:unit": "LISA_COVERAGE_SCOPE=unit lisa-test-run --profile phaser --adapter vitest -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
11
|
-
"test:mutation": "LISA_TEST_SCRATCH_PREFIXES='[\"lisa-mutation-\",\"worker-\"]' lisa-test-run --profile phaser --adapter direct -- node scripts/lisa-mutation.mjs",
|
|
12
|
-
"test:watch": "lisa-test-run --profile phaser --adapter vitest -- vitest",
|
|
13
|
-
"test:e2e": "lisa-test-run --profile phaser --adapter direct -- playwright test",
|
|
14
|
-
"lint:lisa": "oxlint && eslint . --quiet",
|
|
15
|
-
"lint:fix": "oxlint --fix && eslint . --fix",
|
|
16
|
-
"lint:slow:lisa": "eslint . --config eslint.slow.config.ts --quiet",
|
|
17
|
-
"format:check:lisa": "prettier --check .",
|
|
18
4
|
"format": "prettier --write .",
|
|
5
|
+
"format:check:lisa": "prettier --check .",
|
|
19
6
|
"knip:check:lisa": "knip",
|
|
20
7
|
"knip:fix": "knip --fix",
|
|
8
|
+
"lint:fix": "oxlint --fix && eslint . --fix",
|
|
9
|
+
"lint:lisa": "oxlint && eslint . --quiet",
|
|
10
|
+
"lint:slow:lisa": "eslint . --config eslint.slow.config.ts --quiet",
|
|
11
|
+
"prepare": "husky install || true",
|
|
12
|
+
"setup:deploy-key": "setup-deploy-key",
|
|
21
13
|
"sg:scan:lisa": "ast-grep scan",
|
|
22
14
|
"sg:test": "ast-grep test",
|
|
23
|
-
"
|
|
24
|
-
"test:
|
|
15
|
+
"test:cov:lisa": "lisa-test-run --profile phaser --adapter vitest -- vitest run --coverage",
|
|
16
|
+
"test:cov:unit:lisa": "LISA_COVERAGE_SCOPE=unit lisa-test-run --profile phaser --adapter vitest -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
17
|
+
"test:e2e": "lisa-test-run --profile phaser --adapter direct -- playwright test",
|
|
18
|
+
"test:integration:lisa": "lisa-test-run --profile phaser --adapter vitest -- vitest run '.integration.' 'integration/'",
|
|
19
|
+
"test:lisa": "lisa-test-run --profile phaser --adapter vitest -- vitest run",
|
|
20
|
+
"test:mutation": "LISA_TEST_SCRATCH_PREFIXES='[\"lisa-mutation-\",\"worker-\"]' lisa-test-run --profile phaser --adapter direct -- node scripts/lisa-mutation.mjs",
|
|
21
|
+
"test:node": "LISA_TEST_SCRATCH_PREFIXES='[\"node-\"]' lisa-test-run --profile phaser --adapter direct -- node scripts/lisa-test-node.mjs",
|
|
22
|
+
"test:unit:lisa": "lisa-test-run --profile phaser --adapter vitest -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
23
|
+
"test:watch:lisa": "lisa-test-run --profile phaser --adapter vitest -- vitest",
|
|
24
|
+
"typecheck:lisa": "tsc --noEmit"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@ast-grep/cli": "^0.40.4",
|
|
@@ -80,17 +80,22 @@
|
|
|
80
80
|
},
|
|
81
81
|
"defaults": {
|
|
82
82
|
"scripts": {
|
|
83
|
-
"dev": "vite",
|
|
84
83
|
"build": "vite build",
|
|
85
|
-
"
|
|
86
|
-
"test:e2e": "playwright test",
|
|
87
|
-
"size": "size-limit",
|
|
88
|
-
"typecheck": "$npm_execpath run typecheck:lisa",
|
|
89
|
-
"lint": "$npm_execpath run lint:lisa",
|
|
90
|
-
"lint:slow": "$npm_execpath run lint:slow:lisa",
|
|
84
|
+
"dev": "vite",
|
|
91
85
|
"format:check": "$npm_execpath run format:check:lisa",
|
|
92
86
|
"knip:check": "$npm_execpath run knip:check:lisa",
|
|
93
|
-
"
|
|
87
|
+
"lint": "$npm_execpath run lint:lisa",
|
|
88
|
+
"lint:slow": "$npm_execpath run lint:slow:lisa",
|
|
89
|
+
"preview": "vite preview",
|
|
90
|
+
"sg:scan": "$npm_execpath run sg:scan:lisa",
|
|
91
|
+
"size": "size-limit",
|
|
92
|
+
"test": "$npm_execpath run test:lisa",
|
|
93
|
+
"test:cov": "$npm_execpath run test:cov:lisa",
|
|
94
|
+
"test:cov:unit": "$npm_execpath run test:cov:unit:lisa",
|
|
95
|
+
"test:e2e": "playwright test",
|
|
96
|
+
"test:unit": "$npm_execpath run test:unit:lisa",
|
|
97
|
+
"test:watch": "$npm_execpath run test:watch:lisa",
|
|
98
|
+
"typecheck": "$npm_execpath run typecheck:lisa"
|
|
94
99
|
},
|
|
95
100
|
"dependencies": {
|
|
96
101
|
"phaser": "^4.2.0"
|
|
@@ -113,8 +118,11 @@
|
|
|
113
118
|
},
|
|
114
119
|
"adopt": {
|
|
115
120
|
"scripts": {
|
|
116
|
-
"
|
|
117
|
-
"
|
|
121
|
+
"format:check": [
|
|
122
|
+
"prettier --check ."
|
|
123
|
+
],
|
|
124
|
+
"knip:check": [
|
|
125
|
+
"knip"
|
|
118
126
|
],
|
|
119
127
|
"lint": [
|
|
120
128
|
"oxlint && eslint . --quiet",
|
|
@@ -123,14 +131,36 @@
|
|
|
123
131
|
"lint:slow": [
|
|
124
132
|
"eslint . --config eslint.slow.config.ts --quiet"
|
|
125
133
|
],
|
|
126
|
-
"format:check": [
|
|
127
|
-
"prettier --check ."
|
|
128
|
-
],
|
|
129
|
-
"knip:check": [
|
|
130
|
-
"knip"
|
|
131
|
-
],
|
|
132
134
|
"sg:scan": [
|
|
133
135
|
"ast-grep scan"
|
|
136
|
+
],
|
|
137
|
+
"test": [
|
|
138
|
+
"lisa-test-run --profile phaser --adapter vitest -- vitest run",
|
|
139
|
+
"lisa-test-run --profile phaser -- vitest run",
|
|
140
|
+
"lisa-test-run -- vitest run"
|
|
141
|
+
],
|
|
142
|
+
"test:cov": [
|
|
143
|
+
"lisa-test-run --profile phaser --adapter vitest -- vitest run --coverage",
|
|
144
|
+
"lisa-test-run --profile phaser -- vitest run --coverage",
|
|
145
|
+
"lisa-test-run -- vitest run --coverage"
|
|
146
|
+
],
|
|
147
|
+
"test:cov:unit": [
|
|
148
|
+
"LISA_COVERAGE_SCOPE=unit lisa-test-run --profile phaser --adapter vitest -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
149
|
+
"LISA_COVERAGE_SCOPE=unit lisa-test-run --profile phaser -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
150
|
+
"LISA_COVERAGE_SCOPE=unit lisa-test-run -- vitest run --coverage --exclude='**/integration/**' --exclude='**/*.integration.*'"
|
|
151
|
+
],
|
|
152
|
+
"test:unit": [
|
|
153
|
+
"lisa-test-run --profile phaser --adapter vitest -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
154
|
+
"lisa-test-run --profile phaser -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'",
|
|
155
|
+
"lisa-test-run -- vitest run --exclude='**/integration/**' --exclude='**/*.integration.*'"
|
|
156
|
+
],
|
|
157
|
+
"test:watch": [
|
|
158
|
+
"lisa-test-run --profile phaser --adapter vitest -- vitest",
|
|
159
|
+
"lisa-test-run --profile phaser -- vitest",
|
|
160
|
+
"lisa-test-run -- vitest"
|
|
161
|
+
],
|
|
162
|
+
"typecheck": [
|
|
163
|
+
"tsc --noEmit"
|
|
134
164
|
]
|
|
135
165
|
}
|
|
136
166
|
}
|
|
@@ -1136,10 +1136,26 @@ not there, and a lifecycle step performed by hand is one nothing can verify
|
|
|
1136
1136
|
happened.
|
|
1137
1137
|
|
|
1138
1138
|
**The backstop, for the ones that still slip:** `lisa-work-item.mjs sweep`
|
|
1139
|
-
reports every
|
|
1139
|
+
reports every open item — in the **ready** lane as well as the **claimed** one —
|
|
1140
|
+
that a commit on a deploy branch DECLARES via its `Work-Item:` trailer, and
|
|
1140
1141
|
`--apply` completes them. Reporting is the default deliberately — a sweep that
|
|
1141
1142
|
closes things as a side effect of being run is not one anyone runs twice.
|
|
1142
1143
|
|
|
1144
|
+
You do not need to run it. The `🧹 Lifecycle Drift Sweep` workflow runs it
|
|
1145
|
+
daily and files a deduplicated issue when drift exists, because a report with
|
|
1146
|
+
no consumer and no report are the same thing with different amounts of code.
|
|
1147
|
+
|
|
1148
|
+
Two properties worth knowing, because both were once the other way round:
|
|
1149
|
+
|
|
1150
|
+
- **Credit requires a declaration, never a mention.** Evidence is a commit
|
|
1151
|
+
reachable from a deploy branch whose own trailer names the item. It used to
|
|
1152
|
+
be a timeline cross-reference, which any pull request that so much as *named*
|
|
1153
|
+
`#N` created — so one merged land-stack pull request made every sibling in
|
|
1154
|
+
its batch look shipped. Measured: 8 of 53 reported items had no commit
|
|
1155
|
+
declaring them, and every one of the 8 had live work open against it.
|
|
1156
|
+
- **A clean result names the lanes it examined.** "No drift" over a subject
|
|
1157
|
+
list that excluded the ready lane was true and unusable.
|
|
1158
|
+
|
|
1143
1159
|
## 4. Terminal states
|
|
1144
1160
|
|
|
1145
1161
|
Loop until one of:
|
|
@@ -332,6 +332,10 @@ other gate's verdict — however conclusive — may promote an item a person par
|
|
|
332
332
|
4. **Name it in the cycle summary** via `summarizeHumanGateHolds([...])`, so the record
|
|
333
333
|
distinguishes "nothing was eligible" from "something eligible was held for a person". A lane
|
|
334
334
|
mutation nobody can see afterwards is the same class of problem this gate exists to fix.
|
|
335
|
+
Report alongside it what the precision rule SKIPPED, via `summarizeHumanGateMentions(n)`
|
|
336
|
+
— the marker occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815).
|
|
337
|
+
A rule that quietly declines to honour half the occurrences it sees reads exactly like a
|
|
338
|
+
rule that saw none, so the count is printed even when it is zero.
|
|
335
339
|
5. **Continue to the next candidate.** A held item does not end the cycle.
|
|
336
340
|
|
|
337
341
|
|
|
@@ -237,6 +237,10 @@ other gate's verdict — however conclusive — may promote an item a person par
|
|
|
237
237
|
4. **Name it in the cycle summary** via `summarizeHumanGateHolds([...])`, so the record
|
|
238
238
|
distinguishes "nothing was eligible" from "something eligible was held for a person". A lane
|
|
239
239
|
mutation nobody can see afterwards is the same class of problem this gate exists to fix.
|
|
240
|
+
Report alongside it what the precision rule SKIPPED, via `summarizeHumanGateMentions(n)`
|
|
241
|
+
— the marker occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815).
|
|
242
|
+
A rule that quietly declines to honour half the occurrences it sees reads exactly like a
|
|
243
|
+
rule that saw none, so the count is printed even when it is zero.
|
|
240
244
|
5. **Continue to the next candidate.** A held item does not end the cycle.
|
|
241
245
|
|
|
242
246
|
|
|
@@ -231,6 +231,10 @@ other gate's verdict — however conclusive — may promote an item a person par
|
|
|
231
231
|
4. **Name it in the cycle summary** via `summarizeHumanGateHolds([...])`, so the record
|
|
232
232
|
distinguishes "nothing was eligible" from "something eligible was held for a person". A lane
|
|
233
233
|
mutation nobody can see afterwards is the same class of problem this gate exists to fix.
|
|
234
|
+
Report alongside it what the precision rule SKIPPED, via `summarizeHumanGateMentions(n)`
|
|
235
|
+
— the marker occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815).
|
|
236
|
+
A rule that quietly declines to honour half the occurrences it sees reads exactly like a
|
|
237
|
+
rule that saw none, so the count is printed even when it is zero.
|
|
234
238
|
5. **Continue to the next candidate.** A held item does not end the cycle.
|
|
235
239
|
|
|
236
240
|
|
|
@@ -994,7 +994,10 @@ with labels like `build-ready`, or with no Lisa status label at all, that are in
|
|
|
994
994
|
instead — it says that nothing was changed and how a person resumes the item, which is the
|
|
995
995
|
opposite of what the reconciliation note says and must not be substituted for it. A promotion
|
|
996
996
|
declined silently is invisible, which is the quieter version of the failure this step exists to
|
|
997
|
-
prevent, so name every held item in the cycle summary via `summarizeHumanGateHolds([...])`.
|
|
997
|
+
prevent, so name every held item in the cycle summary via `summarizeHumanGateHolds([...])`. Report what the
|
|
998
|
+
precision rule skipped beside it via `summarizeHumanGateMentions(n)`: the marker
|
|
999
|
+
occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815),
|
|
1000
|
+
because a rule that silently drops candidates reads like one that found none.
|
|
998
1001
|
|
|
999
1002
|
### Ungated non-ready filing → surface as an incomplete handoff (read-only)
|
|
1000
1003
|
|
|
@@ -494,6 +494,82 @@ project_dir = os.environ.get("LISA_GUARD_PROJECT_DIR", "")
|
|
|
494
494
|
OVERRIDE_NAME = "LISA_ALLOW_DIRECT_ISSUE_CREATE"
|
|
495
495
|
HUMAN_GATE_MARKER = "[lisa-human-gate]"
|
|
496
496
|
|
|
497
|
+
# Decoration a hold declaration may sit behind, and nothing more: whitespace,
|
|
498
|
+
# blockquote arrows, list bullets or numbers, emphasis, an opening HTML
|
|
499
|
+
# comment. One character class plus two optional groups, deliberately not a
|
|
500
|
+
# nested quantifier — this runs over untrusted issue bodies.
|
|
501
|
+
HUMAN_GATE_DECORATION = re.compile(r"^[ \t>*_+#-]*(?:\d+[.)][ \t]*)?(?:<!--[ \t]*)?[ \t]*")
|
|
502
|
+
HUMAN_GATE_FENCE = re.compile(r"```.*?```", re.DOTALL)
|
|
503
|
+
HUMAN_GATE_CODE_SPAN = re.compile(r"`[^`\n]*`")
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
def declares_human_gate(text):
|
|
507
|
+
"""Whether a text DECLARES a hold rather than mentioning one.
|
|
508
|
+
|
|
509
|
+
The comment this replaces said the marker is matched anywhere because it
|
|
510
|
+
"has no other meaning, so its presence in the title or body IS the
|
|
511
|
+
declaration". That was true when written and is false now: the marker
|
|
512
|
+
acquired a second meaning -- being discussed -- the moment the feature
|
|
513
|
+
became something people file tickets about, and a ticket about the marker
|
|
514
|
+
then declares a hold on itself (CodySwannGT/lisa#3815).
|
|
515
|
+
|
|
516
|
+
A declaration is POSITIONAL: the marker leads its line, behind at most the
|
|
517
|
+
decoration above, with fenced blocks and inline code spans removed first
|
|
518
|
+
because that is how the marker is written ABOUT. The same rule the intake
|
|
519
|
+
matcher applies, so the two surfaces cannot disagree about one body.
|
|
520
|
+
|
|
521
|
+
NOTE the direction here differs from the intake matcher's. There a match
|
|
522
|
+
HOLDS an item, so a false positive parks work. Here a match ADMITS a
|
|
523
|
+
filing, so a false positive is a hole -- which makes this the tightening
|
|
524
|
+
direction on both sides at once.
|
|
525
|
+
|
|
526
|
+
Args:
|
|
527
|
+
text: Any candidate text -- one argv value, a body file, a payload.
|
|
528
|
+
|
|
529
|
+
Returns:
|
|
530
|
+
True when some line of the text declares a hold.
|
|
531
|
+
"""
|
|
532
|
+
if not text:
|
|
533
|
+
return False
|
|
534
|
+
body = HUMAN_GATE_CODE_SPAN.sub("", HUMAN_GATE_FENCE.sub("", str(text)))
|
|
535
|
+
for line in body.split("\n"):
|
|
536
|
+
if HUMAN_GATE_DECORATION.sub("", line, count=1).startswith(
|
|
537
|
+
HUMAN_GATE_MARKER
|
|
538
|
+
):
|
|
539
|
+
return True
|
|
540
|
+
if _comment_carries_marker(line):
|
|
541
|
+
return True
|
|
542
|
+
return False
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
def _comment_carries_marker(line):
|
|
546
|
+
"""Whether an HTML comment on this line carries the marker.
|
|
547
|
+
|
|
548
|
+
The second accepted form, and the one this guard needs most: its inputs
|
|
549
|
+
are not markdown documents. A `--body` value is a single line, and a shell
|
|
550
|
+
script writes its declaration as `# <!-- ... -->`, so a purely
|
|
551
|
+
line-leading rule would refuse two declarations people have already
|
|
552
|
+
written -- both of which are in this repository's own test corpus.
|
|
553
|
+
|
|
554
|
+
It is not a loosening. An HTML comment is invisible when rendered, so
|
|
555
|
+
nobody wraps one around the marker in order to TALK about it; a quotation
|
|
556
|
+
has to be visible to be a quotation. Measured over this repository's 42
|
|
557
|
+
matching issue bodies, adding this branch changes not one verdict.
|
|
558
|
+
|
|
559
|
+
Args:
|
|
560
|
+
line: One line of text.
|
|
561
|
+
|
|
562
|
+
Returns:
|
|
563
|
+
True when some comment on the line contains the marker.
|
|
564
|
+
"""
|
|
565
|
+
segments = line.split("<!--")
|
|
566
|
+
for segment in segments[1:]:
|
|
567
|
+
close = segment.find("-->")
|
|
568
|
+
inside = segment if close == -1 else segment[:close]
|
|
569
|
+
if HUMAN_GATE_MARKER in inside:
|
|
570
|
+
return True
|
|
571
|
+
return False
|
|
572
|
+
|
|
497
573
|
# ---------------------------------------------------------------------------
|
|
498
574
|
# WHY THIS IS A TOKEN SCAN AND NOT A PROGRAM RESOLVER
|
|
499
575
|
#
|
|
@@ -580,7 +656,7 @@ LABEL_FLAGS = {"--label", "--labels", "--add-label", "--status", "--state"}
|
|
|
580
656
|
# None — container: state rolls up from children
|
|
581
657
|
#
|
|
582
658
|
# It is a marker with no other meaning, so it is matched wherever the payload
|
|
583
|
-
# reaches —
|
|
659
|
+
# reaches — the asymmetry `HUMAN_GATE_MARKER` gets, and for the related
|
|
584
660
|
# reason. Reading the declaration the writer already emits is also what keeps
|
|
585
661
|
# the guard and the skill from drifting apart a second time: there is one
|
|
586
662
|
# string, defined in one rule, and both read it.
|
|
@@ -1223,7 +1299,7 @@ def text_declares_readiness(text):
|
|
|
1223
1299
|
Returns:
|
|
1224
1300
|
True when the text declares build-ready or a human gate.
|
|
1225
1301
|
"""
|
|
1226
|
-
if
|
|
1302
|
+
if declares_human_gate(text):
|
|
1227
1303
|
return True
|
|
1228
1304
|
for role in (ready_role, upstream_ready_role, default_ready_role):
|
|
1229
1305
|
if not role:
|
|
@@ -1267,7 +1343,7 @@ def scope_declaration(text, state_role_ok):
|
|
|
1267
1343
|
Returns:
|
|
1268
1344
|
True when the text carries a whole-scope declaration.
|
|
1269
1345
|
"""
|
|
1270
|
-
if
|
|
1346
|
+
if declares_human_gate(text):
|
|
1271
1347
|
return True
|
|
1272
1348
|
return bool(state_role_ok and LIFECYCLE_ROLE_READY.search(text))
|
|
1273
1349
|
|
|
@@ -1497,20 +1573,23 @@ def declares_readiness(raw_args, roles, extra="", state_role_ok=False):
|
|
|
1497
1573
|
candidates = [part.strip().strip("'\"") for part in raw.split(",")]
|
|
1498
1574
|
if role in candidates:
|
|
1499
1575
|
return True
|
|
1500
|
-
#
|
|
1501
|
-
#
|
|
1502
|
-
#
|
|
1503
|
-
#
|
|
1504
|
-
|
|
1576
|
+
# Checked per ARGV VALUE rather than against `" ".join(args)`, and that is
|
|
1577
|
+
# what makes the positional rule mean anything here. Joining first destroys
|
|
1578
|
+
# position: after a join, no value's line start survives except the first
|
|
1579
|
+
# argument's, so "the marker leads its line" would be decided by argument
|
|
1580
|
+
# order. A `--title` value is its own single line, which is exactly the
|
|
1581
|
+
# unit the rule is about -- and titles must keep being read, since this
|
|
1582
|
+
# guard reads them and the intake matcher does not.
|
|
1583
|
+
if any(declares_human_gate(value) for value in args):
|
|
1505
1584
|
return True
|
|
1506
1585
|
for path in body_file_paths(args):
|
|
1507
1586
|
try:
|
|
1508
1587
|
with open(path, encoding="utf-8", errors="replace") as handle:
|
|
1509
|
-
if
|
|
1588
|
+
if declares_human_gate(handle.read()):
|
|
1510
1589
|
return True
|
|
1511
1590
|
except OSError:
|
|
1512
1591
|
continue
|
|
1513
|
-
if extra
|
|
1592
|
+
if declares_human_gate(extra):
|
|
1514
1593
|
return True
|
|
1515
1594
|
# The state-based path. Scoped by `state_role_ok` rather than checked
|
|
1516
1595
|
# unconditionally, so this adds a compliant command where none existed and
|
|
@@ -31,8 +31,14 @@ COMMAND="$(printf '%s' "$JSON_INPUT" | jq -r '.tool_input.command // empty' 2>/d
|
|
|
31
31
|
|
|
32
32
|
# `gh pr create` opens one; `gh pr edit` is the other way a body comes to carry
|
|
33
33
|
# — or lose — its declaration. Both change the answer to gate 4.
|
|
34
|
+
#
|
|
35
|
+
# `gh pr reopen` is here because a work item can hold more than one pull
|
|
36
|
+
# request, and a reopened one is a named case: it was closed, so nothing has
|
|
37
|
+
# discharged its gates since, and it is now live again with no CI run to reveal
|
|
38
|
+
# that. Its backlink no longer displaces anyone else's, so re-running the
|
|
39
|
+
# discharge for it is free (CodySwannGT/lisa#3916).
|
|
34
40
|
case "$COMMAND" in
|
|
35
|
-
*"gh pr create"* | *"gh pr edit"*) ;;
|
|
41
|
+
*"gh pr create"* | *"gh pr edit"* | *"gh pr reopen"*) ;;
|
|
36
42
|
*) exit 0 ;;
|
|
37
43
|
esac
|
|
38
44
|
|
|
@@ -26,6 +26,11 @@
|
|
|
26
26
|
# divergence: upstream blocks unconditionally; Lisa allows clean-tree resets.
|
|
27
27
|
# Residual risk (documented, accepted): the dirty check runs in the hook's
|
|
28
28
|
# cwd at hook time, so a `cd elsewhere && git reset --hard` evades it.
|
|
29
|
+
# - `git read-tree` with an update flag AND `--reset` while the working tree
|
|
30
|
+
# is dirty (issue #3978): the plumbing spelling of the same discard, on the
|
|
31
|
+
# same condition, printing the same remedy. Index-only `read-tree`, and
|
|
32
|
+
# `read-tree -m -u` without `--reset` (which git itself refuses rather than
|
|
33
|
+
# clobber a modified file), stay allowed. Lisa-only guard.
|
|
29
34
|
# - `git rebase --abort`/`--quit` while the in-progress rebase holds
|
|
30
35
|
# human-made conflict resolutions (AUTO_MERGE discriminator; issue #1956).
|
|
31
36
|
# Clean or untouched rebase state stays abortable; the apply backend and a
|
|
@@ -1819,6 +1824,45 @@ $DESTRUCTIVE_GUIDANCE"
|
|
|
1819
1824
|
fi
|
|
1820
1825
|
fi
|
|
1821
1826
|
|
|
1827
|
+
# 3a. `git read-tree` with BOTH an update flag and `--reset`, on the same dirty
|
|
1828
|
+
# tree — the plumbing spelling of guard 3 (issue #3978). It resets the index
|
|
1829
|
+
# and writes the result into the working tree, discarding tracked
|
|
1830
|
+
# modifications: the identical destruction, reached through a command that
|
|
1831
|
+
# carries no `--hard` and no `reset` subcommand, so every pattern in
|
|
1832
|
+
# guard 3 misses it. A guard an agent can walk around is a guard that stops
|
|
1833
|
+
# the honest caller and not the one looking for a way through, and this
|
|
1834
|
+
# spelling is strictly worse than the blocked one — it discards WITHOUT
|
|
1835
|
+
# preserving, which is exactly the property guard 3's remedy supplies. Both
|
|
1836
|
+
# refusals therefore print the same $PRESERVE_GUIDANCE, so what they teach
|
|
1837
|
+
# cannot drift apart.
|
|
1838
|
+
#
|
|
1839
|
+
# `--reset` is the discriminator, not `-u`, and the pairing is deliberate:
|
|
1840
|
+
#
|
|
1841
|
+
# - `read-tree` with no update flag touches the INDEX only and destroys
|
|
1842
|
+
# nothing in the working tree, so a blanket `read-tree` block would be
|
|
1843
|
+
# over-broad.
|
|
1844
|
+
# - `read-tree -m -u` (a merge without `--reset`) is safe by git's own
|
|
1845
|
+
# construction: it REFUSES rather than overwrite a locally modified file
|
|
1846
|
+
# ("entry would be overwritten by merge"). `--reset` is precisely the flag
|
|
1847
|
+
# that switches that refusal off.
|
|
1848
|
+
#
|
|
1849
|
+
# So the destructive combination is an update flag AND `--reset` together,
|
|
1850
|
+
# in either order. The update flag is matched in the checkout guard's idiom
|
|
1851
|
+
# so a bundled short option (`-iu`) cannot dodge the anchor, with leading
|
|
1852
|
+
# whitespace required so a `--index-output=/tmp/out-u` style value cannot
|
|
1853
|
+
# read as the flag. Same conditional dirty-tree shape and same accepted
|
|
1854
|
+
# residual risk as guard 3: the probe runs in the hook's cwd at hook time.
|
|
1855
|
+
readonly GIT_READ_TREE="${GIT_CMD}read-tree"
|
|
1856
|
+
if matches "${GIT_READ_TREE}"'[^;&|]*[[:space:]]--reset([[:space:]]|$)' \
|
|
1857
|
+
&& matches "${GIT_READ_TREE}"'[^;&|]*[[:space:]](-[[:alnum:]]*u[[:alnum:]]*|--update)([[:space:]]|=|$)'; then
|
|
1858
|
+
if git rev-parse --is-inside-work-tree >/dev/null 2>&1 \
|
|
1859
|
+
&& [ -n "$(git status --porcelain 2>/dev/null)" ]; then
|
|
1860
|
+
block "git read-tree -u --reset on a dirty working tree would discard uncommitted changes (commit first, or preserve as below)" "$PRESERVE_GUIDANCE
|
|
1861
|
+
|
|
1862
|
+
$DESTRUCTIVE_GUIDANCE"
|
|
1863
|
+
fi
|
|
1864
|
+
fi
|
|
1865
|
+
|
|
1822
1866
|
# 3b. `git rebase --abort` / `--quit` ONLY while human/agent conflict
|
|
1823
1867
|
# resolutions exist (issue #1956). `--abort` restores the pre-rebase branch
|
|
1824
1868
|
# and discards every resolution; `--quit` deletes the rebase bookkeeping
|