@codyswann/lisa 4.54.13 → 4.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/all/copy-contents/.gitattributes +8 -0
- package/all/copy-overwrite/scripts/check-orphaned-branches.mjs +78 -9
- package/all/copy-overwrite/scripts/check-third-party-action-pins.mjs +17 -1
- package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +194 -7
- package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +31 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-blind-automerge.sh +81 -2
- package/all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh +293 -8
- package/all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh +78 -15
- package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-hooks/guard-dedupe.bash +340 -0
- package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +29 -1
- package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.mjs +183 -1
- package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.sh +21 -0
- package/all/copy-overwrite/scripts/lisa-postinstall.mjs +21 -1
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +100 -5
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +1085 -80
- package/all/create-only/.github/workflows/continuous-gates.yml +7 -0
- package/cdk/create-only/.github/workflows/ci.yml +7 -0
- package/cdk/create-only/.github/workflows/deploy.yml +21 -0
- package/dist/cli/apply.d.ts.map +1 -1
- package/dist/cli/apply.js +9 -1
- package/dist/cli/apply.js.map +1 -1
- package/dist/cli/doctor-apply-deletions.d.ts +61 -0
- package/dist/cli/doctor-apply-deletions.d.ts.map +1 -0
- package/dist/cli/doctor-apply-deletions.js +137 -0
- package/dist/cli/doctor-apply-deletions.js.map +1 -0
- package/dist/cli/doctor-cdk-preset-adoption.d.ts +15 -0
- package/dist/cli/doctor-cdk-preset-adoption.d.ts.map +1 -0
- package/dist/cli/doctor-cdk-preset-adoption.js +316 -0
- package/dist/cli/doctor-cdk-preset-adoption.js.map +1 -0
- package/dist/cli/doctor-config-shadowing.d.ts +22 -0
- package/dist/cli/doctor-config-shadowing.d.ts.map +1 -0
- package/dist/cli/doctor-config-shadowing.js +123 -0
- package/dist/cli/doctor-config-shadowing.js.map +1 -0
- package/dist/cli/doctor-rails-deploy-intent.d.ts +15 -0
- package/dist/cli/doctor-rails-deploy-intent.d.ts.map +1 -0
- package/dist/cli/doctor-rails-deploy-intent.js +197 -0
- package/dist/cli/doctor-rails-deploy-intent.js.map +1 -0
- package/dist/cli/doctor-seeded-artifacts.d.ts +12 -0
- package/dist/cli/doctor-seeded-artifacts.d.ts.map +1 -0
- package/dist/cli/doctor-seeded-artifacts.js +54 -0
- package/dist/cli/doctor-seeded-artifacts.js.map +1 -0
- package/dist/cli/doctor-stale-banner-scan.d.ts +44 -0
- package/dist/cli/doctor-stale-banner-scan.d.ts.map +1 -0
- package/dist/cli/doctor-stale-banner-scan.js +152 -0
- package/dist/cli/doctor-stale-banner-scan.js.map +1 -0
- package/dist/cli/doctor-stale-managed-banner.d.ts +19 -0
- package/dist/cli/doctor-stale-managed-banner.d.ts.map +1 -0
- package/dist/cli/doctor-stale-managed-banner.js +198 -0
- package/dist/cli/doctor-stale-managed-banner.js.map +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +16 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/ui-detected-stacks.d.ts.map +1 -1
- package/dist/cli/ui-detected-stacks.js +3 -2
- package/dist/cli/ui-detected-stacks.js.map +1 -1
- package/dist/cli/update-check.d.ts.map +1 -1
- package/dist/cli/update-check.js +14 -0
- package/dist/cli/update-check.js.map +1 -1
- package/dist/cli/worktree-liveness.d.ts +5 -0
- package/dist/cli/worktree-liveness.d.ts.map +1 -1
- package/dist/cli/worktree-liveness.js +7 -6
- package/dist/cli/worktree-liveness.js.map +1 -1
- package/dist/cli/worktree-ownership.d.ts +13 -0
- package/dist/cli/worktree-ownership.d.ts.map +1 -1
- package/dist/cli/worktree-ownership.js +14 -0
- package/dist/cli/worktree-ownership.js.map +1 -1
- package/dist/configs/eslint/base.d.ts +34 -0
- package/dist/configs/eslint/base.d.ts.map +1 -1
- package/dist/configs/eslint/base.js +34 -0
- package/dist/configs/eslint/base.js.map +1 -1
- package/dist/core/apply-receipt.d.ts +65 -0
- package/dist/core/apply-receipt.d.ts.map +1 -1
- package/dist/core/apply-receipt.js +62 -2
- package/dist/core/apply-receipt.js.map +1 -1
- package/dist/core/cdk-preset-adoption.d.ts +136 -0
- package/dist/core/cdk-preset-adoption.d.ts.map +1 -0
- package/dist/core/cdk-preset-adoption.js +135 -0
- package/dist/core/cdk-preset-adoption.js.map +1 -0
- package/dist/core/config-shadowing.d.ts +36 -0
- package/dist/core/config-shadowing.d.ts.map +1 -1
- package/dist/core/config-shadowing.js +38 -0
- package/dist/core/config-shadowing.js.map +1 -1
- package/dist/core/config.d.ts +11 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/learnings-merge-driver.d.ts +10 -0
- package/dist/core/learnings-merge-driver.d.ts.map +1 -1
- package/dist/core/learnings-merge-driver.js +18 -0
- package/dist/core/learnings-merge-driver.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +136 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +9 -1
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts +5 -5
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +7 -7
- package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
- package/dist/core/ownership-header.d.ts +74 -0
- package/dist/core/ownership-header.d.ts.map +1 -0
- package/dist/core/ownership-header.js +76 -0
- package/dist/core/ownership-header.js.map +1 -0
- package/dist/core/rails-deploy-production-intent.d.ts +36 -0
- package/dist/core/rails-deploy-production-intent.d.ts.map +1 -0
- package/dist/core/rails-deploy-production-intent.js +79 -0
- package/dist/core/rails-deploy-production-intent.js.map +1 -0
- package/dist/core/stale-managed-banner.d.ts +78 -0
- package/dist/core/stale-managed-banner.d.ts.map +1 -0
- package/dist/core/stale-managed-banner.js +118 -0
- package/dist/core/stale-managed-banner.js.map +1 -0
- package/dist/core/two-channel-delivery-scan.d.ts +33 -1
- package/dist/core/two-channel-delivery-scan.d.ts.map +1 -1
- package/dist/core/two-channel-delivery-scan.js +133 -6
- package/dist/core/two-channel-delivery-scan.js.map +1 -1
- package/dist/core/two-channel-delivery.d.ts +101 -4
- package/dist/core/two-channel-delivery.d.ts.map +1 -1
- package/dist/core/two-channel-delivery.js +121 -13
- package/dist/core/two-channel-delivery.js.map +1 -1
- package/dist/core/two-channel-staleness.d.ts +137 -0
- package/dist/core/two-channel-staleness.d.ts.map +1 -0
- package/dist/core/two-channel-staleness.js +268 -0
- package/dist/core/two-channel-staleness.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +265 -121
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/core/workflow-deletion-ownership.d.ts +6 -24
- package/dist/core/workflow-deletion-ownership.d.ts.map +1 -1
- package/dist/core/workflow-deletion-ownership.js +22 -42
- package/dist/core/workflow-deletion-ownership.js.map +1 -1
- package/dist/detection/detectors/cdk.d.ts.map +1 -1
- package/dist/detection/detectors/cdk.js +2 -1
- package/dist/detection/detectors/cdk.js.map +1 -1
- package/dist/health/template-inspection.d.ts.map +1 -1
- package/dist/health/template-inspection.js +2 -1
- package/dist/health/template-inspection.js.map +1 -1
- package/dist/migrations/ensure-lisa-postinstall.d.ts +16 -0
- package/dist/migrations/ensure-lisa-postinstall.d.ts.map +1 -1
- package/dist/migrations/ensure-lisa-postinstall.js +16 -0
- package/dist/migrations/ensure-lisa-postinstall.js.map +1 -1
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts +2 -2
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts.map +1 -1
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.js +98 -34
- package/dist/migrations/ensure-pinned-reusable-workflow-refs.js.map +1 -1
- package/dist/migrations/ensure-playwright-dedicated-caller.d.ts.map +1 -1
- package/dist/migrations/ensure-playwright-dedicated-caller.js +1 -0
- package/dist/migrations/ensure-playwright-dedicated-caller.js.map +1 -1
- package/dist/opencode/hooks-installer.d.ts.map +1 -1
- package/dist/opencode/hooks-installer.js +1 -0
- package/dist/opencode/hooks-installer.js.map +1 -1
- package/dist/opencode/plugin-templates/block-managed-file-edits.sh +78 -15
- package/dist/opencode/plugin-templates/block-no-verify.sh +21 -0
- package/dist/opencode/plugin-templates/guard-dedupe.bash +337 -0
- package/dist/opencode/plugin-templates/lisa-block-direct-issue-create.ts +242 -55
- package/dist/opencode/plugin-templates/parity-safety-net.sh +29 -1
- package/dist/strategies/package-lisa.d.ts.map +1 -1
- package/dist/strategies/package-lisa.js +2 -1
- package/dist/strategies/package-lisa.js.map +1 -1
- package/dist/utils/path-utils.d.ts +29 -0
- package/dist/utils/path-utils.d.ts.map +1 -1
- package/dist/utils/path-utils.js +41 -0
- package/dist/utils/path-utils.js.map +1 -1
- package/expo/create-only/.github/workflows/ci.yml +21 -0
- package/expo/create-only/.github/workflows/deploy.yml +28 -0
- package/expo/create-only/.github/workflows/maestro-e2e.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml +124 -13
- package/expo/create-only/.github/workflows/nightly-e2e-health.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-report.yml +7 -0
- package/expo/create-only/.github/workflows/nightly-e2e-tracking.yml +8 -0
- package/expo/create-only/.github/workflows/playwright-e2e.yml +7 -0
- package/harper-fabric/copy-overwrite/.github/workflows/ci.yml +7 -0
- package/harper-fabric/create-only/.github/workflows/deploy.yml +14 -0
- package/nestjs/create-only/.github/workflows/ci.yml +14 -0
- package/nestjs/create-only/.github/workflows/deploy.yml +28 -0
- package/package.json +10 -5
- package/phaser/copy-overwrite/.github/workflows/ci.yml +7 -0
- package/plugins/lisa/.claude-plugin/plugin.json +28 -1
- package/plugins/lisa/.codex-plugin/hooks.json +27 -0
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-prd-intake/SKILL.md +47 -30
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +4 -4
- package/plugins/lisa/.codex-plugin/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/lisa/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa/hooks/inject-rules.sh +13 -5
- package/plugins/lisa/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa/rules/eager/00-rule-index.md +1 -0
- package/plugins/lisa/rules/eager/operational-hazards.md +50 -0
- package/plugins/lisa/rules/eager/tracked-work.md +1 -1
- package/plugins/lisa/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa/rules/reference/operational-hazards.md +115 -0
- package/plugins/lisa/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-agy/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa-agy/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-agy/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/lisa-agy/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-agy/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-agy/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-agy/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-agy/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-agy/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-agy/hooks.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-agy/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-agy/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-agy/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-agy/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-agy/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-agy/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-agy/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +19 -1
- package/plugins/lisa-copilot/agents/linear-prd-intake.agent.md +8 -8
- package/plugins/lisa-copilot/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-copilot/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-copilot/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-copilot/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-copilot/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa-copilot/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-copilot/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa-copilot/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-copilot/hooks/inject-rules.sh +13 -5
- package/plugins/lisa-copilot/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa-copilot/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa-copilot/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-copilot/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa-copilot/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa-copilot/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa-copilot/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa-copilot/rules/eager/00-rule-index.md +1 -0
- package/plugins/lisa-copilot/rules/eager/operational-hazards.md +50 -0
- package/plugins/lisa-copilot/rules/eager/tracked-work.md +1 -1
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/lisa-copilot/rules/reference/operational-hazards.md +115 -0
- package/plugins/lisa-copilot/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-copilot/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-copilot/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-copilot/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-copilot/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-copilot/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-copilot/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-copilot/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/linear-prd-intake.md +8 -8
- package/plugins/lisa-cursor/hooks/block-blind-automerge.sh +81 -2
- package/plugins/lisa-cursor/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/lisa-cursor/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/lisa-cursor/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/lisa-cursor/hooks/block-no-verify.sh +21 -0
- package/plugins/lisa-cursor/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/lisa-cursor/hooks/failure-signature-index.mjs +240 -5
- package/plugins/lisa-cursor/hooks/guard-dedupe.bash +337 -0
- package/plugins/lisa-cursor/hooks/hooks.json +10 -0
- package/plugins/lisa-cursor/hooks/operational-hazards.mjs +736 -0
- package/plugins/lisa-cursor/hooks/operational-hazards.sh +28 -0
- package/plugins/lisa-cursor/hooks/parity-safety-net.sh +29 -1
- package/plugins/lisa-cursor/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/lisa-cursor/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/lisa-cursor/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/lisa-cursor/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/lisa-cursor/rules/00-rule-index.mdc +1 -0
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/operational-hazards-reference.mdc +120 -0
- package/plugins/lisa-cursor/rules/operational-hazards.mdc +55 -0
- package/plugins/lisa-cursor/rules/tracked-work.mdc +1 -1
- package/plugins/lisa-cursor/rules/work-item-trailer-definition-reference.mdc +134 -0
- package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/lisa-cursor/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/lisa-cursor/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/lisa-cursor/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/lisa-cursor/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/lisa-cursor/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/lisa-cursor/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/lisa-cursor/skills/lisa-track/SKILL.md +1 -1
- package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-harper-fabric/rules/eager/harper-fabric.md +31 -0
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-harper-fabric-copilot/rules/eager/harper-fabric.md +31 -0
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric-reference.mdc +57 -0
- package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric.mdc +32 -53
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-phaser/rules/eager/phaser.md +44 -0
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/hooks/inject-rules.sh +14 -3
- package/plugins/lisa-phaser-copilot/rules/eager/phaser.md +44 -0
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/rules/phaser-reference.mdc +189 -0
- package/plugins/lisa-phaser-cursor/rules/phaser.mdc +45 -185
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/hooks/inject-rules.sh +14 -4
- package/plugins/lisa-rails/rules/eager/rails-conventions.md +23 -0
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/hooks/inject-rules.sh +14 -4
- package/plugins/lisa-rails-copilot/rules/eager/rails-conventions.md +23 -0
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/rules/rails-conventions-reference.mdc +181 -0
- package/plugins/lisa-rails-cursor/rules/rails-conventions.mdc +24 -177
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/materialized-artifacts.json +1 -0
- package/plugins/src/base/.claude-plugin/plugin.json +27 -0
- package/plugins/src/base/agents/linear-prd-intake.md +8 -8
- package/plugins/src/base/hooks/block-blind-automerge.sh +81 -2
- package/plugins/src/base/hooks/block-direct-issue-create.agy.sh +64 -16
- package/plugins/src/base/hooks/block-direct-issue-create.sh +293 -8
- package/plugins/src/base/hooks/block-instruction-file-edits.sh +21 -0
- package/plugins/src/base/hooks/block-managed-file-edits.sh +78 -15
- package/plugins/src/base/hooks/block-no-verify.sh +21 -0
- package/plugins/src/base/hooks/block-shell-json-parsing.sh +21 -0
- package/plugins/src/base/hooks/failure-signature-index.mjs +240 -5
- package/plugins/src/base/hooks/guard-dedupe.bash +337 -0
- package/plugins/src/base/hooks/inject-rules.sh +13 -5
- package/plugins/src/base/hooks/operational-hazards.mjs +736 -0
- package/plugins/src/base/hooks/operational-hazards.sh +28 -0
- package/plugins/src/base/hooks/parity-safety-net.sh +29 -1
- package/plugins/src/base/hooks/threshold-ratchet-compare.mjs +102 -21
- package/plugins/src/base/hooks/threshold-ratchet-families.mjs +130 -2
- package/plugins/src/base/hooks/threshold-ratchet.mjs +63 -13
- package/plugins/src/base/hooks/worktree-binding-guard.mjs +183 -1
- package/plugins/src/base/hooks/worktree-binding-guard.sh +21 -0
- package/plugins/src/base/rules/eager/00-rule-index.md +1 -0
- package/plugins/src/base/rules/eager/operational-hazards.md +50 -0
- package/plugins/src/base/rules/eager/tracked-work.md +1 -1
- package/plugins/src/base/rules/reference/config-resolution.md +1 -1
- package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +1 -1
- package/plugins/src/base/rules/reference/operational-hazards.md +115 -0
- package/plugins/src/base/rules/reference/work-item-trailer-definition.md +129 -0
- package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +407 -26
- package/plugins/src/base/scripts/qa-signal-lifecycle.mjs +507 -0
- package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-github-prd-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-github-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +51 -0
- package/plugins/src/base/skills/lisa-intake/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-jira-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +51 -0
- package/plugins/src/base/skills/lisa-linear-access/SKILL.md +55 -2
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +27 -4
- package/plugins/src/base/skills/lisa-linear-prd-intake/SKILL.md +48 -31
- package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +3 -3
- package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +22 -0
- package/plugins/src/base/skills/lisa-linear-verify/SKILL.md +14 -0
- package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +54 -3
- package/plugins/src/base/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
- package/plugins/src/base/skills/lisa-qa-clear/SKILL.md +19 -7
- package/plugins/src/base/skills/lisa-qa-fail/SKILL.md +28 -3
- package/plugins/src/base/skills/lisa-qa-queue/SKILL.md +28 -3
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +94 -24
- package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +32 -2
- package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +5 -5
- package/plugins/src/base/skills/lisa-track/SKILL.md +1 -1
- package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +9 -0
- package/plugins/src/harper-fabric/hooks/inject-rules.sh +14 -3
- package/plugins/src/harper-fabric/rules/eager/harper-fabric.md +31 -0
- package/plugins/src/phaser/hooks/inject-rules.sh +14 -3
- package/plugins/src/phaser/rules/eager/phaser.md +44 -0
- package/plugins/src/rails/hooks/inject-rules.sh +14 -4
- package/plugins/src/rails/rules/eager/rails-conventions.md +23 -0
- package/rails/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
- package/rails/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
- package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
- package/rails/create-only/.github/workflows/ci.yml +8 -0
- package/rails/create-only/.github/workflows/deploy.yml +22 -0
- package/scripts/build-plugins.sh +2 -1
- package/scripts/check-engine-floor.mjs +361 -0
- package/scripts/check-guard-parity-notes.mjs +709 -0
- package/scripts/check-template-workflow-refs.mjs +9 -0
- package/scripts/check-third-party-action-pins.mjs +17 -1
- package/scripts/check-workflow-contract-assertions.mjs +480 -0
- package/scripts/copy-opencode-plugin-templates.mjs +1 -0
- package/scripts/deployed-guard-advice.mjs +636 -0
- package/scripts/generate-agy-plugin-artifacts.mjs +35 -10
- package/scripts/generate-export-surface.mjs +105 -19
- package/scripts/generate-two-channel-couplings.ts +143 -212
- package/scripts/lisa-enforcement-fallback.sh +31 -0
- package/scripts/measure-scripts-profile-gap.mts +361 -0
- package/scripts/mutation-performance-measure.mjs +21 -5
- package/scripts/reconcile-release-tags.mjs +65 -84
- package/scripts/two-channel-couplings.json +302 -70
- package/scripts/workflow-contract-assertion.sh +47 -0
- package/typescript/copy-overwrite/.lintstagedrc.json +1 -0
- package/typescript/copy-overwrite/eslint.ignore.config.json +1 -0
- package/typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs +527 -53
- package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +301 -13
- package/typescript/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
- package/typescript/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
- package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
- package/typescript/create-only/.github/workflows/ci.yml +7 -0
- /package/plugins/lisa-harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/lisa-harper-fabric-copilot/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/lisa-phaser/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/lisa-phaser-copilot/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/lisa-rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
- /package/plugins/lisa-rails-copilot/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
- /package/plugins/src/harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
- /package/plugins/src/phaser/rules/{phaser.md → reference/phaser.md} +0 -0
- /package/plugins/src/rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
|
@@ -71,7 +71,7 @@ function declarativeText(body) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
* Whether an HTML comment on this line carries the marker.
|
|
74
|
+
* Whether an HTML comment on this line carries the given marker.
|
|
75
75
|
*
|
|
76
76
|
* The second declaration form, and it is not a concession: an HTML comment is
|
|
77
77
|
* invisible when the body is rendered, so nobody writes one to TALK about the
|
|
@@ -83,15 +83,16 @@ function declarativeText(body) {
|
|
|
83
83
|
* `[^\n]*?` runs around a literal is the ambiguous shape this module avoids
|
|
84
84
|
* elsewhere, and an indexOf walk is both linear and easier to be sure about.
|
|
85
85
|
* @param {string} line - One line of the body
|
|
86
|
+
* @param {string} marker - The literal marker to look for
|
|
86
87
|
* @returns {boolean} True when a comment on this line contains the marker
|
|
87
88
|
*/
|
|
88
|
-
function commentCarriesMarker(line) {
|
|
89
|
+
function commentCarriesMarker(line, marker) {
|
|
89
90
|
const segments = line.split("<!--");
|
|
90
91
|
for (let index = 1; index < segments.length; index += 1) {
|
|
91
92
|
const close = segments[index].indexOf("-->");
|
|
92
93
|
const inside =
|
|
93
94
|
close === -1 ? segments[index] : segments[index].slice(0, close);
|
|
94
|
-
if (inside.includes(
|
|
95
|
+
if (inside.includes(marker)) return true;
|
|
95
96
|
}
|
|
96
97
|
return false;
|
|
97
98
|
}
|
|
@@ -106,13 +107,14 @@ function commentCarriesMarker(line) {
|
|
|
106
107
|
* `--body` string and a shell script — where a declaration legitimately sits
|
|
107
108
|
* after other text on its line.
|
|
108
109
|
* @param {string} line - One line of the body
|
|
109
|
-
* @
|
|
110
|
+
* @param {string} [marker] - The declaration marker to test for
|
|
111
|
+
* @returns {boolean} True when the line declares with that marker
|
|
110
112
|
*/
|
|
111
|
-
function declaresOnLine(line) {
|
|
112
|
-
if (line.replace(LEADING_DECORATION, "").startsWith(
|
|
113
|
+
function declaresOnLine(line, marker = HUMAN_GATE_MARKER) {
|
|
114
|
+
if (line.replace(LEADING_DECORATION, "").startsWith(marker)) {
|
|
113
115
|
return true;
|
|
114
116
|
}
|
|
115
|
-
return commentCarriesMarker(line);
|
|
117
|
+
return commentCarriesMarker(line, marker);
|
|
116
118
|
}
|
|
117
119
|
|
|
118
120
|
/**
|
|
@@ -174,6 +176,185 @@ export function bodyDeclaresHold(body) {
|
|
|
174
176
|
return humanGateMentions(body).declared > 0;
|
|
175
177
|
}
|
|
176
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Marker a comment carries to DISCHARGE a hold.
|
|
181
|
+
*
|
|
182
|
+
* ## Why a comment and not the body
|
|
183
|
+
*
|
|
184
|
+
* The hold lives in the description, and the only description write this plugin
|
|
185
|
+
* has is a whole-body replacement — re-read everything, change one line, write
|
|
186
|
+
* it all back. On an item carrying acceptance criteria, a validation journey
|
|
187
|
+
* and a managed usage section, "delete one HTML comment" is therefore "rewrite
|
|
188
|
+
* the record and hope nothing was dropped". A release procedure whose only
|
|
189
|
+
* implementation risks destroying what it releases is not a release procedure:
|
|
190
|
+
* the rational move is always to leave the hold, so holds only accumulate
|
|
191
|
+
* (CodySwannGT/lisa#3852).
|
|
192
|
+
*
|
|
193
|
+
* A comment is append-only. It cannot drop a section it never held, and the
|
|
194
|
+
* same reader that reads the hold reads the discharge.
|
|
195
|
+
*
|
|
196
|
+
* ## Why it is not a superstring of the hold marker
|
|
197
|
+
*
|
|
198
|
+
* `HUMAN_GATE_MARKER` closes with `]`, so `[lisa-human-gate-release]` does not
|
|
199
|
+
* contain it. That is load-bearing rather than incidental: a release record
|
|
200
|
+
* that matched the hold test would declare a fresh hold every time one was
|
|
201
|
+
* lifted, which is the same trap `NORMALIZATION_HOLD_NOTE_MARKER` documents.
|
|
202
|
+
*/
|
|
203
|
+
export const HUMAN_GATE_RELEASE_MARKER = "[lisa-human-gate-release]";
|
|
204
|
+
|
|
205
|
+
/** Structured key a hold and its release both name, so they pair up. */
|
|
206
|
+
const REASON_KEY = "reason=";
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The comparable form of a hold reason.
|
|
210
|
+
*
|
|
211
|
+
* Case and internal whitespace drift between the hand that writes the hold and
|
|
212
|
+
* the hand that writes the release; the identity of the question does not.
|
|
213
|
+
* @param {unknown} value - A raw reason string
|
|
214
|
+
* @returns {string} Its comparable form, empty when there is none
|
|
215
|
+
*/
|
|
216
|
+
function normalizeReason(value) {
|
|
217
|
+
return String(value ?? "")
|
|
218
|
+
.replace(/\s+/gu, " ")
|
|
219
|
+
.trim()
|
|
220
|
+
.toLowerCase();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* The reason a declaring line names, or the empty key when it names none.
|
|
225
|
+
*
|
|
226
|
+
* A keyless declaration is not a defect to be rejected — markers in the wild
|
|
227
|
+
* carry no `reason=` at all, which is why the hold test is not keyed on one.
|
|
228
|
+
* The empty string is a real key here: a keyless hold is discharged by a
|
|
229
|
+
* keyless release and by nothing else, so the two surfaces stay symmetric
|
|
230
|
+
* whether or not a reason was ever written.
|
|
231
|
+
* @param {string} line - A line already known to declare
|
|
232
|
+
* @param {string} marker - The declaration marker it carries
|
|
233
|
+
* @returns {string} The normalized reason key
|
|
234
|
+
*/
|
|
235
|
+
function reasonOnLine(line, marker) {
|
|
236
|
+
const at = line.indexOf(marker);
|
|
237
|
+
if (at === -1) return "";
|
|
238
|
+
const tail = line.slice(at + marker.length).split("-->")[0];
|
|
239
|
+
const key = tail.indexOf(REASON_KEY);
|
|
240
|
+
if (key === -1) return "";
|
|
241
|
+
return normalizeReason(tail.slice(key + REASON_KEY.length));
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* The reason keys of every hold a body DECLARES, deduplicated.
|
|
246
|
+
*
|
|
247
|
+
* Reuses the precision rule rather than restating it, so a body that merely
|
|
248
|
+
* discusses the marker yields no holds here for the same reason it reads as
|
|
249
|
+
* unheld in {@link bodyDeclaresHold}.
|
|
250
|
+
* @param {unknown} body - The item body
|
|
251
|
+
* @returns {string[]} One key per declared hold
|
|
252
|
+
*/
|
|
253
|
+
export function humanGateHolds(body) {
|
|
254
|
+
const keys = declarativeText(body)
|
|
255
|
+
.split("\n")
|
|
256
|
+
.filter(line => declaresOnLine(line))
|
|
257
|
+
.map(line => reasonOnLine(line, HUMAN_GATE_MARKER));
|
|
258
|
+
return [...new Set(keys)];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* The reason keys every recorded release discharges, deduplicated.
|
|
263
|
+
*
|
|
264
|
+
* Accepts comment bodies as strings or as `{ body }` objects, because the three
|
|
265
|
+
* vendor readers return both shapes and a release that a vendor's payload shape
|
|
266
|
+
* could hide would be a release path that exists on one tracker.
|
|
267
|
+
* @param {unknown} comments - Comment bodies, any order
|
|
268
|
+
* @returns {string[]} One key per recorded release
|
|
269
|
+
*/
|
|
270
|
+
export function humanGateReleases(comments) {
|
|
271
|
+
const bodies = (Array.isArray(comments) ? comments : []).map(entry =>
|
|
272
|
+
typeof entry === "string" ? entry : (entry?.body ?? "")
|
|
273
|
+
);
|
|
274
|
+
const keys = bodies.flatMap(body =>
|
|
275
|
+
declarativeText(body)
|
|
276
|
+
.split("\n")
|
|
277
|
+
.filter(line => declaresOnLine(line, HUMAN_GATE_RELEASE_MARKER))
|
|
278
|
+
.map(line => reasonOnLine(line, HUMAN_GATE_RELEASE_MARKER))
|
|
279
|
+
);
|
|
280
|
+
return [...new Set(keys)];
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Whether every hold on this item has a release recorded against it.
|
|
285
|
+
*
|
|
286
|
+
* Matching is per-reason on purpose. A blanket "any release clears everything"
|
|
287
|
+
* rule would make a hold declared AFTER a release be born discharged, which is
|
|
288
|
+
* the unsafe direction — the one this fix must not introduce while correcting
|
|
289
|
+
* the safe one. An item with no declared body hold is discharged only by a
|
|
290
|
+
* keyless release, which is the form that pairs with a label-only hold.
|
|
291
|
+
* @param {{ body?: unknown, comments?: unknown }} input - The item's surfaces
|
|
292
|
+
* @returns {boolean} True when nothing is left outstanding
|
|
293
|
+
*/
|
|
294
|
+
export function humanGateDischarged(input = {}) {
|
|
295
|
+
const released = new Set(humanGateReleases(input.comments));
|
|
296
|
+
const holds = humanGateHolds(input.body);
|
|
297
|
+
if (holds.length === 0) return released.has("");
|
|
298
|
+
return holds.every(reason => released.has(reason));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* The full held-ness verdict for an item, on every surface that carries a hold.
|
|
303
|
+
*
|
|
304
|
+
* Split out of {@link isHumanGated} because the release path needs to know more
|
|
305
|
+
* than yes-or-no: whether a hold existed at all, which reasons are still
|
|
306
|
+
* outstanding, and whether the durable label needs removing. A caller that only
|
|
307
|
+
* wants the boolean still gets exactly the boolean.
|
|
308
|
+
*
|
|
309
|
+
* The label is treated as a MIRROR of a declared body hold, never as a second
|
|
310
|
+
* independent hold, because that is how it is written: the vendor writers stamp
|
|
311
|
+
* both surfaces for one hold, and `planHumanGateReconciliation` adds the label
|
|
312
|
+
* to an item already carrying the marker. Counting it separately would leave
|
|
313
|
+
* every mirrored hold permanently outstanding under a keyed release — the exact
|
|
314
|
+
* defect this function exists to end, one layer down. Only when the body
|
|
315
|
+
* declares nothing does the label stand as a hold in its own right, and then it
|
|
316
|
+
* is a keyless one.
|
|
317
|
+
*
|
|
318
|
+
* Fails CLOSED on an unreadable discharge: with no comments supplied there are
|
|
319
|
+
* no releases, so a held item stays held. Holding a gate that may be stale
|
|
320
|
+
* beats releasing one that is not, and every caller that never passes comments
|
|
321
|
+
* keeps its current behaviour by construction.
|
|
322
|
+
* @param {{ labels?: unknown, body?: unknown, comments?: unknown, humanNeededLabel?: unknown }} input - Candidate surfaces
|
|
323
|
+
* @returns {{ held: boolean, reason: string, declared: number, outstanding: string[], released: string[], labelPresent: boolean }} Held-ness verdict
|
|
324
|
+
*/
|
|
325
|
+
export function humanGateVerdict(input = {}) {
|
|
326
|
+
const configured = String(
|
|
327
|
+
input.humanNeededLabel ?? DEFAULT_HUMAN_NEEDED_LABEL
|
|
328
|
+
)
|
|
329
|
+
.trim()
|
|
330
|
+
.toLowerCase();
|
|
331
|
+
const labelPresent =
|
|
332
|
+
configured.length > 0 && normalizeLabels(input.labels).includes(configured);
|
|
333
|
+
const released = humanGateReleases(input.comments);
|
|
334
|
+
const releasedSet = new Set(released);
|
|
335
|
+
const holds = humanGateHolds(input.body);
|
|
336
|
+
const outstanding = holds.filter(reason => !releasedSet.has(reason));
|
|
337
|
+
const base = {
|
|
338
|
+
declared: holds.length,
|
|
339
|
+
released,
|
|
340
|
+
labelPresent,
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
if (outstanding.length > 0) {
|
|
344
|
+
return { held: true, reason: "hold-outstanding", outstanding, ...base };
|
|
345
|
+
}
|
|
346
|
+
if (holds.length > 0) {
|
|
347
|
+
return { held: false, reason: "hold-released", outstanding: [], ...base };
|
|
348
|
+
}
|
|
349
|
+
if (labelPresent) {
|
|
350
|
+
return releasedSet.has("")
|
|
351
|
+
? { held: false, reason: "hold-released", outstanding: [], ...base }
|
|
352
|
+
: { held: true, reason: "hold-outstanding", outstanding: [""], ...base };
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return { held: false, reason: "no-hold", outstanding: [], ...base };
|
|
356
|
+
}
|
|
357
|
+
|
|
177
358
|
/**
|
|
178
359
|
* Whether an item is held for a person, on either surface.
|
|
179
360
|
*
|
|
@@ -185,23 +366,17 @@ export function bodyDeclaresHold(body) {
|
|
|
185
366
|
* A path that read labels alone judged such an item unheld and promoted it —
|
|
186
367
|
* which is #3805, and is why this is a shared function rather than a shared
|
|
187
368
|
* convention.
|
|
188
|
-
*
|
|
369
|
+
*
|
|
370
|
+
* It is also the only place a hold ENDS, which is why the release lives behind
|
|
371
|
+
* the same call rather than beside it: a reader that could see the hold but not
|
|
372
|
+
* its discharge is how the gate became one-way in the first place. Pass the
|
|
373
|
+
* item's comments and a recorded release is honoured; omit them and the item
|
|
374
|
+
* stays held.
|
|
375
|
+
* @param {{ labels?: unknown, body?: unknown, comments?: unknown, humanNeededLabel?: unknown }} input - Candidate surfaces
|
|
189
376
|
* @returns {boolean} True when a person is holding this item
|
|
190
377
|
*/
|
|
191
378
|
export function isHumanGated(input) {
|
|
192
|
-
|
|
193
|
-
input.humanNeededLabel ?? DEFAULT_HUMAN_NEEDED_LABEL
|
|
194
|
-
)
|
|
195
|
-
.trim()
|
|
196
|
-
.toLowerCase();
|
|
197
|
-
if (
|
|
198
|
-
configured.length > 0 &&
|
|
199
|
-
normalizeLabels(input.labels).includes(configured)
|
|
200
|
-
) {
|
|
201
|
-
return true;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return bodyDeclaresHold(input.body);
|
|
379
|
+
return humanGateVerdict(input).held;
|
|
205
380
|
}
|
|
206
381
|
|
|
207
382
|
/**
|
|
@@ -247,6 +422,7 @@ function judgeProbe(probe) {
|
|
|
247
422
|
* laneType?: unknown
|
|
248
423
|
* labels?: unknown
|
|
249
424
|
* body?: unknown
|
|
425
|
+
* comments?: unknown
|
|
250
426
|
* humanNeededLabel?: unknown
|
|
251
427
|
* statedBlocker?: unknown
|
|
252
428
|
* probe?: { discharged?: unknown, evidence?: unknown } | null
|
|
@@ -359,7 +535,7 @@ export const HUMAN_GATE_NOTE_MARKER = "<!-- [lisa-human-gate-reconciled] -->";
|
|
|
359
535
|
* a parser keyed on the structured field would miss those while appearing to
|
|
360
536
|
* work on every item that happens to have one — reproducing this defect one
|
|
361
537
|
* layer down.
|
|
362
|
-
* @param {{ labels?: unknown, body?: unknown, humanNeededLabel?: unknown }} input - Candidate surfaces
|
|
538
|
+
* @param {{ labels?: unknown, body?: unknown, comments?: unknown, humanNeededLabel?: unknown }} input - Candidate surfaces
|
|
363
539
|
* @returns {{ claimable: boolean, reason: string, humanGated: boolean }} Claim verdict
|
|
364
540
|
*/
|
|
365
541
|
export function classifyReadyCandidate(input = {}) {
|
|
@@ -387,6 +563,7 @@ export function classifyReadyCandidate(input = {}) {
|
|
|
387
563
|
* @param {{
|
|
388
564
|
* labels?: unknown
|
|
389
565
|
* body?: unknown
|
|
566
|
+
* comments?: unknown
|
|
390
567
|
* humanNeededLabel?: unknown
|
|
391
568
|
* readyLabel?: unknown
|
|
392
569
|
* alreadyNotified?: unknown
|
|
@@ -429,6 +606,192 @@ export function planHumanGateReconciliation(input = {}) {
|
|
|
429
606
|
};
|
|
430
607
|
}
|
|
431
608
|
|
|
609
|
+
/**
|
|
610
|
+
* Marker on the note the release path leaves, so a later cycle recognises its
|
|
611
|
+
* own work instead of commenting again.
|
|
612
|
+
*
|
|
613
|
+
* A superstring of neither declaration marker, for the reason
|
|
614
|
+
* {@link HUMAN_GATE_RELEASE_MARKER} gives: a note ABOUT a release must not read
|
|
615
|
+
* as a release, or the note announcing one item's discharge would discharge
|
|
616
|
+
* every item it names.
|
|
617
|
+
*/
|
|
618
|
+
export const HUMAN_GATE_RELEASE_NOTE_MARKER =
|
|
619
|
+
"<!-- [lisa-human-gate-released] -->";
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* The one sentence every hold note gives an operator to END the hold.
|
|
623
|
+
*
|
|
624
|
+
* One constant, two notes, because the instruction IS the release path as far
|
|
625
|
+
* as the person reading it is concerned. Two copies of it drift, and a drifted
|
|
626
|
+
* instruction sends someone to a mechanism that no longer exists — which is
|
|
627
|
+
* worse than the prose it replaced, since that at least described something
|
|
628
|
+
* real. It names a comment because the alternative it replaces — "remove the
|
|
629
|
+
* hold note from the description" — asks for a whole-body rewrite the tooling
|
|
630
|
+
* has no safe way to perform.
|
|
631
|
+
*/
|
|
632
|
+
const RESUME_INSTRUCTION = [
|
|
633
|
+
"- To resume it: leave a comment on this item that starts with ",
|
|
634
|
+
HUMAN_GATE_RELEASE_MARKER,
|
|
635
|
+
" and repeats the reason the hold in the description names. The next sweep ",
|
|
636
|
+
"puts it back in the queue on its own. Nothing else has to change — do not ",
|
|
637
|
+
"edit the description, and do not move it by hand.",
|
|
638
|
+
].join("");
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Plan the state repair for an item whose hold has been discharged.
|
|
642
|
+
*
|
|
643
|
+
* The exact inverse of {@link planHumanGateReconciliation}, and deliberately
|
|
644
|
+
* the same shape: that one takes the ready role away and adds the marker label,
|
|
645
|
+
* this one takes the marker label away and puts the ready role back. A state
|
|
646
|
+
* change with no inverse is the defect class this pair exists to close
|
|
647
|
+
* (`state-changes-without-inverses`), and an inverse that is merely *possible*
|
|
648
|
+
* is not one — it has to sit on a path something actually runs, which is why
|
|
649
|
+
* this is a planner the intake sweeps call rather than an instruction to an
|
|
650
|
+
* operator.
|
|
651
|
+
*
|
|
652
|
+
* Two refusals are load-bearing:
|
|
653
|
+
*
|
|
654
|
+
* - **A still-held item plans nothing.** Every outstanding reason holds the
|
|
655
|
+
* whole item, so an item whose second hold has not been answered is not
|
|
656
|
+
* half-released.
|
|
657
|
+
* - **An item that was never held plans nothing.** Without that, this would be
|
|
658
|
+
* a path that adds the build-ready role to arbitrary items — a promotion
|
|
659
|
+
* mechanism wearing a release mechanism's name.
|
|
660
|
+
*
|
|
661
|
+
* The ready role is restored only when the item carries none of the configured
|
|
662
|
+
* lifecycle labels, mirroring {@link planLabelNormalization}. An item that was
|
|
663
|
+
* held and has since reached a terminal lane must not be dragged back to the
|
|
664
|
+
* queue by its own release.
|
|
665
|
+
*
|
|
666
|
+
* Idempotent by state rather than by memory: an item already unmarked and
|
|
667
|
+
* already back in the queue needs nothing, so asking twice yields no second
|
|
668
|
+
* mutation.
|
|
669
|
+
* @param {{
|
|
670
|
+
* labels?: unknown
|
|
671
|
+
* body?: unknown
|
|
672
|
+
* comments?: unknown
|
|
673
|
+
* humanNeededLabel?: unknown
|
|
674
|
+
* readyLabel?: unknown
|
|
675
|
+
* lifecycleLabels?: unknown
|
|
676
|
+
* alreadyNotified?: unknown
|
|
677
|
+
* }} input - Candidate surfaces plus the configured lane vocabulary
|
|
678
|
+
* @returns {{ released: boolean, reason: string, discharged: string[], actions: { removeHumanNeededLabel: boolean, addReadyLabel: string | null, comment: boolean } }} Release plan
|
|
679
|
+
*/
|
|
680
|
+
export function planHumanGateRelease(input = {}) {
|
|
681
|
+
const idle = Object.freeze({
|
|
682
|
+
removeHumanNeededLabel: false,
|
|
683
|
+
addReadyLabel: null,
|
|
684
|
+
comment: false,
|
|
685
|
+
});
|
|
686
|
+
const verdict = humanGateVerdict(input);
|
|
687
|
+
if (verdict.held) {
|
|
688
|
+
return {
|
|
689
|
+
released: false,
|
|
690
|
+
reason: "hold-outstanding",
|
|
691
|
+
discharged: [],
|
|
692
|
+
actions: idle,
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
if (verdict.declared === 0 && !verdict.labelPresent) {
|
|
696
|
+
return {
|
|
697
|
+
released: false,
|
|
698
|
+
reason: "no-hold",
|
|
699
|
+
discharged: [],
|
|
700
|
+
actions: idle,
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
const needed = String(input.humanNeededLabel ?? DEFAULT_HUMAN_NEEDED_LABEL)
|
|
705
|
+
.trim()
|
|
706
|
+
.toLowerCase();
|
|
707
|
+
// The marker label is excluded from the lane test on both sides. It is one of
|
|
708
|
+
// the configured lifecycle labels AND it is the label this plan removes, so
|
|
709
|
+
// counting it would let the hold's own marker prove the item is already in a
|
|
710
|
+
// lane and veto the restoration — the release would clear the flag and leave
|
|
711
|
+
// the item in no queue at all, which is the original defect with one fewer
|
|
712
|
+
// symptom.
|
|
713
|
+
const labels = normalizeLabels(input.labels).filter(name => name !== needed);
|
|
714
|
+
const lifecycle = normalizeLabels(input.lifecycleLabels).filter(
|
|
715
|
+
name => name !== needed
|
|
716
|
+
);
|
|
717
|
+
const ready = trimmedString(input.readyLabel);
|
|
718
|
+
const inLifecycle = lifecycle.some(name => labels.includes(name));
|
|
719
|
+
const addReadyLabel =
|
|
720
|
+
ready.length > 0 && !inLifecycle && !labels.includes(ready.toLowerCase())
|
|
721
|
+
? ready
|
|
722
|
+
: null;
|
|
723
|
+
const actions = {
|
|
724
|
+
removeHumanNeededLabel: verdict.labelPresent,
|
|
725
|
+
addReadyLabel,
|
|
726
|
+
comment:
|
|
727
|
+
input.alreadyNotified !== true &&
|
|
728
|
+
(verdict.labelPresent || addReadyLabel !== null),
|
|
729
|
+
};
|
|
730
|
+
const changed =
|
|
731
|
+
actions.removeHumanNeededLabel || addReadyLabel !== null || actions.comment;
|
|
732
|
+
|
|
733
|
+
return {
|
|
734
|
+
released: true,
|
|
735
|
+
reason: changed ? "release" : "already-released",
|
|
736
|
+
discharged: verdict.released,
|
|
737
|
+
actions,
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* Render the discharge record a person or a skill leaves to END a hold.
|
|
743
|
+
*
|
|
744
|
+
* Generated rather than retyped, because the release names the hold it ends by
|
|
745
|
+
* its reason and a mistyped reason discharges nothing while looking like it
|
|
746
|
+
* did. The reason is echoed verbatim from the hold, so the pairing is visible
|
|
747
|
+
* to a reader as well as to the matcher.
|
|
748
|
+
* @param {{ reason?: unknown, decidedBy?: unknown, decision?: unknown }} discharge - What was decided, and by whom
|
|
749
|
+
* @returns {string} Comment body carrying the release marker
|
|
750
|
+
*/
|
|
751
|
+
export function formatHumanGateRelease(discharge = {}) {
|
|
752
|
+
const reason = trimmedString(discharge.reason);
|
|
753
|
+
const declaration =
|
|
754
|
+
reason.length > 0
|
|
755
|
+
? `${HUMAN_GATE_RELEASE_MARKER} ${REASON_KEY}${reason}`
|
|
756
|
+
: HUMAN_GATE_RELEASE_MARKER;
|
|
757
|
+
const lines = [declaration, "", "**The hold on this item is lifted.**", ""];
|
|
758
|
+
lines.push(
|
|
759
|
+
`- What was being asked: ${reason.length > 0 ? reason : "(the hold named no reason)"}`
|
|
760
|
+
);
|
|
761
|
+
const decision = trimmedString(discharge.decision);
|
|
762
|
+
if (decision.length > 0) lines.push(`- What was decided: ${decision}`);
|
|
763
|
+
const decidedBy = trimmedString(discharge.decidedBy);
|
|
764
|
+
if (decidedBy.length > 0) lines.push(`- Decided by: ${decidedBy}`);
|
|
765
|
+
lines.push(
|
|
766
|
+
"- What happens next: this item goes back into the queue that agents build from."
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
return lines.join("\n");
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Render the notice for an item this sweep released.
|
|
774
|
+
*
|
|
775
|
+
* Distinct from {@link formatHumanGateNote} for the same reason
|
|
776
|
+
* {@link formatNormalizationHoldNote} is: the two report opposite events, and
|
|
777
|
+
* reusing one to report the other tells an operator the wrong thing happened.
|
|
778
|
+
* @returns {string} Comment body, carrying the marker that keeps a re-run quiet
|
|
779
|
+
*/
|
|
780
|
+
export function formatHumanGateReleaseNote() {
|
|
781
|
+
return [
|
|
782
|
+
"**Back in the queue: the hold was answered**",
|
|
783
|
+
"",
|
|
784
|
+
"- What was found: this item was being held for a person, and the " +
|
|
785
|
+
"decision it was waiting for has since been recorded on it.",
|
|
786
|
+
"- What changed: the hold flag has been taken off and the item has been " +
|
|
787
|
+
"put back into the queue that agents build from.",
|
|
788
|
+
"- Nothing was rewritten: the description is exactly as it was, hold note " +
|
|
789
|
+
"and all, so the history of why it was held stays readable.",
|
|
790
|
+
"",
|
|
791
|
+
HUMAN_GATE_RELEASE_NOTE_MARKER,
|
|
792
|
+
].join("\n");
|
|
793
|
+
}
|
|
794
|
+
|
|
432
795
|
/**
|
|
433
796
|
* Marker on the note the normalization sweep leaves, so a later cycle
|
|
434
797
|
* recognises its own work instead of commenting again.
|
|
@@ -467,6 +830,7 @@ export const NORMALIZATION_HOLD_NOTE_MARKER =
|
|
|
467
830
|
* @param {{
|
|
468
831
|
* labels?: unknown
|
|
469
832
|
* body?: unknown
|
|
833
|
+
* comments?: unknown
|
|
470
834
|
* humanNeededLabel?: unknown
|
|
471
835
|
* lifecycleLabels?: unknown
|
|
472
836
|
* readyLabel?: unknown
|
|
@@ -529,8 +893,7 @@ export function formatNormalizationHoldNote() {
|
|
|
529
893
|
"it was not put into the queue that agents work from.",
|
|
530
894
|
"- What changed: nothing at all. It was left exactly as it is, and " +
|
|
531
895
|
"nothing will pick it up on its own.",
|
|
532
|
-
|
|
533
|
-
"into the build queue.",
|
|
896
|
+
RESUME_INSTRUCTION,
|
|
534
897
|
"",
|
|
535
898
|
NORMALIZATION_HOLD_NOTE_MARKER,
|
|
536
899
|
].join("\n");
|
|
@@ -553,8 +916,7 @@ export function formatHumanGateNote() {
|
|
|
553
916
|
"been picked up and built anyway.",
|
|
554
917
|
"- What changed: it has been taken out of that queue and flagged as " +
|
|
555
918
|
"needing a person, so nothing will build it automatically.",
|
|
556
|
-
|
|
557
|
-
"back in the build queue.",
|
|
919
|
+
RESUME_INSTRUCTION,
|
|
558
920
|
"",
|
|
559
921
|
HUMAN_GATE_NOTE_MARKER,
|
|
560
922
|
].join("\n");
|
|
@@ -596,3 +958,22 @@ export function summarizeHumanGateHolds(held = []) {
|
|
|
596
958
|
if (names.length === 0) return "Held for a person: none.";
|
|
597
959
|
return `Held for a person (${String(names.length)}): ${names.join(", ")}.`;
|
|
598
960
|
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Render the cycle-summary line naming what was RELEASED.
|
|
964
|
+
*
|
|
965
|
+
* The counterpart of {@link summarizeHumanGateHolds}, printed even when it is
|
|
966
|
+
* zero. Without it a release path that has stopped working is indistinguishable
|
|
967
|
+
* from a cycle where nothing needed releasing — which is exactly how the
|
|
968
|
+
* missing inverse went unnoticed for as long as it did, and a fix that cannot
|
|
969
|
+
* be observed to fire is a fix nobody can tell has regressed.
|
|
970
|
+
* @param {readonly unknown[]} released - Item references released this cycle
|
|
971
|
+
* @returns {string} One summary line
|
|
972
|
+
*/
|
|
973
|
+
export function summarizeHumanGateReleases(released = []) {
|
|
974
|
+
const names = (Array.isArray(released) ? released : [])
|
|
975
|
+
.map(item => trimmedString(item))
|
|
976
|
+
.filter(name => name.length > 0);
|
|
977
|
+
if (names.length === 0) return "Released back to the queue: none.";
|
|
978
|
+
return `Released back to the queue (${String(names.length)}): ${names.join(", ")}.`;
|
|
979
|
+
}
|