@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.
Files changed (578) hide show
  1. package/all/copy-contents/.gitattributes +8 -0
  2. package/all/copy-overwrite/scripts/check-orphaned-branches.mjs +78 -9
  3. package/all/copy-overwrite/scripts/check-third-party-action-pins.mjs +17 -1
  4. package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +194 -7
  5. package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +31 -0
  6. package/all/copy-overwrite/scripts/lisa-hooks/block-blind-automerge.sh +81 -2
  7. package/all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh +293 -8
  8. package/all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh +21 -0
  9. package/all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh +78 -15
  10. package/all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh +21 -0
  11. package/all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh +21 -0
  12. package/all/copy-overwrite/scripts/lisa-hooks/guard-dedupe.bash +340 -0
  13. package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +29 -1
  14. package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.mjs +183 -1
  15. package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.sh +21 -0
  16. package/all/copy-overwrite/scripts/lisa-postinstall.mjs +21 -1
  17. package/all/copy-overwrite/scripts/lisa-run-gates.mjs +100 -5
  18. package/all/copy-overwrite/scripts/lisa-work-item.mjs +1085 -80
  19. package/all/create-only/.github/workflows/continuous-gates.yml +7 -0
  20. package/cdk/create-only/.github/workflows/ci.yml +7 -0
  21. package/cdk/create-only/.github/workflows/deploy.yml +21 -0
  22. package/dist/cli/apply.d.ts.map +1 -1
  23. package/dist/cli/apply.js +9 -1
  24. package/dist/cli/apply.js.map +1 -1
  25. package/dist/cli/doctor-apply-deletions.d.ts +61 -0
  26. package/dist/cli/doctor-apply-deletions.d.ts.map +1 -0
  27. package/dist/cli/doctor-apply-deletions.js +137 -0
  28. package/dist/cli/doctor-apply-deletions.js.map +1 -0
  29. package/dist/cli/doctor-cdk-preset-adoption.d.ts +15 -0
  30. package/dist/cli/doctor-cdk-preset-adoption.d.ts.map +1 -0
  31. package/dist/cli/doctor-cdk-preset-adoption.js +316 -0
  32. package/dist/cli/doctor-cdk-preset-adoption.js.map +1 -0
  33. package/dist/cli/doctor-config-shadowing.d.ts +22 -0
  34. package/dist/cli/doctor-config-shadowing.d.ts.map +1 -0
  35. package/dist/cli/doctor-config-shadowing.js +123 -0
  36. package/dist/cli/doctor-config-shadowing.js.map +1 -0
  37. package/dist/cli/doctor-rails-deploy-intent.d.ts +15 -0
  38. package/dist/cli/doctor-rails-deploy-intent.d.ts.map +1 -0
  39. package/dist/cli/doctor-rails-deploy-intent.js +197 -0
  40. package/dist/cli/doctor-rails-deploy-intent.js.map +1 -0
  41. package/dist/cli/doctor-seeded-artifacts.d.ts +12 -0
  42. package/dist/cli/doctor-seeded-artifacts.d.ts.map +1 -0
  43. package/dist/cli/doctor-seeded-artifacts.js +54 -0
  44. package/dist/cli/doctor-seeded-artifacts.js.map +1 -0
  45. package/dist/cli/doctor-stale-banner-scan.d.ts +44 -0
  46. package/dist/cli/doctor-stale-banner-scan.d.ts.map +1 -0
  47. package/dist/cli/doctor-stale-banner-scan.js +152 -0
  48. package/dist/cli/doctor-stale-banner-scan.js.map +1 -0
  49. package/dist/cli/doctor-stale-managed-banner.d.ts +19 -0
  50. package/dist/cli/doctor-stale-managed-banner.d.ts.map +1 -0
  51. package/dist/cli/doctor-stale-managed-banner.js +198 -0
  52. package/dist/cli/doctor-stale-managed-banner.js.map +1 -0
  53. package/dist/cli/doctor.d.ts.map +1 -1
  54. package/dist/cli/doctor.js +16 -0
  55. package/dist/cli/doctor.js.map +1 -1
  56. package/dist/cli/ui-detected-stacks.d.ts.map +1 -1
  57. package/dist/cli/ui-detected-stacks.js +3 -2
  58. package/dist/cli/ui-detected-stacks.js.map +1 -1
  59. package/dist/cli/update-check.d.ts.map +1 -1
  60. package/dist/cli/update-check.js +14 -0
  61. package/dist/cli/update-check.js.map +1 -1
  62. package/dist/cli/worktree-liveness.d.ts +5 -0
  63. package/dist/cli/worktree-liveness.d.ts.map +1 -1
  64. package/dist/cli/worktree-liveness.js +7 -6
  65. package/dist/cli/worktree-liveness.js.map +1 -1
  66. package/dist/cli/worktree-ownership.d.ts +13 -0
  67. package/dist/cli/worktree-ownership.d.ts.map +1 -1
  68. package/dist/cli/worktree-ownership.js +14 -0
  69. package/dist/cli/worktree-ownership.js.map +1 -1
  70. package/dist/configs/eslint/base.d.ts +34 -0
  71. package/dist/configs/eslint/base.d.ts.map +1 -1
  72. package/dist/configs/eslint/base.js +34 -0
  73. package/dist/configs/eslint/base.js.map +1 -1
  74. package/dist/core/apply-receipt.d.ts +65 -0
  75. package/dist/core/apply-receipt.d.ts.map +1 -1
  76. package/dist/core/apply-receipt.js +62 -2
  77. package/dist/core/apply-receipt.js.map +1 -1
  78. package/dist/core/cdk-preset-adoption.d.ts +136 -0
  79. package/dist/core/cdk-preset-adoption.d.ts.map +1 -0
  80. package/dist/core/cdk-preset-adoption.js +135 -0
  81. package/dist/core/cdk-preset-adoption.js.map +1 -0
  82. package/dist/core/config-shadowing.d.ts +36 -0
  83. package/dist/core/config-shadowing.d.ts.map +1 -1
  84. package/dist/core/config-shadowing.js +38 -0
  85. package/dist/core/config-shadowing.js.map +1 -1
  86. package/dist/core/config.d.ts +11 -0
  87. package/dist/core/config.d.ts.map +1 -1
  88. package/dist/core/config.js.map +1 -1
  89. package/dist/core/learnings-merge-driver.d.ts +10 -0
  90. package/dist/core/learnings-merge-driver.d.ts.map +1 -1
  91. package/dist/core/learnings-merge-driver.js +18 -0
  92. package/dist/core/learnings-merge-driver.js.map +1 -1
  93. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  94. package/dist/core/lisa-owned-hash-ledger.js +136 -0
  95. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  96. package/dist/core/lisa.d.ts.map +1 -1
  97. package/dist/core/lisa.js +9 -1
  98. package/dist/core/lisa.js.map +1 -1
  99. package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts +5 -5
  100. package/dist/core/nightly-e2e-guard-behavior-certificate.js +7 -7
  101. package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
  102. package/dist/core/ownership-header.d.ts +74 -0
  103. package/dist/core/ownership-header.d.ts.map +1 -0
  104. package/dist/core/ownership-header.js +76 -0
  105. package/dist/core/ownership-header.js.map +1 -0
  106. package/dist/core/rails-deploy-production-intent.d.ts +36 -0
  107. package/dist/core/rails-deploy-production-intent.d.ts.map +1 -0
  108. package/dist/core/rails-deploy-production-intent.js +79 -0
  109. package/dist/core/rails-deploy-production-intent.js.map +1 -0
  110. package/dist/core/stale-managed-banner.d.ts +78 -0
  111. package/dist/core/stale-managed-banner.d.ts.map +1 -0
  112. package/dist/core/stale-managed-banner.js +118 -0
  113. package/dist/core/stale-managed-banner.js.map +1 -0
  114. package/dist/core/two-channel-delivery-scan.d.ts +33 -1
  115. package/dist/core/two-channel-delivery-scan.d.ts.map +1 -1
  116. package/dist/core/two-channel-delivery-scan.js +133 -6
  117. package/dist/core/two-channel-delivery-scan.js.map +1 -1
  118. package/dist/core/two-channel-delivery.d.ts +101 -4
  119. package/dist/core/two-channel-delivery.d.ts.map +1 -1
  120. package/dist/core/two-channel-delivery.js +121 -13
  121. package/dist/core/two-channel-delivery.js.map +1 -1
  122. package/dist/core/two-channel-staleness.d.ts +137 -0
  123. package/dist/core/two-channel-staleness.d.ts.map +1 -0
  124. package/dist/core/two-channel-staleness.js +268 -0
  125. package/dist/core/two-channel-staleness.js.map +1 -0
  126. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  127. package/dist/core/upstream-evidence-manifest.js +265 -121
  128. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  129. package/dist/core/workflow-deletion-ownership.d.ts +6 -24
  130. package/dist/core/workflow-deletion-ownership.d.ts.map +1 -1
  131. package/dist/core/workflow-deletion-ownership.js +22 -42
  132. package/dist/core/workflow-deletion-ownership.js.map +1 -1
  133. package/dist/detection/detectors/cdk.d.ts.map +1 -1
  134. package/dist/detection/detectors/cdk.js +2 -1
  135. package/dist/detection/detectors/cdk.js.map +1 -1
  136. package/dist/health/template-inspection.d.ts.map +1 -1
  137. package/dist/health/template-inspection.js +2 -1
  138. package/dist/health/template-inspection.js.map +1 -1
  139. package/dist/migrations/ensure-lisa-postinstall.d.ts +16 -0
  140. package/dist/migrations/ensure-lisa-postinstall.d.ts.map +1 -1
  141. package/dist/migrations/ensure-lisa-postinstall.js +16 -0
  142. package/dist/migrations/ensure-lisa-postinstall.js.map +1 -1
  143. package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts +2 -2
  144. package/dist/migrations/ensure-pinned-reusable-workflow-refs.d.ts.map +1 -1
  145. package/dist/migrations/ensure-pinned-reusable-workflow-refs.js +98 -34
  146. package/dist/migrations/ensure-pinned-reusable-workflow-refs.js.map +1 -1
  147. package/dist/migrations/ensure-playwright-dedicated-caller.d.ts.map +1 -1
  148. package/dist/migrations/ensure-playwright-dedicated-caller.js +1 -0
  149. package/dist/migrations/ensure-playwright-dedicated-caller.js.map +1 -1
  150. package/dist/opencode/hooks-installer.d.ts.map +1 -1
  151. package/dist/opencode/hooks-installer.js +1 -0
  152. package/dist/opencode/hooks-installer.js.map +1 -1
  153. package/dist/opencode/plugin-templates/block-managed-file-edits.sh +78 -15
  154. package/dist/opencode/plugin-templates/block-no-verify.sh +21 -0
  155. package/dist/opencode/plugin-templates/guard-dedupe.bash +337 -0
  156. package/dist/opencode/plugin-templates/lisa-block-direct-issue-create.ts +242 -55
  157. package/dist/opencode/plugin-templates/parity-safety-net.sh +29 -1
  158. package/dist/strategies/package-lisa.d.ts.map +1 -1
  159. package/dist/strategies/package-lisa.js +2 -1
  160. package/dist/strategies/package-lisa.js.map +1 -1
  161. package/dist/utils/path-utils.d.ts +29 -0
  162. package/dist/utils/path-utils.d.ts.map +1 -1
  163. package/dist/utils/path-utils.js +41 -0
  164. package/dist/utils/path-utils.js.map +1 -1
  165. package/expo/create-only/.github/workflows/ci.yml +21 -0
  166. package/expo/create-only/.github/workflows/deploy.yml +28 -0
  167. package/expo/create-only/.github/workflows/maestro-e2e.yml +7 -0
  168. package/expo/create-only/.github/workflows/nightly-e2e-bypass-reaper.yml +124 -13
  169. package/expo/create-only/.github/workflows/nightly-e2e-health.yml +7 -0
  170. package/expo/create-only/.github/workflows/nightly-e2e-report.yml +7 -0
  171. package/expo/create-only/.github/workflows/nightly-e2e-tracking.yml +8 -0
  172. package/expo/create-only/.github/workflows/playwright-e2e.yml +7 -0
  173. package/harper-fabric/copy-overwrite/.github/workflows/ci.yml +7 -0
  174. package/harper-fabric/create-only/.github/workflows/deploy.yml +14 -0
  175. package/nestjs/create-only/.github/workflows/ci.yml +14 -0
  176. package/nestjs/create-only/.github/workflows/deploy.yml +28 -0
  177. package/package.json +10 -5
  178. package/phaser/copy-overwrite/.github/workflows/ci.yml +7 -0
  179. package/plugins/lisa/.claude-plugin/plugin.json +28 -1
  180. package/plugins/lisa/.codex-plugin/hooks.json +27 -0
  181. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  182. package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  183. package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +27 -4
  184. package/plugins/lisa/.codex-plugin/skills/lisa-github-prd-intake/SKILL.md +1 -1
  185. package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +22 -0
  186. package/plugins/lisa/.codex-plugin/skills/lisa-github-verify/SKILL.md +14 -0
  187. package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +51 -0
  188. package/plugins/lisa/.codex-plugin/skills/lisa-intake/SKILL.md +1 -1
  189. package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +27 -4
  190. package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  191. package/plugins/lisa/.codex-plugin/skills/lisa-jira-verify/SKILL.md +14 -0
  192. package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  193. package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +55 -2
  194. package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +27 -4
  195. package/plugins/lisa/.codex-plugin/skills/lisa-linear-prd-intake/SKILL.md +47 -30
  196. package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  197. package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  198. package/plugins/lisa/.codex-plugin/skills/lisa-linear-verify/SKILL.md +14 -0
  199. package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +54 -3
  200. package/plugins/lisa/.codex-plugin/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  201. package/plugins/lisa/.codex-plugin/skills/lisa-qa-clear/SKILL.md +19 -7
  202. package/plugins/lisa/.codex-plugin/skills/lisa-qa-fail/SKILL.md +28 -3
  203. package/plugins/lisa/.codex-plugin/skills/lisa-qa-queue/SKILL.md +28 -3
  204. package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +94 -24
  205. package/plugins/lisa/.codex-plugin/skills/lisa-rework-triage/SKILL.md +32 -2
  206. package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +4 -4
  207. package/plugins/lisa/.codex-plugin/skills/lisa-track/SKILL.md +1 -1
  208. package/plugins/lisa/.codex-plugin/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  209. package/plugins/lisa/agents/linear-prd-intake.md +8 -8
  210. package/plugins/lisa/hooks/block-blind-automerge.sh +81 -2
  211. package/plugins/lisa/hooks/block-direct-issue-create.agy.sh +64 -16
  212. package/plugins/lisa/hooks/block-direct-issue-create.sh +293 -8
  213. package/plugins/lisa/hooks/block-instruction-file-edits.sh +21 -0
  214. package/plugins/lisa/hooks/block-managed-file-edits.sh +78 -15
  215. package/plugins/lisa/hooks/block-no-verify.sh +21 -0
  216. package/plugins/lisa/hooks/block-shell-json-parsing.sh +21 -0
  217. package/plugins/lisa/hooks/failure-signature-index.mjs +240 -5
  218. package/plugins/lisa/hooks/guard-dedupe.bash +337 -0
  219. package/plugins/lisa/hooks/inject-rules.sh +13 -5
  220. package/plugins/lisa/hooks/operational-hazards.mjs +736 -0
  221. package/plugins/lisa/hooks/operational-hazards.sh +28 -0
  222. package/plugins/lisa/hooks/parity-safety-net.sh +29 -1
  223. package/plugins/lisa/hooks/threshold-ratchet-compare.mjs +102 -21
  224. package/plugins/lisa/hooks/threshold-ratchet-families.mjs +130 -2
  225. package/plugins/lisa/hooks/threshold-ratchet.mjs +63 -13
  226. package/plugins/lisa/hooks/worktree-binding-guard.mjs +183 -1
  227. package/plugins/lisa/hooks/worktree-binding-guard.sh +21 -0
  228. package/plugins/lisa/rules/eager/00-rule-index.md +1 -0
  229. package/plugins/lisa/rules/eager/operational-hazards.md +50 -0
  230. package/plugins/lisa/rules/eager/tracked-work.md +1 -1
  231. package/plugins/lisa/rules/reference/config-resolution.md +1 -1
  232. package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +1 -1
  233. package/plugins/lisa/rules/reference/operational-hazards.md +115 -0
  234. package/plugins/lisa/rules/reference/work-item-trailer-definition.md +129 -0
  235. package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +407 -26
  236. package/plugins/lisa/scripts/qa-signal-lifecycle.mjs +507 -0
  237. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  238. package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +27 -4
  239. package/plugins/lisa/skills/lisa-github-prd-intake/SKILL.md +1 -1
  240. package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +22 -0
  241. package/plugins/lisa/skills/lisa-github-verify/SKILL.md +14 -0
  242. package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +51 -0
  243. package/plugins/lisa/skills/lisa-intake/SKILL.md +1 -1
  244. package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +27 -4
  245. package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  246. package/plugins/lisa/skills/lisa-jira-verify/SKILL.md +14 -0
  247. package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  248. package/plugins/lisa/skills/lisa-linear-access/SKILL.md +55 -2
  249. package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +27 -4
  250. package/plugins/lisa/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  251. package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  252. package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  253. package/plugins/lisa/skills/lisa-linear-verify/SKILL.md +14 -0
  254. package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +54 -3
  255. package/plugins/lisa/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  256. package/plugins/lisa/skills/lisa-qa-clear/SKILL.md +19 -7
  257. package/plugins/lisa/skills/lisa-qa-fail/SKILL.md +28 -3
  258. package/plugins/lisa/skills/lisa-qa-queue/SKILL.md +28 -3
  259. package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +94 -24
  260. package/plugins/lisa/skills/lisa-rework-triage/SKILL.md +32 -2
  261. package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +5 -5
  262. package/plugins/lisa/skills/lisa-track/SKILL.md +1 -1
  263. package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  264. package/plugins/lisa-agy/agents/linear-prd-intake.md +8 -8
  265. package/plugins/lisa-agy/hooks/block-blind-automerge.sh +81 -2
  266. package/plugins/lisa-agy/hooks/block-direct-issue-create.agy.sh +64 -16
  267. package/plugins/lisa-agy/hooks/block-direct-issue-create.sh +293 -8
  268. package/plugins/lisa-agy/hooks/block-instruction-file-edits.sh +21 -0
  269. package/plugins/lisa-agy/hooks/block-managed-file-edits.sh +78 -15
  270. package/plugins/lisa-agy/hooks/block-shell-json-parsing.sh +21 -0
  271. package/plugins/lisa-agy/hooks/guard-dedupe.bash +337 -0
  272. package/plugins/lisa-agy/hooks/parity-safety-net.sh +29 -1
  273. package/plugins/lisa-agy/hooks.json +1 -1
  274. package/plugins/lisa-agy/plugin.json +1 -1
  275. package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +407 -26
  276. package/plugins/lisa-agy/scripts/qa-signal-lifecycle.mjs +507 -0
  277. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  278. package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +27 -4
  279. package/plugins/lisa-agy/skills/lisa-github-prd-intake/SKILL.md +1 -1
  280. package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +22 -0
  281. package/plugins/lisa-agy/skills/lisa-github-verify/SKILL.md +14 -0
  282. package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +51 -0
  283. package/plugins/lisa-agy/skills/lisa-intake/SKILL.md +1 -1
  284. package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +27 -4
  285. package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  286. package/plugins/lisa-agy/skills/lisa-jira-verify/SKILL.md +14 -0
  287. package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  288. package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +55 -2
  289. package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +27 -4
  290. package/plugins/lisa-agy/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  291. package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  292. package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  293. package/plugins/lisa-agy/skills/lisa-linear-verify/SKILL.md +14 -0
  294. package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +54 -3
  295. package/plugins/lisa-agy/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  296. package/plugins/lisa-agy/skills/lisa-qa-clear/SKILL.md +19 -7
  297. package/plugins/lisa-agy/skills/lisa-qa-fail/SKILL.md +28 -3
  298. package/plugins/lisa-agy/skills/lisa-qa-queue/SKILL.md +28 -3
  299. package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +94 -24
  300. package/plugins/lisa-agy/skills/lisa-rework-triage/SKILL.md +32 -2
  301. package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +5 -5
  302. package/plugins/lisa-agy/skills/lisa-track/SKILL.md +1 -1
  303. package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  304. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  305. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  306. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  307. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  308. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  309. package/plugins/lisa-copilot/.claude-plugin/plugin.json +19 -1
  310. package/plugins/lisa-copilot/agents/linear-prd-intake.agent.md +8 -8
  311. package/plugins/lisa-copilot/hooks/block-blind-automerge.sh +81 -2
  312. package/plugins/lisa-copilot/hooks/block-direct-issue-create.sh +293 -8
  313. package/plugins/lisa-copilot/hooks/block-instruction-file-edits.sh +21 -0
  314. package/plugins/lisa-copilot/hooks/block-managed-file-edits.sh +78 -15
  315. package/plugins/lisa-copilot/hooks/block-no-verify.sh +21 -0
  316. package/plugins/lisa-copilot/hooks/block-shell-json-parsing.sh +21 -0
  317. package/plugins/lisa-copilot/hooks/failure-signature-index.mjs +240 -5
  318. package/plugins/lisa-copilot/hooks/guard-dedupe.bash +337 -0
  319. package/plugins/lisa-copilot/hooks/inject-rules.sh +13 -5
  320. package/plugins/lisa-copilot/hooks/operational-hazards.mjs +736 -0
  321. package/plugins/lisa-copilot/hooks/operational-hazards.sh +28 -0
  322. package/plugins/lisa-copilot/hooks/parity-safety-net.sh +29 -1
  323. package/plugins/lisa-copilot/hooks/threshold-ratchet-compare.mjs +102 -21
  324. package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +130 -2
  325. package/plugins/lisa-copilot/hooks/threshold-ratchet.mjs +63 -13
  326. package/plugins/lisa-copilot/hooks/worktree-binding-guard.mjs +183 -1
  327. package/plugins/lisa-copilot/hooks/worktree-binding-guard.sh +21 -0
  328. package/plugins/lisa-copilot/rules/eager/00-rule-index.md +1 -0
  329. package/plugins/lisa-copilot/rules/eager/operational-hazards.md +50 -0
  330. package/plugins/lisa-copilot/rules/eager/tracked-work.md +1 -1
  331. package/plugins/lisa-copilot/rules/reference/config-resolution.md +1 -1
  332. package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +1 -1
  333. package/plugins/lisa-copilot/rules/reference/operational-hazards.md +115 -0
  334. package/plugins/lisa-copilot/rules/reference/work-item-trailer-definition.md +129 -0
  335. package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +407 -26
  336. package/plugins/lisa-copilot/scripts/qa-signal-lifecycle.mjs +507 -0
  337. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  338. package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +27 -4
  339. package/plugins/lisa-copilot/skills/lisa-github-prd-intake/SKILL.md +1 -1
  340. package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +22 -0
  341. package/plugins/lisa-copilot/skills/lisa-github-verify/SKILL.md +14 -0
  342. package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +51 -0
  343. package/plugins/lisa-copilot/skills/lisa-intake/SKILL.md +1 -1
  344. package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +27 -4
  345. package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  346. package/plugins/lisa-copilot/skills/lisa-jira-verify/SKILL.md +14 -0
  347. package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  348. package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +55 -2
  349. package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +27 -4
  350. package/plugins/lisa-copilot/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  351. package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  352. package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  353. package/plugins/lisa-copilot/skills/lisa-linear-verify/SKILL.md +14 -0
  354. package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +54 -3
  355. package/plugins/lisa-copilot/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  356. package/plugins/lisa-copilot/skills/lisa-qa-clear/SKILL.md +19 -7
  357. package/plugins/lisa-copilot/skills/lisa-qa-fail/SKILL.md +28 -3
  358. package/plugins/lisa-copilot/skills/lisa-qa-queue/SKILL.md +28 -3
  359. package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +94 -24
  360. package/plugins/lisa-copilot/skills/lisa-rework-triage/SKILL.md +32 -2
  361. package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +5 -5
  362. package/plugins/lisa-copilot/skills/lisa-track/SKILL.md +1 -1
  363. package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  364. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  365. package/plugins/lisa-cursor/agents/linear-prd-intake.md +8 -8
  366. package/plugins/lisa-cursor/hooks/block-blind-automerge.sh +81 -2
  367. package/plugins/lisa-cursor/hooks/block-direct-issue-create.sh +293 -8
  368. package/plugins/lisa-cursor/hooks/block-instruction-file-edits.sh +21 -0
  369. package/plugins/lisa-cursor/hooks/block-managed-file-edits.sh +78 -15
  370. package/plugins/lisa-cursor/hooks/block-no-verify.sh +21 -0
  371. package/plugins/lisa-cursor/hooks/block-shell-json-parsing.sh +21 -0
  372. package/plugins/lisa-cursor/hooks/failure-signature-index.mjs +240 -5
  373. package/plugins/lisa-cursor/hooks/guard-dedupe.bash +337 -0
  374. package/plugins/lisa-cursor/hooks/hooks.json +10 -0
  375. package/plugins/lisa-cursor/hooks/operational-hazards.mjs +736 -0
  376. package/plugins/lisa-cursor/hooks/operational-hazards.sh +28 -0
  377. package/plugins/lisa-cursor/hooks/parity-safety-net.sh +29 -1
  378. package/plugins/lisa-cursor/hooks/threshold-ratchet-compare.mjs +102 -21
  379. package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +130 -2
  380. package/plugins/lisa-cursor/hooks/threshold-ratchet.mjs +63 -13
  381. package/plugins/lisa-cursor/hooks/worktree-binding-guard.mjs +183 -1
  382. package/plugins/lisa-cursor/hooks/worktree-binding-guard.sh +21 -0
  383. package/plugins/lisa-cursor/rules/00-rule-index.mdc +1 -0
  384. package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +1 -1
  385. package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +1 -1
  386. package/plugins/lisa-cursor/rules/operational-hazards-reference.mdc +120 -0
  387. package/plugins/lisa-cursor/rules/operational-hazards.mdc +55 -0
  388. package/plugins/lisa-cursor/rules/tracked-work.mdc +1 -1
  389. package/plugins/lisa-cursor/rules/work-item-trailer-definition-reference.mdc +134 -0
  390. package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +407 -26
  391. package/plugins/lisa-cursor/scripts/qa-signal-lifecycle.mjs +507 -0
  392. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  393. package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +27 -4
  394. package/plugins/lisa-cursor/skills/lisa-github-prd-intake/SKILL.md +1 -1
  395. package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +22 -0
  396. package/plugins/lisa-cursor/skills/lisa-github-verify/SKILL.md +14 -0
  397. package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +51 -0
  398. package/plugins/lisa-cursor/skills/lisa-intake/SKILL.md +1 -1
  399. package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +27 -4
  400. package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  401. package/plugins/lisa-cursor/skills/lisa-jira-verify/SKILL.md +14 -0
  402. package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  403. package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +55 -2
  404. package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +27 -4
  405. package/plugins/lisa-cursor/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  406. package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  407. package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  408. package/plugins/lisa-cursor/skills/lisa-linear-verify/SKILL.md +14 -0
  409. package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +54 -3
  410. package/plugins/lisa-cursor/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  411. package/plugins/lisa-cursor/skills/lisa-qa-clear/SKILL.md +19 -7
  412. package/plugins/lisa-cursor/skills/lisa-qa-fail/SKILL.md +28 -3
  413. package/plugins/lisa-cursor/skills/lisa-qa-queue/SKILL.md +28 -3
  414. package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +94 -24
  415. package/plugins/lisa-cursor/skills/lisa-rework-triage/SKILL.md +32 -2
  416. package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +5 -5
  417. package/plugins/lisa-cursor/skills/lisa-track/SKILL.md +1 -1
  418. package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  419. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  420. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  421. package/plugins/lisa-expo-agy/plugin.json +1 -1
  422. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  423. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  424. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  425. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  426. package/plugins/lisa-harper-fabric/hooks/inject-rules.sh +14 -3
  427. package/plugins/lisa-harper-fabric/rules/eager/harper-fabric.md +31 -0
  428. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  429. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  430. package/plugins/lisa-harper-fabric-copilot/hooks/inject-rules.sh +14 -3
  431. package/plugins/lisa-harper-fabric-copilot/rules/eager/harper-fabric.md +31 -0
  432. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  433. package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric-reference.mdc +57 -0
  434. package/plugins/lisa-harper-fabric-cursor/rules/harper-fabric.mdc +32 -53
  435. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  436. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  437. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  438. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  439. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  440. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  441. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  442. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  443. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  444. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  445. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  446. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  447. package/plugins/lisa-phaser/hooks/inject-rules.sh +14 -3
  448. package/plugins/lisa-phaser/rules/eager/phaser.md +44 -0
  449. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  450. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  451. package/plugins/lisa-phaser-copilot/hooks/inject-rules.sh +14 -3
  452. package/plugins/lisa-phaser-copilot/rules/eager/phaser.md +44 -0
  453. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  454. package/plugins/lisa-phaser-cursor/rules/phaser-reference.mdc +189 -0
  455. package/plugins/lisa-phaser-cursor/rules/phaser.mdc +45 -185
  456. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  457. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  458. package/plugins/lisa-rails/hooks/inject-rules.sh +14 -4
  459. package/plugins/lisa-rails/rules/eager/rails-conventions.md +23 -0
  460. package/plugins/lisa-rails-agy/plugin.json +1 -1
  461. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  462. package/plugins/lisa-rails-copilot/hooks/inject-rules.sh +14 -4
  463. package/plugins/lisa-rails-copilot/rules/eager/rails-conventions.md +23 -0
  464. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  465. package/plugins/lisa-rails-cursor/rules/rails-conventions-reference.mdc +181 -0
  466. package/plugins/lisa-rails-cursor/rules/rails-conventions.mdc +24 -177
  467. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  468. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  469. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  470. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  471. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  472. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  473. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  474. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  475. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  476. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  477. package/plugins/materialized-artifacts.json +1 -0
  478. package/plugins/src/base/.claude-plugin/plugin.json +27 -0
  479. package/plugins/src/base/agents/linear-prd-intake.md +8 -8
  480. package/plugins/src/base/hooks/block-blind-automerge.sh +81 -2
  481. package/plugins/src/base/hooks/block-direct-issue-create.agy.sh +64 -16
  482. package/plugins/src/base/hooks/block-direct-issue-create.sh +293 -8
  483. package/plugins/src/base/hooks/block-instruction-file-edits.sh +21 -0
  484. package/plugins/src/base/hooks/block-managed-file-edits.sh +78 -15
  485. package/plugins/src/base/hooks/block-no-verify.sh +21 -0
  486. package/plugins/src/base/hooks/block-shell-json-parsing.sh +21 -0
  487. package/plugins/src/base/hooks/failure-signature-index.mjs +240 -5
  488. package/plugins/src/base/hooks/guard-dedupe.bash +337 -0
  489. package/plugins/src/base/hooks/inject-rules.sh +13 -5
  490. package/plugins/src/base/hooks/operational-hazards.mjs +736 -0
  491. package/plugins/src/base/hooks/operational-hazards.sh +28 -0
  492. package/plugins/src/base/hooks/parity-safety-net.sh +29 -1
  493. package/plugins/src/base/hooks/threshold-ratchet-compare.mjs +102 -21
  494. package/plugins/src/base/hooks/threshold-ratchet-families.mjs +130 -2
  495. package/plugins/src/base/hooks/threshold-ratchet.mjs +63 -13
  496. package/plugins/src/base/hooks/worktree-binding-guard.mjs +183 -1
  497. package/plugins/src/base/hooks/worktree-binding-guard.sh +21 -0
  498. package/plugins/src/base/rules/eager/00-rule-index.md +1 -0
  499. package/plugins/src/base/rules/eager/operational-hazards.md +50 -0
  500. package/plugins/src/base/rules/eager/tracked-work.md +1 -1
  501. package/plugins/src/base/rules/reference/config-resolution.md +1 -1
  502. package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +1 -1
  503. package/plugins/src/base/rules/reference/operational-hazards.md +115 -0
  504. package/plugins/src/base/rules/reference/work-item-trailer-definition.md +129 -0
  505. package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +407 -26
  506. package/plugins/src/base/scripts/qa-signal-lifecycle.mjs +507 -0
  507. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +130 -19
  508. package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +27 -4
  509. package/plugins/src/base/skills/lisa-github-prd-intake/SKILL.md +1 -1
  510. package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +22 -0
  511. package/plugins/src/base/skills/lisa-github-verify/SKILL.md +14 -0
  512. package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +51 -0
  513. package/plugins/src/base/skills/lisa-intake/SKILL.md +1 -1
  514. package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +27 -4
  515. package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +22 -0
  516. package/plugins/src/base/skills/lisa-jira-verify/SKILL.md +14 -0
  517. package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +51 -0
  518. package/plugins/src/base/skills/lisa-linear-access/SKILL.md +55 -2
  519. package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +27 -4
  520. package/plugins/src/base/skills/lisa-linear-prd-intake/SKILL.md +48 -31
  521. package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  522. package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +22 -0
  523. package/plugins/src/base/skills/lisa-linear-verify/SKILL.md +14 -0
  524. package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +54 -3
  525. package/plugins/src/base/skills/lisa-prd-ticket-coverage/SKILL.md +2 -2
  526. package/plugins/src/base/skills/lisa-qa-clear/SKILL.md +19 -7
  527. package/plugins/src/base/skills/lisa-qa-fail/SKILL.md +28 -3
  528. package/plugins/src/base/skills/lisa-qa-queue/SKILL.md +28 -3
  529. package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +94 -24
  530. package/plugins/src/base/skills/lisa-rework-triage/SKILL.md +32 -2
  531. package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +5 -5
  532. package/plugins/src/base/skills/lisa-track/SKILL.md +1 -1
  533. package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +9 -0
  534. package/plugins/src/harper-fabric/hooks/inject-rules.sh +14 -3
  535. package/plugins/src/harper-fabric/rules/eager/harper-fabric.md +31 -0
  536. package/plugins/src/phaser/hooks/inject-rules.sh +14 -3
  537. package/plugins/src/phaser/rules/eager/phaser.md +44 -0
  538. package/plugins/src/rails/hooks/inject-rules.sh +14 -4
  539. package/plugins/src/rails/rules/eager/rails-conventions.md +23 -0
  540. package/rails/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
  541. package/rails/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
  542. package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
  543. package/rails/create-only/.github/workflows/ci.yml +8 -0
  544. package/rails/create-only/.github/workflows/deploy.yml +22 -0
  545. package/scripts/build-plugins.sh +2 -1
  546. package/scripts/check-engine-floor.mjs +361 -0
  547. package/scripts/check-guard-parity-notes.mjs +709 -0
  548. package/scripts/check-template-workflow-refs.mjs +9 -0
  549. package/scripts/check-third-party-action-pins.mjs +17 -1
  550. package/scripts/check-workflow-contract-assertions.mjs +480 -0
  551. package/scripts/copy-opencode-plugin-templates.mjs +1 -0
  552. package/scripts/deployed-guard-advice.mjs +636 -0
  553. package/scripts/generate-agy-plugin-artifacts.mjs +35 -10
  554. package/scripts/generate-export-surface.mjs +105 -19
  555. package/scripts/generate-two-channel-couplings.ts +143 -212
  556. package/scripts/lisa-enforcement-fallback.sh +31 -0
  557. package/scripts/measure-scripts-profile-gap.mts +361 -0
  558. package/scripts/mutation-performance-measure.mjs +21 -5
  559. package/scripts/reconcile-release-tags.mjs +65 -84
  560. package/scripts/two-channel-couplings.json +302 -70
  561. package/scripts/workflow-contract-assertion.sh +47 -0
  562. package/typescript/copy-overwrite/.lintstagedrc.json +1 -0
  563. package/typescript/copy-overwrite/eslint.ignore.config.json +1 -0
  564. package/typescript/copy-overwrite/scripts/check-nightly-e2e-health.mjs +527 -53
  565. package/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +301 -13
  566. package/typescript/copy-overwrite/scripts/check-threshold-ratchet.mjs +63 -13
  567. package/typescript/copy-overwrite/scripts/threshold-ratchet-compare.mjs +102 -21
  568. package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +130 -2
  569. package/typescript/create-only/.github/workflows/ci.yml +7 -0
  570. /package/plugins/lisa-harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
  571. /package/plugins/lisa-harper-fabric-copilot/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
  572. /package/plugins/lisa-phaser/rules/{phaser.md → reference/phaser.md} +0 -0
  573. /package/plugins/lisa-phaser-copilot/rules/{phaser.md → reference/phaser.md} +0 -0
  574. /package/plugins/lisa-rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
  575. /package/plugins/lisa-rails-copilot/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
  576. /package/plugins/src/harper-fabric/rules/{harper-fabric.md → reference/harper-fabric.md} +0 -0
  577. /package/plugins/src/phaser/rules/{phaser.md → reference/phaser.md} +0 -0
  578. /package/plugins/src/rails/rules/{rails-conventions.md → reference/rails-conventions.md} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownership-header.d.ts","sourceRoot":"","sources":["../../src/core/ownership-header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAE1C;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,6DAA6D;AAC7D,MAAM,MAAM,eAAe;AACzB,wDAAwD;AACtD,cAAc;AAChB,sEAAsE;GACpE,iBAAiB;AACnB,oEAAoE;GAClE,gBAAgB,CAAC;AAErB;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CASzE"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The ownership contract a Lisa template states about itself, in its own first
3
+ * lines, and the bounded read that recovers it from a file on disk.
4
+ *
5
+ * Every template Lisa ships carries one of exactly two headers, and which one
6
+ * is enforced repo-wide by `tests/unit/templates/template-ownership-header.test.ts`:
7
+ *
8
+ * - **`copy-overwrite`**: "This file is managed by Lisa and IS replaced on each
9
+ * `lisa` run." Lisa asserts ownership of the bytes.
10
+ * - **`create-only`**: "Seeded by Lisa on first setup — this file is YOURS.
11
+ * Lisa will not overwrite it." Lisa disclaims ownership at seed time.
12
+ *
13
+ * The headers are not decoration; they are opposite contracts, and more than
14
+ * one guard has to read them. `core/workflow-deletion-ownership` reads one to
15
+ * decide whether Lisa may delete a file, and `core/stale-managed-banner` reads
16
+ * the same one to decide whether the sentence is still TRUE. Both need the
17
+ * marker strings, the precedence between them, and the bound on how far into
18
+ * the file counts as "the header" — and a second copy of any of the three
19
+ * would drift silently, which is the failure mode both callers exist to end.
20
+ * So the reading lives here once and the callers ask it questions.
21
+ * @module core/ownership-header
22
+ */
23
+ /**
24
+ * The sentence a `copy-overwrite` template carries, minus its comment prefix.
25
+ *
26
+ * Matched as a substring rather than a whole line because the prefix differs by
27
+ * file type (`#`, `//`, ` *`) and the wording has been revised once already —
28
+ * the retired header said "changes will be overwritten on the next `lisa` run".
29
+ * Both spellings contain this phrase, so a consumer still holding a years-old
30
+ * Lisa artifact is still correctly attributed.
31
+ */
32
+ export const LISA_MANAGED_MARKER = "managed by Lisa";
33
+ /**
34
+ * The word a `create-only` seed header shouts, minus its comment prefix.
35
+ *
36
+ * "YOURS" is the load-bearing token of that contract and the one the header
37
+ * test asserts. A file carrying it came out of Lisa's template tree AND was
38
+ * handed to the consumer.
39
+ */
40
+ export const LISA_SEEDED_MARKER = "YOURS";
41
+ /**
42
+ * How many leading lines of a file count as its ownership header.
43
+ *
44
+ * Bounded on purpose. A whole-file search would let any mention of Lisa
45
+ * anywhere in a consumer's file — a step name, a comment about a Lisa command —
46
+ * read as an ownership claim, which is the false-positive direction. Every
47
+ * shipped template puts its header on the first two lines; four covers a
48
+ * leading `---` document marker, a shebang, or a blank line above it and still
49
+ * stops short of any file body.
50
+ */
51
+ export const OWNERSHIP_HEADER_LINES = 4;
52
+ /**
53
+ * Read the ownership contract a file states about itself.
54
+ *
55
+ * Precedence is seed-before-managed. A `create-only` header mentions
56
+ * `copy-overwrite` in its own second line, so a naive managed-first check would
57
+ * read every seeded file as Lisa-managed — which, on the deletion path, deletes
58
+ * files Lisa promised to keep (CodySwannGT/lisa#3656) and, on the banner path,
59
+ * reports a truthful seed header as a false managed one. Ordering it this way
60
+ * means the strongest claim a file can make is the one that keeps it.
61
+ * @param contents - Raw text of the file, or a leading prefix of it long enough
62
+ * to contain {@link OWNERSHIP_HEADER_LINES} lines
63
+ * @returns The contract its header states
64
+ */
65
+ export function classifyOwnershipHeader(contents) {
66
+ const header = contents
67
+ .split("\n")
68
+ .slice(0, OWNERSHIP_HEADER_LINES)
69
+ .join("\n");
70
+ if (header.includes(LISA_SEEDED_MARKER))
71
+ return "host-owned-seed";
72
+ return header.includes(LISA_MANAGED_MARKER)
73
+ ? "lisa-managed"
74
+ : "unattributable";
75
+ }
76
+ //# sourceMappingURL=ownership-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownership-header.js","sourceRoot":"","sources":["../../src/core/ownership-header.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAE1C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAWxC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,MAAM,MAAM,GAAG,QAAQ;SACpB,KAAK,CAAC,IAAI,CAAC;SACX,KAAK,CAAC,CAAC,EAAE,sBAAsB,CAAC;SAChC,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,IAAI,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAClE,OAAO,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC;QACzC,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC,gBAAgB,CAAC;AACvB,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The repository secret that has to exist before `- main` may be uncommented.
3
+ *
4
+ * Load-bearing, and the reason this is the marker of an actionable
5
+ * explanation rather than any prose at all: `noliran/branch-based-secrets`
6
+ * expands `AWS_ACCOUNT_ID` into `AWS_ACCOUNT_ID_<BRANCH IN UPPERCASE>`, so a
7
+ * `main` trigger without this secret resolves an empty account id and fails at
8
+ * the credentials step. A comment saying only "enable when ready" is the bare
9
+ * marker with more words.
10
+ */
11
+ export declare const PRODUCTION_ACCOUNT_SECRET = "AWS_ACCOUNT_ID_MAIN";
12
+ /**
13
+ * What a deploy workflow says about deploying production.
14
+ *
15
+ * `unstated` is the defect: production is off and the file gives no reason,
16
+ * so a reader cannot tell a decision from an accident. The other three are
17
+ * all fine, and are kept apart because they are different facts about the
18
+ * project, not different renderings of "nothing to report".
19
+ */
20
+ export type ProductionDeployIntent =
21
+ /** A live `main` entry: production deploys, deliberately. */
22
+ "triggers"
23
+ /** Commented out, with the enabling precondition named. */
24
+ | "explained"
25
+ /** Commented out, bare. */
26
+ | "unstated"
27
+ /** No `main` entry at all, live or commented. */
28
+ | "unmentioned";
29
+ /**
30
+ * Classify what a deploy workflow says about production deployment.
31
+ * @param workflowText - Full deploy workflow source
32
+ * @returns The intent the workflow states, or fails to
33
+ * @throws {Error} When the workflow cannot be parsed as YAML
34
+ */
35
+ export declare function classifyProductionDeployIntent(workflowText: string): ProductionDeployIntent;
36
+ //# sourceMappingURL=rails-deploy-production-intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rails-deploy-production-intent.d.ts","sourceRoot":"","sources":["../../src/core/rails-deploy-production-intent.ts"],"names":[],"mappings":"AA6BA;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAW/D;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB;AAChC,6DAA6D;AAC3D,UAAU;AACZ,2DAA2D;GACzD,WAAW;AACb,2BAA2B;GACzB,UAAU;AACZ,iDAAiD;GAC/C,aAAa,CAAC;AAuBlB;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,YAAY,EAAE,MAAM,GACnB,sBAAsB,CAMxB"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Does a Rails deploy workflow SAY why it does not deploy production?
3
+ *
4
+ * The Rails deploy template shipped `# - main` commented out with nothing
5
+ * beside it, which reads exactly like a line someone forgot to restore. The
6
+ * seed was fixed, but that file is `create-only`: Lisa writes it once and
7
+ * never again, so every project seeded before the fix still carries the bare
8
+ * marker and nothing in the toolchain looks for it. The population is not
9
+ * merely unfixed, it is unknown — which is what this module exists to end
10
+ * (CodySwannGT/lisa#3743, CodySwannGT/lisa#3779).
11
+ *
12
+ * The classification lives here, apart from both callers, because two
13
+ * surfaces have to ask the identical question: the regression guard on the
14
+ * shipped template, and the `lisa doctor` check that lets an already-seeded
15
+ * project find itself. Two spellings of "bare" would drift, and the drift
16
+ * would be silent in the direction that matters — a doctor check quietly
17
+ * accepting a shape the seed guard rejects.
18
+ *
19
+ * Every answer here is derived from the workflow text alone, and the one
20
+ * answer it cannot derive — a document it cannot parse — is thrown rather
21
+ * than folded into "production is off". Guessing "no live `main`" out of
22
+ * unparsed YAML would report an ENABLED production deploy as withheld.
23
+ * @module core/rails-deploy-production-intent
24
+ */
25
+ import { loadYaml } from "../utils/yaml.js";
26
+ /** Branch this template deploys production from. */
27
+ const PRODUCTION_BRANCH = "main";
28
+ /**
29
+ * The repository secret that has to exist before `- main` may be uncommented.
30
+ *
31
+ * Load-bearing, and the reason this is the marker of an actionable
32
+ * explanation rather than any prose at all: `noliran/branch-based-secrets`
33
+ * expands `AWS_ACCOUNT_ID` into `AWS_ACCOUNT_ID_<BRANCH IN UPPERCASE>`, so a
34
+ * `main` trigger without this secret resolves an empty account id and fails at
35
+ * the credentials step. A comment saying only "enable when ready" is the bare
36
+ * marker with more words.
37
+ */
38
+ export const PRODUCTION_ACCOUNT_SECRET = "AWS_ACCOUNT_ID_MAIN";
39
+ /**
40
+ * A commented-out production entry in a `branches:` list, in the spellings a
41
+ * YAML sequence entry can take. Anchored end-to-end so a line that comments
42
+ * out `- main` AND says something is not matched here — that text is what
43
+ * `PRODUCTION_ACCOUNT_SECRET` is then asked about.
44
+ */
45
+ const COMMENTED_PRODUCTION_ENTRY = /^[ \t]*#[ \t]*-[ \t]*(?:"main"|'main'|main)[ \t]*\r?$/mu;
46
+ /**
47
+ * Branches the workflow pushes on, as YAML actually parses them.
48
+ *
49
+ * `on:` is YAML 1.1 truthy, so a parser may key the trigger block as `true`;
50
+ * both spellings are read. A scalar `branches:` is one branch.
51
+ * @param workflowText - Full deploy workflow source
52
+ * @returns Every push branch the workflow declares
53
+ * @throws {Error} When the document cannot be parsed
54
+ */
55
+ function pushBranches(workflowText) {
56
+ const document = loadYaml(workflowText);
57
+ const branches = (document?.on ?? document?.true)?.push?.branches;
58
+ if (typeof branches === "string")
59
+ return [branches];
60
+ return Array.isArray(branches)
61
+ ? branches.filter((entry) => typeof entry === "string")
62
+ : [];
63
+ }
64
+ /**
65
+ * Classify what a deploy workflow says about production deployment.
66
+ * @param workflowText - Full deploy workflow source
67
+ * @returns The intent the workflow states, or fails to
68
+ * @throws {Error} When the workflow cannot be parsed as YAML
69
+ */
70
+ export function classifyProductionDeployIntent(workflowText) {
71
+ if (pushBranches(workflowText).includes(PRODUCTION_BRANCH))
72
+ return "triggers";
73
+ if (!COMMENTED_PRODUCTION_ENTRY.test(workflowText))
74
+ return "unmentioned";
75
+ return workflowText.includes(PRODUCTION_ACCOUNT_SECRET)
76
+ ? "explained"
77
+ : "unstated";
78
+ }
79
+ //# sourceMappingURL=rails-deploy-production-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rails-deploy-production-intent.js","sourceRoot":"","sources":["../../src/core/rails-deploy-production-intent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,oDAAoD;AACpD,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,qBAAqB,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,0BAA0B,GAC9B,yDAAyD,CAAC;AAoB5D;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,YAAoB;IACxC,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAG9B,CAAC;IACT,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,EAAE,IAAI,QAAQ,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC;IAClE,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC5B,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC;QACxE,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAC5C,YAAoB;IAEpB,IAAI,YAAY,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAAE,OAAO,UAAU,CAAC;IAC9E,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,YAAY,CAAC;QAAE,OAAO,aAAa,CAAC;IACzE,OAAO,YAAY,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QACrD,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,UAAU,CAAC;AACjB,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * How the installed package ships a destination path.
3
+ *
4
+ * Only the two ownership-header strategies are named. Every other strategy —
5
+ * `merge`, `tagged-merge`, `copy-contents`, `package-lisa` — collapses to
6
+ * `other` because the question those answer is the same one: Lisa still writes
7
+ * this path, so a banner saying so is not false. Distinguishing them further
8
+ * would add states no caller acts on.
9
+ */
10
+ export type ShippedTemplateStrategy = "copy-overwrite" | "create-only" | "other";
11
+ /** What a file's managed banner is worth, given what the package ships. */
12
+ export type ManagedBannerVerdict =
13
+ /** The banner is true: Lisa still writes this path. */
14
+ {
15
+ readonly kind: "accurate";
16
+ }
17
+ /**
18
+ * Lisa still ships this path, but as a `create-only` seed — so the file is
19
+ * the host's and the managed wording overstates Lisa's claim.
20
+ *
21
+ * Reported as its own verdict rather than folded into `retired` because the
22
+ * two have different remedies and different populations: this one is the
23
+ * template that MOVED (CodySwannGT/lisa#3582), and calling it retired would
24
+ * tell an operator that a template still in the package is gone.
25
+ */
26
+ | {
27
+ readonly kind: "overstated";
28
+ }
29
+ /** Lisa ships nothing at this path. The banner is false and the file is the host's. */
30
+ | {
31
+ readonly kind: "retired";
32
+ }
33
+ /** The file makes no managed claim, so there is nothing to be wrong about. */
34
+ | {
35
+ readonly kind: "not-managed";
36
+ };
37
+ /**
38
+ * How many stale paths to name inline before deferring to a count.
39
+ *
40
+ * Naming them is the point of the finding, so the cap is generous; a doctor
41
+ * line that runs to two hundred filenames is one an operator scrolls past.
42
+ */
43
+ export declare const MAX_NAMED_STALE_BANNERS = 10;
44
+ /**
45
+ * Judge one file's managed banner against what the installed package ships.
46
+ *
47
+ * `shippedDestinations` must be the destinations of EVERY lane the package
48
+ * ships, not the lanes this project detected as. A template that ships only
49
+ * under one stack is still shipped; scoping the index to detected stacks would
50
+ * report every stack-specific artifact in the repository as retired the moment
51
+ * detection shifted, which is the same false accusation with a different cause.
52
+ *
53
+ * An empty index is rejected rather than answered. "Ships nothing anywhere" is
54
+ * not a state a real package can be in, so it means the tree was unreadable or
55
+ * was never enumerated — and answering it would classify every managed file in
56
+ * the project as retired at once.
57
+ * @param relativePath - Repo-relative path of the file on disk
58
+ * @param header - The file's leading bytes, long enough to carry its header
59
+ * @param shippedDestinations - Every destination the installed package ships,
60
+ * with the strategy that ships it
61
+ * @returns What the file's banner is worth
62
+ * @throws {Error} When the shipped index is empty, which is not an answer
63
+ */
64
+ export declare function classifyManagedBanner(relativePath: string, header: string, shippedDestinations: ReadonlyMap<string, ShippedTemplateStrategy>): ManagedBannerVerdict;
65
+ /**
66
+ * The operator-facing finding for files whose managed banner has gone false.
67
+ *
68
+ * Written for whoever is about to decide whether they may touch one of these
69
+ * files. It names them, states the provable fact rather than the causal story,
70
+ * and says what changes — the sentence, not the file. It deliberately does not
71
+ * suggest removing the file: whether the workflow or script should still exist
72
+ * is a separate question, and answering it here is how the original harm
73
+ * happened in reverse.
74
+ * @param relativePaths - Repo-relative paths carrying a false managed banner
75
+ * @returns One operator-readable detail line
76
+ */
77
+ export declare function describeStaleManagedBanners(relativePaths: readonly string[]): string;
78
+ //# sourceMappingURL=stale-managed-banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-managed-banner.d.ts","sourceRoot":"","sources":["../../src/core/stale-managed-banner.ts"],"names":[],"mappings":"AA8CA;;;;;;;;GAQG;AACH,MAAM,MAAM,uBAAuB,GAC/B,gBAAgB,GAChB,aAAa,GACb,OAAO,CAAC;AAEZ,2EAA2E;AAC3E,MAAM,MAAM,oBAAoB;AAC9B,uDAAuD;AACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE;AAC/B;;;;;;;;GAQG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;CAAE;AACjC,uFAAuF;GACrF;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE;AAC9B,8EAA8E;GAC5E;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAW1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,uBAAuB,CAAC,GAChE,oBAAoB,CActB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,MAAM,CAYR"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Is a "managed by Lisa" banner on a consumer's file still TRUE?
3
+ *
4
+ * The banner is not decoration and it is not a label — it is an instruction.
5
+ * "This file is managed by Lisa and IS replaced on each `lisa` run. Do not edit
6
+ * directly" tells an engineer, and every agent reading the repository, that a
7
+ * local fix to that file is pointless. When the template it came from has been
8
+ * removed upstream, the sentence is false in the most expensive direction
9
+ * available: it discourages exactly the edits the file now needs, and it
10
+ * inverts any "is this ours to change?" audit that trusts it. A consuming
11
+ * repository had a proposal to remove one such workflow declined on the stated
12
+ * grounds that it was "a Lisa-managed file". It was not one
13
+ * (CodySwannGT/lisa#3703).
14
+ *
15
+ * ## The claim this module makes, and the one it refuses to make
16
+ *
17
+ * It answers exactly one question: **does the installed package ship anything
18
+ * at this destination path?** That is provable from the package on disk. It
19
+ * does NOT claim to know why the answer is no — a template genuinely retired
20
+ * upstream and a file the consumer derived by copying a Lisa template to a new
21
+ * name are indistinguishable without a provenance record neither one carries.
22
+ * Both make the banner false, and both make the file the host's, so the
23
+ * finding is worded as the provable claim rather than the causal story.
24
+ *
25
+ * ## Report, never repair
26
+ *
27
+ * Nothing here edits, rewrites, or deletes anything. That is deliberate and it
28
+ * is the whole safety argument. The file under a stale banner may now be the
29
+ * host's only copy of that workflow or script, Lisa no longer has a template to
30
+ * reconcile it against, and an automatic "strip the banner" pass would be Lisa
31
+ * rewriting a file it has just finished proving it does not own. The remedy is
32
+ * a one-line edit a human makes with the context to make it.
33
+ *
34
+ * ## Three states, never two
35
+ *
36
+ * The caller must distinguish "ships a template here", "ships nothing here",
37
+ * and "could not establish what it ships". The last one is not a variant of the
38
+ * second: a probe run against an unreadable or absent template tree reports
39
+ * every file as unshipped, which would condemn a whole repository's banners at
40
+ * once. This module refuses to be handed an empty index — see
41
+ * {@link classifyManagedBanner} — and the caller carries the indeterminate case
42
+ * as its own reported outcome.
43
+ * @module core/stale-managed-banner
44
+ */
45
+ import { classifyOwnershipHeader } from "./ownership-header.js";
46
+ /**
47
+ * How many stale paths to name inline before deferring to a count.
48
+ *
49
+ * Naming them is the point of the finding, so the cap is generous; a doctor
50
+ * line that runs to two hundred filenames is one an operator scrolls past.
51
+ */
52
+ export const MAX_NAMED_STALE_BANNERS = 10;
53
+ /**
54
+ * Normalise a repo-relative path so Windows separators compare equal.
55
+ * @param relativePath - Repo-relative path as the caller spelled it
56
+ * @returns The same path with forward slashes
57
+ */
58
+ function normalise(relativePath) {
59
+ return relativePath.replaceAll("\\", "/");
60
+ }
61
+ /**
62
+ * Judge one file's managed banner against what the installed package ships.
63
+ *
64
+ * `shippedDestinations` must be the destinations of EVERY lane the package
65
+ * ships, not the lanes this project detected as. A template that ships only
66
+ * under one stack is still shipped; scoping the index to detected stacks would
67
+ * report every stack-specific artifact in the repository as retired the moment
68
+ * detection shifted, which is the same false accusation with a different cause.
69
+ *
70
+ * An empty index is rejected rather than answered. "Ships nothing anywhere" is
71
+ * not a state a real package can be in, so it means the tree was unreadable or
72
+ * was never enumerated — and answering it would classify every managed file in
73
+ * the project as retired at once.
74
+ * @param relativePath - Repo-relative path of the file on disk
75
+ * @param header - The file's leading bytes, long enough to carry its header
76
+ * @param shippedDestinations - Every destination the installed package ships,
77
+ * with the strategy that ships it
78
+ * @returns What the file's banner is worth
79
+ * @throws {Error} When the shipped index is empty, which is not an answer
80
+ */
81
+ export function classifyManagedBanner(relativePath, header, shippedDestinations) {
82
+ if (shippedDestinations.size === 0) {
83
+ throw new Error("refusing to judge banners against an empty template index: an unreadable package ships nothing, which is not the same as removing everything");
84
+ }
85
+ if (classifyOwnershipHeader(header) !== "lisa-managed") {
86
+ return { kind: "not-managed" };
87
+ }
88
+ const shippedAs = shippedDestinations.get(normalise(relativePath));
89
+ if (shippedAs === undefined)
90
+ return { kind: "retired" };
91
+ return shippedAs === "create-only"
92
+ ? { kind: "overstated" }
93
+ : { kind: "accurate" };
94
+ }
95
+ /**
96
+ * The operator-facing finding for files whose managed banner has gone false.
97
+ *
98
+ * Written for whoever is about to decide whether they may touch one of these
99
+ * files. It names them, states the provable fact rather than the causal story,
100
+ * and says what changes — the sentence, not the file. It deliberately does not
101
+ * suggest removing the file: whether the workflow or script should still exist
102
+ * is a separate question, and answering it here is how the original harm
103
+ * happened in reverse.
104
+ * @param relativePaths - Repo-relative paths carrying a false managed banner
105
+ * @returns One operator-readable detail line
106
+ */
107
+ export function describeStaleManagedBanners(relativePaths) {
108
+ const named = relativePaths.slice(0, MAX_NAMED_STALE_BANNERS);
109
+ const withheld = relativePaths.length - named.length;
110
+ const suffix = withheld > 0 ? `, and ${withheld} more` : "";
111
+ return (`These files say Lisa manages them and replaces them on each run, but the ` +
112
+ `installed Lisa ships no template at their paths, so nothing replaces ` +
113
+ `them and the banner is false: ${named.join(", ")}${suffix}. The files are ` +
114
+ `yours — edit them, and correct or remove the banner sentence so the next ` +
115
+ `reader is not told a local fix is pointless. Lisa will not rewrite or ` +
116
+ `remove these files; it no longer has a template for them`);
117
+ }
118
+ //# sourceMappingURL=stale-managed-banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-managed-banner.js","sourceRoot":"","sources":["../../src/core/stale-managed-banner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAmChE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAE1C;;;;GAIG;AACH,SAAS,SAAS,CAAC,YAAoB;IACrC,OAAO,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,qBAAqB,CACnC,YAAoB,EACpB,MAAc,EACd,mBAAiE;IAEjE,IAAI,mBAAmB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,8IAA8I,CAC/I,CAAC;IACJ,CAAC;IACD,IAAI,uBAAuB,CAAC,MAAM,CAAC,KAAK,cAAc,EAAE,CAAC;QACvD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IACjC,CAAC;IACD,MAAM,SAAS,GAAG,mBAAmB,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;IACnE,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IACxD,OAAO,SAAS,KAAK,aAAa;QAChC,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE;QACxB,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B,CACzC,aAAgC;IAEhC,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IACrD,MAAM,MAAM,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,OAAO,CACL,2EAA2E;QAC3E,uEAAuE;QACvE,iCAAiC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,kBAAkB;QAC5E,2EAA2E;QAC3E,wEAAwE;QACxE,0DAA0D,CAC3D,CAAC;AACJ,CAAC"}
@@ -34,9 +34,39 @@
34
34
  * will fail. `guarded` runs the other way and is true if ANY occurrence is
35
35
  * guarded, because one silent-skip path is enough to make the absence silent.
36
36
  * Both directions point at reporting more rather than less.
37
+ *
38
+ * ## Why the handling signals are literal, and stay literal
39
+ *
40
+ * `guarded` says the step can TELL the path is missing. It has never said what
41
+ * the step then does, and a narrative that inferred the consequence from it
42
+ * asserted control flow nothing had read (CodySwannGT/lisa#3860). Deciding what
43
+ * an absent branch does needs a shell parser, and the answer would still be a
44
+ * guess. So this module reports the other checkable thing: which literal
45
+ * absence-handling tokens the step's own text contains. `else-branch` does not
46
+ * mean the else covers this read — it means the characters are there, so a
47
+ * reader who was about to conclude "this skips silently" is told, in the same
48
+ * sentence, that the step has a branch they have not read.
49
+ *
50
+ * ## Why the staleness probe is reported at two scopes
51
+ *
52
+ * The second dimension — can this coupling tell an OLD artifact from a current
53
+ * one — needs the same treatment, with one wrinkle the handling signals do not
54
+ * have. A read can reach the step it is used in through a `workflow_call`
55
+ * input default: `nightly-e2e-health.yml` defaults `guard_script` to
56
+ * `scripts/check-nightly-e2e-health.mjs`, and the step that compares contract
57
+ * versions names `$GUARD` and never the path. A step-scoped signal would
58
+ * therefore MISS a handshake that exists — a false negative on the one arm
59
+ * where a false negative reads as "this cannot detect staleness".
60
+ *
61
+ * So both scopes are reported, under names that say which is which:
62
+ * `step-requests-version` is exact for the step that reads the path, and
63
+ * `workflow-requests-version` says only that some step of this workflow asks.
64
+ * Neither is allowed to conclude anything alone — the artifact half, which the
65
+ * caller supplies and which IS exact for the path, is what bounds them.
37
66
  * @module core/two-channel-delivery-scan
38
67
  */
39
- import type { CouplingInput } from "./two-channel-delivery.js";
68
+ import { type CouplingInput } from "./two-channel-delivery.js";
69
+ import { type StalenessSignal } from "./two-channel-staleness.js";
40
70
  /** One step of a workflow, reduced to the text a scan needs. */
41
71
  export interface WorkflowStep {
42
72
  /** The step's `name:`, or an empty string when it has none. */
@@ -61,12 +91,14 @@ export declare function extractSteps(text: string): readonly WorkflowStep[];
61
91
  * @param options.workflow - Workflow file name, as a consumer spells it after `@main`
62
92
  * @param options.text - Raw workflow YAML
63
93
  * @param options.lanesFor - Delivery lanes shipping a caller path
94
+ * @param options.artifactSignalsFor - Staleness tokens the delivered artifact carries, or null when nothing is delivered there
64
95
  * @returns One coupling per distinct caller path, sorted by path
65
96
  */
66
97
  export declare function scanWorkflow(options: {
67
98
  workflow: string;
68
99
  text: string;
69
100
  lanesFor: (callerPath: string) => readonly string[];
101
+ artifactSignalsFor: (callerPath: string) => readonly StalenessSignal[] | null;
70
102
  }): readonly CouplingInput[];
71
103
  /**
72
104
  * Whether a workflow can be called by another repository at all.
@@ -1 +1 @@
1
- {"version":3,"file":"two-channel-delivery-scan.d.ts","sourceRoot":"","sources":["../../src/core/two-channel-delivery-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AA6B/D,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAgBlE;AAgKD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAC;CACrD,GAAG,SAAS,aAAa,EAAE,CAO3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIhD"}
1
+ {"version":3,"file":"two-channel-delivery-scan.d.ts","sourceRoot":"","sources":["../../src/core/two-channel-delivery-scan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AA6BpC,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAgBlE;AA+OD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAC;IACpD,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,SAAS,eAAe,EAAE,GAAG,IAAI,CAAC;CAC/E,GAAG,SAAS,aAAa,EAAE,CAW3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIhD"}