@codyswann/lisa 4.49.0 → 4.50.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 (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 +120 -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 +83 -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,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
@@ -35,95 +35,8 @@ This applies before declaring connection state, before running any `acli jira *`
35
35
 
36
36
  Project tracker (`jira` / `github` / `linear`) is read from `.lisa.config.json` `tracker`. Vendor-neutral skills MUST dispatch through the configured tracker, never infer it from arguments. Missing `tracker` → stop and instruct the user to run the matching `/lisa:setup:*` skill.
37
37
 
38
- ## Tracker status vocabulary
39
-
40
- **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.
41
-
42
- - **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.
43
- - **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.
44
- - **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.
45
-
46
- 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.
47
-
48
38
  ## Repo identity
49
39
 
50
40
  `repo:<name>` is the canonical label for which repo a work item belongs to. Resolve current-repo identity in this priority order: `.lisa.config.local.json` `repo` → `.lisa.config.json` `repo` → `.lisa.config.json` `github.repo` → `basename -s .git "$(git remote get-url origin)"`. If none resolve, stop with a clear error.
51
41
 
52
- ## Project rules and learnings
53
-
54
- Host-authored project rules live in the fixed, agent-neutral directory
55
- `.agents/rules/` — not a configurable file. Every agent reaches it through the
56
- Lisa-managed pointer block in `AGENTS.md`, so it is read once, on demand. A
57
- project that still carries the retired `.claude/rules/PROJECT_RULES.md` keeps
58
- it, untouched and authoritative; the pointer names it too. Automated
59
- learnings never append to host rules: they use the separate machine-managed
60
- ledger resolved from `.lisa.config.json` — the optional `learnings.file`
61
- override, else the default `.lisa/PROJECT_LEARNINGS.md`. The ledger lives in the
62
- cold `.lisa/` tree (never an auto-loaded rules directory) and is consumed only
63
- through the contract's bounded projection, never read raw wholesale. Both
64
- writers and budget checks import the executable contract from
65
- `@codyswann/lisa/learnings`; they must not copy its numeric limits.
66
-
67
- ## Optional Kane browser provider
68
-
69
- Kane is selected only through `verification.browser.kane`: require `enabled: true`, exact version
70
- `0.6.3`, `cloudUploadApproved: true`, an explicit non-production `allowedEnvironments` entry, a
71
- Test Manager `projectId`, and a resolved `exploration` mutation policy of `full`. Credentials never
72
- live in Lisa config. Run `lisa kane probe` before use and invoke only through `lisa-kane-browser`;
73
- provider/auth/upload/schema failures are tooling failures, not product failures. Kane supplies
74
- empirical evidence only—native Playwright/Cypress/Maestro remains the regression authority.
75
-
76
- ## Env → base branch
77
-
78
- The `## Target Backend Environment` grammar is durable: human-confirmed values
79
- are a bare configured key or `Confirmed: <env>`; automation writes either
80
- `Inferred: <env> — evidence: <title|body|reproduction|hostname>` or
81
- `Assumption: <env> — remote default branch <branch>`. When no unique environment
82
- maps to the default branch, use `Assumption: remote default branch <branch>`.
83
- Human confirmation replaces an automated annotation with a bare key or
84
- `Confirmed: <env>`. For legacy bare values, use managed draft markers and current
85
- ticket content only; provider edit history is not required. A marker proves
86
- automation and requires re-annotation; otherwise unknown provenance with
87
- conflicting evidence stops for confirmation.
88
-
89
- Resolution order is human-confirmed value; validated `Inferred:` evidence; then
90
- one unambiguous signal from the human-authored title, body, and reproduction
91
- steps or a URL hostname. Exclude the complete `Target Backend Environment`
92
- section and other machine-authored metadata/draft blocks from the scan so an
93
- annotation cannot validate or conflict with itself. Evidence supersedes only an
94
- `Assumption:`. A signal must be an exact
95
- `deploy.branches` key as a complete token/hostname label. The sole normalization
96
- is `prod` ↔ `production` when exactly one is configured; no other aliases exist.
97
- Conflicting signals stop. Never infer from arbitrary branch text, URL paths or
98
- query strings, or substrings. With no signals, use the remote default branch and
99
- record an assumption: include `<env>` only for a unique reverse-map, otherwise
100
- use the branch-only form without inventing an environment or blocking. Require
101
- any selected environment mapping and its remote branch to exist.
102
- A non-integration environment bug is fixed, merged, and verified on that
103
- environment branch first, then
104
- forward cherry-picked down to the integration branch via a linked follow-up.
105
-
106
- ## Env-keyed `done` — promotion completeness
107
-
108
- A merged PR's base branch names the environment a change **entered**, never the environments it has
109
- **reached**. Before writing an env-keyed `done`, walk `deploy.order` from its lowest rung and write
110
- the highest **contiguously reached** rung at or below the resolved env. A rung is reached only when
111
- the merge commit is an ancestor of its `deploy.branches` branch
112
- (`git merge-base --is-ancestor <merge-sha> origin/<branch>`, asserted for **every** env branch at or
113
- below the resolved one, not only the PR's base) **and** that branch's most recent deploy
114
- **concluded `success`** — read the `conclusion`, never the `status`, because an in-flight deploy has
115
- a null conclusion and looks identical to a pass. Only a concluded `success` promotes: a null
116
- conclusion and every other conclusion (`failure`, `cancelled`, `timed_out`, `neutral`, `skipped`,
117
- `stale`, `action_required`) leave the rung unreached. Where `deploy.order` is absent the ladder is
118
- the single resolved env; where a branch exposes no deploy surface at all, ancestry alone decides
119
- that rung.
120
-
121
- A hotfix straight to `main` that skipped `staging` therefore resolves to the rung below the gap and
122
- stays open; the terminal value, and provider-native closure with it, is earned only by a
123
- promotion-complete merge. The recorded reason always carries all three fields —
124
- `<first unreached env> (<its branch>) — <condition>`, where the condition is `missing ancestry`,
125
- `deploy unknown: <run URL or "no concluded run">`, or `deploy concluded <conclusion>: <run URL>`. A
126
- failing run named without its environment and branch is an incomplete reason. An open back-fill PR
127
- against a skipped environment branch is outstanding delivery, not branch hygiene.
128
-
129
- Full reference: [reference/config-resolution.md](config-resolution-reference.mdc).
42
+ Full reference (tracker status vocabulary, project rules and learnings, the optional Kane provider, the `Target Backend Environment` grammar, and env-keyed `done` promotion completeness): [reference/config-resolution.md](config-resolution-reference.mdc).
@@ -5,6 +5,50 @@ alwaysApply: false
5
5
 
6
6
  # Control Reachability — reference
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
+ ## Control Reachability — A Prescribed Control Must Reach the Changed Path (load-bearing)
13
+
14
+ A work item may hand the implementer a falsifiable stopping rule: *"make the change; `<named existing test>` must go red. If it still passes, the fix did nothing."* That is good practice — it replaces eyeballing with an observation. It is also **only valid if that test's fixture exercises the path the change touches.**
15
+
16
+ When it does not, the test stays green **for a reason unrelated to the change**: execution never reached the changed code. The stopping rule then instructs the implementer to revert a correct fix, and the more faithfully the implementer follows the item, the more reliably it happens. Measured once in the portfolio: a pinned test's fixture omitted the field the fix read, execution fell through to a default branch, the test stayed green, and the fix had worked.
17
+
18
+ This is the specification-side sibling of `falsifiable-checks`, which governs a check *you authored*. Here the check is **prescribed by the work item** and the defect is in the prose, not the code.
19
+
20
+ ## Authoring obligation — checkable, not advisory
21
+
22
+ **A work item that names an existing test as a red-before-green control must say what makes that test reach the code the change touches.** Naming the code is not enough; the item names the *input*.
23
+
24
+ Declare it in `## Validation Journey`, one marker per named control:
25
+
26
+ ```text
27
+ [CONTROL: <test-identifier> | reaches: <input-or-field>]
28
+ ```
29
+
30
+ - `<test-identifier>` — non-empty: the test file path, the test name, or both.
31
+ - `reaches:` — the literal key, then the **input, field, fixture key, argument, or state** that carries execution into the changed code. `reaches: the fix` and `reaches: the changed code` restate the assertion and do not satisfy it.
32
+
33
+ Enforced by gate **S20** in `lisa-jira-validate-ticket`, `lisa-github-validate-issue`, and `lisa-linear-validate-issue`; rendered by `lisa-jira-write-ticket`, `lisa-github-write-issue`, and `lisa-linear-write-issue`; read at claim time by `lisa-ticket-triage` and `lisa-implement`.
34
+
35
+ **An item that prescribes no existing-test control is exempt.** Introducing a *new* test carries no reachability obligation — the gate is `N/A` and the item is never reported as incomplete on this basis.
36
+
37
+ ## Implementer obligation — a green control is two facts, not one
38
+
39
+ `lisa-tdd-implementation` and `lisa-reproduce-bug` bind this arm: **when a prescribed control does not change state as the item predicted, stop. Establish which cause holds before acting on the stopping rule.**
40
+
41
+ | Cause | Correct action |
42
+ |---|---|
43
+ | The change had no effect on behaviour | Revisit the change |
44
+ | The fixture never reaches the changed code path | Fix or extend the control — do **not** revert |
45
+
46
+ They demand opposite actions, and the cheaper reading ("the fix did nothing") wins by default when nothing forces the distinction. So force it: **prove reachability by execution, never by reading the fixture.** Put a temporary throw, log line, or counter in the changed code and run that one test; or run coverage scoped to it and read whether the changed lines were hit. Reasoning that the fixture *looks like* it reaches the path is the same move `falsifiable-checks` rejects as "mentally reverting".
47
+
48
+ **Never revert on an unexplained green.** An unexplained control is a blocked observation, not a verdict — and a reachable-but-still-green control is the only form of it that licenses revisiting the change.
49
+
50
+ ---
51
+
8
52
  The full body behind the `control-reachability` eager head. It defines one vendor-neutral contract consumed by the three tracker writers (`lisa-jira-write-ticket`, `lisa-github-write-issue`, `lisa-linear-write-issue`), the three validators (`lisa-jira-validate-ticket`, `lisa-github-validate-issue`, `lisa-linear-validate-issue`) via gate **S20**, and the implementer surfaces `lisa-ticket-triage`, `lisa-tdd-implementation`, `lisa-reproduce-bug` and `lisa-implement`. Each surface cites this slug rather than growing its own prose, exactly as the vendor arms cite `leaf-only-lifecycle`, `repo-scope-split` and `derived-branch-plan`. One slug is what keeps a control rejected on JIRA from being accepted on Linear.
9
53
 
10
54
  ## The measured instance
@@ -5,6 +5,37 @@ alwaysApply: false
5
5
 
6
6
  # Convergent Review
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
+ ## Convergent Review
13
+
14
+ Review exists to get correct work merged, not to keep a PR in review orbit.
15
+
16
+ - Block only concrete correctness, security, data-loss, or contract-violation
17
+ failures. Lint-owned style, formatting, taste, and speculative improvements
18
+ are non-blocking unless the work item or repository rules make them release
19
+ criteria.
20
+ - Every finding must state severity, blocking yes/no, a concrete failure
21
+ scenario, evidence, and the smallest actionable fix — plus
22
+ `invariant_violated` (the property at risk) and `machinery_to_remove` (what
23
+ becomes deletable, or `none`), required for `readiness-rubric` findings and
24
+ recommended elsewhere.
25
+ - Present findings highest-consequence first, by severity and blast radius, not
26
+ by discovery order. Report section order stays stable.
27
+ - A blocking finding without a concrete failure scenario is malformed by
28
+ contract; downgrade it to non-blocking and ask for evidence.
29
+ - Resolve each finding as `fixed`, `deferred`, or `pushed-back`. If the reviewer
30
+ cannot refute a pushback with fresh evidence, the author's disposition stands.
31
+ - After suggestion implementation completes and gates pass, review does not
32
+ reopen absent new evidence: a relevant new commit, a failed gate, a newly cited
33
+ failure scenario, or a scope change.
34
+ - Irreconcilable blocking disagreement becomes a blocked work item with both
35
+ positions summarized for the operator, not an endless loop.
36
+
37
+ ---
38
+
8
39
  Review exists to get correct work merged, not to keep a PR in review orbit.
9
40
  Apply this contract to every product, quality, local, bot-parity, and suggestion
10
41
  implementation pass.
@@ -5,6 +5,63 @@ alwaysApply: false
5
5
 
6
6
  # Credential-Substrate Precedence
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
+ ## Credential-Substrate Precedence (load-bearing)
13
+
14
+ **When more than one substrate can reach an external system, the configured credentials
15
+ provider's token/CLI path goes first and the interactive MCP is the fallback — and
16
+ identity-match verification is mandatory on every substrate, at every tier.**
17
+
18
+ **One shared, vendor-neutral contract cited by every `*-access` skill** (the
19
+ `leaf-only-lifecycle` / `repo-scope-split` precedent: one shared slug, never divergent
20
+ per-skill prose). An access skill states its per-vendor mechanics — which token, which
21
+ CLI, which identity anchor — and cites this rule for the ordering. It never restates,
22
+ narrows, or locally overrides that ordering.
23
+
24
+ Settled by decision record `2026-08-12-credential-substrate-precedence` (D6), and
25
+ settled in the `settled-decisions` sense: re-arguing MCP-first inside a skill is out of
26
+ scope for that skill's work.
27
+
28
+ ## The ladder
29
+
30
+ 1. **Tier 1 — configured-provider substrate.** The token or CLI path fed by
31
+ `lisa-secrets-access`, chosen whenever its bootstrap credential is available **and**
32
+ the resolved substrate identity-matches the configured tenant/workspace/site.
33
+ `lisa-secrets-access` is the single chokepoint — never read an OS keychain a second
34
+ time. The two legacy OS-keychain rungs that remain (`lisa-atlassian-access`,
35
+ `lisa-notion-access`) are a dated migration ramp with a **removal date of
36
+ 2026-11-01**, not a standing exemption; no new access skill may add one.
37
+ 2. **Tier 2 — interactive MCP**, used only when tier 1 is *genuinely* unavailable:
38
+ no bootstrap, no adapter for the operation (per-operation, not per-session), or a
39
+ provider outage. "The MCP happens to be authenticated" and "tier 1 is slower" are
40
+ **not** qualifying reasons.
41
+ 3. **Tier 3 — loud, actionable failure** naming the exact credential to set and the exact
42
+ remediation. Never silently no-op, never blind-retry a failed or absent substrate,
43
+ never fall through to one that failed identity-match.
44
+
45
+ ## Identity-match is mandatory on every substrate
46
+
47
+ Verified **in both directions** before any operation: the substrate must claim the
48
+ configured tenant, and the configured tenant must be one the substrate can reach. A
49
+ substrate authenticated as a different account is **skipped, never used — including at
50
+ tier 1**. A credential is not an identity claim; the identity claim is what the provider
51
+ says when asked. Skipping the check because "the user obviously meant this workspace" is
52
+ forbidden.
53
+
54
+ ## Mutating operations: fallback is guarded, never routine
55
+
56
+ Falling back to an ambient-bound substrate for a **write** requires: switch profile and
57
+ assert identity immediately before the write → write → re-read the affected objects →
58
+ assert the tenant **from the response** (self URL host, cloudId in the path, response
59
+ metadata), not from the pre-flight check → on mismatch, stop, report a cross-tenant
60
+ hazard, and best-effort roll back. A successful pre-flight switch is not sufficient:
61
+ another process can mutate global state between the check and the write.
62
+
63
+ ---
64
+
8
65
  **When more than one substrate can reach an external system, the configured credentials
9
66
  provider's token/CLI path goes first and the interactive MCP is the fallback — and
10
67
  identity-match verification is mandatory on every substrate, at every tier.**
@@ -5,6 +5,43 @@ alwaysApply: false
5
5
 
6
6
  # Dependency Decisions
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
+ ## Dependency Decisions (load-bearing)
13
+
14
+ Material dependencies are recorded as decisions, not lockfile trivia. The
15
+ governed record is `.lisa/DEPENDENCY_DECISIONS.md`, seeded once by `lisa apply`
16
+ from the `all/create-only` template surface and never overwritten afterward.
17
+
18
+ A *material* dependency is one that owns a user-visible capability or would cost
19
+ real time to replace. Each record entry must name, in this order: why we keep it
20
+ in plain language, what it is, its owned capability, trust basis, exposure,
21
+ replacement cost, detection evidence, owner/review cadence, and last-reviewed
22
+ date. Field labels lead with the operator's question and keep the technical term
23
+ in parentheses. "Why we keep it" comes first on purpose — an entry that opens
24
+ with a version range opens with the trivia the record exists to replace.
25
+
26
+ When you add, upgrade across a major version, or remove a material dependency,
27
+ update its entry in the same change. When you cannot name the detection evidence
28
+ that would fail if an update broke the owned capability, write "nothing would
29
+ catch it" rather than inventing a check — the gap is the finding.
30
+
31
+ Write every entry so a non-technical operator can tell why the dependency is
32
+ kept and what evidence would detect a bad update. Lead with the outcome it
33
+ protects, not the mechanism.
34
+
35
+ Entries are repeatable blocks appended under `## Records`, so a seeding script
36
+ can add one without rewriting the file. An honest gap is written as
37
+ `_Not yet decided_` — never left blank.
38
+
39
+ Escalate, rather than just recording, when detection evidence says "nothing
40
+ would catch it", when `Last reviewed` predates the dependency's last major
41
+ upgrade, or when the trust basis names no maintainer or owner.
42
+
43
+ ---
44
+
8
45
  Lisa already governs dependency *mechanics* — pinning, audit gates, override
9
46
  resolution, duplicate detection. What those mechanics cannot tell anyone is
10
47
  **why** a dependency is in the project at all, what capability it owns, how much