agentera 3.0.0-dev.4 → 3.0.0-dev.46

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