@codyswann/lisa 4.49.0 → 4.50.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (409) hide show
  1. package/all/copy-overwrite/scripts/check-conflict-markers.mjs +4 -1
  2. package/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +163 -0
  3. package/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +178 -1
  4. package/all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh +89 -10
  5. package/all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh +44 -0
  6. package/all/copy-overwrite/scripts/lisa-lint-staged-preflight.mjs +1 -1
  7. package/all/copy-overwrite/scripts/lisa-run-gates.mjs +24 -24
  8. package/all/copy-overwrite/scripts/lisa-work-item.mjs +490 -81
  9. package/cdk/package-lisa/package.lisa.json +45 -15
  10. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  11. package/dist/core/lisa-owned-hash-ledger.js +76 -0
  12. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  13. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  14. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  15. package/dist/core/upstream-evidence-manifest.js +121 -227
  16. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  17. package/dist/opencode/plugin-templates/lisa-block-direct-issue-create.ts +45 -1
  18. package/dist/opencode/plugin-templates/parity-safety-net.sh +44 -0
  19. package/expo/package-lisa/package.lisa.json +110 -53
  20. package/harper-fabric/package-lisa/package.lisa.json +62 -32
  21. package/nestjs/package-lisa/package.lisa.json +57 -27
  22. package/npm-package/package-lisa/package.lisa.json +43 -7
  23. package/package.json +11 -7
  24. package/phaser/copy-overwrite/ast-grep/rules/no-day-truncating-file-age-predicate.yml +50 -0
  25. package/phaser/package-lisa/package.lisa.json +62 -32
  26. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  28. package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
  29. package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +4 -0
  30. package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +4 -0
  31. package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +4 -0
  32. package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +4 -1
  33. package/plugins/lisa/hooks/block-direct-issue-create.sh +89 -10
  34. package/plugins/lisa/hooks/discharge-work-item-gates.sh +7 -1
  35. package/plugins/lisa/hooks/parity-safety-net.sh +44 -0
  36. package/plugins/lisa/hooks/threshold-ratchet-families.mjs +12 -0
  37. package/plugins/lisa/rules/eager/00-rule-index.md +79 -0
  38. package/plugins/lisa/rules/eager/base-rules.md +10 -0
  39. package/plugins/lisa/rules/eager/config-resolution.md +1 -88
  40. package/plugins/lisa/rules/reference/automation-runbook-contract.md +97 -0
  41. package/plugins/lisa/rules/reference/bdd-e2e-coverage.md +56 -0
  42. package/plugins/lisa/rules/reference/blocker-containment.md +58 -0
  43. package/plugins/lisa/rules/reference/claim-archaeology.md +42 -0
  44. package/plugins/lisa/rules/reference/claim-evidence-mapping.md +83 -0
  45. package/plugins/lisa/rules/reference/claim-time-guards.md +37 -0
  46. package/plugins/lisa/rules/reference/config-resolution.md +97 -0
  47. package/plugins/lisa/rules/reference/control-reachability.md +44 -0
  48. package/plugins/lisa/rules/reference/convergent-review.md +31 -0
  49. package/plugins/lisa/rules/reference/credential-substrate-precedence.md +57 -0
  50. package/plugins/lisa/rules/reference/dependency-decision-records.md +37 -0
  51. package/plugins/lisa/rules/reference/dependency-internalization-kit.md +47 -0
  52. package/plugins/lisa/rules/reference/dependency-trust-classes.md +48 -0
  53. package/plugins/lisa/rules/reference/deployed-state-readback.md +52 -0
  54. package/plugins/lisa/rules/reference/derived-branch-plan.md +52 -0
  55. package/plugins/lisa/rules/reference/design-source-of-truth.md +43 -0
  56. package/plugins/lisa/rules/reference/design-value-binding.md +103 -0
  57. package/plugins/lisa/rules/reference/documentation-source-paths.md +18 -0
  58. package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +75 -0
  59. package/plugins/lisa/rules/reference/observability-audit.md +20 -0
  60. package/plugins/lisa/rules/reference/prd-definition-of-ready.md +37 -0
  61. package/plugins/lisa/rules/reference/prd-lifecycle-rollup.md +36 -0
  62. package/plugins/lisa/rules/reference/pre-flight-autofill.md +88 -0
  63. package/plugins/lisa/rules/reference/promotion-contract.md +21 -0
  64. package/plugins/lisa/rules/reference/readiness-rubric.md +63 -0
  65. package/plugins/lisa/rules/reference/ready-role-filing.md +34 -0
  66. package/plugins/lisa/rules/reference/rejection-detection.md +69 -0
  67. package/plugins/lisa/rules/reference/repo-scope-split.md +48 -0
  68. package/plugins/lisa/rules/reference/reset-seed-coverage.md +55 -0
  69. package/plugins/lisa/rules/reference/usage-accounting.md +38 -0
  70. package/plugins/lisa/rules/reference/work-item-definition-of-ready.md +32 -0
  71. package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +158 -1
  72. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
  73. package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +4 -0
  74. package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +4 -0
  75. package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +4 -0
  76. package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +4 -1
  77. package/plugins/lisa-agy/hooks/block-direct-issue-create.sh +89 -10
  78. package/plugins/lisa-agy/hooks/parity-safety-net.sh +44 -0
  79. package/plugins/lisa-agy/plugin.json +1 -1
  80. package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +158 -1
  81. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
  82. package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +4 -0
  83. package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +4 -0
  84. package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +4 -0
  85. package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +4 -1
  86. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  88. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  89. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-copilot/hooks/block-direct-issue-create.sh +89 -10
  93. package/plugins/lisa-copilot/hooks/discharge-work-item-gates.sh +7 -1
  94. package/plugins/lisa-copilot/hooks/parity-safety-net.sh +44 -0
  95. package/plugins/lisa-copilot/hooks/threshold-ratchet-families.mjs +12 -0
  96. package/plugins/lisa-copilot/rules/eager/00-rule-index.md +79 -0
  97. package/plugins/lisa-copilot/rules/eager/base-rules.md +10 -0
  98. package/plugins/lisa-copilot/rules/eager/config-resolution.md +1 -88
  99. package/plugins/lisa-copilot/rules/reference/automation-runbook-contract.md +97 -0
  100. package/plugins/lisa-copilot/rules/reference/bdd-e2e-coverage.md +56 -0
  101. package/plugins/lisa-copilot/rules/reference/blocker-containment.md +58 -0
  102. package/plugins/lisa-copilot/rules/reference/claim-archaeology.md +42 -0
  103. package/plugins/lisa-copilot/rules/reference/claim-evidence-mapping.md +83 -0
  104. package/plugins/lisa-copilot/rules/reference/claim-time-guards.md +37 -0
  105. package/plugins/lisa-copilot/rules/reference/config-resolution.md +97 -0
  106. package/plugins/lisa-copilot/rules/reference/control-reachability.md +44 -0
  107. package/plugins/lisa-copilot/rules/reference/convergent-review.md +31 -0
  108. package/plugins/lisa-copilot/rules/reference/credential-substrate-precedence.md +57 -0
  109. package/plugins/lisa-copilot/rules/reference/dependency-decision-records.md +37 -0
  110. package/plugins/lisa-copilot/rules/reference/dependency-internalization-kit.md +47 -0
  111. package/plugins/lisa-copilot/rules/reference/dependency-trust-classes.md +48 -0
  112. package/plugins/lisa-copilot/rules/reference/deployed-state-readback.md +52 -0
  113. package/plugins/lisa-copilot/rules/reference/derived-branch-plan.md +52 -0
  114. package/plugins/lisa-copilot/rules/reference/design-source-of-truth.md +43 -0
  115. package/plugins/lisa-copilot/rules/reference/design-value-binding.md +103 -0
  116. package/plugins/lisa-copilot/rules/reference/documentation-source-paths.md +18 -0
  117. package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +75 -0
  118. package/plugins/lisa-copilot/rules/reference/observability-audit.md +20 -0
  119. package/plugins/lisa-copilot/rules/reference/prd-definition-of-ready.md +37 -0
  120. package/plugins/lisa-copilot/rules/reference/prd-lifecycle-rollup.md +36 -0
  121. package/plugins/lisa-copilot/rules/reference/pre-flight-autofill.md +88 -0
  122. package/plugins/lisa-copilot/rules/reference/promotion-contract.md +21 -0
  123. package/plugins/lisa-copilot/rules/reference/readiness-rubric.md +63 -0
  124. package/plugins/lisa-copilot/rules/reference/ready-role-filing.md +34 -0
  125. package/plugins/lisa-copilot/rules/reference/rejection-detection.md +69 -0
  126. package/plugins/lisa-copilot/rules/reference/repo-scope-split.md +48 -0
  127. package/plugins/lisa-copilot/rules/reference/reset-seed-coverage.md +55 -0
  128. package/plugins/lisa-copilot/rules/reference/usage-accounting.md +38 -0
  129. package/plugins/lisa-copilot/rules/reference/work-item-definition-of-ready.md +32 -0
  130. package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +158 -1
  131. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
  132. package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +4 -0
  133. package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +4 -0
  134. package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +4 -0
  135. package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +4 -1
  136. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  137. package/plugins/lisa-cursor/hooks/block-direct-issue-create.sh +89 -10
  138. package/plugins/lisa-cursor/hooks/discharge-work-item-gates.sh +7 -1
  139. package/plugins/lisa-cursor/hooks/parity-safety-net.sh +44 -0
  140. package/plugins/lisa-cursor/hooks/threshold-ratchet-families.mjs +12 -0
  141. package/plugins/lisa-cursor/rules/00-rule-index.mdc +84 -0
  142. package/plugins/lisa-cursor/rules/automation-runbook-contract-reference.mdc +97 -0
  143. package/plugins/lisa-cursor/rules/base-rules.mdc +10 -0
  144. package/plugins/lisa-cursor/rules/bdd-e2e-coverage-reference.mdc +56 -0
  145. package/plugins/lisa-cursor/rules/blocker-containment-reference.mdc +58 -0
  146. package/plugins/lisa-cursor/rules/claim-archaeology-reference.mdc +42 -0
  147. package/plugins/lisa-cursor/rules/claim-evidence-mapping-reference.mdc +83 -0
  148. package/plugins/lisa-cursor/rules/claim-time-guards-reference.mdc +37 -0
  149. package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +97 -0
  150. package/plugins/lisa-cursor/rules/config-resolution.mdc +1 -88
  151. package/plugins/lisa-cursor/rules/control-reachability-reference.mdc +44 -0
  152. package/plugins/lisa-cursor/rules/convergent-review-reference.mdc +31 -0
  153. package/plugins/lisa-cursor/rules/credential-substrate-precedence-reference.mdc +57 -0
  154. package/plugins/lisa-cursor/rules/dependency-decision-records-reference.mdc +37 -0
  155. package/plugins/lisa-cursor/rules/dependency-internalization-kit-reference.mdc +47 -0
  156. package/plugins/lisa-cursor/rules/dependency-trust-classes-reference.mdc +48 -0
  157. package/plugins/lisa-cursor/rules/deployed-state-readback-reference.mdc +52 -0
  158. package/plugins/lisa-cursor/rules/derived-branch-plan-reference.mdc +52 -0
  159. package/plugins/lisa-cursor/rules/design-source-of-truth-reference.mdc +43 -0
  160. package/plugins/lisa-cursor/rules/design-value-binding-reference.mdc +103 -0
  161. package/plugins/lisa-cursor/rules/documentation-source-paths-reference.mdc +18 -0
  162. package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +75 -0
  163. package/plugins/lisa-cursor/rules/observability-audit-reference.mdc +20 -0
  164. package/plugins/lisa-cursor/rules/prd-definition-of-ready-reference.mdc +37 -0
  165. package/plugins/lisa-cursor/rules/prd-lifecycle-rollup-reference.mdc +36 -0
  166. package/plugins/lisa-cursor/rules/pre-flight-autofill-reference.mdc +88 -0
  167. package/plugins/lisa-cursor/rules/promotion-contract-reference.mdc +21 -0
  168. package/plugins/lisa-cursor/rules/readiness-rubric-reference.mdc +63 -0
  169. package/plugins/lisa-cursor/rules/ready-role-filing-reference.mdc +34 -0
  170. package/plugins/lisa-cursor/rules/rejection-detection-reference.mdc +69 -0
  171. package/plugins/lisa-cursor/rules/repo-scope-split-reference.mdc +48 -0
  172. package/plugins/lisa-cursor/rules/reset-seed-coverage-reference.mdc +55 -0
  173. package/plugins/lisa-cursor/rules/usage-accounting-reference.mdc +38 -0
  174. package/plugins/lisa-cursor/rules/work-item-definition-of-ready-reference.mdc +32 -0
  175. package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +158 -1
  176. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
  177. package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +4 -0
  178. package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +4 -0
  179. package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +4 -0
  180. package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +4 -1
  181. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  182. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  183. package/plugins/lisa-expo-agy/plugin.json +1 -1
  184. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  185. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  186. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  187. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  188. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  189. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  190. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  191. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  192. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  193. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  194. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  195. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  196. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  197. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  198. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  199. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  200. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  201. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  202. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  203. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  204. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  205. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  206. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  207. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  208. package/plugins/lisa-rails-agy/plugin.json +1 -1
  209. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  210. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  211. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  212. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  213. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  214. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  215. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  216. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  217. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  218. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  219. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  220. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  221. package/plugins/src/base/hooks/block-direct-issue-create.sh +89 -10
  222. package/plugins/src/base/hooks/discharge-work-item-gates.sh +7 -1
  223. package/plugins/src/base/hooks/parity-safety-net.sh +44 -0
  224. package/plugins/src/base/hooks/threshold-ratchet-families.mjs +12 -0
  225. package/plugins/src/base/rules/eager/00-rule-index.md +79 -0
  226. package/plugins/src/base/rules/eager/base-rules.md +10 -0
  227. package/plugins/src/base/rules/eager/config-resolution.md +1 -88
  228. package/plugins/src/base/rules/reference/automation-runbook-contract.md +97 -0
  229. package/plugins/src/base/rules/reference/bdd-e2e-coverage.md +56 -0
  230. package/plugins/src/base/rules/reference/blocker-containment.md +58 -0
  231. package/plugins/src/base/rules/reference/claim-archaeology.md +42 -0
  232. package/plugins/src/base/rules/reference/claim-evidence-mapping.md +83 -0
  233. package/plugins/src/base/rules/reference/claim-time-guards.md +37 -0
  234. package/plugins/src/base/rules/reference/config-resolution.md +97 -0
  235. package/plugins/src/base/rules/reference/control-reachability.md +44 -0
  236. package/plugins/src/base/rules/reference/convergent-review.md +31 -0
  237. package/plugins/src/base/rules/reference/credential-substrate-precedence.md +57 -0
  238. package/plugins/src/base/rules/reference/dependency-decision-records.md +37 -0
  239. package/plugins/src/base/rules/reference/dependency-internalization-kit.md +47 -0
  240. package/plugins/src/base/rules/reference/dependency-trust-classes.md +48 -0
  241. package/plugins/src/base/rules/reference/deployed-state-readback.md +52 -0
  242. package/plugins/src/base/rules/reference/derived-branch-plan.md +52 -0
  243. package/plugins/src/base/rules/reference/design-source-of-truth.md +43 -0
  244. package/plugins/src/base/rules/reference/design-value-binding.md +103 -0
  245. package/plugins/src/base/rules/reference/documentation-source-paths.md +18 -0
  246. package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +75 -0
  247. package/plugins/src/base/rules/reference/observability-audit.md +20 -0
  248. package/plugins/src/base/rules/reference/prd-definition-of-ready.md +37 -0
  249. package/plugins/src/base/rules/reference/prd-lifecycle-rollup.md +36 -0
  250. package/plugins/src/base/rules/reference/pre-flight-autofill.md +88 -0
  251. package/plugins/src/base/rules/reference/promotion-contract.md +21 -0
  252. package/plugins/src/base/rules/reference/readiness-rubric.md +63 -0
  253. package/plugins/src/base/rules/reference/ready-role-filing.md +34 -0
  254. package/plugins/src/base/rules/reference/rejection-detection.md +69 -0
  255. package/plugins/src/base/rules/reference/repo-scope-split.md +48 -0
  256. package/plugins/src/base/rules/reference/reset-seed-coverage.md +55 -0
  257. package/plugins/src/base/rules/reference/usage-accounting.md +38 -0
  258. package/plugins/src/base/rules/reference/work-item-definition-of-ready.md +32 -0
  259. package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +158 -1
  260. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +17 -1
  261. package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +4 -0
  262. package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +4 -0
  263. package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +4 -0
  264. package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +4 -1
  265. package/rails/copy-overwrite/ast-grep/rules/no-day-truncating-file-age-predicate.yml +50 -0
  266. package/rails/copy-overwrite/scripts/threshold-ratchet-families.mjs +12 -0
  267. package/scripts/check-eager-rule-budget.mjs +176 -0
  268. package/scripts/check-generated-artifact-merge-coverage.mjs +7 -0
  269. package/scripts/check-rules-pairing.sh +45 -14
  270. package/scripts/check-shipped-surface-removals.mjs +851 -0
  271. package/scripts/generate-export-surface.mjs +318 -0
  272. package/scripts/lib/shipped-surface.mjs +212 -0
  273. package/scripts/lisa-enforcement-fallback.sh +178 -1
  274. package/scripts/remedy-conformance.mjs +435 -0
  275. package/scripts/two-channel-couplings.json +2 -2
  276. package/typescript/copy-contents/.husky/pre-push +147 -2
  277. package/typescript/copy-overwrite/ast-grep/rules/no-day-truncating-file-age-predicate.yml +50 -0
  278. package/typescript/copy-overwrite/audit.ignore.config.json +0 -10
  279. package/typescript/copy-overwrite/scripts/lisa-mutation.mjs +180 -29
  280. package/typescript/copy-overwrite/scripts/threshold-ratchet-families.mjs +12 -0
  281. package/typescript/package-lisa/package.lisa.json +72 -42
  282. package/plugins/lisa/rules/eager/automation-runbook-contract.md +0 -92
  283. package/plugins/lisa/rules/eager/bdd-e2e-coverage.md +0 -51
  284. package/plugins/lisa/rules/eager/blocker-containment.md +0 -53
  285. package/plugins/lisa/rules/eager/claim-archaeology.md +0 -37
  286. package/plugins/lisa/rules/eager/claim-evidence-mapping.md +0 -78
  287. package/plugins/lisa/rules/eager/claim-time-guards.md +0 -32
  288. package/plugins/lisa/rules/eager/control-reachability.md +0 -39
  289. package/plugins/lisa/rules/eager/convergent-review.md +0 -24
  290. package/plugins/lisa/rules/eager/credential-substrate-precedence.md +0 -54
  291. package/plugins/lisa/rules/eager/dependency-decision-records.md +0 -32
  292. package/plugins/lisa/rules/eager/dependency-internalization-kit.md +0 -42
  293. package/plugins/lisa/rules/eager/dependency-trust-classes.md +0 -43
  294. package/plugins/lisa/rules/eager/deployed-state-readback.md +0 -47
  295. package/plugins/lisa/rules/eager/derived-branch-plan.md +0 -47
  296. package/plugins/lisa/rules/eager/design-source-of-truth.md +0 -38
  297. package/plugins/lisa/rules/eager/design-value-binding.md +0 -98
  298. package/plugins/lisa/rules/eager/documentation-source-paths.md +0 -13
  299. package/plugins/lisa/rules/eager/factory-model.md +0 -41
  300. package/plugins/lisa/rules/eager/leaf-only-lifecycle.md +0 -70
  301. package/plugins/lisa/rules/eager/observability-audit.md +0 -15
  302. package/plugins/lisa/rules/eager/prd-definition-of-ready.md +0 -32
  303. package/plugins/lisa/rules/eager/prd-lifecycle-rollup.md +0 -31
  304. package/plugins/lisa/rules/eager/pre-flight-autofill.md +0 -84
  305. package/plugins/lisa/rules/eager/project-learnings.md +0 -22
  306. package/plugins/lisa/rules/eager/promotion-contract.md +0 -18
  307. package/plugins/lisa/rules/eager/readiness-rubric.md +0 -58
  308. package/plugins/lisa/rules/eager/ready-role-filing.md +0 -29
  309. package/plugins/lisa/rules/eager/rejection-detection.md +0 -64
  310. package/plugins/lisa/rules/eager/repo-scope-split.md +0 -43
  311. package/plugins/lisa/rules/eager/reset-seed-coverage.md +0 -50
  312. package/plugins/lisa/rules/eager/usage-accounting.md +0 -33
  313. package/plugins/lisa/rules/eager/work-item-definition-of-ready.md +0 -27
  314. package/plugins/lisa-copilot/rules/eager/automation-runbook-contract.md +0 -92
  315. package/plugins/lisa-copilot/rules/eager/bdd-e2e-coverage.md +0 -51
  316. package/plugins/lisa-copilot/rules/eager/blocker-containment.md +0 -53
  317. package/plugins/lisa-copilot/rules/eager/claim-archaeology.md +0 -37
  318. package/plugins/lisa-copilot/rules/eager/claim-evidence-mapping.md +0 -78
  319. package/plugins/lisa-copilot/rules/eager/claim-time-guards.md +0 -32
  320. package/plugins/lisa-copilot/rules/eager/control-reachability.md +0 -39
  321. package/plugins/lisa-copilot/rules/eager/convergent-review.md +0 -24
  322. package/plugins/lisa-copilot/rules/eager/credential-substrate-precedence.md +0 -54
  323. package/plugins/lisa-copilot/rules/eager/dependency-decision-records.md +0 -32
  324. package/plugins/lisa-copilot/rules/eager/dependency-internalization-kit.md +0 -42
  325. package/plugins/lisa-copilot/rules/eager/dependency-trust-classes.md +0 -43
  326. package/plugins/lisa-copilot/rules/eager/deployed-state-readback.md +0 -47
  327. package/plugins/lisa-copilot/rules/eager/derived-branch-plan.md +0 -47
  328. package/plugins/lisa-copilot/rules/eager/design-source-of-truth.md +0 -38
  329. package/plugins/lisa-copilot/rules/eager/design-value-binding.md +0 -98
  330. package/plugins/lisa-copilot/rules/eager/documentation-source-paths.md +0 -13
  331. package/plugins/lisa-copilot/rules/eager/factory-model.md +0 -41
  332. package/plugins/lisa-copilot/rules/eager/leaf-only-lifecycle.md +0 -70
  333. package/plugins/lisa-copilot/rules/eager/observability-audit.md +0 -15
  334. package/plugins/lisa-copilot/rules/eager/prd-definition-of-ready.md +0 -32
  335. package/plugins/lisa-copilot/rules/eager/prd-lifecycle-rollup.md +0 -31
  336. package/plugins/lisa-copilot/rules/eager/pre-flight-autofill.md +0 -84
  337. package/plugins/lisa-copilot/rules/eager/project-learnings.md +0 -22
  338. package/plugins/lisa-copilot/rules/eager/promotion-contract.md +0 -18
  339. package/plugins/lisa-copilot/rules/eager/readiness-rubric.md +0 -58
  340. package/plugins/lisa-copilot/rules/eager/ready-role-filing.md +0 -29
  341. package/plugins/lisa-copilot/rules/eager/rejection-detection.md +0 -64
  342. package/plugins/lisa-copilot/rules/eager/repo-scope-split.md +0 -43
  343. package/plugins/lisa-copilot/rules/eager/reset-seed-coverage.md +0 -50
  344. package/plugins/lisa-copilot/rules/eager/usage-accounting.md +0 -33
  345. package/plugins/lisa-copilot/rules/eager/work-item-definition-of-ready.md +0 -27
  346. package/plugins/lisa-cursor/rules/automation-runbook-contract.mdc +0 -97
  347. package/plugins/lisa-cursor/rules/bdd-e2e-coverage.mdc +0 -56
  348. package/plugins/lisa-cursor/rules/blocker-containment.mdc +0 -58
  349. package/plugins/lisa-cursor/rules/claim-archaeology.mdc +0 -42
  350. package/plugins/lisa-cursor/rules/claim-evidence-mapping.mdc +0 -83
  351. package/plugins/lisa-cursor/rules/claim-time-guards.mdc +0 -37
  352. package/plugins/lisa-cursor/rules/control-reachability.mdc +0 -44
  353. package/plugins/lisa-cursor/rules/convergent-review.mdc +0 -29
  354. package/plugins/lisa-cursor/rules/credential-substrate-precedence.mdc +0 -59
  355. package/plugins/lisa-cursor/rules/dependency-decision-records.mdc +0 -37
  356. package/plugins/lisa-cursor/rules/dependency-internalization-kit.mdc +0 -47
  357. package/plugins/lisa-cursor/rules/dependency-trust-classes.mdc +0 -48
  358. package/plugins/lisa-cursor/rules/deployed-state-readback.mdc +0 -52
  359. package/plugins/lisa-cursor/rules/derived-branch-plan.mdc +0 -52
  360. package/plugins/lisa-cursor/rules/design-source-of-truth.mdc +0 -43
  361. package/plugins/lisa-cursor/rules/design-value-binding.mdc +0 -103
  362. package/plugins/lisa-cursor/rules/documentation-source-paths.mdc +0 -18
  363. package/plugins/lisa-cursor/rules/factory-model.mdc +0 -46
  364. package/plugins/lisa-cursor/rules/leaf-only-lifecycle.mdc +0 -75
  365. package/plugins/lisa-cursor/rules/observability-audit.mdc +0 -20
  366. package/plugins/lisa-cursor/rules/prd-definition-of-ready.mdc +0 -37
  367. package/plugins/lisa-cursor/rules/prd-lifecycle-rollup.mdc +0 -36
  368. package/plugins/lisa-cursor/rules/pre-flight-autofill.mdc +0 -89
  369. package/plugins/lisa-cursor/rules/project-learnings.mdc +0 -27
  370. package/plugins/lisa-cursor/rules/promotion-contract.mdc +0 -23
  371. package/plugins/lisa-cursor/rules/readiness-rubric.mdc +0 -63
  372. package/plugins/lisa-cursor/rules/ready-role-filing.mdc +0 -34
  373. package/plugins/lisa-cursor/rules/rejection-detection.mdc +0 -69
  374. package/plugins/lisa-cursor/rules/repo-scope-split.mdc +0 -48
  375. package/plugins/lisa-cursor/rules/reset-seed-coverage.mdc +0 -55
  376. package/plugins/lisa-cursor/rules/usage-accounting.mdc +0 -38
  377. package/plugins/lisa-cursor/rules/work-item-definition-of-ready.mdc +0 -32
  378. package/plugins/src/base/rules/eager/automation-runbook-contract.md +0 -92
  379. package/plugins/src/base/rules/eager/bdd-e2e-coverage.md +0 -51
  380. package/plugins/src/base/rules/eager/blocker-containment.md +0 -53
  381. package/plugins/src/base/rules/eager/claim-archaeology.md +0 -37
  382. package/plugins/src/base/rules/eager/claim-evidence-mapping.md +0 -78
  383. package/plugins/src/base/rules/eager/claim-time-guards.md +0 -32
  384. package/plugins/src/base/rules/eager/control-reachability.md +0 -39
  385. package/plugins/src/base/rules/eager/convergent-review.md +0 -24
  386. package/plugins/src/base/rules/eager/credential-substrate-precedence.md +0 -54
  387. package/plugins/src/base/rules/eager/dependency-decision-records.md +0 -32
  388. package/plugins/src/base/rules/eager/dependency-internalization-kit.md +0 -42
  389. package/plugins/src/base/rules/eager/dependency-trust-classes.md +0 -43
  390. package/plugins/src/base/rules/eager/deployed-state-readback.md +0 -47
  391. package/plugins/src/base/rules/eager/derived-branch-plan.md +0 -47
  392. package/plugins/src/base/rules/eager/design-source-of-truth.md +0 -38
  393. package/plugins/src/base/rules/eager/design-value-binding.md +0 -98
  394. package/plugins/src/base/rules/eager/documentation-source-paths.md +0 -13
  395. package/plugins/src/base/rules/eager/factory-model.md +0 -41
  396. package/plugins/src/base/rules/eager/leaf-only-lifecycle.md +0 -70
  397. package/plugins/src/base/rules/eager/observability-audit.md +0 -15
  398. package/plugins/src/base/rules/eager/prd-definition-of-ready.md +0 -32
  399. package/plugins/src/base/rules/eager/prd-lifecycle-rollup.md +0 -31
  400. package/plugins/src/base/rules/eager/pre-flight-autofill.md +0 -84
  401. package/plugins/src/base/rules/eager/project-learnings.md +0 -22
  402. package/plugins/src/base/rules/eager/promotion-contract.md +0 -18
  403. package/plugins/src/base/rules/eager/readiness-rubric.md +0 -58
  404. package/plugins/src/base/rules/eager/ready-role-filing.md +0 -29
  405. package/plugins/src/base/rules/eager/rejection-detection.md +0 -64
  406. package/plugins/src/base/rules/eager/repo-scope-split.md +0 -43
  407. package/plugins/src/base/rules/eager/reset-seed-coverage.md +0 -50
  408. package/plugins/src/base/rules/eager/usage-accounting.md +0 -33
  409. package/plugins/src/base/rules/eager/work-item-definition-of-ready.md +0 -27
@@ -5,6 +5,103 @@ alwaysApply: false
5
5
 
6
6
  # Automation Runbook Contract
7
7
 
8
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
9
+ > section below is the former eager head, preserved verbatim; the full
10
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
11
+
12
+ ## Automation Runbook Contract (load-bearing)
13
+
14
+ **Every registered automation loop carries a checked-in runbook, and every run of that loop ends in
15
+ exactly one of six run outcomes** with a one-line, operator-readable summary. A registered loop with
16
+ no runbook, or a run that stops without naming its outcome, is a contract violation.
17
+
18
+ **One vendor-neutral contract, to be cited by (wired in the loop-conformance ticket)
19
+ `lisa-setup-automations`, `lisa-automation-status`, `lisa-tear-down-automations`, and every
20
+ registered loop skill** (the `leaf-only-lifecycle` / `repo-scope-split` precedent: one shared slug,
21
+ never divergent per-loop prose).
22
+
23
+ ## Membership
24
+
25
+ Membership is **registration, not skill-existence**: a loop is under this contract the moment it is
26
+ registered as a scheduled automation, and registering a new one pulls it in automatically. There is
27
+ no hardcoded roster of loops anywhere.
28
+
29
+ ### Interactive flows are members too
30
+
31
+ The outcome vocabulary is **not cron-specific** — it answers "did this need me?", which an operator
32
+ asks of an interactive run exactly as often as of a scheduled one. Every Lisa flow that terminates
33
+ is a member: `lisa-implement`, `lisa-verify`, `lisa-plan`, `lisa-git-submit-pr`,
34
+ `lisa-drive-pr-to-merge`, `lisa-research`, and any skill invoked as a slash command.
35
+
36
+ For an interactive flow the required run record is the **final user-facing message**, not a JSONL
37
+ row written by `automation-run-record.mjs`. Interactive flows may also record local JSONL telemetry
38
+ when a specific skill owns that surface, but this contract's mandatory record is the final answer.
39
+ It opens with the outcome and the operator action, before any narrative:
40
+
41
+ ```
42
+ change-proved — nothing for you. PR #6393 open, auto-merge on, CI running.
43
+ approval-requested — need a decision: ship the 135 Regular→Bold flips, or hold for design sign-off?
44
+ recovery-required — need you: staging E2E gate red for congestion; rerun or admin-merge.
45
+ ```
46
+
47
+ The operator must learn whether they are needed **from the first line**, without reading the report.
48
+ Findings, evidence and caveats follow; they never replace the action line and never precede it.
49
+
50
+ An interactive flow that ends in prose with the action buried — or absent — is the same contract
51
+ violation as a silent cron exit. "I flagged X, I noticed Y, worth knowing Z" is narrative, not an
52
+ outcome. If nothing is needed, say **"nothing for you"** in those words and stop.
53
+
54
+ ## The six run outcomes
55
+
56
+ Exactly one per run:
57
+ **`nothing-needed | candidate-proposed | change-proved | approval-requested | recovery-required | policy-obsolete`**
58
+
59
+ Health and operator action are **orthogonal** — a healthy run can still need an answer:
60
+
61
+ - `nothing-needed` — the loop ran and found nothing to act on. **Healthy.** Operator action: none.
62
+ A queue scanner's `nothing-needed` summary must name the lanes it swept and the total open — a dry
63
+ queue and a wrong denominator are otherwise indistinguishable. See the reference body.
64
+ - `candidate-proposed` — the loop proposed work (ticket, PRD, recommendation). **Healthy.** Operator
65
+ action: review the proposed item and flip it ready when you want it built.
66
+ - `change-proved` — the loop made a change and proved it with evidence. **Healthy.** Operator
67
+ action: none (informational).
68
+ - `approval-requested` — the loop reached a boundary it may not cross alone. **Healthy.** Operator
69
+ action: answer the approval question.
70
+ - `recovery-required` — the loop itself could not complete (access, tooling, or substrate broken)
71
+ and escalated a decision-ready packet. **Not healthy.** Operator action: restore the named
72
+ capability, then close the escalation item.
73
+ - `policy-obsolete` — the loop's own retirement policy (the retirement condition written in its
74
+ runbook) tripped, so it proposed its own teardown. **Healthy.** Operator action: approve the
75
+ teardown, decline it (close the proposal as **Not planned**; the loop keeps running at cadence),
76
+ or re-cadence it.
77
+
78
+ ## A run outcome is NOT a work-item lifecycle terminal state (CRITICAL)
79
+
80
+ A **run outcome** describes the LOOP ITERATION. A **terminal state** describes a TICKET — Lisa
81
+ already uses that phrase for work-item lifecycles (`lisa-intake`: "`Blocked` is a valid terminal
82
+ state of the downstream lifecycles"). The two vocabularies never merge in an operator-facing report.
83
+ A healthy cycle that routes a work item to `Blocked` with clarifying questions is
84
+ `candidate-proposed` — it produced something — so it is **never `nothing-needed`**, which is
85
+ reserved for runs that found nothing at all, and **never `recovery-required`**, which means the
86
+ loop itself is broken, not that a work item was blocked.
87
+
88
+ ## No silent exit
89
+
90
+ Every run — including a trivial early termination — ends by naming exactly one run outcome plus a
91
+ one-line operator summary of what happened, recorded where the status surface can read it —
92
+ there is no silent exit. The shared local substrate is
93
+ `plugins/src/base/scripts/automation-run-record.mjs`, which writes bounded JSONL records under
94
+ `.lisa/automations/runs/<loop-id>.jsonl`. Silence and health must never look identical to an
95
+ operator.
96
+
97
+ ## Never block, always degrade
98
+
99
+ A missing runbook, an unreadable record surface, or an absent optional dependency **degrades** the
100
+ run — say so in the summary and finish with an outcome — it never crashes the loop, never blocks
101
+ other work, and never leaves the run unreported.
102
+
103
+ ---
104
+
8
105
  Scheduled loops are the busiest machinery in the factory and historically the least explicitly
9
106
  contracted: what a loop maintains, what it may do on its own, what it must escalate, and when it
10
107
  should stop existing all lived implicitly in each loop's prose. The cost lands on the operator — a
@@ -7,6 +7,16 @@ alwaysApply: true
7
7
 
8
8
  These are mandatory disciplines that apply to every session. Full prose, JIRA dev-status query, ADF templates, etc. live in [reference/base-rules.md](base-rules-reference.mdc).
9
9
 
10
+ ## Factory Operating Mode
11
+
12
+ You are factory machinery, not a chat assistant. Three consequences bind every session:
13
+
14
+ - **Do not pause mid-flow to ask a human whether to proceed.** Handoff happens at the gates — the ready-role flips and intake's adversarial validation — never in the middle of a flow.
15
+ - **Every flow must work headless**: no interactive prompts, idempotent re-runs, clean exits on empty queues. Flows run under native schedulers as often as under a human.
16
+ - **Never weaken a gate to get work through it — fix the work.**
17
+
18
+ The model these follow from (the four factories, the gate, the loops, the brownfield on-ramp) is [reference/factory-model.md](factory-model-reference.mdc); read it when you need the shape rather than the obligations.
19
+
10
20
  ## Requirement Verification
11
21
 
12
22
  Treat every request as potentially underspecified. Before starting any work:
@@ -5,6 +5,62 @@ alwaysApply: false
5
5
 
6
6
  # BDD Behavior Contract & E2E Coverage
7
7
 
8
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
9
+ > section below is the former eager head, preserved verbatim; the full
10
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
11
+
12
+ ## BDD Behavior Contract & E2E Coverage (load-bearing)
13
+
14
+ **Every frontend work item ships its behavior as Gherkin scenarios with stable IDs, and seals each required scenario-platform obligation with aligned e2e automation in the project's configured runner for that platform.** A frontend change that adds no scenario, or a required scenario-platform obligation with neither a mapped test nor a dated waiver, is a contract violation.
15
+
16
+ **One vendor-neutral contract, cited by** `lisa-research`, `lisa-acceptance-criteria`, `lisa-task-decomposition`, `lisa-test-strategy`, `lisa-tdd-implementation`, `lisa-implement`, `lisa-codify-verification`, `lisa-verification-lifecycle`, `lisa-spec-conformance`, and `lisa-verify` (the `leaf-only-lifecycle` / `repo-scope-split` precedent: one shared slug, never divergent per-skill prose).
17
+
18
+ ## Membership
19
+
20
+ Membership is **surface, not repo name or ticket label**: a work item is frontend-type the moment it adds or changes something a user can observe — a screen, route, component, interaction, visual state, empty/error/loading state, navigation path, or copy a user reads. It applies on every platform the project ships. Backend-only, infrastructure, docs, tooling, and refactors with no user-observable delta are out; a refactor that changes what the user sees is in.
21
+
22
+ ## The contract lives in the repo
23
+
24
+ Default locations (a project that already has an equivalent contract keeps its own paths and records them in `.lisa.config.json`):
25
+
26
+ | Artifact | Default path | What it is |
27
+ |---|---|---|
28
+ | Scenarios | `bdd/features/*.feature` | Gherkin, the product-level behavior contract |
29
+ | Coverage map | `bdd/coverage-map.json` | scenario → runner/platform/file/evidence mappings, plus waivers, per-runner test-discovery roots, and exclusions |
30
+ | Generated matrix | `docs/bdd-scenario-matrix.md` | regenerated, never hand-edited |
31
+ | Burndown | `docs/e2e-bdd-coverage.md` | current coverage per platform |
32
+
33
+ ## Scenario shape
34
+
35
+ Every scenario carries **one stable `@BDD-<DOMAIN>-<NNN>` ID**, the platforms it requires (`@web`, `@ios`, `@android`, … as the project declares them), provenance (design node, ratified decision), and a tracker tag tying it to the work item that introduced or changed it. IDs are never renumbered or reused: behavior that stays user-observably the same keeps its ID through a rewrite; genuinely different behavior gets a new ID and the old one is marked `@superseded`.
36
+
37
+ Lifecycle tag, exactly one or none:
38
+
39
+ - **no tag** — ratified and required; it is in the coverage denominator.
40
+ - **`@blocked`** — specified but awaiting a decision or dependency; the *product* does not do this yet.
41
+ - **`@reference-only`** — intentionally not authoritative.
42
+ - **`@superseded`** — replaced by a ratified rule or a newer scenario.
43
+
44
+ The last three are out of the denominator. Deleting a committed capability to make coverage look better is a violation; mark it, do not drop it.
45
+
46
+ ## What seals a scenario
47
+
48
+ Coverage is counted per **required scenario-platform obligation**, and an obligation is sealed only by **aligned e2e automation in the project's configured runner for that platform** — the runner→platform mapping is project configuration (e.g. a web runner covering `web`, a device runner covering `ios`/`android`), never named by this contract. A unit test, a route boot, a screenshot, a fixture, an API test, or a passing test on a *different* platform never seals an obligation: they prove something else. Each mapping names the runner, the platforms, the file, and the evidence string inside it, so the gate can prove the mapping still resolves.
49
+
50
+ **The gate reads in both directions.** It also walks the test roots the project declares per runner, so an e2e test that exists but that the contract never mentions is a violation — map it to a scenario, or record an exclusion stating why it aligns to no product behavior. Roots are configuration: a subflow or helper directory left undeclared is structurally invisible, which is the same failure as having no gate for it.
51
+
52
+ **Waivers are dated IOUs, never coverage.** An obligation whose runner genuinely cannot decide it today (no camera on the simulator, no request interception, no provisioned provider credential) is recorded with scenario, platforms, reason, and `recordedAt`. It leaves the denominator; it never counts as covered, and nothing about it asserts the behavior works. A waiver is invalid — and fails the gate — when it names a nonexistent scenario or an undeclared platform, covers an already-excluded scenario, or masks a scenario-platform that already has a mapping. Revisit a waiver when its reason dies.
53
+
54
+ ## Definition of done
55
+
56
+ A frontend work item is not done until: (1) every user-facing behavior it adds or changes exists as a Gherkin scenario with a stable ID in the project's behavior contract, traceable to the work item; (2) every required scenario-platform obligation it introduces is either mapped to aligned e2e automation in the project's configured runner for that platform, or carries a dated waiver naming the runner limitation; and (3) the coverage gate passes and the generated matrix and burndown are regenerated and committed in the same PR. **Missing BDD coverage is a verification failure, not a warning** — it blocks completion exactly as a `PARTIAL` spec-conformance verdict does, and it is never demoted to "optional", "if cheap", or a follow-up without a linked build-ready ticket created before merge.
57
+
58
+ ## Bootstrap and degradation
59
+
60
+ A project with no `bdd/` contract yet is not exempt — the first frontend work item scaffolds the minimum (features dir, coverage map with the project's detected runner→platform mapping, gate + matrix scripts) and covers **its own** behavior. It never backfills the whole app: pre-existing uncovered behavior is recorded as burndown, not treated as this item's blocker. If no e2e runner exists for a required platform at all, record the checked locations and the absence as the reason, exactly as the regression-spec absence path in `verification` does — a silent skip is never one of the exits.
61
+
62
+ ---
63
+
8
64
  Frontend behavior has historically been specified twice and owned nowhere: once as prose acceptance
9
65
  criteria on a ticket that closes and disappears, and once as whatever e2e tests someone had time to
10
66
  write. Neither survives the work item. The cost lands at verification time — nobody can answer "what
@@ -5,6 +5,64 @@ alwaysApply: false
5
5
 
6
6
  # Blocker Containment
7
7
 
8
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
9
+ > section below is the former eager head, preserved verbatim; the full
10
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
11
+
12
+ ## Blocker Containment (load-bearing)
13
+
14
+ **An `is blocked by` dependency is cleared by one fact only: the blocker's code is present on the branch the dependent will be built from.** A lifecycle status name — `done`, `on-stg`, `on-dev`, `code-review`, or any configured equivalent — is never that fact. It is a label that correlates with the fact in a single-trunk workflow and comes apart from it in a promotion workflow.
15
+
16
+ **One vendor-neutral contract, cited by** `lisa-repair-intake` (Class A dependency clearing), `lisa-intake-explain` (dependency hold gate), and `lisa-ticket-triage` (Phase 1.5 open-blocker gate) — the `leaf-only-lifecycle` / `repo-scope-split` precedent: one shared slug, never divergent per-consumer prose.
17
+
18
+ ## Why a status name is the wrong test
19
+
20
+ Where promotion runs `dev → staging → main`, `main` is the **trailing** branch. A blocker at `On Stg` is merged to `staging` and absent from `main`, so a dependent that builds from `main` does not have it. A blocker in `Code Review` is merged to nothing at all. The two failures are symmetric and both are live in the tree:
21
+
22
+ - Test too **loosely** (any env-staged `done` clears) and a dependent is dispatched into work whose prerequisite is not on its branch. Nothing goes red; the item moves to `ready`, which is indistinguishable from a repair that worked.
23
+ - Test too **strictly** (only the production terminal clears) and every dependent strands behind a blocker that is already merged where it matters.
24
+
25
+ Containment is the one predicate that gets both right, because it asks the question the status name was standing in for.
26
+
27
+ ## The predicate
28
+
29
+ 1. **Resolve the dependent's base branch.** Take the dependent's `## Target Backend Environment` and map that exact key forward through `.lisa.config.json` `deploy.branches`, per `derived-branch-plan` and `config-resolution`. **Never read the rendered `Branch Plan` section as input** — `derived-branch-plan` forbids it; a surface needing the base branch derives it again.
30
+ 2. **Resolve the blocker's merge commit** — the commit that landed the blocker's PR.
31
+ 3. **Test ancestry on the remote:** is that commit an ancestor of the resolved base branch (`git merge-base --is-ancestor <sha> origin/<base>`)?
32
+ 4. **Cleared** iff the answer is yes. Otherwise **still blocking**.
33
+
34
+ ## Fail closed
35
+
36
+ **Never fail open on an unresolvable ancestry check.** Any step that cannot be positively resolved leaves the dependency **blocking**, and the run record says which step failed:
37
+
38
+ - no linked PR, or a PR that is not merged;
39
+ - the blocker is inaccessible (deleted, cross-org, permission denied) — containment across repositories is not defined;
40
+ - the dependent's environment is not derivable, maps non-uniquely, or maps to a branch absent from the remote;
41
+ - the ancestry query itself fails.
42
+
43
+ A false negative (left blocked) costs a cycle and is visible. A false positive (dispatched into a missing prerequisite) is invisible and surfaces days later as work begun before its dependency existed. Prefer the visible failure.
44
+
45
+ ## The one carve-out: a blocker with no code
46
+
47
+ A dependency need not deliver code. A blocker **closed as completed** that positively declares no code deliverable — `Target Backend Environment: None — no runtime behavior change` (doc-only / config-only / type-only), no linked PR, no merge commit — is **cleared**, because there is no artifact whose location could matter.
48
+
49
+ This requires a **positive determination**, never an absence. "I could not find a PR" is fail-closed under the rule above; "the item declares it ships no code" is this carve-out. Collapsing the two turns the carve-out into a universal bypass.
50
+
51
+ ## Ancestry answers a development question, not a deployment one
52
+
53
+ This rule requires an ancestry test. `deployed-state-readback` says ancestry is **never** evidence of deployment. Both are correct — they answer different questions:
54
+
55
+ - **Here:** *is the blocker's code on the branch I will build from?* An `is blocked by` link is a **development** dependency, satisfied once the code is on your base branch. Ancestry is the right test, and waiting for production strands dependents.
56
+ - **There:** *is this thing live?* A commit can be an ancestor of the default branch and never have shipped — a discarded pipeline execution leaves it merged and undeployed. Ancestry is provably insufficient.
57
+
58
+ Never use this rule's test to answer a "does it already exist in the environment?" question.
59
+
60
+ ## Human override
61
+
62
+ A human statement on the item that the dependency is satisfied clears it, and outranks a failed containment check. Record it as the reason in the run record. This is the escape hatch for cross-repo and untracked dependencies, and it is the only one. An automation may never synthesize one on its own behalf.
63
+
64
+ ---
65
+
8
66
  An `is blocked by` link is a **development** dependency. It asks one question: *does the dependent have the blocker's code on the branch it will be built from?* This rule makes that the test, replacing the lifecycle-status-name checks that three Lisa surfaces had each grown independently.
9
67
 
10
68
  It is a **single vendor-neutral contract** consumed by `lisa-repair-intake` (Class A dependency clearing), `lisa-intake-explain` (dependency hold gate), and `lisa-ticket-triage` (Phase 1.5 open-blocker gate). Each cites this slug rather than re-implementing the test, exactly as they cite `leaf-only-lifecycle` and `repo-scope-split`. That is what keeps the three from drifting apart again.
@@ -5,6 +5,48 @@ alwaysApply: false
5
5
 
6
6
  # Claim-Time Archaeology
7
7
 
8
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
9
+ > section below is the former eager head, preserved verbatim; the full
10
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
11
+
12
+ ## Claim-Time Archaeology (load-bearing)
13
+
14
+ Lisa lifecycles are one-way — a done issue never reopens, so a residual failure comes back as a **new** issue with no visible link to the issue that shipped it. Archaeology recovers that link at claim time: the claiming agent learns it is working on round 2 of a past failure, and what specifically went wrong the first time.
15
+
16
+ **One vendor-neutral contract, cited by every build-intake arm** (the `leaf-only-lifecycle` / `repo-scope-split` / `rejection-detection` precedent: one shared slug, never three divergent implementations).
17
+
18
+ ## When it runs
19
+
20
+ In build-intake step 3b, **AFTER the rejection-detection classification and BEFORE the relabel/transition** `$READY → $CLAIMED`. Rejection detection runs first; its classification is an **input** to archaeology — a detected `rejection-reclaim` passes straight through, never re-derived.
21
+
22
+ ## Classify the claimed item
23
+
24
+ Return exactly one of:
25
+
26
+ - **`rejection-reclaim`** — taken directly from the `rejection-detection` result. Reuse it; do not re-derive.
27
+ - **`retry-of-done-issue`** — an ancestry signal names a closed done issue whose shipped work this issue exists to fix.
28
+ - **`fresh`** — no ancestor found, signals weak/inconclusive, budget exhausted, or the pass errored. The default and the safe degrade.
29
+
30
+ ## Ancestry signals (summary — full bindings in the reference body)
31
+
32
+ 1. **Tracker metadata** — the typed relations the read skills already parse (Blocks / Blocked by / Relates to / Duplicates / Cloned from, `closingIssuesReferences`, cross-references).
33
+ 2. **Text similarity** — tracker search primitives over recently-closed issues touching the same implicated files, ranked by title/label overlap. Lexical only; no embedding machinery exists.
34
+ 3. **Git ancestry** — deterministic `git log --follow` / `git blame` / merge-commit queries yielding a parseable `{file, sha, pr, date}` result. Never delegate this to the prose-report `git-history-analyzer` agent.
35
+
36
+ ## Learning-loop exclusion (scan-side)
37
+
38
+ An artifact this flow produced is **never** an ancestor. Exclude anything carrying `[lisa-learning-drop]`, `[lisa-learning-pr]`, `[lisa-learning-upstream-handoff]`, `[lisa-rejection-candidate]`, or `[lisa-archaeology-candidate]` markers, or the `learning:needs-triage` label.
39
+
40
+ ## Cost budget — never block the claim
41
+
42
+ The pass runs inside a hard budget: `.lisa.config.json` `archaeology.maxSteps` (default **8** tracker/git queries; optional `archaeology.maxSeconds`). Budget exhausted, weak signals, or an exception → classify `fresh` and proceed. Archaeology is a bonus layered on the claim; it **never blocks the claim**. Exceeding the budget degrades to `fresh` — a normal outcome, not an error.
43
+
44
+ ## On `retry-of-done-issue`
45
+
46
+ Reconstruct what the ancestor's PR shipped (merged PR, review threads, evidence comments) and derive **ONE** candidate learning citing the **delta** between what was done and what this issue proves was needed — routed to `lisa-persist-learning` exactly like the rejection-reflection path. Fallback when that skill is absent: a comment with a visible prose line plus `<!-- [lisa-archaeology-candidate] key=<issue>::<ancestor> -->` (marker-dedupe; re-claims produce no duplicate). `fresh` → no candidate, zero comments.
47
+
48
+ ---
49
+
8
50
  Lisa lifecycles are ONE-WAY — a done issue never reopens, so residual failures come back as NEW issues, and the causal link "issue B exists because issue A was done wrong" is invisible unless someone digs. Reopening terminal issues is out of scope, so claim-time archaeology is the only way to recover that link: at claim time, determine whether the item being claimed is round 2 of a past failure, and if so, what specifically went wrong the first time.
9
51
 
10
52
  It is a **single vendor-neutral contract** consumed by all three build-intake skills (`lisa-jira-build-intake`, `lisa-github-build-intake`, `lisa-linear-build-intake`). Each vendor arm cites this slug in its claim step rather than growing its own archaeology, exactly as the arms cite `leaf-only-lifecycle`, `repo-scope-split`, and `rejection-detection`. One slug is what keeps an ancestor found on JIRA from being missed on Linear.
@@ -5,6 +5,89 @@ alwaysApply: false
5
5
 
6
6
  # Claim → Evidence Mapping Contract
7
7
 
8
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
9
+ > section below is the former eager head, preserved verbatim; the full
10
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
11
+
12
+ ## Claim → Evidence Mapping Contract (load-bearing)
13
+
14
+ **Every claim about the software declares a boundary, and a claim is established only by evidence of
15
+ a kind that reaches that boundary.** Unit tests are a quality prerequisite, not a claim discharger:
16
+ a passing unit `test-run-log` reaches only the **code-unit** boundary. Citing evidence whose *kind*
17
+ does not reach a claim's *boundary* — a unit log offered as proof that a button works in the browser
18
+ — is a contract violation, and a review-rejectable defect.
19
+
20
+ ## The claim-boundary taxonomy (closed set)
21
+
22
+ Every claim binds to exactly one boundary, and each boundary is discharged only by evidence of the
23
+ kind(s) that reach it. The boundaries and their establishing evidence kinds are seeded verbatim from
24
+ the `verification` rule's artifact-type taxonomy — no new vocabulary is invented here:
25
+
26
+ - **`code-unit`** — pure-logic behavior in isolation → unit `test-run-log`. Reaches no boundary
27
+ below it.
28
+ - **`browser`** — user-visible UI behavior → `screenshot`, `recording`. **Never** a unit
29
+ `test-run-log`.
30
+ - **`http-api`** — request/response contract → `http-transcript`. **Never** a unit `test-run-log`.
31
+ - **`cli`** — command behavior → `cli-output`.
32
+ - **`data`** — persisted state → `db-query-output`, `state-dump`.
33
+ - **`deploy-health`** — a healthy running deployment → `deploy-log`. **Never** any pre-deploy
34
+ artifact.
35
+ - **`performance`** — latency/throughput/frame timing → `perf-trace` (with methodology).
36
+ - **`standards-compat`** — conformance to an external standard → `cli-output` / `test-run-log` from
37
+ the compat runner.
38
+
39
+ ## The core inequality
40
+
41
+ **unit tests ≠ browser behavior ≠ healthy deployment ≠ standards compatibility.** Each is a distinct
42
+ boundary; evidence at one never discharges a claim at another. "Verified" must name the boundary its
43
+ evidence actually reaches, so a report read at the gate states its own limits (`factory-model`
44
+ rule 5).
45
+
46
+ ## Field names (fixed here, made executable later)
47
+
48
+ A claim carries three fields — `claim_id`, `boundary`, and `required_evidence_kinds` — named here so
49
+ every downstream surface uses one spelling. This ticket only writes the contract down; the schema and
50
+ gate that make these fields executable ship with **BCE-2 (#1836)** — do not assume that surface is
51
+ present in this branch.
52
+
53
+ ## Security buckets (conservative by default)
54
+
55
+ A security finding is **proven** only with both a reproducer of a reaching kind and a bounded
56
+ impact/exploitability statement; missing either, it renders **unproven** with its reason and **stays
57
+ in the security section** — never auto-demoted to maintenance. The label is one policy point,
58
+ `security.review.unprovenBucket` (default `security-unproven`); the procedure lives in the
59
+ `lisa-security-review` skill.
60
+
61
+ ## Artifact identity (pinned, never assumed)
62
+
63
+ A claim applies only to the artifact its evidence was collected against. Every verdict pins
64
+ `artifact.head_sha` — the commit the run observed — and every evidence entry pins the
65
+ `artifact_head_sha` in force when it was captured, its `sha256` content digest, and `captured_at`.
66
+ Evidence collected on a pre-merge head is valid for the merge commit **only** when that head is a
67
+ parent of the merge, per the ancestry + deploy-run definition of "what shipped" that
68
+ `lisa-drive-pr-to-merge` already owns — cite it, never write a second one. A mismatched SHA or a
69
+ recomputed digest that disagrees fails loudly, naming both SHAs / the evidence id, and verification
70
+ re-runs against the merged head before completion is declared. Full definition: the reference body.
71
+
72
+ ## Not established (required, never omitted)
73
+
74
+ A claim with no reaching evidence is **Not established**, and every report says so out loud. Each
75
+ evidence comment and verdict carries a `Not established` section listing what was *not* proved —
76
+ boundaries not exercised, environments not tested, behavior consciously out of scope. It is never
77
+ omitted and never blank: with nothing outstanding it still renders `None outstanding — reviewed`, and
78
+ `not_established_reviewed` attests the list was reviewed even when the list itself is empty. This
79
+ generalizes the required, never-empty `Known limits` field of `lisa-improve-harness`. Full definition
80
+ and operator-voice exemplars: the reference body.
81
+
82
+ ## No behavior change; degrade, never block
83
+
84
+ This rule is documentation, not a gate: it changes no schema, no skill, and no check. Where a later
85
+ surface it names is not yet installed, cite the boundary a claim reaches and continue — never block
86
+ on the absent surface. Read the contract to someone who has never seen Lisa and they should be able
87
+ to say why a unit-test log does not prove a button works in the browser.
88
+
89
+ ---
90
+
8
91
  Lisa's verification machinery already proves outcomes empirically, but nothing states *which kind of
9
92
  evidence establishes which kind of claim*. So a claim about browser-visible behavior, supported only
10
93
  by a unit-test log, currently reads as "verified" — the report never names the boundary its evidence
@@ -5,6 +5,43 @@ alwaysApply: false
5
5
 
6
6
  # Claim-Time Guards
7
7
 
8
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
9
+ > section below is the former eager head, preserved verbatim; the full
10
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
11
+
12
+ ## Claim-Time Guards (load-bearing)
13
+
14
+ Two guards that run when build-intake claims a ready item, both from failures observed in the fleet: an item built twice because it had already shipped, and a loop burning cycles re-attempting an item that was never going to succeed.
15
+
16
+ **One vendor-neutral contract, cited by every build-intake arm** (the `leaf-only-lifecycle` / `repo-scope-split` / `rejection-detection` / `claim-archaeology` precedent: one shared slug, never three divergent implementations).
17
+
18
+ ## When they run
19
+
20
+ Inside build-intake step `3b`, after `rejection-detection` and `claim-archaeology`, still before the `$READY → $CLAIMED` transition. The `two-failed-attempts` valve runs first — it is cheaper and it is the only pass that can stop the claim outright.
21
+
22
+ ## `already-implemented` → `verify-and-close`
23
+
24
+ A ready item may already be implemented, because agents ship without transitioning. Before implementing, probe for the item's **own** key:
25
+
26
+ ```bash
27
+ git log --all --grep "<key>" --format='%H %aI %s' -n 10
28
+ gh pr list --repo <org>/<repo> --state all --search "<key>" --json number,state,mergedAt,url
29
+ ```
30
+
31
+ On a hit, do not build it twice — switch `3c` to **verify-and-close**: verify what shipped against this item's acceptance criteria, post evidence naming the shipping PR/commit, then run the ordinary `3d` transition and rollup. If the shipped change only partially satisfies the criteria, implement the remaining gap instead of closing.
32
+
33
+ Distinct from `claim-archaeology` (finds a **different** ancestor issue) and from `DUPLICATE_ALREADY_FIXED` (a **different** canonical issue). Unreadable history degrades to "no hit"; the guard never blocks the claim.
34
+
35
+ ## `two-failed-attempts` → blocked
36
+
37
+ Every non-success terminal outcome records a durable marker on the item — a visible line plus `<!-- [lisa-build-attempt] n=<N> outcome=<outcome> measures=<work|machine> -->` (match on the marker, never the title). A cron holds no memory between cycles, so the item carries the count.
38
+
39
+ **Two filters before counting.** Count a marker only when it is `measures=work` — a run terminated by a signal, or whose outcome was `recovery-required`, measures the box and not the item — and only when it was recorded **after the item most recently entered the ready lane**. An unlabelled marker counts as `work`; an unreadable lane history falls back to counting every `work` marker. Both defaults keep the valve shut rather than open (CodySwannGT/lisa#3854).
40
+
41
+ With **two or more** surviving markers at claim time: do not claim. Move the item to the configured `blocked` role (resolved per `config-resolution`, never hardcoded), post an operator-readable comment naming both attempts and what a human must decide or supply, and **stop the loop** for this cycle. Recovery is deliberate and it works — a human or a `lisa-repair-intake` cycle with the blocker provably cleared returns it to the queue, which ends the period the old markers describe without deleting them.
42
+
43
+ ---
44
+
8
45
  Two guards that run when build-intake claims a ready item. Both come from acmeorgb's hand-rolled `sprint-loop` and both address failures actually observed there — an item built twice because it had already shipped, and a loop burning cycles re-attempting an item that was never going to succeed.
9
46
 
10
47
  It is a **single vendor-neutral contract** consumed by all three build-intake skills (`lisa-github-build-intake`, `lisa-jira-build-intake`, `lisa-linear-build-intake`). Each arm cites this slug in its claim step rather than growing its own copy, exactly as the arms cite `leaf-only-lifecycle`, `repo-scope-split`, `rejection-detection`, and `claim-archaeology`. One slug is what keeps a guard that fires on GitHub from being absent on Linear.
@@ -7,6 +7,103 @@ alwaysApply: false
7
7
 
8
8
  Lisa is vendor-agnostic. PRDs can be sourced from Notion, Confluence, Linear, GitHub Issues, or JIRA. Tickets can be written to JIRA, GitHub Issues, or Linear. Per-project configuration lives in `.lisa.config.json` at the repo root, with optional `.lisa.config.local.json` overriding on a per-key basis.
9
9
 
10
+
11
+ > The sections between here and the horizontal rule were demoted out of the
12
+ > always-on eager head by CodySwannGT/lisa#3992, verbatim. They are tracker-write
13
+ > and provider mechanics: needed when a flow writes to a tracker or resolves a
14
+ > deploy target, not on every session. The eager head keeps the resolution
15
+ > pointer, the Atlassian identity switch, tracker selection, and repo identity.
16
+
17
+ ## Tracker status vocabulary
18
+
19
+ **A status transition may target only a status named in the project's configured workflow map** (`jira.workflow.*` for JIRA; the equivalent label/state map for GitHub and Linear). The configured map is the COMPLETE authorized vocabulary — not a starting point.
20
+
21
+ - **Never adopt statuses discovered from the tracker's live workflow metadata** — transition lists (`getTransitionsForJiraIssue` targets), board columns, status descriptions, or statuses seen on other tickets. A tracker workflow usually contains more statuses than the config names; those extra statuses are not lisa's to use. The live workflow is consulted only to find the transition *id* that reaches a config-named status.
22
+ - **A lifecycle stage with no configured status gets no transition.** If the flow reaches a stage the map does not name (e.g. "PR open awaiting review" when `jira.workflow.review` is unset, or a QA-ready stage with no `qa` mapping), leave the status where it is and record the stage in a comment. Do not pick the nearest-sounding tracker status.
23
+ - **This binds every actor that writes to the tracker** — the lead as much as any subagent. In runtimes where interactively-authenticated MCPs are lead-only, the lead performs the tracker writes for the whole flow; loading an implement/sync skill without the agent definition does not relax this rule.
24
+
25
+ This is the shared slug for the config-bound-transitions policy (the `leaf-only-lifecycle` precedent: one slug, never divergent per-surface prose). Skills and agent definitions cite it rather than restating it.
26
+
27
+ ## Project rules and learnings
28
+
29
+ Host-authored project rules live in the fixed, agent-neutral directory
30
+ `.agents/rules/` — not a configurable file. Every agent reaches it through the
31
+ Lisa-managed pointer block in `AGENTS.md`, so it is read once, on demand. A
32
+ project that still carries the retired `.claude/rules/PROJECT_RULES.md` keeps
33
+ it, untouched and authoritative; the pointer names it too. Automated
34
+ learnings never append to host rules: they use the separate machine-managed
35
+ ledger resolved from `.lisa.config.json` — the optional `learnings.file`
36
+ override, else the default `.lisa/PROJECT_LEARNINGS.md`. The ledger lives in the
37
+ cold `.lisa/` tree (never an auto-loaded rules directory) and is consumed only
38
+ through the contract's bounded projection, never read raw wholesale. Both
39
+ writers and budget checks import the executable contract from
40
+ `@codyswann/lisa/learnings`; they must not copy its numeric limits.
41
+
42
+ ## Optional Kane browser provider
43
+
44
+ Kane is selected only through `verification.browser.kane`: require `enabled: true`, exact version
45
+ `0.6.3`, `cloudUploadApproved: true`, an explicit non-production `allowedEnvironments` entry, a
46
+ Test Manager `projectId`, and a resolved `exploration` mutation policy of `full`. Credentials never
47
+ live in Lisa config. Run `lisa kane probe` before use and invoke only through `lisa-kane-browser`;
48
+ provider/auth/upload/schema failures are tooling failures, not product failures. Kane supplies
49
+ empirical evidence only—native Playwright/Cypress/Maestro remains the regression authority.
50
+
51
+ ## Env → base branch
52
+
53
+ The `## Target Backend Environment` grammar is durable: human-confirmed values
54
+ are a bare configured key or `Confirmed: <env>`; automation writes either
55
+ `Inferred: <env> — evidence: <title|body|reproduction|hostname>` or
56
+ `Assumption: <env> — remote default branch <branch>`. When no unique environment
57
+ maps to the default branch, use `Assumption: remote default branch <branch>`.
58
+ Human confirmation replaces an automated annotation with a bare key or
59
+ `Confirmed: <env>`. For legacy bare values, use managed draft markers and current
60
+ ticket content only; provider edit history is not required. A marker proves
61
+ automation and requires re-annotation; otherwise unknown provenance with
62
+ conflicting evidence stops for confirmation.
63
+
64
+ Resolution order is human-confirmed value; validated `Inferred:` evidence; then
65
+ one unambiguous signal from the human-authored title, body, and reproduction
66
+ steps or a URL hostname. Exclude the complete `Target Backend Environment`
67
+ section and other machine-authored metadata/draft blocks from the scan so an
68
+ annotation cannot validate or conflict with itself. Evidence supersedes only an
69
+ `Assumption:`. A signal must be an exact
70
+ `deploy.branches` key as a complete token/hostname label. The sole normalization
71
+ is `prod` ↔ `production` when exactly one is configured; no other aliases exist.
72
+ Conflicting signals stop. Never infer from arbitrary branch text, URL paths or
73
+ query strings, or substrings. With no signals, use the remote default branch and
74
+ record an assumption: include `<env>` only for a unique reverse-map, otherwise
75
+ use the branch-only form without inventing an environment or blocking. Require
76
+ any selected environment mapping and its remote branch to exist.
77
+ A non-integration environment bug is fixed, merged, and verified on that
78
+ environment branch first, then
79
+ forward cherry-picked down to the integration branch via a linked follow-up.
80
+
81
+ ## Env-keyed `done` — promotion completeness
82
+
83
+ A merged PR's base branch names the environment a change **entered**, never the environments it has
84
+ **reached**. Before writing an env-keyed `done`, walk `deploy.order` from its lowest rung and write
85
+ the highest **contiguously reached** rung at or below the resolved env. A rung is reached only when
86
+ the merge commit is an ancestor of its `deploy.branches` branch
87
+ (`git merge-base --is-ancestor <merge-sha> origin/<branch>`, asserted for **every** env branch at or
88
+ below the resolved one, not only the PR's base) **and** that branch's most recent deploy
89
+ **concluded `success`** — read the `conclusion`, never the `status`, because an in-flight deploy has
90
+ a null conclusion and looks identical to a pass. Only a concluded `success` promotes: a null
91
+ conclusion and every other conclusion (`failure`, `cancelled`, `timed_out`, `neutral`, `skipped`,
92
+ `stale`, `action_required`) leave the rung unreached. Where `deploy.order` is absent the ladder is
93
+ the single resolved env; where a branch exposes no deploy surface at all, ancestry alone decides
94
+ that rung.
95
+
96
+ A hotfix straight to `main` that skipped `staging` therefore resolves to the rung below the gap and
97
+ stays open; the terminal value, and provider-native closure with it, is earned only by a
98
+ promotion-complete merge. The recorded reason always carries all three fields —
99
+ `<first unreached env> (<its branch>) — <condition>`, where the condition is `missing ancestry`,
100
+ `deploy unknown: <run URL or "no concluded run">`, or `deploy concluded <conclusion>: <run URL>`. A
101
+ failing run named without its environment and branch is an incomplete reason. An open back-fill PR
102
+ against a skipped environment branch is outstanding delivery, not branch hygiene.
103
+
104
+
105
+ ---
106
+
10
107
  This rule is the single source of truth for the `.lisa.config.json` schema, the resolution algorithm, and the dispatch tables every vendor-neutral skill follows.
11
108
 
12
109
  ## File location and precedence