agentera 3.0.0-dev.5 → 3.0.0-dev.51

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 (598) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +119 -22
  3. package/bundle/CHANGELOG.md +1351 -0
  4. package/bundle/DESIGN.md +229 -0
  5. package/bundle/LICENSE +201 -0
  6. package/bundle/README.md +143 -0
  7. package/bundle/UPGRADE.md +236 -0
  8. package/bundle/extract-corpus-parity.json +21 -0
  9. package/bundle/fixtures/routing/hybrid-corpus.yaml +154 -0
  10. package/bundle/references/adapters/package-publication.json +437 -0
  11. package/bundle/references/adapters/package-registry.yaml +435 -189
  12. package/bundle/references/adapters/package-surface-characterization.md +66 -35
  13. package/bundle/references/adapters/runtime-lifecycle-adapters.yaml +74 -0
  14. package/bundle/references/adapters/runtime-lifecycle-authority.yaml +62 -0
  15. package/bundle/references/adapters/runtime-lifecycle-operation-contract.yaml +84 -0
  16. package/bundle/references/adapters/runtime-retired-resources.yaml +333 -0
  17. package/bundle/references/analysis/evidence-tier-authority.yaml +518 -0
  18. package/bundle/references/analysis/verification-policy.yaml +191 -0
  19. package/bundle/references/artifacts/artifact-registry-interface-model.yaml +20 -10
  20. package/bundle/references/artifacts/glossary-entry-contract.yaml +1254 -0
  21. package/bundle/references/artifacts/state-storage-authority.yaml +3022 -0
  22. package/bundle/references/artifacts/verbosity-budget-authority.yaml +42 -0
  23. package/bundle/references/cli/app-lifecycle-vocabulary.yaml +7 -8
  24. package/bundle/references/cli/capability-instruction-contract.yaml +11 -14
  25. package/bundle/references/cli/hybrid-route-contract.yaml +438 -0
  26. package/bundle/references/cli/routing-model.md +155 -0
  27. package/bundle/references/cli/trigger-schema-enrichment.md +147 -0
  28. package/bundle/references/cli/update-channels.yaml +19 -1
  29. package/bundle/references/cli/vocabulary-index.yaml +20 -17
  30. package/bundle/references/cli/vocabulary.md +326 -361
  31. package/bundle/references/meta/retained-reference-authority.yaml +151 -0
  32. package/bundle/registry.json +13 -13
  33. package/bundle/skills/agentera/SKILL.md +224 -422
  34. package/bundle/skills/agentera/capabilities/audit/schemas/artifacts.yaml +84 -0
  35. package/bundle/skills/agentera/capabilities/{inspektera → audit}/schemas/exit.yaml +2 -2
  36. package/bundle/skills/agentera/capabilities/audit/schemas/triggers.yaml +25 -0
  37. package/bundle/skills/agentera/capabilities/{inspektera → audit}/schemas/validation.yaml +37 -18
  38. package/bundle/skills/agentera/capabilities/build/schemas/artifacts.yaml +102 -0
  39. package/bundle/skills/agentera/capabilities/{realisera → build}/schemas/exit.yaml +6 -5
  40. package/bundle/skills/agentera/capabilities/build/schemas/triggers.yaml +27 -0
  41. package/bundle/skills/agentera/capabilities/build/schemas/validation.yaml +176 -0
  42. package/bundle/skills/agentera/capabilities/{visualisera → design}/schemas/artifacts.yaml +12 -12
  43. package/bundle/skills/agentera/capabilities/{visualisera → design}/schemas/exit.yaml +5 -5
  44. package/bundle/skills/agentera/capabilities/design/schemas/triggers.yaml +16 -0
  45. package/bundle/skills/agentera/capabilities/{visualisera → design}/schemas/validation.yaml +7 -7
  46. package/bundle/skills/agentera/capabilities/discuss/schemas/artifacts.yaml +51 -0
  47. package/bundle/skills/agentera/capabilities/{resonera → discuss}/schemas/exit.yaml +2 -2
  48. package/bundle/skills/agentera/capabilities/discuss/schemas/triggers.yaml +20 -0
  49. package/bundle/skills/agentera/capabilities/discuss/schemas/validation.yaml +144 -0
  50. package/bundle/skills/agentera/capabilities/document/schemas/artifacts.yaml +80 -0
  51. package/bundle/skills/agentera/capabilities/document/schemas/triggers.yaml +16 -0
  52. package/bundle/skills/agentera/capabilities/{dokumentera → document}/schemas/validation.yaml +18 -18
  53. package/bundle/skills/agentera/capabilities/{optimera → optimize}/schemas/artifacts.yaml +18 -18
  54. package/bundle/skills/agentera/capabilities/{optimera → optimize}/schemas/exit.yaml +2 -2
  55. package/bundle/skills/agentera/capabilities/optimize/schemas/triggers.yaml +16 -0
  56. package/bundle/skills/agentera/capabilities/{optimera → optimize}/schemas/validation.yaml +9 -9
  57. package/bundle/skills/agentera/capabilities/orchestrate/schemas/artifacts.yaml +76 -0
  58. package/bundle/skills/agentera/capabilities/{orkestrera → orchestrate}/schemas/exit.yaml +9 -7
  59. package/bundle/skills/agentera/capabilities/orchestrate/schemas/triggers.yaml +23 -0
  60. package/bundle/skills/agentera/capabilities/orchestrate/schemas/validation.yaml +121 -0
  61. package/bundle/skills/agentera/capabilities/plan/schemas/artifacts.yaml +66 -0
  62. package/bundle/skills/agentera/capabilities/{planera → plan}/schemas/exit.yaml +2 -2
  63. package/bundle/skills/agentera/capabilities/plan/schemas/triggers.yaml +23 -0
  64. package/bundle/skills/agentera/capabilities/plan/schemas/validation.yaml +121 -0
  65. package/bundle/skills/agentera/capabilities/profile/schemas/artifacts.yaml +23 -0
  66. package/bundle/skills/agentera/capabilities/{profilera → profile}/schemas/exit.yaml +6 -5
  67. package/bundle/skills/agentera/capabilities/profile/schemas/triggers.yaml +20 -0
  68. package/bundle/skills/agentera/capabilities/profile/schemas/validation.yaml +115 -0
  69. package/bundle/skills/agentera/capabilities/research/schemas/artifacts.yaml +24 -0
  70. package/bundle/skills/agentera/capabilities/research/schemas/triggers.yaml +16 -0
  71. package/bundle/skills/agentera/capabilities/{inspirera → research}/schemas/validation.yaml +2 -2
  72. package/bundle/skills/agentera/capabilities/status/schemas/artifacts.yaml +73 -0
  73. package/bundle/skills/agentera/capabilities/status/schemas/triggers.yaml +22 -0
  74. package/bundle/skills/agentera/capabilities/{hej → status}/schemas/validation.yaml +5 -5
  75. package/bundle/skills/agentera/capabilities/{visionera → vision}/schemas/artifacts.yaml +16 -16
  76. package/bundle/skills/agentera/capabilities/{visionera → vision}/schemas/exit.yaml +7 -6
  77. package/bundle/skills/agentera/capabilities/vision/schemas/triggers.yaml +23 -0
  78. package/bundle/skills/agentera/capabilities/{visionera → vision}/schemas/validation.yaml +18 -20
  79. package/bundle/skills/agentera/capability_schema_contract.yaml +178 -34
  80. package/bundle/skills/agentera/protocol.yaml +31 -31
  81. package/bundle/skills/agentera/route-phrases.yaml +81 -0
  82. package/bundle/skills/agentera/schemas/artifacts/changelog.yaml +5 -4
  83. package/bundle/skills/agentera/schemas/artifacts/decisions.yaml +39 -21
  84. package/bundle/skills/agentera/schemas/artifacts/design.yaml +5 -4
  85. package/bundle/skills/agentera/schemas/artifacts/docs.yaml +15 -19
  86. package/bundle/skills/agentera/schemas/artifacts/experiments.yaml +145 -14
  87. package/bundle/skills/agentera/schemas/artifacts/glossary.yaml +82 -0
  88. package/bundle/skills/agentera/schemas/artifacts/health.yaml +58 -21
  89. package/bundle/skills/agentera/schemas/artifacts/objective.yaml +22 -8
  90. package/bundle/skills/agentera/schemas/artifacts/plan.yaml +458 -36
  91. package/bundle/skills/agentera/schemas/artifacts/progress.yaml +128 -17
  92. package/bundle/skills/agentera/schemas/artifacts/todo.yaml +342 -42
  93. package/bundle/skills/agentera/schemas/artifacts/vision.yaml +3 -3
  94. package/dist/analytics/extractCorpus/cli.js +190 -0
  95. package/dist/analytics/extractCorpus/copilotSessions.js +275 -0
  96. package/dist/analytics/extractCorpus/core.js +392 -0
  97. package/dist/analytics/extractCorpus/corpus.js +167 -0
  98. package/dist/analytics/extractCorpus/coverageAudit.js +260 -0
  99. package/dist/analytics/extractCorpus/cursorSessions.js +425 -0
  100. package/dist/analytics/extractCorpus/evidenceTiers.js +603 -0
  101. package/dist/analytics/extractCorpus/extractCorpusParity.js +105 -0
  102. package/dist/analytics/extractCorpus/filesystemSources.js +118 -0
  103. package/dist/analytics/extractCorpus/index.js +14 -0
  104. package/dist/analytics/extractCorpus/jsonlSessions.js +204 -0
  105. package/dist/analytics/extractCorpus/sqliteCaps.js +43 -0
  106. package/dist/analytics/extractCorpus/sqliteSessions.js +367 -0
  107. package/dist/analytics/extractCorpus/tierReader.js +108 -0
  108. package/dist/analytics/extractCorpus.js +2 -1791
  109. package/dist/analytics/glossaryAdviceResolution.js +166 -0
  110. package/dist/analytics/glossaryInputAcquisition.js +319 -0
  111. package/dist/analytics/personalGlossaryAdmission.js +133 -0
  112. package/dist/analytics/personalGlossaryProfile.js +219 -0
  113. package/dist/analytics/profileSignals.js +211 -0
  114. package/dist/analytics/usageStats.js +169 -42
  115. package/dist/audit/terminologyDrift.js +281 -0
  116. package/dist/bin/agentera.js +3 -2
  117. package/dist/capabilities/audit/instructions.js +16 -0
  118. package/dist/capabilities/build/instructions.js +56 -0
  119. package/dist/capabilities/design/instructions.js +4 -0
  120. package/dist/capabilities/discuss/instructions.js +29 -0
  121. package/dist/capabilities/document/instructions.js +11 -0
  122. package/dist/capabilities/index.js +29 -27
  123. package/dist/capabilities/optimize/instructions.js +14 -0
  124. package/dist/capabilities/orchestrate/instructions.js +42 -0
  125. package/dist/capabilities/plan/instructions.js +33 -0
  126. package/dist/capabilities/profile/instructions.js +70 -0
  127. package/dist/capabilities/research/instructions.js +5 -0
  128. package/dist/capabilities/status/instructions.js +15 -0
  129. package/dist/capabilities/status/startupInstructions.js +34 -0
  130. package/dist/capabilities/vision/instructions.js +4 -0
  131. package/dist/cli/appContext.js +30 -24
  132. package/dist/cli/argvalidate.js +0 -1
  133. package/dist/cli/capabilityContext/benchmark.js +565 -0
  134. package/dist/cli/capabilityContext/bespoke.js +44 -0
  135. package/dist/cli/capabilityContext/build.js +242 -0
  136. package/dist/cli/capabilityContext/closeout.js +233 -0
  137. package/dist/cli/capabilityContext/contract.js +179 -0
  138. package/dist/cli/capabilityContext/evidence.js +463 -0
  139. package/dist/cli/capabilityContext/index.js +3 -0
  140. package/dist/cli/capabilityContext/orchestration.js +131 -0
  141. package/dist/cli/capabilityContext/planState.js +260 -0
  142. package/dist/cli/capabilityContext/progress.js +142 -0
  143. package/dist/cli/capabilityContext/projectVerification.js +409 -0
  144. package/dist/cli/capabilityContext/shared.js +83 -0
  145. package/dist/cli/capabilityContext/slim.js +152 -0
  146. package/dist/cli/capabilityContext/startup.js +150 -0
  147. package/dist/cli/capabilityContext/startupAggregation.js +68 -0
  148. package/dist/cli/capabilityContext/types.js +56 -0
  149. package/dist/cli/capabilityContext.js +1 -2487
  150. package/dist/cli/commands/appHome.js +22 -0
  151. package/dist/cli/commands/capability.js +4 -4
  152. package/dist/cli/commands/compact.js +164 -14
  153. package/dist/cli/commands/doctor.js +122 -97
  154. package/dist/cli/commands/durability.js +81 -0
  155. package/dist/cli/commands/glossaryAdvice.js +138 -0
  156. package/dist/cli/commands/lint.js +26 -44
  157. package/dist/cli/commands/personalGlossary.js +176 -0
  158. package/dist/cli/commands/prime/briefOrientation.js +747 -0
  159. package/dist/cli/commands/prime/buildExecutionRequest.js +165 -0
  160. package/dist/cli/commands/prime/bundleStatus.js +190 -0
  161. package/dist/cli/commands/prime/collectEntityOrientation.js +326 -0
  162. package/dist/cli/commands/prime/collectOrientationState.js +212 -0
  163. package/dist/cli/commands/prime/orientationOutput.js +399 -0
  164. package/dist/cli/commands/prime/types.js +1 -0
  165. package/dist/cli/commands/prime/v1Migration.js +38 -0
  166. package/dist/cli/commands/prime.js +80 -558
  167. package/dist/cli/commands/profileGrounding.js +55 -0
  168. package/dist/cli/commands/query.js +78 -53
  169. package/dist/cli/commands/report.js +96 -25
  170. package/dist/cli/commands/route.js +142 -0
  171. package/dist/cli/commands/schema.js +266 -143
  172. package/dist/cli/commands/state/decisions.js +387 -0
  173. package/dist/cli/commands/state/docs.js +70 -0
  174. package/dist/cli/commands/state/experimentRecords.js +151 -0
  175. package/dist/cli/commands/state/experiments.js +14 -0
  176. package/dist/cli/commands/state/get.js +129 -0
  177. package/dist/cli/commands/state/health.js +14 -0
  178. package/dist/cli/commands/state/index.js +16 -0
  179. package/dist/cli/commands/state/list.js +194 -0
  180. package/dist/cli/commands/state/objective.js +25 -0
  181. package/dist/cli/commands/state/plan.js +14 -0
  182. package/dist/cli/commands/state/planTasks.js +154 -0
  183. package/dist/cli/commands/state/plans.js +154 -0
  184. package/dist/cli/commands/state/progress.js +13 -0
  185. package/dist/cli/commands/state/shared.js +14 -0
  186. package/dist/cli/commands/state/todo.js +42 -0
  187. package/dist/cli/commands/state/write.js +430 -0
  188. package/dist/cli/commands/upgrade.js +146 -5
  189. package/dist/cli/commands/upgradeVerify.js +118 -0
  190. package/dist/cli/commands/validate.js +272 -223
  191. package/dist/cli/commands/verify.js +24 -9
  192. package/dist/cli/contracts/bundleStatus.js +1 -0
  193. package/dist/cli/contracts/orientationState.js +1 -0
  194. package/dist/cli/dispatch/argvParser.js +32 -0
  195. package/dist/cli/dispatch/check.js +372 -0
  196. package/dist/cli/dispatch/commands.js +27 -0
  197. package/dist/cli/dispatch/index.js +207 -0
  198. package/dist/cli/dispatch/lifecycle.js +652 -0
  199. package/dist/cli/dispatch/prime.js +139 -0
  200. package/dist/cli/dispatch/projections.js +17 -0
  201. package/dist/cli/dispatch/shared.js +63 -0
  202. package/dist/cli/dispatch/state.js +140 -0
  203. package/dist/cli/dispatch.js +1 -1294
  204. package/dist/cli/errors.js +16 -17
  205. package/dist/cli/help.js +394 -43
  206. package/dist/cli/migrationRequired.js +87 -0
  207. package/dist/cli/orientation/attention.js +61 -0
  208. package/dist/cli/orientation/corpusCoverage.js +102 -0
  209. package/dist/cli/orientation.js +438 -170
  210. package/dist/cli/planArtifacts.js +350 -0
  211. package/dist/cli/planEvidence.js +157 -0
  212. package/dist/cli/planLifecycleState.js +36 -0
  213. package/dist/cli/planTaskIndex.js +11 -0
  214. package/dist/cli/preCutoverCommand.js +32 -0
  215. package/dist/cli/prime-blob.js +71 -3
  216. package/dist/cli/profileAcquisition.js +167 -0
  217. package/dist/cli/startupCompletenessContract.js +59 -0
  218. package/dist/cli/stateQuery.js +56 -14
  219. package/dist/cli/structured.js +0 -1
  220. package/dist/cli/todoMarkdown.js +25 -12
  221. package/dist/cli/todoReadinessSelection.js +192 -0
  222. package/dist/cli/todoSeverity.js +18 -0
  223. package/dist/core/atomicWriter.js +20 -0
  224. package/dist/core/developmentChannel.js +1 -0
  225. package/dist/core/developmentInvocation.js +374 -0
  226. package/dist/core/difflib.js +0 -1
  227. package/dist/core/envPaths.js +20 -0
  228. package/dist/core/jsonValue.js +5 -0
  229. package/dist/core/paths.js +0 -1
  230. package/dist/core/pyjson.js +67 -3
  231. package/dist/core/shell.js +4 -0
  232. package/dist/core/skillIdentity.js +23 -0
  233. package/dist/core/sourceRoot.js +9 -12
  234. package/dist/core/text.js +10 -0
  235. package/dist/core/toml.js +0 -1
  236. package/dist/core/yaml.js +8 -1
  237. package/dist/eval/evalSkills.js +30 -26
  238. package/dist/eval/hybridRouteEvaluation.js +155 -0
  239. package/dist/eval/semanticEval.js +43 -20
  240. package/dist/eval/semanticFixtures.js +16 -5
  241. package/dist/hooks/common.js +11 -79
  242. package/dist/hooks/compaction/apply.js +446 -0
  243. package/dist/hooks/compaction/dryRun.js +184 -0
  244. package/dist/hooks/compaction/index.js +22 -0
  245. package/dist/hooks/compaction/parse.js +325 -0
  246. package/dist/hooks/compaction/retention.js +202 -0
  247. package/dist/hooks/compaction/status.js +360 -0
  248. package/dist/hooks/compaction/types.js +5 -0
  249. package/dist/hooks/validateArtifact/agentFacing.js +9 -0
  250. package/dist/hooks/validateArtifact/index.js +92 -0
  251. package/dist/hooks/validateArtifact/markdown.js +145 -0
  252. package/dist/hooks/validateArtifact/schema.js +546 -0
  253. package/dist/hooks/validateArtifact/traversal.js +107 -0
  254. package/dist/hooks/validateArtifact/violations.js +107 -0
  255. package/dist/migrate/v2HandoffManifest.js +452 -0
  256. package/dist/registries/activationContract.js +2 -0
  257. package/dist/registries/activationTuples.js +107 -0
  258. package/dist/registries/artifactProtocolIds.js +78 -0
  259. package/dist/registries/artifactRegistry.js +224 -63
  260. package/dist/registries/artifactSchemaProjection.js +45 -0
  261. package/dist/registries/capabilityContract.js +129 -2
  262. package/dist/registries/evaluatorHandoffContract.js +2 -3
  263. package/dist/registries/evidenceTierContract.js +371 -0
  264. package/dist/registries/glossaryAdviceContract.js +79 -0
  265. package/dist/registries/glossaryCaveatContract.js +67 -0
  266. package/dist/registries/glossaryConsumerContractValidation.js +787 -0
  267. package/dist/registries/glossaryEntryContract.js +757 -0
  268. package/dist/registries/glossaryTermIdentity.js +17 -0
  269. package/dist/registries/glossaryTermOccurrence.js +20 -0
  270. package/dist/registries/hybridRoute.js +274 -0
  271. package/dist/registries/hybridRouteReceipt.js +221 -0
  272. package/dist/registries/packagePublication.js +229 -0
  273. package/dist/registries/packageRegistry.js +187 -211
  274. package/dist/registries/todoReadinessContract.js +448 -0
  275. package/dist/registries/triggerLoader.js +174 -0
  276. package/dist/registries/verbosityBudgetContract.js +205 -0
  277. package/dist/release/releaseMetadata.js +385 -0
  278. package/dist/runtime/lifecycleAdapterContract.js +457 -0
  279. package/dist/runtime/lifecycleAdapters.js +777 -0
  280. package/dist/runtime/lifecycleAuthority.js +453 -0
  281. package/dist/runtime/lifecycleOperationContract.js +123 -0
  282. package/dist/runtime/lifecycleOperations.js +634 -0
  283. package/dist/runtime/lifecycleOwnershipJournal.js +622 -0
  284. package/dist/runtime/lifecyclePublication.js +415 -0
  285. package/dist/runtime/lifecycleSnapshot.js +438 -0
  286. package/dist/runtime/nativeResourceCleanup.js +502 -0
  287. package/dist/setup/opencode.js +20 -0
  288. package/dist/setup/opencodeConstants.js +1 -0
  289. package/dist/setup/sharedSkill.js +45 -0
  290. package/dist/setup/smokeChecks.js +21 -82
  291. package/dist/state/archiveDiscovery.js +580 -0
  292. package/dist/state/archivePublication.js +225 -0
  293. package/dist/state/archiveRecovery.js +237 -0
  294. package/dist/state/archiveReplay.js +53 -0
  295. package/dist/state/canonicalMigrationRecord.js +36 -0
  296. package/dist/state/changelog.js +221 -0
  297. package/dist/state/decisionEntities.js +367 -0
  298. package/dist/state/decisionLegacyValidation.js +215 -0
  299. package/dist/state/decisionMigrationProvenance.js +199 -0
  300. package/dist/state/decisionOverlay.js +254 -0
  301. package/dist/state/decisionRevision.js +256 -0
  302. package/dist/state/decisionRevisionMigration.js +89 -0
  303. package/dist/state/directRetrieval.js +323 -0
  304. package/dist/state/durability.js +324 -0
  305. package/dist/state/entityCutover.js +459 -0
  306. package/dist/state/entityCutoverGit.js +127 -0
  307. package/dist/state/entityGlossaryAuthority.js +13 -0
  308. package/dist/state/entityListProjection.js +187 -0
  309. package/dist/state/entityListRuntimeRegistry.js +85 -0
  310. package/dist/state/entityMigrationCausality.js +97 -0
  311. package/dist/state/entityMigrationIdentity.js +5 -0
  312. package/dist/state/entityMigrationPreview.js +846 -0
  313. package/dist/state/entityMigrationTodo.js +133 -0
  314. package/dist/state/entityPublicationContext.js +806 -0
  315. package/dist/state/entityRetrievalHelp.js +506 -0
  316. package/dist/state/entityStorage.js +899 -0
  317. package/dist/state/exactReplacementRecovery.js +18 -0
  318. package/dist/state/experimentArchive.js +63 -0
  319. package/dist/state/experimentIdentity.js +202 -0
  320. package/dist/state/healthEntities.js +262 -0
  321. package/dist/state/healthEntityValidation.js +18 -0
  322. package/dist/state/healthRepair.js +69 -0
  323. package/dist/state/installRoot.js +64 -25
  324. package/dist/state/legacyEntityCutoverEvidence.js +65 -0
  325. package/dist/state/legacyIdentity.js +47 -0
  326. package/dist/state/legacySummaryRecord.js +6 -0
  327. package/dist/state/listAccounting.js +54 -0
  328. package/dist/state/listClassification.js +17 -0
  329. package/dist/state/listCursor.js +42 -0
  330. package/dist/state/listRetrieval.js +781 -0
  331. package/dist/state/migrationSourceBinding.js +30 -0
  332. package/dist/state/objectiveExperimentEntities.js +322 -0
  333. package/dist/state/planEntities.js +982 -0
  334. package/dist/state/planIdentity.js +47 -0
  335. package/dist/state/planLineageValidation.js +52 -0
  336. package/dist/state/planReplacementTransaction.js +475 -0
  337. package/dist/state/planRetrieval.js +313 -0
  338. package/dist/state/planTaskRetrieval.js +294 -0
  339. package/dist/state/progressEntities.js +512 -0
  340. package/dist/state/progressGlossaryCaveat.js +168 -0
  341. package/dist/state/progressPublicationOrder.js +19 -0
  342. package/dist/state/projectRoot.js +62 -0
  343. package/dist/state/projectionPolicy.js +190 -0
  344. package/dist/state/retrievalAuthority.js +156 -0
  345. package/dist/state/safeProjectFile.js +155 -0
  346. package/dist/state/startupAnalysis/benchmark.js +432 -0
  347. package/dist/state/startupAnalysis/contract.js +160 -0
  348. package/dist/state/startupAnalysis/helpers.js +286 -0
  349. package/dist/state/startupAnalysis/index.js +6 -0
  350. package/dist/state/startupAnalysis/metrics.js +340 -0
  351. package/dist/state/startupAnalysis/records.js +198 -0
  352. package/dist/state/startupAnalysis/report.js +111 -0
  353. package/dist/state/startupAnalysis/threshold.js +512 -0
  354. package/dist/state/startupAnalysis.js +2 -1953
  355. package/dist/state/startupProjection.js +499 -0
  356. package/dist/state/stateMode.js +85 -0
  357. package/dist/state/stateStorageAuthority.js +47 -0
  358. package/dist/state/summaryEntityRead.js +25 -0
  359. package/dist/state/summaryMigrationProvenance.js +66 -0
  360. package/dist/state/summarySourceRowAuthority.js +36 -0
  361. package/dist/state/todoActivationSafety.js +58 -0
  362. package/dist/state/todoDocsEntities.js +1069 -0
  363. package/dist/state/todoDocsEntityValidation.js +158 -0
  364. package/dist/state/todoMarkdownProjection.js +51 -0
  365. package/dist/state/todoReconciliationActivation.js +140 -0
  366. package/dist/state/todoReconciliationInspection.js +169 -0
  367. package/dist/state/todoReconciliationRepair.js +170 -0
  368. package/dist/state/todoReconciliationTransaction.js +582 -0
  369. package/dist/state/write/assign.js +20 -0
  370. package/dist/state/write/candidateMutation.js +269 -0
  371. package/dist/state/write/errors.js +11 -0
  372. package/dist/state/write/experimentPublication.js +192 -0
  373. package/dist/state/write/explain.js +363 -0
  374. package/dist/state/write/fields.js +61 -0
  375. package/dist/state/write/glossaryPublication.js +263 -0
  376. package/dist/state/write/grammar.js +285 -0
  377. package/dist/state/write/helpers.js +29 -0
  378. package/dist/state/write/index.js +12 -0
  379. package/dist/state/write/input.js +367 -0
  380. package/dist/state/write/lock.js +837 -0
  381. package/dist/state/write/mutation.js +234 -0
  382. package/dist/state/write/operations.js +170 -0
  383. package/dist/state/write/planEvaluation.js +128 -0
  384. package/dist/state/write/planPublication.js +179 -0
  385. package/dist/state/write/runtimeOperations.js +144 -0
  386. package/dist/state/write/serialize.js +1 -0
  387. package/dist/state/write/transaction.js +52 -0
  388. package/dist/state/write/validate.js +7 -0
  389. package/dist/upgrade/appContentRefresh.js +383 -0
  390. package/dist/upgrade/appModel.js +8 -7
  391. package/dist/upgrade/atomicWriter.js +1 -0
  392. package/dist/upgrade/bundleEvidence.js +33 -0
  393. package/dist/upgrade/channels.js +12 -8
  394. package/dist/upgrade/compatibility.js +56 -21
  395. package/dist/upgrade/doctor.js +197 -192
  396. package/dist/upgrade/doctorClassifier.js +187 -0
  397. package/dist/upgrade/installedHooksRetirement.js +196 -0
  398. package/dist/upgrade/legacyAgentCleanup.js +282 -0
  399. package/dist/upgrade/lifecycleUpgrade.js +113 -0
  400. package/dist/upgrade/migrateArtifactsV2ToV3.js +367 -149
  401. package/dist/upgrade/migrationPublication.js +122 -0
  402. package/dist/upgrade/nextMajorDoctor.js +42 -8
  403. package/dist/upgrade/npxPlatformStatus.js +22 -0
  404. package/dist/upgrade/projectIntegration.js +145 -187
  405. package/dist/upgrade/projectIntegrationDecision.js +50 -0
  406. package/dist/upgrade/retiredResourceDiagnostics.js +117 -0
  407. package/dist/upgrade/runtimeMigration.js +273 -363
  408. package/dist/upgrade/upgradeCommands.js +14 -1
  409. package/dist/upgrade/upgradeLock.js +85 -0
  410. package/dist/upgrade/upgradeOrchestrator.js +263 -59
  411. package/dist/upgrade/v3CapabilitySurface.js +14 -0
  412. package/dist/upgrade/versionResolution.js +8 -1
  413. package/dist/validate/activationArtifactEvidence.js +844 -0
  414. package/dist/validate/activationConjunction.js +816 -0
  415. package/dist/validate/activationEvidenceManifest.js +515 -0
  416. package/dist/validate/activationPackageSemantics.js +29 -0
  417. package/dist/validate/appHomeContract.js +5 -11
  418. package/dist/validate/bootstrapAuthority.js +44 -0
  419. package/dist/validate/capability.js +133 -12
  420. package/dist/validate/crossCapability.js +15 -10
  421. package/dist/validate/retainedReferenceAuthority.js +879 -0
  422. package/dist/validate/selfAudit.js +73 -37
  423. package/dist/validate/v1LegacyCruft.js +131 -0
  424. package/dist/validate/vocabularyAuthority.js +303 -0
  425. package/package.json +53 -27
  426. package/bundle/references/adapters/cursor.md +0 -213
  427. package/bundle/references/adapters/opencode.md +0 -530
  428. package/bundle/references/adapters/package-manifest-interface-model.yaml +0 -337
  429. package/bundle/references/adapters/runtime-adapter-characterization.md +0 -79
  430. package/bundle/references/adapters/runtime-adapter-interface-model.yaml +0 -200
  431. package/bundle/references/adapters/runtime-adapter-registry.yaml +0 -548
  432. package/bundle/references/adapters/runtime-feature-parity.md +0 -189
  433. package/bundle/references/analysis/benchmark.md +0 -267
  434. package/bundle/references/analysis/startup-measurement-contract.yaml +0 -424
  435. package/bundle/references/cli/agent-ready-state-contract.yaml +0 -953
  436. package/bundle/references/cli/audience-namespace-cli-migration.yaml +0 -355
  437. package/bundle/references/cli/bundle-skill-vocabulary.yaml +0 -278
  438. package/bundle/references/cli/capability-tool-classification.yaml +0 -53
  439. package/bundle/references/cli/routing-execution-vocabulary.yaml +0 -281
  440. package/bundle/references/meta/documentation-inventory.md +0 -43
  441. package/bundle/references/v1-section-mapping.md +0 -47
  442. package/bundle/skills/agentera/.claude-plugin/plugin.json +0 -27
  443. package/bundle/skills/agentera/agents/dokumentera.toml +0 -6
  444. package/bundle/skills/agentera/agents/hej.toml +0 -6
  445. package/bundle/skills/agentera/agents/inspektera.toml +0 -6
  446. package/bundle/skills/agentera/agents/inspirera.toml +0 -6
  447. package/bundle/skills/agentera/agents/optimera.toml +0 -6
  448. package/bundle/skills/agentera/agents/orkestrera.toml +0 -6
  449. package/bundle/skills/agentera/agents/planera.toml +0 -6
  450. package/bundle/skills/agentera/agents/profilera.toml +0 -6
  451. package/bundle/skills/agentera/agents/realisera.toml +0 -6
  452. package/bundle/skills/agentera/agents/resonera.toml +0 -6
  453. package/bundle/skills/agentera/agents/visionera.toml +0 -6
  454. package/bundle/skills/agentera/agents/visualisera.toml +0 -6
  455. package/bundle/skills/agentera/capabilities/dokumentera/schemas/artifacts.yaml +0 -73
  456. package/bundle/skills/agentera/capabilities/dokumentera/schemas/triggers.yaml +0 -35
  457. package/bundle/skills/agentera/capabilities/hej/schemas/artifacts.yaml +0 -69
  458. package/bundle/skills/agentera/capabilities/hej/schemas/triggers.yaml +0 -58
  459. package/bundle/skills/agentera/capabilities/inspektera/schemas/artifacts.yaml +0 -76
  460. package/bundle/skills/agentera/capabilities/inspektera/schemas/triggers.yaml +0 -38
  461. package/bundle/skills/agentera/capabilities/inspirera/schemas/artifacts.yaml +0 -24
  462. package/bundle/skills/agentera/capabilities/inspirera/schemas/triggers.yaml +0 -34
  463. package/bundle/skills/agentera/capabilities/optimera/schemas/triggers.yaml +0 -39
  464. package/bundle/skills/agentera/capabilities/orkestrera/schemas/artifacts.yaml +0 -64
  465. package/bundle/skills/agentera/capabilities/orkestrera/schemas/triggers.yaml +0 -42
  466. package/bundle/skills/agentera/capabilities/orkestrera/schemas/validation.yaml +0 -120
  467. package/bundle/skills/agentera/capabilities/planera/schemas/artifacts.yaml +0 -62
  468. package/bundle/skills/agentera/capabilities/planera/schemas/triggers.yaml +0 -34
  469. package/bundle/skills/agentera/capabilities/planera/schemas/validation.yaml +0 -61
  470. package/bundle/skills/agentera/capabilities/profilera/schemas/artifacts.yaml +0 -18
  471. package/bundle/skills/agentera/capabilities/profilera/schemas/triggers.yaml +0 -45
  472. package/bundle/skills/agentera/capabilities/profilera/schemas/validation.yaml +0 -57
  473. package/bundle/skills/agentera/capabilities/realisera/schemas/artifacts.yaml +0 -80
  474. package/bundle/skills/agentera/capabilities/realisera/schemas/triggers.yaml +0 -39
  475. package/bundle/skills/agentera/capabilities/realisera/schemas/validation.yaml +0 -110
  476. package/bundle/skills/agentera/capabilities/resonera/schemas/artifacts.yaml +0 -47
  477. package/bundle/skills/agentera/capabilities/resonera/schemas/triggers.yaml +0 -46
  478. package/bundle/skills/agentera/capabilities/resonera/schemas/validation.yaml +0 -77
  479. package/bundle/skills/agentera/capabilities/visionera/schemas/triggers.yaml +0 -41
  480. package/bundle/skills/agentera/capabilities/visualisera/schemas/triggers.yaml +0 -33
  481. package/bundle/skills/agentera/references/contract.md +0 -1039
  482. package/bundle/skills/hej/.claude-plugin/plugin.json +0 -6
  483. package/bundle/skills/hej/SKILL.md +0 -69
  484. package/bundle/skills/hej/agents/hej.toml +0 -11
  485. package/bundle/skills/hej/agents/openai.yaml +0 -8
  486. package/dist/analytics/extractCorpus.js.map +0 -1
  487. package/dist/analytics/usageStats.js.map +0 -1
  488. package/dist/bin/agentera.js.map +0 -1
  489. package/dist/capabilities/dokumentera/instructions.js +0 -6
  490. package/dist/capabilities/dokumentera/instructions.js.map +0 -1
  491. package/dist/capabilities/hej/instructions.js +0 -6
  492. package/dist/capabilities/hej/instructions.js.map +0 -1
  493. package/dist/capabilities/index.js.map +0 -1
  494. package/dist/capabilities/inspektera/instructions.js +0 -6
  495. package/dist/capabilities/inspektera/instructions.js.map +0 -1
  496. package/dist/capabilities/inspirera/instructions.js +0 -6
  497. package/dist/capabilities/inspirera/instructions.js.map +0 -1
  498. package/dist/capabilities/optimera/instructions.js +0 -6
  499. package/dist/capabilities/optimera/instructions.js.map +0 -1
  500. package/dist/capabilities/orkestrera/instructions.js +0 -6
  501. package/dist/capabilities/orkestrera/instructions.js.map +0 -1
  502. package/dist/capabilities/planera/instructions.js +0 -6
  503. package/dist/capabilities/planera/instructions.js.map +0 -1
  504. package/dist/capabilities/profilera/instructions.js +0 -6
  505. package/dist/capabilities/profilera/instructions.js.map +0 -1
  506. package/dist/capabilities/realisera/instructions.js +0 -6
  507. package/dist/capabilities/realisera/instructions.js.map +0 -1
  508. package/dist/capabilities/resonera/instructions.js +0 -6
  509. package/dist/capabilities/resonera/instructions.js.map +0 -1
  510. package/dist/capabilities/visionera/instructions.js +0 -6
  511. package/dist/capabilities/visionera/instructions.js.map +0 -1
  512. package/dist/capabilities/visualisera/instructions.js +0 -6
  513. package/dist/capabilities/visualisera/instructions.js.map +0 -1
  514. package/dist/cli/appContext.js.map +0 -1
  515. package/dist/cli/argvalidate.js.map +0 -1
  516. package/dist/cli/capabilityContext.js.map +0 -1
  517. package/dist/cli/commands/capability.js.map +0 -1
  518. package/dist/cli/commands/compact.js.map +0 -1
  519. package/dist/cli/commands/doctor.js.map +0 -1
  520. package/dist/cli/commands/lint.js.map +0 -1
  521. package/dist/cli/commands/prime.js.map +0 -1
  522. package/dist/cli/commands/query.js.map +0 -1
  523. package/dist/cli/commands/report.js.map +0 -1
  524. package/dist/cli/commands/schema.js.map +0 -1
  525. package/dist/cli/commands/state.js +0 -1023
  526. package/dist/cli/commands/state.js.map +0 -1
  527. package/dist/cli/commands/upgrade.js.map +0 -1
  528. package/dist/cli/commands/validate.js.map +0 -1
  529. package/dist/cli/commands/verify.js.map +0 -1
  530. package/dist/cli/dispatch.js.map +0 -1
  531. package/dist/cli/errors.js.map +0 -1
  532. package/dist/cli/help.js.map +0 -1
  533. package/dist/cli/orientation.js.map +0 -1
  534. package/dist/cli/prime-blob.js.map +0 -1
  535. package/dist/cli/stateQuery.js.map +0 -1
  536. package/dist/cli/structured.js.map +0 -1
  537. package/dist/cli/todoMarkdown.js.map +0 -1
  538. package/dist/core/difflib.js.map +0 -1
  539. package/dist/core/paths.js.map +0 -1
  540. package/dist/core/pyjson.js.map +0 -1
  541. package/dist/core/sourceRoot.js.map +0 -1
  542. package/dist/core/toml.js.map +0 -1
  543. package/dist/core/yaml.js.map +0 -1
  544. package/dist/eval/evalSkills.js.map +0 -1
  545. package/dist/eval/semanticEval.js.map +0 -1
  546. package/dist/eval/semanticFixtures.js.map +0 -1
  547. package/dist/hooks/common.js.map +0 -1
  548. package/dist/hooks/compaction.js +0 -935
  549. package/dist/hooks/compaction.js.map +0 -1
  550. package/dist/hooks/cursorPreToolUse.js +0 -19
  551. package/dist/hooks/cursorPreToolUse.js.map +0 -1
  552. package/dist/hooks/cursorSessionStart.js +0 -71
  553. package/dist/hooks/cursorSessionStart.js.map +0 -1
  554. package/dist/hooks/sessionStart.js +0 -209
  555. package/dist/hooks/sessionStart.js.map +0 -1
  556. package/dist/hooks/sessionStop.js +0 -212
  557. package/dist/hooks/sessionStop.js.map +0 -1
  558. package/dist/hooks/validateArtifact.js +0 -935
  559. package/dist/hooks/validateArtifact.js.map +0 -1
  560. package/dist/registries/artifactRegistry.js.map +0 -1
  561. package/dist/registries/capabilityContract.js.map +0 -1
  562. package/dist/registries/evaluatorHandoffContract.js.map +0 -1
  563. package/dist/registries/packageRegistry.js.map +0 -1
  564. package/dist/registries/runtimeAdapterRegistry.js +0 -315
  565. package/dist/registries/runtimeAdapterRegistry.js.map +0 -1
  566. package/dist/setup/codex.js +0 -1197
  567. package/dist/setup/codex.js.map +0 -1
  568. package/dist/setup/copilot.js +0 -227
  569. package/dist/setup/copilot.js.map +0 -1
  570. package/dist/setup/cursor.js +0 -127
  571. package/dist/setup/cursor.js.map +0 -1
  572. package/dist/setup/doctor.js +0 -1297
  573. package/dist/setup/doctor.js.map +0 -1
  574. package/dist/setup/smokeChecks.js.map +0 -1
  575. package/dist/state/installRoot.js.map +0 -1
  576. package/dist/state/startupAnalysis.js.map +0 -1
  577. package/dist/upgrade/appModel.js.map +0 -1
  578. package/dist/upgrade/channels.js.map +0 -1
  579. package/dist/upgrade/compatibility.js.map +0 -1
  580. package/dist/upgrade/doctor.js.map +0 -1
  581. package/dist/upgrade/migrateArtifactsV1ToV2.js +0 -570
  582. package/dist/upgrade/migrateArtifactsV1ToV2.js.map +0 -1
  583. package/dist/upgrade/migrateArtifactsV2ToV3.js.map +0 -1
  584. package/dist/upgrade/nextMajorDoctor.js.map +0 -1
  585. package/dist/upgrade/projectIntegration.js.map +0 -1
  586. package/dist/upgrade/runtimeMigration.js.map +0 -1
  587. package/dist/upgrade/upgradeCommands.js.map +0 -1
  588. package/dist/upgrade/upgradeOrchestrator.js.map +0 -1
  589. package/dist/upgrade/versionResolution.js.map +0 -1
  590. package/dist/validate/appHomeContract.js.map +0 -1
  591. package/dist/validate/capability.js.map +0 -1
  592. package/dist/validate/crossCapability.js.map +0 -1
  593. package/dist/validate/lifecycleAdapters.js +0 -772
  594. package/dist/validate/lifecycleAdapters.js.map +0 -1
  595. package/dist/validate/selfAudit.js.map +0 -1
  596. /package/bundle/skills/agentera/capabilities/{dokumentera → document}/schemas/exit.yaml +0 -0
  597. /package/bundle/skills/agentera/capabilities/{inspirera → research}/schemas/exit.yaml +0 -0
  598. /package/bundle/skills/agentera/capabilities/{hej → status}/schemas/exit.yaml +0 -0
@@ -0,0 +1,158 @@
1
+ import path from "node:path";
2
+ import { loadTodoReadinessContract, todoReadinessRecordViolations } from "../registries/todoReadinessContract.js";
3
+ export const TODO_SEVERITIES = ["critical", "degraded", "normal", "annoying"];
4
+ export const TODO_STATUSES = ["open", "resolved"];
5
+ export const TODO_KIND_RE = /^[a-z][a-z0-9_-]{0,31}$/;
6
+ export const DOC_STATUSES = ["current", "stale", "missing", "intent", "generated"];
7
+ const TODO_INPUT_FIELDS = new Set([
8
+ "kind", "target_version", "title", "requirements", "acceptance", "release_blocker", "severity", "readiness",
9
+ ]);
10
+ const TODO_CLEARABLE_FIELDS = new Set(["target_version", "requirements", "acceptance", "readiness"]);
11
+ const TODO_LIFECYCLE_REASON_MAX_CODE_POINTS = 500;
12
+ const TODO_RECONCILIATION_VERSION = "agentera.todoReconciliation.v1";
13
+ function mapping(value) {
14
+ return value !== null && typeof value === "object" && !Array.isArray(value);
15
+ }
16
+ function stringList(value, field) {
17
+ if (!Array.isArray(value) || value.some((item) => typeof item !== "string"))
18
+ return [`${field} must be a list of strings`];
19
+ return [];
20
+ }
21
+ function publicTodoViolations(record) {
22
+ const violations = [];
23
+ const typed = record.title !== undefined || record.kind !== undefined || record.target_version !== undefined
24
+ || record.requirements !== undefined || record.acceptance !== undefined || record.release_blocker !== undefined;
25
+ if (!typed && (typeof record.description !== "string" || !record.description.trim()))
26
+ violations.push("title or legacy description is required");
27
+ if (typed) {
28
+ if (typeof record.kind !== "string" || !TODO_KIND_RE.test(record.kind))
29
+ violations.push("kind must be a lowercase identifier of at most 32 characters");
30
+ if (typeof record.title !== "string" || !record.title.trim())
31
+ violations.push("title is required");
32
+ if (record.target_version !== undefined && record.target_version !== null && (typeof record.target_version !== "string" || !record.target_version.trim()))
33
+ violations.push("target_version must be a non-empty string or null");
34
+ if (record.requirements !== undefined)
35
+ violations.push(...stringList(record.requirements, "requirements"));
36
+ if (record.acceptance !== undefined)
37
+ violations.push(...stringList(record.acceptance, "acceptance"));
38
+ if (record.release_blocker !== undefined && typeof record.release_blocker !== "boolean")
39
+ violations.push("release_blocker must be a boolean");
40
+ }
41
+ return violations;
42
+ }
43
+ export function todoInputViolations(input, mode) {
44
+ const violations = [];
45
+ for (const field of Object.keys(input)) {
46
+ if (!TODO_INPUT_FIELDS.has(field))
47
+ violations.push(`unsupported TODO input field '${field}'`);
48
+ }
49
+ if (mode === "create") {
50
+ for (const field of ["kind", "target_version", "title", "requirements", "acceptance", "release_blocker", "severity"]) {
51
+ if (!(field in input))
52
+ violations.push(`${field} is required in a full typed TODO record`);
53
+ }
54
+ }
55
+ else if (Object.keys(input).length === 0) {
56
+ violations.push("TODO update requires at least one patch field");
57
+ }
58
+ if (input.kind !== undefined && (typeof input.kind !== "string" || !TODO_KIND_RE.test(input.kind)))
59
+ violations.push("kind must be a lowercase identifier of at most 32 characters");
60
+ if (input.title !== undefined && (typeof input.title !== "string" || !input.title.trim()))
61
+ violations.push("title must be a non-empty string");
62
+ if (input.target_version !== undefined && input.target_version !== null && (typeof input.target_version !== "string" || !input.target_version.trim()))
63
+ violations.push("target_version must be a non-empty string or null");
64
+ if (input.requirements !== undefined && input.requirements !== null)
65
+ violations.push(...stringList(input.requirements, "requirements"));
66
+ if (input.acceptance !== undefined && input.acceptance !== null)
67
+ violations.push(...stringList(input.acceptance, "acceptance"));
68
+ if (input.release_blocker !== undefined && typeof input.release_blocker !== "boolean")
69
+ violations.push("release_blocker must be a boolean; false is the typed non-blocking value");
70
+ if (input.severity !== undefined && !TODO_SEVERITIES.includes(input.severity))
71
+ violations.push(`severity must be one of: ${TODO_SEVERITIES.join(", ")}`);
72
+ if (input.description !== undefined)
73
+ violations.push("description is a retired legacy field; use title and the typed TODO record");
74
+ if (mode === "update") {
75
+ for (const field of ["kind", "title", "severity", "release_blocker", "description"])
76
+ if (input[field] === null)
77
+ violations.push(`${field} cannot be cleared; omit it or supply a typed value`);
78
+ for (const field of ["target_version", "requirements", "acceptance", "readiness"])
79
+ if (input[field] === null && !TODO_CLEARABLE_FIELDS.has(field))
80
+ violations.push(`${field} is not clearable`);
81
+ }
82
+ if (input.readiness !== undefined && input.readiness !== null) {
83
+ const readiness = mapping(input.readiness) ? input.readiness : null;
84
+ if (!readiness)
85
+ violations.push("readiness must be a complete mapping or null");
86
+ else {
87
+ const dependencies = readiness.dependencies;
88
+ const normalized = Array.isArray(dependencies)
89
+ ? dependencies.map((dependency) => typeof dependency === "string" ? { artifact: "todo", id: dependency } : dependency)
90
+ : dependencies;
91
+ violations.push(...todoReadinessRecordViolations({ ...readiness, dependencies: normalized }));
92
+ }
93
+ }
94
+ return [...new Set(violations)];
95
+ }
96
+ export function todoDocsRecordViolations(boundary, record, sourceRoot) {
97
+ const violations = [];
98
+ if (boundary === "todo_item") {
99
+ if (!TODO_SEVERITIES.includes(record.severity))
100
+ violations.push(`severity must be one of: ${TODO_SEVERITIES.join(", ")}`);
101
+ if (!TODO_STATUSES.includes(record.status))
102
+ violations.push(`status must be one of: ${TODO_STATUSES.join(", ")}`);
103
+ violations.push(...publicTodoViolations(record));
104
+ if (record.lifecycle !== undefined) {
105
+ if (!mapping(record.lifecycle))
106
+ violations.push("lifecycle must be a mapping");
107
+ else {
108
+ const lifecycle = record.lifecycle;
109
+ if (!["set-severity", "supersede", "resolve", "reopen"].includes(String(lifecycle.operation)))
110
+ violations.push("lifecycle.operation is invalid");
111
+ if (typeof lifecycle.reason !== "string" || !lifecycle.reason.trim())
112
+ violations.push("lifecycle.reason must be a non-empty string");
113
+ else if ([...lifecycle.reason].length > TODO_LIFECYCLE_REASON_MAX_CODE_POINTS)
114
+ violations.push(`lifecycle.reason must be at most ${TODO_LIFECYCLE_REASON_MAX_CODE_POINTS} code points`);
115
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(String(lifecycle.date ?? "")))
116
+ violations.push("lifecycle.date must be YYYY-MM-DD");
117
+ if (lifecycle.replacement !== undefined && !/^[a-z]{10}$/.test(String(lifecycle.replacement)))
118
+ violations.push("lifecycle.replacement must be a ten-letter TODO ID");
119
+ }
120
+ }
121
+ if (record.readiness !== undefined) {
122
+ const contract = sourceRoot
123
+ ? loadTodoReadinessContract(path.join(sourceRoot, "skills/agentera/schemas/artifacts/todo.yaml"), path.join(sourceRoot, "skills/agentera/protocol.yaml"), path.join(sourceRoot, "skills/agentera/capability_schema_contract.yaml"))
124
+ : undefined;
125
+ violations.push(...todoReadinessRecordViolations(record.readiness, contract));
126
+ }
127
+ if (record.reconciliation !== undefined) {
128
+ if (!mapping(record.reconciliation) || record.reconciliation.schema_version !== TODO_RECONCILIATION_VERSION || !mapping(record.reconciliation.public))
129
+ violations.push("reconciliation must be a canonical TODO public baseline");
130
+ else {
131
+ const baseline = record.reconciliation.public;
132
+ if (typeof baseline.present !== "boolean")
133
+ violations.push("reconciliation.public.present must be a boolean");
134
+ if (baseline.present) {
135
+ if (typeof baseline.description !== "string" || !baseline.description.trim())
136
+ violations.push("reconciliation.public.description is required when present");
137
+ if (!TODO_SEVERITIES.includes(baseline.severity))
138
+ violations.push(`reconciliation.public.severity must be one of: ${TODO_SEVERITIES.join(", ")}`);
139
+ if (!TODO_STATUSES.includes(baseline.status))
140
+ violations.push(`reconciliation.public.status must be one of: ${TODO_STATUSES.join(", ")}`);
141
+ if (!Number.isSafeInteger(baseline.order) || Number(baseline.order) < 1)
142
+ violations.push("reconciliation.public.order must be a positive integer");
143
+ }
144
+ }
145
+ }
146
+ }
147
+ if (boundary === "documentation_inventory_entry") {
148
+ if (typeof record.document !== "string" || !record.document.trim())
149
+ violations.push("document is required");
150
+ if (typeof record.path !== "string" || !record.path.trim())
151
+ violations.push("path is required record data");
152
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(String(record.last_updated ?? "")))
153
+ violations.push("last_updated must be YYYY-MM-DD");
154
+ if (!DOC_STATUSES.includes(record.status))
155
+ violations.push(`status must be one of: ${DOC_STATUSES.join(", ")}`);
156
+ }
157
+ return violations;
158
+ }
@@ -0,0 +1,51 @@
1
+ import fs from "node:fs";
2
+ import { renderTodoPublicRecord } from "../cli/todoMarkdown.js";
3
+ import { reject } from "./write/errors.js";
4
+ const TODO_MARKDOWN_MAX_BYTES = 1024 * 1024;
5
+ export function readTodoMarkdown(target) {
6
+ if (!fs.existsSync(target))
7
+ return { bytes: Buffer.from(""), text: "" };
8
+ const stat = fs.lstatSync(target);
9
+ if (!stat.isFile() || stat.isSymbolicLink())
10
+ reject({ class: "conflict", message: "managed TODO Markdown must be a regular file", recovery: "Restore the docs-mapped TODO artifact as a regular file within the project and retry; no state was changed." });
11
+ if (stat.size > TODO_MARKDOWN_MAX_BYTES)
12
+ reject({ class: "conflict", message: `managed TODO Markdown exceeds the ${TODO_MARKDOWN_MAX_BYTES}-byte reconciliation bound`, recovery: "Compact unmanaged or resolved Markdown content below the declared bound and retry; no state was changed." });
13
+ const bytes = fs.readFileSync(target);
14
+ let text;
15
+ try {
16
+ text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
17
+ }
18
+ catch {
19
+ reject({ class: "conflict", message: "managed TODO Markdown is not valid UTF-8", recovery: "Restore valid UTF-8 TODO Markdown and retry; no state was changed." });
20
+ }
21
+ return { bytes, text: text };
22
+ }
23
+ function sectionFor(record) { return record.status === "resolved" ? "resolved" : String(record.severity); }
24
+ function headingFor(section) { return section === "resolved" ? "## ✓ Resolved" : `## → ${section[0].toUpperCase()}${section.slice(1)}`; }
25
+ function rowFor(id, record) { return `- [${record.status === "resolved" ? "x" : " "}] [id:${id}] ${renderTodoPublicRecord(record)}`; }
26
+ export function renderManagedMarkdown(markdown, records, existing) {
27
+ const byLine = new Map([...existing.values()].map((row) => [row.line, row]));
28
+ const retained = new Set();
29
+ const lines = markdown.split(/\r?\n/).flatMap((line, index) => { const row = byLine.get(index); if (!row)
30
+ return [line]; const record = records.get(row.id); if (!record || sectionFor(record) !== row.section)
31
+ return []; retained.add(row.id); return [rowFor(row.id, record)]; });
32
+ for (const section of ["critical", "degraded", "normal", "annoying", "resolved"]) {
33
+ const ids = [...records.entries()].filter(([id, record]) => !retained.has(id) && sectionFor(record) === section).sort(([left], [right]) => { const a = existing.get(left); const b = existing.get(right); return (a?.section === section ? a.snapshot.order : Number.MAX_SAFE_INTEGER) - (b?.section === section ? b.snapshot.order : Number.MAX_SAFE_INTEGER) || left.localeCompare(right); }).map(([id]) => id);
34
+ if (!ids.length)
35
+ continue;
36
+ let heading = lines.findIndex((line) => line.trim().toLowerCase() === headingFor(section).toLowerCase());
37
+ if (heading < 0) {
38
+ if (lines.at(-1)?.trim())
39
+ lines.push("");
40
+ lines.push(headingFor(section));
41
+ heading = lines.length - 1;
42
+ }
43
+ let insert = heading + 1;
44
+ while (insert < lines.length && !/^##\s+/.test(lines[insert].trim()))
45
+ insert += 1;
46
+ while (insert > heading + 1 && !lines[insert - 1].trim())
47
+ insert -= 1;
48
+ lines.splice(insert, 0, ...ids.map((id) => rowFor(id, records.get(id))));
49
+ }
50
+ return `${lines.join("\n").replace(/\n*$/, "")}\n`;
51
+ }
@@ -0,0 +1,140 @@
1
+ import { createHash } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { reject } from "./write/errors.js";
5
+ import { CANONICAL_DEVELOPMENT_CLI } from "../core/developmentChannel.js";
6
+ import { canonicalRecordJson } from "./archiveDiscovery.js";
7
+ export const TODO_RECONCILIATION_ACTIVATION_PATH = ".agentera/todo-reconciliation-activation.json";
8
+ export const TODO_RECONCILIATION_ACTIVATION_VERSION = "agentera.todoReconciliationActivation.v1";
9
+ export const TODO_RECONCILIATION_ITEM_LIMIT = 256;
10
+ const MAX_ACTIVATION_BYTES = 32 * 1024;
11
+ const SHA256 = /^[a-f0-9]{64}$/;
12
+ export const TODO_ACTIVATION_PREVIEW_COMMAND = `${CANONICAL_DEVELOPMENT_CLI} state todo activate --dry-run --format json`;
13
+ export const TODO_ACTIVATION_APPLY_COMMAND = `${CANONICAL_DEVELOPMENT_CLI} state todo activate --effect-sha256 EFFECT_SHA256 --yes --format json`;
14
+ export const TODO_REPAIR_PREVIEW_COMMAND = `${CANONICAL_DEVELOPMENT_CLI} state todo repair --dry-run --format json`;
15
+ export const TODO_REPAIR_APPLY_COMMAND = `${CANONICAL_DEVELOPMENT_CLI} state todo repair --effect-sha256 EFFECT_SHA256 --yes --format json`;
16
+ export const TODO_UNSAFE_INACTIVE_RECOVERY = "Owner correction required: restore Markdown-owned public rows and Agentera-owned entity status to exact one-to-one pre-activation evidence. Do not activate or repair. If a correction needs a mutation, stop and request replanning; no state was changed.";
17
+ export const TODO_ACTIVATION_RISK_LIMIT = 20;
18
+ function activationFailure(message) {
19
+ reject({
20
+ class: "conflict",
21
+ message,
22
+ recovery: `Preserve '${TODO_RECONCILIATION_ACTIVATION_PATH}', restore its last valid committed bytes, and retry the exact TODO mutation; no state was changed.`,
23
+ });
24
+ }
25
+ export function todoLegacyRowFingerprint(section, line) {
26
+ return createHash("sha256").update(section).update("\0").update(line).digest("hex");
27
+ }
28
+ export function todoReconciliationActivationBytes(retainedLegacyRows, effectSha256, effectOperation = "activate") {
29
+ const retained = [...retainedLegacyRows].sort();
30
+ if (retained.length > TODO_RECONCILIATION_ITEM_LIMIT
31
+ || new Set(retained).size !== retained.length
32
+ || retained.some((digest) => !SHA256.test(digest)))
33
+ activationFailure("TODO reconciliation activation has invalid retained legacy-row identities");
34
+ if (effectSha256 !== undefined && !SHA256.test(effectSha256))
35
+ activationFailure("TODO reconciliation activation has an invalid effect authorization");
36
+ return `${JSON.stringify({
37
+ schema_version: TODO_RECONCILIATION_ACTIVATION_VERSION,
38
+ retained_legacy_rows: retained,
39
+ ...(effectSha256 ? { effect_sha256: effectSha256 } : {}),
40
+ ...(effectSha256 ? { effect_operation: effectOperation } : {}),
41
+ })}\n`;
42
+ }
43
+ export function loadTodoReconciliationActivation(root) {
44
+ const target = path.join(root, TODO_RECONCILIATION_ACTIVATION_PATH);
45
+ if (!fs.existsSync(target))
46
+ return null;
47
+ const stat = fs.lstatSync(target);
48
+ if (!stat.isFile() || stat.isSymbolicLink()) {
49
+ activationFailure("TODO reconciliation activation must be a regular file");
50
+ }
51
+ const bytes = fs.readFileSync(target);
52
+ if (bytes.length > MAX_ACTIVATION_BYTES) {
53
+ activationFailure("TODO reconciliation activation exceeds its 32768-byte bound");
54
+ }
55
+ let value;
56
+ try {
57
+ value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
58
+ }
59
+ catch {
60
+ activationFailure("TODO reconciliation activation is not valid bounded UTF-8 JSON");
61
+ }
62
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
63
+ activationFailure("TODO reconciliation activation is not a mapping");
64
+ }
65
+ const record = value;
66
+ if (!["retained_legacy_rows,schema_version", "effect_operation,effect_sha256,retained_legacy_rows,schema_version", "effect_sha256,retained_legacy_rows,schema_version"].includes(Object.keys(record).sort().join(","))
67
+ || record.schema_version !== TODO_RECONCILIATION_ACTIVATION_VERSION
68
+ || !Array.isArray(record.retained_legacy_rows)
69
+ || record.retained_legacy_rows.length > TODO_RECONCILIATION_ITEM_LIMIT
70
+ || record.retained_legacy_rows.some((digest) => typeof digest !== "string" || !SHA256.test(digest))
71
+ || new Set(record.retained_legacy_rows).size !== record.retained_legacy_rows.length
72
+ || (record.effect_sha256 !== undefined && (typeof record.effect_sha256 !== "string" || !SHA256.test(record.effect_sha256)))
73
+ || (record.effect_operation !== undefined && !["activate", "repair"].includes(record.effect_operation)))
74
+ activationFailure("TODO reconciliation activation has an invalid canonical record");
75
+ return { record: record, bytes };
76
+ }
77
+ function sha256(bytes) { return createHash("sha256").update(bytes).digest("hex"); }
78
+ export function todoActivationRisks(resurrectedIds) {
79
+ return {
80
+ resurrected_count: resurrectedIds.length,
81
+ resurrected_ids: resurrectedIds.slice(0, TODO_ACTIVATION_RISK_LIMIT),
82
+ omitted_count: Math.max(0, resurrectedIds.length - TODO_ACTIVATION_RISK_LIMIT),
83
+ };
84
+ }
85
+ function boundedPublicChanges(before, after) {
86
+ const beforeLines = before.split(/\r?\n/);
87
+ const afterLines = after.split(/\r?\n/);
88
+ const changes = [];
89
+ let count = 0;
90
+ for (let index = 0; index < Math.max(beforeLines.length, afterLines.length); index += 1) {
91
+ if (beforeLines[index] === afterLines[index])
92
+ continue;
93
+ count += 1;
94
+ if (changes.length < TODO_ACTIVATION_RISK_LIMIT)
95
+ changes.push({ line: index + 1, before: (beforeLines[index] ?? "").slice(0, 240), after: (afterLines[index] ?? "").slice(0, 240) });
96
+ }
97
+ return { count, items: changes, omitted_count: count - changes.length };
98
+ }
99
+ export function todoActivationEffect(scan, targets, publicPath, markdownBefore, rendered, resurrectedIds) {
100
+ const changedTargets = targets.filter((target) => target.before === null || !target.before.equals(Buffer.from(target.after))).map((target) => ({ path: target.path, before_sha256: target.before === null ? null : sha256(target.before), after_sha256: sha256(target.after) }));
101
+ const evidence = {
102
+ counts: { matched: scan.matchedRows, converted: scan.convertedRows, retained: scan.retainedLegacyRows.length, conflicting: 0 }, targets: changedTargets,
103
+ public_document: { path: publicPath, changed: !markdownBefore.equals(Buffer.from(rendered)), before_bytes: markdownBefore.length, after_bytes: Buffer.byteLength(rendered), before_sha256: sha256(markdownBefore), after_sha256: sha256(rendered), changed_lines: boundedPublicChanges(markdownBefore.toString("utf8"), rendered) },
104
+ risks: todoActivationRisks(resurrectedIds),
105
+ };
106
+ const authorizedTargets = changedTargets.map((target) => target.path === TODO_RECONCILIATION_ACTIVATION_PATH ? { ...target, after_sha256: "activation_effect_authorization" } : target);
107
+ return { ...evidence, effect_sha256: sha256(canonicalRecordJson({ ...evidence, targets: authorizedTargets })) };
108
+ }
109
+ export function unchangedTodoActivationEffect(publicPath, markdown, retained, authorizedEffectSha256) {
110
+ const evidence = { counts: { matched: 0, converted: 0, retained, conflicting: 0 }, targets: [], public_document: { path: publicPath, changed: false, before_bytes: markdown.length, after_bytes: markdown.length, before_sha256: sha256(markdown), after_sha256: sha256(markdown), changed_lines: { count: 0, items: [], omitted_count: 0 } }, risks: todoActivationRisks([]) };
111
+ return { ...evidence, effect_sha256: authorizedEffectSha256 ?? sha256(canonicalRecordJson(evidence)) };
112
+ }
113
+ export function todoRepairEffect(diagnosis, targets, publicPath, markdownBefore, rendered) {
114
+ const changedTargets = targets
115
+ .filter((target) => target.before === null || !target.before.equals(Buffer.from(target.after)))
116
+ .map((target) => ({ path: target.path, before_sha256: target.before === null ? null : sha256(target.before), after_sha256: sha256(target.after) }));
117
+ const evidence = {
118
+ diagnosis,
119
+ targets: changedTargets,
120
+ public_document: {
121
+ path: publicPath,
122
+ changed: !markdownBefore.equals(Buffer.from(rendered)),
123
+ before_bytes: markdownBefore.length,
124
+ after_bytes: Buffer.byteLength(rendered),
125
+ before_sha256: sha256(markdownBefore),
126
+ after_sha256: sha256(rendered),
127
+ changed_lines: boundedPublicChanges(markdownBefore.toString("utf8"), rendered),
128
+ },
129
+ };
130
+ const activationTarget = targets.find((target) => target.path === TODO_RECONCILIATION_ACTIVATION_PATH);
131
+ let normalizedActivationSha256 = null;
132
+ if (activationTarget) {
133
+ const parsed = JSON.parse(activationTarget.after);
134
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || typeof parsed.effect_sha256 !== "string")
135
+ throw new Error("TODO repair activation target cannot be normalized for effect authorization");
136
+ normalizedActivationSha256 = sha256(canonicalRecordJson({ ...parsed, effect_sha256: "activation_effect_authorization" }));
137
+ }
138
+ const authorizedTargets = changedTargets.map((target) => target.path === TODO_RECONCILIATION_ACTIVATION_PATH ? { ...target, after_sha256: normalizedActivationSha256 } : target);
139
+ return { ...evidence, effect_sha256: sha256(canonicalRecordJson({ ...evidence, targets: authorizedTargets })) };
140
+ }
@@ -0,0 +1,169 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { resolveSourceRoot } from "../core/sourceRoot.js";
4
+ import { renderTodoPublicRecord } from "../cli/todoMarkdown.js";
5
+ import { canonicalRecordJson } from "./archiveDiscovery.js";
6
+ import { detectStateMode } from "./stateMode.js";
7
+ import { StateWriteInputError } from "./write/errors.js";
8
+ import { TODO_ACTIVATION_APPLY_COMMAND, TODO_ACTIVATION_PREVIEW_COMMAND, TODO_RECONCILIATION_ACTIVATION_PATH, TODO_REPAIR_APPLY_COMMAND, TODO_REPAIR_PREVIEW_COMMAND, TODO_UNSAFE_INACTIVE_RECOVERY, loadTodoReconciliationActivation, todoReconciliationActivationBytes, } from "./todoReconciliationActivation.js";
9
+ import { planTodoRepair } from "./todoReconciliationRepair.js";
10
+ import { readTodoMarkdown } from "./todoMarkdownProjection.js";
11
+ import { inactiveTodoActivationSafety } from "./todoActivationSafety.js";
12
+ import { managedRows, relevant, todoPublicPath } from "./todoDocsEntities.js";
13
+ const DIAGNOSTIC_LIMIT = 20;
14
+ function mapping(value) {
15
+ return value !== null && typeof value === "object" && !Array.isArray(value);
16
+ }
17
+ function numberValue(value) {
18
+ return Number.isSafeInteger(value) && Number(value) >= 0 ? Number(value) : 0;
19
+ }
20
+ function boundedCounts(value) {
21
+ const raw = {
22
+ matched: numberValue(value.matched),
23
+ converted: numberValue(value.converted),
24
+ retained: numberValue(value.retained),
25
+ duplicate: numberValue(value.duplicate),
26
+ stale: numberValue(value.stale),
27
+ conflicting: numberValue(value.conflicting),
28
+ };
29
+ const counts = Object.fromEntries(Object.entries(raw).map(([key, count]) => [key, Math.min(count, DIAGNOSTIC_LIMIT)]));
30
+ const omitted = Object.values(raw).reduce((total, count) => total + Math.max(0, count - DIAGNOSTIC_LIMIT), numberValue(value.omitted_count));
31
+ return { ...counts, omitted: Math.min(DIAGNOSTIC_LIMIT, omitted) };
32
+ }
33
+ function recovery(preview, apply) {
34
+ return `Run exactly '${preview}', review its bounded read-only effect, then run exactly the preview's exact apply_command (the supported form is '${apply}'); no state was changed.`;
35
+ }
36
+ function invalidLifecycle() {
37
+ return {
38
+ state: "invalid_lifecycle",
39
+ status: "action_required",
40
+ counts: { matched: 0, converted: 0, retained: 0, duplicate: 0, stale: 0, conflicting: 0 },
41
+ omitted_count: 0,
42
+ preview_command: null,
43
+ apply_command: null,
44
+ recovery_command: "Restore the valid committed TODO reconciliation lifecycle metadata, then rerun `npx -y agentera@next check validate state --format json`; no state was changed.",
45
+ };
46
+ }
47
+ function inspection(state, rawCounts, risks) {
48
+ const bounded = boundedCounts(rawCounts);
49
+ const active = state === "healthy_active" || state === "unsafe_active";
50
+ const preview = state === "inactive" ? TODO_ACTIVATION_PREVIEW_COMMAND : active ? TODO_REPAIR_PREVIEW_COMMAND : null;
51
+ const apply = state === "inactive" ? TODO_ACTIVATION_APPLY_COMMAND : active ? TODO_REPAIR_APPLY_COMMAND : null;
52
+ return {
53
+ state,
54
+ status: state === "healthy_active" ? "operable" : "action_required",
55
+ counts: {
56
+ matched: bounded.matched,
57
+ converted: bounded.converted,
58
+ retained: bounded.retained,
59
+ duplicate: bounded.duplicate,
60
+ stale: bounded.stale,
61
+ conflicting: bounded.conflicting,
62
+ },
63
+ omitted_count: bounded.omitted,
64
+ ...(risks === undefined ? {} : { risks }),
65
+ preview_command: preview,
66
+ apply_command: apply,
67
+ recovery_command: state === "unsafe_inactive" ? TODO_UNSAFE_INACTIVE_RECOVERY : preview && apply ? recovery(preview, apply) : "",
68
+ };
69
+ }
70
+ function errorCounts(error) {
71
+ if (!(error instanceof StateWriteInputError) || !mapping(error.body.diagnosis))
72
+ return { conflicting: 1 };
73
+ const diagnosis = error.body.diagnosis;
74
+ return {
75
+ ...(mapping(diagnosis.counts) ? diagnosis.counts : { conflicting: 1 }),
76
+ ...(diagnosis.omitted_count !== undefined ? { omitted_count: diagnosis.omitted_count } : {}),
77
+ };
78
+ }
79
+ /** Read-only classification shared by prime, doctor, and whole-state validation. */
80
+ export function inspectTodoReconciliationState(root, sourceRoot = resolveSourceRoot(), discovery) {
81
+ try {
82
+ if (detectStateMode(root, sourceRoot) !== "entities")
83
+ return null;
84
+ }
85
+ catch {
86
+ return invalidLifecycle();
87
+ }
88
+ const activationPath = path.join(root, TODO_RECONCILIATION_ACTIVATION_PATH);
89
+ if (!fs.existsSync(activationPath)) {
90
+ try {
91
+ if (!fs.existsSync(todoPublicPath(root, sourceRoot)))
92
+ return null;
93
+ }
94
+ catch {
95
+ return null;
96
+ }
97
+ }
98
+ const entities = relevant(root, sourceRoot, "todo", discovery).filter(({ boundary }) => boundary === "todo_item");
99
+ let activation;
100
+ try {
101
+ activation = loadTodoReconciliationActivation(root);
102
+ }
103
+ catch {
104
+ return invalidLifecycle();
105
+ }
106
+ if (!activation) {
107
+ try {
108
+ const scan = managedRows(readTodoMarkdown(todoPublicPath(root, sourceRoot)).text, null, entities);
109
+ const safety = inactiveTodoActivationSafety(scan, entities);
110
+ return inspection(safety.safe ? "inactive" : "unsafe_inactive", safety.counts, safety.safe ? undefined : safety.risks);
111
+ }
112
+ catch (error) {
113
+ return inspection("unsafe_inactive", errorCounts(error));
114
+ }
115
+ }
116
+ try {
117
+ const plan = planTodoRepair(readTodoMarkdown(todoPublicPath(root, sourceRoot)).text, activation.record, entities);
118
+ const counts = mapping(plan.diagnosis.counts) ? plan.diagnosis.counts : {};
119
+ const unsafe = numberValue(counts.duplicate) > 0 || numberValue(counts.stale) > 0 || numberValue(counts.conflicting) > 0;
120
+ return inspection(unsafe ? "unsafe_active" : "healthy_active", counts);
121
+ }
122
+ catch (error) {
123
+ return inspection("unsafe_active", errorCounts(error));
124
+ }
125
+ }
126
+ function publicSnapshot(record, order) {
127
+ return { present: true, description: renderTodoPublicRecord(record), severity: String(record.severity), status: String(record.status), ...(order === undefined ? {} : { order }) };
128
+ }
129
+ function baseline(record) {
130
+ const reconciliation = record.reconciliation;
131
+ if (!mapping(reconciliation) || reconciliation.schema_version !== "agentera.todoReconciliation.v1" || !mapping(reconciliation.public))
132
+ return null;
133
+ return structuredClone(reconciliation.public);
134
+ }
135
+ function rowSnapshot(row, record) {
136
+ return { ...row.snapshot, severity: row.section === "resolved" ? String(record.severity) : row.snapshot.severity };
137
+ }
138
+ function samePublic(left, right, includeOrder = true) {
139
+ const fields = includeOrder ? ["present", "description", "severity", "status", "order"] : ["present", "description", "severity", "status"];
140
+ return fields.every((field) => left[field] === right[field]);
141
+ }
142
+ export function todoCutoverPublicProjectionViolations(markdown, targets) {
143
+ let rows;
144
+ try {
145
+ const activation = JSON.parse(todoReconciliationActivationBytes([]));
146
+ rows = managedRows(markdown, activation, targets.map(({ id, record }) => ({ boundary: "todo_item", id, record }))).rows;
147
+ }
148
+ catch (error) {
149
+ return [error instanceof StateWriteInputError ? error.body.message : error.message];
150
+ }
151
+ const targetIds = new Set(targets.map(({ id }) => id));
152
+ if (targetIds.size !== targets.length)
153
+ return ["pending TODO cutover target IDs are not unique"];
154
+ const unexpected = [...rows.keys()].find((id) => !targetIds.has(id));
155
+ if (unexpected)
156
+ return [`final managed TODO Markdown ID '${unexpected}' has no journal entity target`];
157
+ for (const { id, record } of targets) {
158
+ const row = rows.get(id);
159
+ if (!row)
160
+ return [`journal TODO entity '${id}' has no final managed Markdown row`];
161
+ const projected = rowSnapshot(row, record);
162
+ const prior = baseline(record);
163
+ if (!prior || canonicalRecordJson(prior) !== canonicalRecordJson(projected))
164
+ return [`journal TODO entity '${id}' has no exact final public baseline`];
165
+ if (!samePublic(publicSnapshot(record), projected, false))
166
+ return [`journal TODO entity '${id}' public values do not match its final managed Markdown row`];
167
+ }
168
+ return rows.size === targets.length ? [] : ["final managed TODO Markdown rows do not match the journal entity target set"];
169
+ }