@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
@@ -1,5 +1,74 @@
1
1
  # Rejection Detection at Claim Time
2
2
 
3
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
4
+ > section below is the former eager head, preserved verbatim; the full
5
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
6
+
7
+ ## Rejection Detection at Claim Time (load-bearing)
8
+
9
+ A QA rejection — an item that reached a `review`/`done`-ward state and is now back in the build-ready lane — is a **teaching signal**, not fresh work. Detect it at claim time so the re-claim can reflect on the rejection instead of repeating it.
10
+
11
+ **One vendor-neutral contract, cited by every build-intake arm** (the `leaf-only-lifecycle` / `repo-scope-split` precedent: one shared slug, never three divergent implementations).
12
+
13
+ ## When it runs
14
+
15
+ At the **top of build-intake step 3b (Claim), BEFORE the relabel** `$READY → $CLAIMED`. After the relabel the current-lane signal is gone, so detection must read history first. Detection is a pure read — idempotent, headless-safe, no side effects.
16
+
17
+ ## Classify the claimed item
18
+
19
+ Return exactly one of:
20
+
21
+ - **`rejection-reclaim`** — history shows the item reached a `review`/`done`-ward lane and is now back in `$READY`.
22
+ - **`forward-only`** — history shows only forward moves (never returned to `$READY` from a later lane).
23
+ - **`never-left-ready`** — history shows the item never left `$READY`.
24
+ - **`unknown`** — the vendor history query failed, was inconclusive, or is absent.
25
+
26
+ ## Vendor history sources (through the access layers only — `integration-access-layer`)
27
+
28
+ - **GitHub** — `LABELED` / `UNLABELED` timeline events on the configured **ready** label (the Label-Event History surface from `lisa-github-read-issue`).
29
+ - **JIRA** — the `changelog` operation on `lisa-atlassian-access` (`?expand=changelog`, status items).
30
+ - **Linear** — the `history` operation on `lisa-linear-access`, keyed on **workflow-state** history (`fromState.name` / `toState.name`, inlined on each node — no label-ID resolution needed).
31
+
32
+ **Lane names ALWAYS come from `.lisa.config.json` lanes** (`github.labels.build.{ready,claimed,done}` for GitHub, `jira.workflow.*` and `linear.workflow.*` for the status/state trackers; `src/sync/registry.ts` `BUILD_LABEL_DEFAULTS` and `LINEAR_WORKFLOW_DEFAULTS`). **Never hardcode** `status:ready`, `Ready`, `Todo`, etc.
33
+
34
+ ## Never block the build
35
+
36
+ `unknown` is a first-class result, not an error. A failing/absent history yields `unknown` and **the build proceeds** to implement the item. Detection never stops a claim.
37
+
38
+ ## Learning-loop exclusion (no learning about learning)
39
+
40
+ An artifact this flow produced is **never** a rejection-reflection trigger, no matter how it moves. Before classifying as `rejection-reclaim`, exclude items carrying any learning marker — `[lisa-learning-drop]`, `[lisa-learning-pr]`, `[lisa-learning-upstream-handoff]` — or the `learning:needs-triage` label. Such items short-circuit to `forward-only` (treated as normal work) so the detector never fires on the flow's own learning PRs/issues.
41
+
42
+ ## Reflect on a `rejection-reclaim`
43
+
44
+ On `rejection-reclaim` only, before re-implementing: read the rejection evidence (comments after the backward transition, review threads on the rejected PR) through the access layers, assemble **one** candidate learning with the rejection linked as provenance, and route it to the `lisa-persist-learning` skill. If that skill is absent, record the candidate as a comment that carries a **visible prose line** plus the marker (a bare marker renders as an empty comment bubble) — `Recorded a candidate learning from this rejection (queued for the judgment gate): <one-line candidate rule>.` followed by `<!-- [lisa-rejection-candidate] key=<issue>-<transition-ts> -->` — and proceed. **Marker-dedupe** on `<issue>-<backward-transition-timestamp>`: re-claiming twice produces no duplicate. Unreadable/absent evidence → proceed without a candidate, never block.
45
+
46
+ ## Proposal rejection memory (proposal-side — orthogonal to the reclaim path above)
47
+
48
+ A **loop-proposed** item that a human **closed as _not planned_** is a durable decline. Every *proposing* loop (`lisa-exploratory-qa`, `lisa-project-ideation`, `lisa-monitor`, `lisa-repair-intake`; `lisa-learnings-audit` is the shipped precedent) MUST consult it **before filing a candidate**. This is orthogonal to the `rejection-reclaim` path above — that classification and its reflection are untouched. The memory lives in the **tracker, not a new state file**.
49
+
50
+ - **Signal:** the prior item is closed *not planned* (GitHub `stateReason == "not_planned"`; the JIRA/Linear equivalent resolved via `config-resolution` — never hardcode). The GitHub compare is **case-insensitive** — raw `gh --json stateReason` returns `NOT_PLANNED` UPPERCASE, so normalize to lowercase (or read via `lisa-github-read-issue`) before comparing, never string-match raw `gh` JSON. Closed as **completed** is NOT a decline — a recurrence after a completed fix is a regression and may file.
51
+ - **Marker:** `<!-- [<loop-marker>] key=<candidate-key> -->`, key computed deterministically `printf '%s' "$normalized" | shasum -a 256 | cut -c1-12`. Search **open AND closed** items for the marker before filing (body-enumeration fallback on search-index lag); **match on the marker, never the title.**
52
+ - **Rule:** a hit on a closed-**not-planned** item **suppresses** the proposal. Re-file **only** with evidence postdating the decline, carrying BOTH the machine token (`declined <date>; recurred <date> in <ref>`) and a human acknowledgment sentence (`You declined this on <date>. It has recurred (<date>, <ref>), so we're raising it once more for your review.`).
53
+ - **Operator footer:** every loop-filed proposal ticket MUST carry, as visible prose, `To stop this from being raised again, close it as **Not planned**. Close it as **Completed** if it was fixed — a later recurrence may be re-filed as a regression.` — so the operator knows which close-reason produces which outcome.
54
+ - **Outcomes:** an all-suppressed cycle ends `nothing-needed` naming the **suppression count**; a memory check that cannot read the tracker ends `recovery-required`, never a silent `nothing-needed` (e.g. `Tracker unreachable during the decline check — restore credentials; nothing was filed this run.`).
55
+ - **Concurrency:** search-then-write = convergence, not mutual exclusion — a transient duplicate is closed by the next run; no cross-run lock.
56
+
57
+ ## Automation-reversal memory (repair-side — orthogonal to both halves above)
58
+
59
+ A human who **undoes a lifecycle transition this flow made** is correcting the flow, not supplying new state. Every loop that writes a lifecycle role as a **repair** (`lisa-repair-intake`) consults this before re-making a transition. It is a third classification, never merged into `rejection-reclaim`: that one is anchored on the ready lane and answers a rejection with re-implementation; this one lands in `$BLOCKED` and answers a correction by withdrawing a decision.
60
+
61
+ - **Seam:** top of the repair walk for each item, **before any lifecycle write** — after the write the current-lane signal is gone.
62
+ - **Classify:** `automation-reversal` — a role change **authored by** this flow, then a later **backward** move of that role **authored by** a human, with no automation move after it. Otherwise `no-reversal`. Authorship unavailable or history unreadable → `unknown`.
63
+ - **Authorship is the signal, not the backward move.** An item can return to `$BLOCKED` because a real new blocker appeared — that is the world moving on. Read the `actor` (GitHub timeline, Linear history) or `author` (JIRA changelog) through the access layers; an unexposed actor is `unknown`, never an assumed human. **A marker and a transition on the same item say nothing until you know their order** — compare timestamps, and treat an unorderable pair as `unknown`.
64
+ - **Lanes from config** (`github.labels.build.blocked` + the JIRA/Linear equivalents, `config-resolution`) — never hardcode.
65
+ - **Degrade:** `unknown` is **neither a reversal nor a clearance** — the item is judged by the loop's normal rules and detection **never blocks the sweep**. The learning-loop exclusion above applies unchanged.
66
+ - **Rule:** on `automation-reversal`, do not re-apply the reversed classification; leave the item where the human put it, ensure `human_needed`, and **name the reversed transition in the run record**. Re-attempt **only** on evidence that **postdates the reversal**, cited in the run record — mirroring the re-proposal rule the proposal half enforces.
67
+ - **A changed lifecycle role is no longer a sufficient warrant on its own.** A consuming loop's recurrence brake must carry **authorship and an overturn bit**, not state alone.
68
+ - **Signed per path.** Apply the inversion only where the loop decides whether to re-make a transition. A staleness/keep-alive path where a human comment already *suppresses* action is protective — leave it. One global sign reads as tightening and removes that protection.
69
+
70
+ ---
71
+
3
72
  When QA rejects an item, it moves the item **backward** — from a `review`/`done`-ward lane back to the build-ready lane — usually with a comment naming the defect. Today the re-claiming agent treats that bounced item as fresh work and repeats the rejected approach. This rule turns the backward move into a detectable, teachable signal.
4
73
 
5
74
  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 at its claim step rather than re-implementing detection, exactly as the vendor arms cite `leaf-only-lifecycle` and `repo-scope-split`. That is what keeps a rejection detected on JIRA from being missed on Linear.
@@ -1,5 +1,53 @@
1
1
  # Repo Scope & Work-Time Splitting
2
2
 
3
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
4
+ > section below is the former eager head, preserved verbatim; the full
5
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
6
+
7
+ ## Repo Scope & Work-Time Splitting (load-bearing)
8
+
9
+ **Leaf work units are single-repo.** A leaf is an individually implementable ticket with no open children — the by-design leaf types **Bug, Task, Sub-task, Improvement**, plus a childless **Story** or **Spike** (structurally a leaf per `leaf-only-lifecycle`). Each names exactly one repo. An **Epic**, and any **Story/Spike that still holds child work**, are coordination containers and may span repos.
10
+
11
+ Enforced at four points: gate **S10** (`*-validate-*`, write time), `task-decomposition` step 1.5 (PRD-decomposition time), claim-time repo scoping (`*-build-intake`), and the work-time split procedure (an existing ticket about to be implemented).
12
+
13
+ ## Choose the right strategy
14
+
15
+ - **Decomposition-time (no tickets exist yet):** use `task-decomposition` step 1.5 — one work unit per repo under a parent Story.
16
+ - **Work-time (a ticket already exists):** narrow the original to one repo, spin off a sibling per additional repo, link by dependency. Do NOT invent a new parent — siblings inherit the original's existing parent.
17
+
18
+ ## Work-time split (pre-flight gate, agent-performed)
19
+
20
+ 1. **Detect repos.** Parse description + AC + approach, confirm against actual code surfaces. If single-repo, no split.
21
+ 2. **Pick the keeper.** Default: the original keeps the consumer / user-facing repo.
22
+ 3. **Create one sibling per extra repo**, cloning metadata (re-prefix summary, scope AC, carry parent, env, sign-in).
23
+ 4. **Link by dependency.** Producer **blocks** consumer (`is blocked by` on consumer / `blocks` on producer). No clear direction → `relates to`.
24
+ 5. **Narrow the original.** Edit summary prefix, Repository section, AC; remove cross-repo references.
25
+ 6. **Comment** on the original noting the split, linking each sibling.
26
+ 7. **Re-validate.** Run `tracker-verify` (S10) on the original and every sibling. All must PASS single-repo.
27
+ 8. **Proceed in dependency order.** Producer siblings first.
28
+
29
+ ## When to BLOCK instead of split
30
+
31
+ Fall back to the standard BLOCK + reassign-to-Reporter path when:
32
+
33
+ - Repos cannot be determined confidently from ticket + code.
34
+ - Splitting would strand stakeholder context only the reporter can re-scope.
35
+ - Required clone metadata (parent, env, credentials) is itself missing.
36
+
37
+ ## Claim-time repo scoping (build-intake)
38
+
39
+ A tracker can oversee multiple repos. Build-intake claims only current-repo tickets. Resolve current repo per `config-resolution` (config `repo` → `github.repo` → git remote basename).
40
+
41
+ **Query-time pre-filter (do this first, where expressible).** Scope the candidate query to the current repo so sibling-repo tickets never enter the set — on JIRA, append `AND (labels = "repo:<current>" OR labels IS EMPTY)`. This pre-applies only the unambiguous wrong-repo → skip arm; `labels IS EMPTY` keeps unlabeled tickets visible so the per-candidate gate below can still determine + stamp them. Skip it (broad scan) when the current repo can't be resolved or the query already constrains repo. Apply only where the query layer can express `OR labels IS EMPTY`: JIRA does (applied); GitHub issues are inherently single-repo (not needed); Linear's label filter can't, so it keeps the broad query and relies on the per-candidate gate.
42
+
43
+ Then, for each ready candidate:
44
+
45
+ 1. **Read `repo:<name>` label.** Wrong repo → skip. Current repo → leaf-only gate + claim. Unlabeled → determine + stamp + re-apply.
46
+ 2. **Multi-repo leaf → split, never claim.** Each split sibling is created build-ready and stamped with its own `repo:<name>`.
47
+ 3. **Wrong-repo single-repo leaf → skip** (label keeps it cheap next cycle).
48
+
49
+ ---
50
+
3
51
  Leaf work units are single-repo. A **leaf work unit** is an individually implementable ticket with no open child tickets — the by-design leaf types **Bug, Task, Sub-task, Improvement**, plus a childless **Story** or **Spike** (a childless Story/Spike is structurally a leaf — see `leaf-only-lifecycle`). Each must name exactly one repository. An **Epic**, and any **Story or Spike that still holds child work**, are coordination containers and may span repos.
4
52
 
5
53
  This invariant is enforced at four points: gate **S10** in the `*-validate-*` skills (write time), `task-decomposition` step 1.5 (PRD-decomposition time), **claim-time repo scoping** in the build-intake skills (when intake decides whether to claim a ready ticket for the current repo — see below), and the work-time split procedure below (when an agent picks up an existing ticket to implement it).
@@ -1,5 +1,60 @@
1
1
  # Reset/Seed Coverage & State Classification
2
2
 
3
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
4
+ > section below is the former eager head, preserved verbatim; the full
5
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
6
+
7
+ ## Reset/Seed Coverage & State Classification (load-bearing)
8
+
9
+ **Every persistent entity a project owns carries exactly one declared reset policy, and a work item that adds or changes persistent state is not done until the reset/seed contract covers it.** An entity the running system holds but the contract does not classify is a contract violation, and the check that finds it **fails closed** — an unclassified entity is never treated as safe to keep and never treated as safe to delete.
10
+
11
+ **One vendor-neutral contract, cited by** `lisa-research`, `lisa-acceptance-criteria`, `lisa-task-decomposition`, `lisa-test-strategy`, `lisa-implement`, `lisa-codify-verification`, `lisa-verification-lifecycle`, and `lisa-verify` (the `leaf-only-lifecycle` / `repo-scope-split` precedent: one shared slug, never divergent per-skill prose). It never names a database engine, cloud, identity provider, or test runner — those are project configuration.
12
+
13
+ ## Why this exists
14
+
15
+ Test suites create state. Without a contract, cleanup is a habit: a flow creates a uniquely-marked record and deletes it on the happy path only, so every early failure leaks one more. Nothing sweeps it, nothing complains, and the suite degrades until someone reads a flake as a product bug. The observed shape is always the same — leaked records accumulate silently until a list view, a uniqueness constraint, or a count assertion breaks. Per-flow self-cleanup is not coverage; it is the failure mode.
16
+
17
+ ## Membership
18
+
19
+ Membership is **state, not repo name, ticket label, or storage engine**: an entity is in scope the moment something the project writes **outlives the process that wrote it**. That includes rows and tables, but rows are only one kind of state. Also in scope: identity-provider objects (accounts, groups, memberships, sessions), object storage (buckets, prefixes, uploaded files), search indexes, queues and topics (in-flight and dead-letter), caches with a persistence tier, materialized/derived views and projections, feature-flag and configuration overrides, scheduled jobs created at runtime, and analytics or third-party side effects a run leaves behind. Out of scope: values that live only in memory for the duration of one process.
20
+
21
+ A work item is in scope when it **adds** such an entity, **changes what owns or writes** one, or **changes the lifetime** of one. Renames count as changes, not as new entities plus deletions.
22
+
23
+ ## The four policies
24
+
25
+ Every entity is classified as exactly one of:
26
+
27
+ - **`fixture-owned`** — the reset may create, mutate, and delete rows here, but only those it owns. Ownership is declared as a predicate (a reserved id shape, a reserved account or namespace, a marker attribute), never as "everything in this entity."
28
+ - **`preserve`** — the reset must leave this untouched. Catalog, reference data, anything a migration seeds, anything expensive or impossible to rebuild, and any state belonging to someone who is not the fixture.
29
+ - **`derived-rebuild`** — not authored by anyone; recomputed from its sources after the reset (projections, materialized views, search indexes, caches). The reset rebuilds it rather than clearing or preserving it, and proves it converged.
30
+ - **`forbidden`** — the reset must be structurally unable to touch it: ledgers, payments, wallets, withdrawals, audit trails, anything irreversible. Declaring `forbidden` obliges naming the enforcement outside the script — a least-privilege role, a revoked grant, a separate account or credential boundary — because a script-only promise dies in the refactor that drops the safe caller.
31
+
32
+ **Classify by provenance, never by observation.** "The table looked empty" is not evidence it is unused; runtime statistics are approximations, and a table that has never been analyzed reports rows it holds. Ask who writes it and whether anything can put it back.
33
+
34
+ ## Keep-lists are a detector, not the safety model
35
+
36
+ Deriving the clear-list by subtracting a keep-list from a schema listing is a **useful detector** — run it, and let it flag entities the contract has not seen. It is not the boundary. It cannot model renames, multiple schemas, framework-generated entities, views, partitions, row-level ownership, or any of the non-DB state above, and "new entities are cleared unless exempted" erases unrelated data the first time something adds one. The boundary is the classification; subtraction only tells you the classification is stale.
37
+
38
+ ## Required assurances
39
+
40
+ A reset contract is not complete until it declares, and points at evidence for, all of: non-fixture and catalog data survive; reserved fixture identifiers are rejected on collision with anything real; foreign references into preserved entities are refused rather than cascaded; every write is **acknowledged** (a mutation reported by the caller and not confirmed by the system is a failure, not a success); a second apply converges to the same state and reports no further change; the post-state is verified by **exact expected counts**, not "at least one"; and production fails closed with no override of any kind. Where the platform can enforce a boundary with roles, grants, or constraints, it does — the in-process guard remains as defense in depth, never as the primary control.
41
+
42
+ ## Definition of done
43
+
44
+ A work item that adds or changes persistent state is not done until: (1) every entity it introduces or changes is classified in the project's state contract with a reason and an owner; (2) `fixture-owned` entities it introduces declare their ownership predicate **and** are actually swept by the reset — an entity a suite creates but nothing removes is the leak this rule exists to prevent; (3) `preserve`/`forbidden` entities it introduces name their enforcement; (4) any seed the suite depends on covers the new state, with the verify step asserting exact counts; and (5) the state-classification check passes in the same PR. **A missing or stale classification is a verification failure, not a warning** — it blocks completion exactly as a `PARTIAL` spec-conformance verdict does, and is never demoted to "optional", "if cheap", or a follow-up without a linked build-ready ticket created before merge.
45
+
46
+ ## Bootstrap, noop, and degradation
47
+
48
+ A project with no state contract yet is not exempt: the first work item touching persistent state scaffolds the minimum (the contract file, its own entities classified, the check wired into CI) and covers **its own** state. It never backfills the whole system — pre-existing unclassified entities are recorded as burndown with an owner and a date, not treated as this item's blocker. A project that genuinely holds no persistent state declares a **machine-readable noop** (`mode: "declared-noop"` with reason, owner, and a capability-manifest reference) which the check verifies against the repo rather than taking on faith — a bare exit 0 is indistinguishable from a successful destructive run and never satisfies this rule. A project that cannot produce a runtime inventory records the checked sources and the absence, exactly as the regression-spec absence path in `verification` does; a silent skip is never one of the exits.
49
+
50
+ ## Command envelope
51
+
52
+ Every reset, seed, verify, inventory, and classification adapter answers the **same interface** — one validated JSON result on stdout, exit 0 only when the operation both completed **and** verified, `--dry-run` mandatory before anything destructive, and a requested stage always re-checked against server-resolved identity rather than trusted. The envelope is specified in the reference body and is what makes "every repo answers the same question the same way" checkable instead of aspirational.
53
+
54
+ **The production arm of this is executable, not advisory.** `scripts/lisa-destructive-guard.mjs` ships to every adopter and is wired into the envelope itself: a destructive run against a production-resolved — or unresolvable — environment has **no representable success envelope**, so it can never exit 0, and there is no parameter, field, or environment variable anywhere in the guard that changes the answer. A dry run is not an exemption, and `--dry-run` is the default rather than an opt-in. Read this as what it is: a check at the one interface every adapter passes through, which an adapter that misreports its own environment still defeats. The end state is a destructive capability that is **not deployed to production at all** — non-existence beats refusal — and that design, with the failure modes it must still close, is recorded in `docs/design/reset-production-absence.md`.
55
+
56
+ ---
57
+
3
58
  Automated suites create state, and the state outlives them. The historical pattern is per-flow
4
59
  self-cleanup: a flow creates a uniquely-marked record at the top and deletes it as its last step, so
5
60
  the record survives every failure that happens in between. Nothing sweeps the survivors and nothing
@@ -1,5 +1,43 @@
1
1
  # Usage Accounting
2
2
 
3
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
4
+ > section below is the former eager head, preserved verbatim; the full
5
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
6
+
7
+ ## Usage Accounting (load-bearing)
8
+
9
+ Lisa attaches AI usage and cost telemetry to every artifact it creates/updates. The format is a single canonical managed section.
10
+
11
+ ## Managed section
12
+
13
+ Every artifact with inline body content gets exactly one section:
14
+
15
+ ```markdown
16
+ ## Lisa Usage
17
+ ```
18
+
19
+ **Canonical. Rewrite in place; never append a second usage section.** If the host can't safely edit body, write the same section in a comment and treat that comment as the managed artifact for future rewrites.
20
+
21
+ ## Required field semantics
22
+
23
+ Each direct entry records ONE logical Lisa run on ONE artifact. `entry_id` is the stable dedupe key — rewriting the same logical run with the same `entry_id` updates in place; a different run gets a different `entry_id`.
24
+
25
+ - **`source`**: `observed` (runtime supplied) / `estimated` (derived from trustworthy metadata + pricing contract) / `measured-subset` (a trustworthy subtotal exists, but the complete run total is unknown) / `unavailable`.
26
+ - **`measured_subset_tokens`**: optional measured subtotal for `measured-subset` entries only. Omission is normalized to `null` for backward-compatible callers. Keep `total_tokens = null` so rollups do not treat a subset as a complete total.
27
+ - **`pricing_status`**: same trinary plus `missing` (cost not known but should be).
28
+ - **Absence ≠ zero.** `null` means unknown; `0` means explicitly zero. Always write the entry — never silently omit.
29
+ - Do NOT replace observed counts with estimates.
30
+
31
+ ## Rollup
32
+
33
+ Container artifacts (Epic, PRD, etc.) roll up usage from their direct children. Roll-up is recursive — a parent's `## Lisa Usage` aggregates its descendants' direct entries. Re-writes are idempotent: re-running an intake or lifecycle skill must not duplicate entries.
34
+
35
+ Measured-child incompleteness is durable across ordinary rewrites through the optional
36
+ `lisa:usage-rollup-token-status` extension. Do not infer completeness merely because a rewrite did
37
+ not re-fetch child ledgers.
38
+
39
+ ---
40
+
3
41
  Lisa usage accounting is a vendor-neutral contract for attaching AI usage and cost telemetry to the artifacts Lisa creates or updates. It governs the section shape, machine-readable tokens, source/pricing semantics, rollup behavior, and idempotent rewrite rules. Writer skills and lifecycle skills attach telemetry by following this contract; they do not invent artifact-local formats.
4
42
 
5
43
  ## Managed section
@@ -1,5 +1,37 @@
1
1
  # Work-Item Definition of Ready — Reference
2
2
 
3
+ > Demoted from the always-on eager tier by CodySwannGT/lisa#3992. The
4
+ > section below is the former eager head, preserved verbatim; the full
5
+ > contract follows it. Reachable on demand via `rules/eager/00-rule-index.md`.
6
+
7
+ ## Work-Item Definition of Ready (type-keyed)
8
+
9
+ **`ready` means: a stateless agent can claim this item and drive it to its terminal state with zero human clarification.** Every readiness gate exists because its absence forces a question; the bar is type-keyed because different work types break autonomy differently.
10
+
11
+ ## Shared core (every leaf, enforced by `*-validate-*` S1–S16)
12
+
13
+ Three-audience description · Gherkin acceptance criteria (except Spike) · Out of Scope · single-repo scope · relationship search · typed evidence manifest on runtime changes · Source Requirement traceability when PRD-sourced · provable read access to every named external surface · declared reachability for any **existing** test the item pins as a red-before-green control (`control-reachability`, gate S20 — `N/A` when the item introduces a new test instead).
14
+
15
+ ## Per-type additions
16
+
17
+ | Type | Must additionally carry | Terminal state is |
18
+ |---|---|---|
19
+ | **Bug** | agent-executable reproduction (or a failing test) · expected-vs-actual with the *source* of "expected" · environment + version observed, last-known-good when known · reproducibility rate (always / intermittent + frequency) · at least one occurrence evidence link | the same repro/test fails before the fix and passes after |
20
+ | **Story** | user-visible AC; SHOULD name non-happy-path states (error / empty / loading) for UI stories · design source precedence when artifacts exist | every AC exercised on the running product |
21
+ | **Task** | an observable done-state and the command/check that proves it | the verification check passes |
22
+ | **Improvement** | metric + measurement method the agent can run · measured baseline value · numeric target | measured value meets the target |
23
+ | **Spike** | the question · the decision it enables + options weighed · a timebox · deliverable format **and location** | a deliverable at the named location that answers the question — findings, decision, options weighed |
24
+ | **Sub-task** | a parent, always · otherwise the bar of its own type | per its type |
25
+ | **Epic / container** | never build-ready (`leaf-only-lifecycle`) · judged on decomposition completeness, not buildability | all required children terminal |
26
+
27
+ ## The stateless-pickup test (S18)
28
+
29
+ The final gate checks the property itself instead of proxies for it: read the item as a fresh agent with no session context, using only the item and what it links to. List every question you would have to ask a human before starting, choosing between materially different implementations, or declaring done. **Ready = zero questions.** Each question found is the FAIL remediation, verbatim.
30
+
31
+ Sources this bar distills: INVEST (stories) · ISTQB / IEEE 1044 defect anatomy and minimal-reproducible-example practice (bugs) · SMART (improvements) · Scrum's Definition of Ready (the framing) · TASC AC8.6 (the normative criterion).
32
+
33
+ ---
34
+
3
35
  The eager head carries the table; this reference carries the reasoning, the
4
36
  failure modes each requirement prevents, and worked examples. The enforcing
5
37
  gates live in the three tracker validators (`lisa-jira-validate-ticket`,
@@ -37,6 +37,143 @@ function normalizeLabels(labels) {
37
37
  .filter(label => label.length > 0);
38
38
  }
39
39
 
40
+ /**
41
+ * Decoration a declaration may sit behind, and nothing more.
42
+ *
43
+ * Whitespace, blockquote arrows, list bullets or numbers, emphasis, a comment
44
+ * hash, and an opening HTML comment. `#` is there on EVIDENCE rather than
45
+ * taste: a shell script declares a hold as `# <marker> reason=…` — a bare
46
+ * marker behind a SHELL comment, with no HTML comment anywhere — and that form
47
+ * is in this repository's own guard fixtures. A single character class plus two
48
+ * optional groups —
49
+ * deliberately not a nested-quantifier pattern, because this runs over
50
+ * untrusted work-item bodies and `sonarjs/slow-regex` is right about that
51
+ * shape.
52
+ */
53
+ const LEADING_DECORATION =
54
+ /^[ \t>*_+#-]*(?:\d+[.)][ \t]*)?(?:<!--[ \t]*)?[ \t]*/u;
55
+
56
+ /**
57
+ * The body with fenced blocks and inline code spans removed.
58
+ *
59
+ * Documentation of a declaration is not a declaration, and a fenced example is
60
+ * how the declaration form gets written ABOUT. The same move
61
+ * `pr-arming-sweep.mjs` makes for the auto-merge-off marker
62
+ * (CodySwannGT/lisa#3986), and the same one `block-direct-issue-create.sh`
63
+ * makes when it strips heredoc bodies before tokenising argv.
64
+ * @param {unknown} body - The raw item body
65
+ * @returns {string} The body with quoted and code regions blanked out
66
+ */
67
+ function declarativeText(body) {
68
+ return String(body ?? "")
69
+ .replace(/```[\s\S]*?```/gu, "")
70
+ .replace(/`[^`\n]*`/gu, "");
71
+ }
72
+
73
+ /**
74
+ * Whether an HTML comment on this line carries the marker.
75
+ *
76
+ * The second declaration form, and it is not a concession: an HTML comment is
77
+ * invisible when the body is rendered, so nobody writes one to TALK about the
78
+ * marker — a quotation has to be visible to be a quotation. Prose about the
79
+ * marker is written in sentences, code spans and fenced examples, all of which
80
+ * this rule already excludes.
81
+ *
82
+ * Scanned rather than pattern-matched. A regular expression with two lazy
83
+ * `[^\n]*?` runs around a literal is the ambiguous shape this module avoids
84
+ * elsewhere, and an indexOf walk is both linear and easier to be sure about.
85
+ * @param {string} line - One line of the body
86
+ * @returns {boolean} True when a comment on this line contains the marker
87
+ */
88
+ function commentCarriesMarker(line) {
89
+ const segments = line.split("<!--");
90
+ for (let index = 1; index < segments.length; index += 1) {
91
+ const close = segments[index].indexOf("-->");
92
+ const inside =
93
+ close === -1 ? segments[index] : segments[index].slice(0, close);
94
+ if (inside.includes(HUMAN_GATE_MARKER)) return true;
95
+ }
96
+ return false;
97
+ }
98
+
99
+ /**
100
+ * Whether one line DECLARES a hold rather than mentioning one.
101
+ *
102
+ * Two accepted forms, and the corpus says they cost nothing to combine:
103
+ * measured over this repository's 42 matching bodies, line-leading alone and
104
+ * line-leading-or-comment hold the SAME 29. The comment branch exists because
105
+ * the filing guard reads inputs that are not markdown documents — a one-line
106
+ * `--body` string and a shell script — where a declaration legitimately sits
107
+ * after other text on its line.
108
+ * @param {string} line - One line of the body
109
+ * @returns {boolean} True when the line declares a hold
110
+ */
111
+ function declaresOnLine(line) {
112
+ if (line.replace(LEADING_DECORATION, "").startsWith(HUMAN_GATE_MARKER)) {
113
+ return true;
114
+ }
115
+ return commentCarriesMarker(line);
116
+ }
117
+
118
+ /**
119
+ * Count what a body says about the hold marker, split by what it MEANS.
120
+ *
121
+ * ## Why the substring test had to go
122
+ *
123
+ * `isHumanGated` asked one question — does the body contain the marker
124
+ * anywhere — and that form was deliberate, documented, and correct when it was
125
+ * written: *"it is a marker with no other meaning, so its presence IS the
126
+ * declaration."* The premise expired. The marker acquired a second meaning —
127
+ * **being discussed** — the moment the feature became something people file
128
+ * tickets about, so a sentence quoting it, a Gherkin line naming it, and a
129
+ * ticket about it all read as declared holds (CodySwannGT/lisa#3815).
130
+ *
131
+ * The consequence is not one skipped cycle. `planHumanGateReconciliation`
132
+ * removes the ready role and applies the human-needed label, so a false
133
+ * positive rewrites the item's own metadata and every later sweep agrees with
134
+ * the first. And the affected population GROWS with the documentation: 38
135
+ * matching bodies measured 2026-09-04, 42 on 2026-09-05.
136
+ *
137
+ * ## The rule
138
+ *
139
+ * A declaration is POSITIONAL — the marker leads its line, behind at most
140
+ * blockquote, list, emphasis or opening-comment decoration — evaluated after
141
+ * code regions are removed. Measured over this repository's 42 matching bodies:
142
+ * this holds 29 of them and correctly releases the two live ready-lane items
143
+ * that only discussed the marker.
144
+ *
145
+ * The stricter HTML-comment-only rule was measured and REJECTED: it holds only
146
+ * 18, dropping declarations that carry `human-needed` today. Losing a real hold
147
+ * is the unsafe direction and would need a retrofit of the tracker.
148
+ *
149
+ * ## Why it counts rather than answering yes or no
150
+ *
151
+ * A heuristic that silently drops candidates is indistinguishable from one that
152
+ * found none. Every occurrence this rule declines to honour is counted and
153
+ * reported, so "the rule demoted 33 mentions" is a fact an operator can read
154
+ * rather than an absence they must infer.
155
+ * @param {unknown} body - The item body
156
+ * @returns {{ total: number, declared: number, demoted: number }} Occurrences,
157
+ * those that declare a hold, and those demoted to mentions
158
+ */
159
+ export function humanGateMentions(body) {
160
+ const raw = String(body ?? "");
161
+ const total = raw.split(HUMAN_GATE_MARKER).length - 1;
162
+ const declared = declarativeText(raw)
163
+ .split("\n")
164
+ .filter(line => declaresOnLine(line)).length;
165
+ return { total, declared, demoted: total - declared };
166
+ }
167
+
168
+ /**
169
+ * Whether a body declares a hold, as opposed to discussing one.
170
+ * @param {unknown} body - The item body
171
+ * @returns {boolean} True when at least one line declares a hold
172
+ */
173
+ export function bodyDeclaresHold(body) {
174
+ return humanGateMentions(body).declared > 0;
175
+ }
176
+
40
177
  /**
41
178
  * Whether an item is held for a person, on either surface.
42
179
  *
@@ -64,7 +201,7 @@ export function isHumanGated(input) {
64
201
  return true;
65
202
  }
66
203
 
67
- return String(input.body ?? "").includes(HUMAN_GATE_MARKER);
204
+ return bodyDeclaresHold(input.body);
68
205
  }
69
206
 
70
207
  /**
@@ -432,6 +569,26 @@ export function formatHumanGateNote() {
432
569
  * @param {readonly unknown[]} held - Item references held this cycle
433
570
  * @returns {string} One summary line
434
571
  */
572
+ /**
573
+ * Render the cycle-summary line naming what the precision rule DEMOTED.
574
+ *
575
+ * The counterpart of {@link summarizeHumanGateHolds}, and it exists for the
576
+ * same reason: a mutation nobody can see afterwards is the problem this whole
577
+ * area keeps having. A rule that quietly declines to honour half the marker
578
+ * occurrences it sees reads exactly like a rule that saw none, so the count is
579
+ * printed even when it is zero — measured across this repository's matching
580
+ * bodies, 33 of 62 occurrences are mentions rather than declarations.
581
+ * @param {unknown} demoted - How many occurrences were mentions, not declarations
582
+ * @returns {string} One summary line
583
+ */
584
+ export function summarizeHumanGateMentions(demoted = 0) {
585
+ const count = Number.isFinite(Number(demoted))
586
+ ? Math.trunc(Number(demoted))
587
+ : 0;
588
+ const shown = count > 0 ? String(count) : "none";
589
+ return `Marker mentions demoted (not declarations): ${shown}.`;
590
+ }
591
+
435
592
  export function summarizeHumanGateHolds(held = []) {
436
593
  const names = (Array.isArray(held) ? held : [])
437
594
  .map(item => trimmedString(item))
@@ -1136,10 +1136,26 @@ not there, and a lifecycle step performed by hand is one nothing can verify
1136
1136
  happened.
1137
1137
 
1138
1138
  **The backstop, for the ones that still slip:** `lisa-work-item.mjs sweep`
1139
- reports every claimed item that already has a merged pull request, and
1139
+ reports every open item — in the **ready** lane as well as the **claimed** one —
1140
+ that a commit on a deploy branch DECLARES via its `Work-Item:` trailer, and
1140
1141
  `--apply` completes them. Reporting is the default deliberately — a sweep that
1141
1142
  closes things as a side effect of being run is not one anyone runs twice.
1142
1143
 
1144
+ You do not need to run it. The `🧹 Lifecycle Drift Sweep` workflow runs it
1145
+ daily and files a deduplicated issue when drift exists, because a report with
1146
+ no consumer and no report are the same thing with different amounts of code.
1147
+
1148
+ Two properties worth knowing, because both were once the other way round:
1149
+
1150
+ - **Credit requires a declaration, never a mention.** Evidence is a commit
1151
+ reachable from a deploy branch whose own trailer names the item. It used to
1152
+ be a timeline cross-reference, which any pull request that so much as *named*
1153
+ `#N` created — so one merged land-stack pull request made every sibling in
1154
+ its batch look shipped. Measured: 8 of 53 reported items had no commit
1155
+ declaring them, and every one of the 8 had live work open against it.
1156
+ - **A clean result names the lanes it examined.** "No drift" over a subject
1157
+ list that excluded the ready lane was true and unusable.
1158
+
1143
1159
  ## 4. Terminal states
1144
1160
 
1145
1161
  Loop until one of:
@@ -332,6 +332,10 @@ other gate's verdict — however conclusive — may promote an item a person par
332
332
  4. **Name it in the cycle summary** via `summarizeHumanGateHolds([...])`, so the record
333
333
  distinguishes "nothing was eligible" from "something eligible was held for a person". A lane
334
334
  mutation nobody can see afterwards is the same class of problem this gate exists to fix.
335
+ Report alongside it what the precision rule SKIPPED, via `summarizeHumanGateMentions(n)`
336
+ — the marker occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815).
337
+ A rule that quietly declines to honour half the occurrences it sees reads exactly like a
338
+ rule that saw none, so the count is printed even when it is zero.
335
339
  5. **Continue to the next candidate.** A held item does not end the cycle.
336
340
 
337
341
 
@@ -237,6 +237,10 @@ other gate's verdict — however conclusive — may promote an item a person par
237
237
  4. **Name it in the cycle summary** via `summarizeHumanGateHolds([...])`, so the record
238
238
  distinguishes "nothing was eligible" from "something eligible was held for a person". A lane
239
239
  mutation nobody can see afterwards is the same class of problem this gate exists to fix.
240
+ Report alongside it what the precision rule SKIPPED, via `summarizeHumanGateMentions(n)`
241
+ — the marker occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815).
242
+ A rule that quietly declines to honour half the occurrences it sees reads exactly like a
243
+ rule that saw none, so the count is printed even when it is zero.
240
244
  5. **Continue to the next candidate.** A held item does not end the cycle.
241
245
 
242
246
 
@@ -231,6 +231,10 @@ other gate's verdict — however conclusive — may promote an item a person par
231
231
  4. **Name it in the cycle summary** via `summarizeHumanGateHolds([...])`, so the record
232
232
  distinguishes "nothing was eligible" from "something eligible was held for a person". A lane
233
233
  mutation nobody can see afterwards is the same class of problem this gate exists to fix.
234
+ Report alongside it what the precision rule SKIPPED, via `summarizeHumanGateMentions(n)`
235
+ — the marker occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815).
236
+ A rule that quietly declines to honour half the occurrences it sees reads exactly like a
237
+ rule that saw none, so the count is printed even when it is zero.
234
238
  5. **Continue to the next candidate.** A held item does not end the cycle.
235
239
 
236
240
 
@@ -994,7 +994,10 @@ with labels like `build-ready`, or with no Lisa status label at all, that are in
994
994
  instead — it says that nothing was changed and how a person resumes the item, which is the
995
995
  opposite of what the reconciliation note says and must not be substituted for it. A promotion
996
996
  declined silently is invisible, which is the quieter version of the failure this step exists to
997
- prevent, so name every held item in the cycle summary via `summarizeHumanGateHolds([...])`.
997
+ prevent, so name every held item in the cycle summary via `summarizeHumanGateHolds([...])`. Report what the
998
+ precision rule skipped beside it via `summarizeHumanGateMentions(n)`: the marker
999
+ occurrences that were mentions rather than declarations (CodySwannGT/lisa#3815),
1000
+ because a rule that silently drops candidates reads like one that found none.
998
1001
 
999
1002
  ### Ungated non-ready filing → surface as an incomplete handoff (read-only)
1000
1003