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,332 @@
1
+ import path from "node:path";
2
+ import { ArtifactSchemaValidator } from "../../hooks/validateArtifact/index.js";
3
+ import { loadArtifactRegistry, resolveArtifactPath } from "../../registries/artifactRegistry.js";
4
+ import { schemaBudget, projectedFields } from "./fields.js";
5
+ import { loadMutationGrammar, } from "./grammar.js";
6
+ import { operationSpec, mutationParityMatrix, writerOwnedFields, verbsForArtifact, } from "./operations.js";
7
+ import { reject } from "./errors.js";
8
+ import { structuredInputDescriptor, structuredInputSchemaProjection } from "./input.js";
9
+ import { artifactSchemaFieldsForOperation } from "../../registries/artifactSchemaProjection.js";
10
+ function defaultVerb(artifact) {
11
+ const verb = verbsForArtifact(artifact).find((candidate) => candidate !== "explain");
12
+ if (!verb)
13
+ reject({ class: "unsupported_target", message: `artifact "${artifact}" has no public mutation` });
14
+ return verb;
15
+ }
16
+ function entityBoundary(artifact, verb) {
17
+ if (artifact === "progress")
18
+ return "progress_cycle";
19
+ if (artifact === "health")
20
+ return "health_audit";
21
+ if (artifact === "plan")
22
+ return ["append", "update", "set-status", "supersede", "record-evaluation"].includes(verb) ? "plan_task" : "plan";
23
+ if (artifact === "objective")
24
+ return "objective";
25
+ if (artifact === "experiments")
26
+ return "experiment";
27
+ if (artifact === "todo")
28
+ return "todo_item";
29
+ if (artifact === "docs")
30
+ return "documentation_inventory_entry";
31
+ return verb === "append" ? "decision" : verb === "update" ? "decision_satisfaction" : "decision_revision";
32
+ }
33
+ function exposedFields(artifact, verb, spec, validator) {
34
+ let source = projectedFields(spec, validator);
35
+ return source.map((field) => ({
36
+ flag: field.flag,
37
+ field: field.field,
38
+ required: field.required === true,
39
+ type: field.kind,
40
+ ...(field.validValues ? { valid_values: field.validValues } : {}),
41
+ ...(field.repeatable ? { repeatable: true } : {}),
42
+ ...(field.description ? { description: artifact === "objective" && field.flag === "--id"
43
+ ? "Bare ten-letter objective ID returned by objective create or list."
44
+ : artifact === "plan" && field.flag === "--id" && ["update", "set-status", "supersede", "record-evaluation"].includes(verb)
45
+ ? "Bare ten-letter task ID returned by plan task append or list."
46
+ : artifact === "plan" && field.flag === "--plan"
47
+ ? "Bare ten-letter plan ID returned by plan create or list."
48
+ : artifact === "experiments" && field.flag === "--objective"
49
+ ? "Bare ten-letter objective ID owning the experiment."
50
+ : artifact === "experiments" && field.flag === "--id"
51
+ ? "Existing bare ten-letter experiment ID for exact immutable replay."
52
+ : field.description } : {}),
53
+ ...(field.kind === "date" ? { format: "YYYY-MM-DD" } : {}),
54
+ ...(field.kind === "datetime" ? { format: "YYYY-MM-DD HH:MM" } : {}),
55
+ ...(field.flag === "--timestamp" ? { default: "now" } : {}),
56
+ ...(field.flag === "--date" ? { default: "today" } : {}),
57
+ }));
58
+ }
59
+ function pathFor(artifact, verb, projectRoot) {
60
+ const record = loadArtifactRegistry().get(artifact);
61
+ if (!record)
62
+ reject({ class: "unsupported_target", message: `artifact "${artifact}" is not registered` });
63
+ const entityArtifact = artifact !== "glossary";
64
+ const resolved = entityArtifact
65
+ ? path.join(projectRoot, ".agentera", "entities", artifact, entityBoundary(artifact, verb), "<id>.yaml")
66
+ : resolveArtifactPath(record, projectRoot, { strictWrite: true });
67
+ return path.relative(projectRoot, resolved) || resolved;
68
+ }
69
+ function inputProjection(spec) {
70
+ return {
71
+ mode: spec.inputMode,
72
+ ...(spec.inputRoot ? { root: spec.inputRoot } : {}),
73
+ sources: spec.inputSources,
74
+ structured_sources: spec.structuredInputSources,
75
+ cli_owned_fields: spec.cliOwnedFields,
76
+ ...(spec.inputMode === "structured" ? {
77
+ flag: "--input",
78
+ stdin_value: "-",
79
+ parser: "yaml_or_json_mapping",
80
+ } : {}),
81
+ };
82
+ }
83
+ export function buildExplain(artifact, projectRoot, requestedVerb) {
84
+ const verb = (requestedVerb ?? defaultVerb(artifact));
85
+ const spec = operationSpec(artifact, verb);
86
+ const grammar = loadMutationGrammar();
87
+ const declaration = grammar.operations.find((operation) => operation.artifact === artifact && operation.verb === verb);
88
+ if (!spec || !declaration) {
89
+ reject({
90
+ class: "invalid_choice",
91
+ message: `verb "${verb}" does not apply to ${artifact}`,
92
+ valid_values: verbsForArtifact(artifact),
93
+ });
94
+ }
95
+ const record = loadArtifactRegistry().get(artifact);
96
+ if (!record)
97
+ reject({ class: "unsupported_target", message: `artifact "${artifact}" is not registered` });
98
+ const validator = new ArtifactSchemaValidator();
99
+ const result = {
100
+ schemaVersion: "agentera.stateWriteExplain.v1",
101
+ command: `state ${artifact} explain`,
102
+ requested_verb: verb,
103
+ artifact,
104
+ path: pathFor(artifact, verb, projectRoot),
105
+ verbs: verbsForArtifact(artifact),
106
+ contract_digest: grammar.contractDigest,
107
+ mutation_class: declaration.mutationClass,
108
+ selectors: declaration.selectors,
109
+ preconditions: declaration.preconditions,
110
+ owned_fields: declaration.ownedFields,
111
+ input: inputProjection(spec),
112
+ recovery: declaration.recovery,
113
+ examples: declaration.examples,
114
+ bounds: declaration.bounds,
115
+ next: {},
116
+ budget: schemaBudget(artifact, validator),
117
+ fields: exposedFields(artifact, verb, spec, validator),
118
+ };
119
+ const owned = writerOwnedFields(artifact);
120
+ if (owned.length)
121
+ result.writer_owned_fields = owned;
122
+ if (spec.compacts) {
123
+ result.compaction = `not applicable; each canonical ${artifact} entity is authority and no aggregate projection or numbered archive is written`;
124
+ }
125
+ if (spec.inputMode === "structured") {
126
+ const structured = structuredInputDescriptor(artifact, verb);
127
+ result.input_schema = {
128
+ flag: "--input",
129
+ sources: spec.inputSources,
130
+ parser: "yaml_or_json_mapping",
131
+ accepts_json: true,
132
+ root: spec.inputRoot,
133
+ cli_owned_fields: spec.cliOwnedFields,
134
+ defaulted_fields: artifact === "health" ? { date: "today" } : {},
135
+ groups: artifact === "glossary"
136
+ ? ["PROPOSAL", "CONFIRMATION"]
137
+ : artifact === "health"
138
+ ? ["AUDIT", "DIMENSION", "FINDING", "TRENDS"]
139
+ : artifact === "experiments"
140
+ ? ["EXPERIMENT"]
141
+ : artifact === "todo"
142
+ ? ["TODO_PUBLIC", "TODO_OPERATIONAL"]
143
+ : artifact === "progress"
144
+ ? ["CYCLE", "CONTEXT", "GLOSSARY_CAVEAT"]
145
+ : artifact === "decisions"
146
+ ? ["DECISION", "ALTERNATIVES"]
147
+ : ["HEADER", "PLAN", "SCOPE", "TASK"],
148
+ };
149
+ if (structured) {
150
+ const projection = structuredInputSchemaProjection(structured);
151
+ result.input_schema = {
152
+ ...result.input_schema,
153
+ structured_fields: projection.fields,
154
+ semantics: projection.semantics,
155
+ owned_fields: projection.owned_fields,
156
+ immutable_fields: projection.immutable_fields,
157
+ bounds: projection.bounds,
158
+ examples: projection.examples,
159
+ };
160
+ }
161
+ const artifactSchemaFields = artifactSchemaFieldsForOperation(validator.loadSchema(artifact), verb);
162
+ if (artifactSchemaFields.length > 0)
163
+ result.input_schema = {
164
+ ...result.input_schema,
165
+ artifact_schema_fields: artifactSchemaFields,
166
+ };
167
+ if (artifact === "progress" && verb === "append")
168
+ result.input_schema = { ...result.input_schema, record_fields: ["timestamp", "type", "phase", "what", "inspiration", "discovered", "verified", "next", "context", "glossary_caveat"] };
169
+ if (artifact === "decisions" && verb === "append")
170
+ result.input_schema = { ...result.input_schema, record_fields: ["date", "question", "context", "alternatives", "choice", "reasoning", "confidence", "feeds_into"] };
171
+ if (artifact === "decisions" && verb === "amend")
172
+ result.input_schema = { ...result.input_schema, record_fields: ["question", "context", "alternatives", "choice", "reasoning", "confidence", "feeds_into"] };
173
+ if (artifact === "plan" && verb === "append")
174
+ result.input_schema = { ...result.input_schema, record_fields: ["name", "depends_on", "acceptance", "evidence", "blocked_reason"] };
175
+ if (artifact === "plan" && verb === "update")
176
+ result.input_schema = { ...result.input_schema, record_fields: ["name", "depends_on", "acceptance", "evidence", "blocked_reason", "surprise"], clearable_patch_fields: ["depends_on", "acceptance", "evidence", "blocked_reason"] };
177
+ if (artifact === "todo") {
178
+ result.input_schema = {
179
+ ...result.input_schema,
180
+ typed_fields: ["kind", "target_version", "title", "requirements", "acceptance", "release_blocker", "severity", "readiness"],
181
+ clearable_patch_fields: ["target_version", "requirements", "acceptance", "readiness"],
182
+ full_record_required_fields: ["kind", "target_version", "title", "requirements", "acceptance", "release_blocker", "severity"],
183
+ };
184
+ }
185
+ }
186
+ if (artifact === "glossary") {
187
+ result.identity = {
188
+ display_name: record.displayName,
189
+ default_path: record.defaultPath,
190
+ authority: "artifact registry",
191
+ };
192
+ result.implementation_status = record.implementationStatus;
193
+ result.producer = [...record.producers].sort();
194
+ result.request_schema_version = "agentera.glossaryPublicationRequest.v1";
195
+ result.document_schema_version = "agentera.projectGlossary.v1";
196
+ }
197
+ result.guidance = decisionsGuidance(artifact, verb, artifact === "health", true);
198
+ result.example = exampleFor(artifact, verb);
199
+ return result;
200
+ }
201
+ export function buildExplainAll(artifact, projectRoot) {
202
+ const grammar = loadMutationGrammar();
203
+ const operations = verbsForArtifact(artifact)
204
+ .filter((verb) => verb !== "explain")
205
+ .map((verb) => buildExplain(artifact, projectRoot, verb));
206
+ return {
207
+ schemaVersion: "agentera.stateWriteExplainAll.v1",
208
+ command: `state ${artifact} explain --all`,
209
+ artifact,
210
+ authority: grammar.authority,
211
+ contract_digest: grammar.contractDigest,
212
+ verbs: operations.map((operation) => operation.requested_verb),
213
+ operations,
214
+ parity_matrix: mutationParityMatrix([artifact]),
215
+ };
216
+ }
217
+ function decisionsGuidance(artifact, verb, _entityHealth = false, entityArtifact = false) {
218
+ const base = [
219
+ "do not embed commit hashes; evidence belongs in the commit message (Decision 66)",
220
+ "fold the artifact write into the implementation commit per AGENTS.md",
221
+ ];
222
+ if (artifact === "glossary")
223
+ return [
224
+ "build is the only publisher; audit and discuss remain mutation-free",
225
+ "confirmation.confirmed_by must be user and must bind the exact proposal digest and timestamp",
226
+ "the writer revalidates every cited project source line and publishes approval plus entry as one atomic document",
227
+ ...base,
228
+ ];
229
+ if (entityArtifact && artifact === "plan" && verb === "create")
230
+ return ["the CLI assigns bare ten-letter envelope IDs to the plan and each task and publishes one canonical file per entity", "task numbers and dependency values in this atomic input are create-local symbolic ordinals; the writer removes them and resolves dependencies to bare task IDs", "legacy composite header.id values are migration-only and never public selectors", ...base];
231
+ if (entityArtifact && artifact === "plan" && verb === "record-evaluation")
232
+ return [
233
+ "select one task entity with its bare ten-letter --id; numeric and composite selectors are unavailable",
234
+ "evaluate before completing a task during normal orchestration",
235
+ "a first PASS on an unevaluated complete replacement is recovery only when an open same-plan superseded predecessor names it in superseded_by",
236
+ ...base,
237
+ ];
238
+ if (entityArtifact && artifact === "plan" && verb === "supersede")
239
+ return [
240
+ "select one task entity with its bare ten-letter --id; numeric and composite selectors are unavailable",
241
+ "each replacement must be complete with latest persisted PASS",
242
+ "if a non-PASS replacement is not already referenced by a historical superseded predecessor, reopen it, record PASS, complete it, and retry",
243
+ "if a referenced historical replacement is unevaluated complete, record its allowed first PASS while it remains complete, then retry",
244
+ "if a referenced historical replacement has an existing non-PASS evaluation, first-PASS recovery is unavailable; use another complete latest-PASS replacement, or keep or archive the plan without claiming completion as applicable",
245
+ ...base,
246
+ ];
247
+ if (entityArtifact && artifact === "plan" && verb === "update")
248
+ return ["select one task entity with its bare ten-letter --id; supply an omission-preserving YAML/JSON task patch through --input", "task status, supersession, evaluation, and plan lifecycle remain flag-only transitions; surprise remains plan-level content", ...base];
249
+ if (entityArtifact && artifact === "plan" && verb === "set-status")
250
+ return ["select one task entity with its bare ten-letter --id; lifecycle status is a flag-only transition", ...base];
251
+ if (entityArtifact && artifact === "plan" && verb === "append")
252
+ return ["the CLI assigns a bare ten-letter ID to the new task entity", "supply one complete YAML/JSON task record through --input; dependencies must be bare ten-letter IDs in the selected plan", ...base];
253
+ if (entityArtifact && artifact === "plan")
254
+ return [
255
+ "the active plan entity is selected by lifecycle state",
256
+ ...(verb === "set-plan-status" ? ["open-to-complete requires every superseded_by replacement to be complete with latest persisted PASS; historical unevaluated complete replacements may record their allowed first PASS, then retry"] : []),
257
+ ...base,
258
+ ];
259
+ if (entityArtifact && artifact === "experiments")
260
+ return ["select the owner with its bare ten-letter --objective ID; numeric and composite selectors are unavailable", "omit --id for a new immutable experiment; pass an existing bare --id only for exact replay", ...base];
261
+ if (entityArtifact && artifact === "objective" && verb === "update")
262
+ return ["select one objective with its bare ten-letter --id; numeric selectors are unavailable", "the CLI preserves that ID while replacing the validated objective record", ...base];
263
+ if (entityArtifact && artifact === "objective")
264
+ return ["a bare ten-letter objective ID is assigned by the CLI; do not pass an identity", ...base];
265
+ if (entityArtifact && artifact === "todo" && verb === "update")
266
+ return [
267
+ "select one TODO item with its bare ten-letter --id; numeric, prefixed, composite, alias, and path identities are unavailable",
268
+ "the input document is a patch: omitted fields preserve state and only target_version, requirements, acceptance, and readiness accept typed clears",
269
+ "public fields are TODO.md-owned; readiness, dependencies, gates, and evidence are Agentera-owned",
270
+ ...base,
271
+ ];
272
+ if (entityArtifact && artifact === "todo" && ["set-severity", "supersede", "resolve", "reopen"].includes(verb))
273
+ return [
274
+ "select one TODO item with its bare ten-letter --id; lifecycle transitions are flag-only and accept no --input record",
275
+ "supply a reason and YYYY-MM-DD date; supersede additionally requires a distinct existing replacement ID",
276
+ ...base,
277
+ ];
278
+ if (entityArtifact && artifact === "todo")
279
+ return [
280
+ "a bare ten-letter TODO item ID is assigned by the CLI; status starts open",
281
+ "create requires a full typed TODO record; readiness is optional and absent means needs-triage",
282
+ "the public marker is rendered as [kind:target] and is not stored in title prose",
283
+ ...base,
284
+ ];
285
+ if (entityArtifact && artifact === "docs" && verb === "update")
286
+ return ["select one documentation inventory entry with its bare ten-letter --id; path remains record data, not identity", ...base];
287
+ if (entityArtifact && artifact === "docs")
288
+ return ["a bare ten-letter documentation inventory ID is assigned by the CLI; path remains record data", ...base];
289
+ if (artifact === "progress" && verb === "append")
290
+ return ["supply one progress cycle mapping with --input PATH or --input -; the writer assigns id, artifact, and publication_order", "record content flags are retired; inspect the structured record_fields in explain before writing", ...base];
291
+ if (artifact === "decisions" && verb === "append")
292
+ return ["a bare ten-letter ID is assigned by the CLI; do not pass an identity", "supply one decision record mapping with --input PATH or --input -; the writer assigns id and artifact", "record content flags are retired; satisfaction remains a separate flag-only transition", ...base];
293
+ if (artifact === "decisions" && verb === "update")
294
+ return ["select one base decision with its bare --id; numeric selectors are unavailable", "update replaces only that decision's authority-owned satisfaction entity after transition validation", ...base];
295
+ if (artifact === "decisions" && verb === "amend")
296
+ return ["select one base decision with its bare --id and current --base-sha256", "supply amendable decision content with --input PATH or --input -; record content flags are retired", "apply publishes one immutable revision entity; identical retries converge and same-base divergence conflicts", ...base];
297
+ return [entityArtifact ? "a bare ten-letter ID is assigned by the CLI; do not pass an identity" : "the writer assigns canonical identity", ...base];
298
+ }
299
+ export function exampleFor(artifact, verb) {
300
+ const declaration = loadMutationGrammar().operations.find((operation) => operation.artifact === artifact && operation.verb === verb);
301
+ if (declaration?.examples[0])
302
+ return declaration.examples[0];
303
+ return `agentera state ${artifact} ${verb} --format json`;
304
+ }
305
+ export function renderExplainText(explain) {
306
+ const lines = [
307
+ `usage: agentera state ${explain.artifact} ${explain.requested_verb ?? "explain --all"} [flags]`,
308
+ "",
309
+ `${explain.artifact} (${explain.path ?? "mutation grammar"})`,
310
+ `Class: ${String(explain.mutation_class ?? "all")}`,
311
+ `Contract digest: ${String(explain.contract_digest ?? "unknown")}`,
312
+ ];
313
+ const fields = Array.isArray(explain.fields) ? explain.fields : [];
314
+ if (fields.length) {
315
+ const required = fields.filter((field) => field.required);
316
+ const optional = fields.filter((field) => !field.required);
317
+ for (const [heading, entries] of [["Required", required], ["Optional", optional]]) {
318
+ if (!entries.length)
319
+ continue;
320
+ lines.push("", `${heading}:`);
321
+ for (const field of entries) {
322
+ const values = Array.isArray(field.valid_values) ? ` one of: ${field.valid_values.join(", ")}` : "";
323
+ lines.push(` ${String(field.flag).padEnd(24)}${values || String(field.description ?? field.field)}`);
324
+ }
325
+ }
326
+ }
327
+ const input = explain.input;
328
+ if (input?.mode === "structured")
329
+ lines.push("", "Required:", " --input PATH YAML/JSON document; use - for stdin");
330
+ lines.push("", "Recovery:", ` ${String(explain.recovery ?? "Correct the input and retry; no state was changed.")}`, "", "Example:", ` ${String(explain.example ?? "")}`);
331
+ return lines.join("\n") + "\n";
332
+ }
@@ -0,0 +1,61 @@
1
+ import { ArtifactSchemaValidator } from "../../hooks/validateArtifact/index.js";
2
+ function schemaEntry(schema, fieldPath) {
3
+ const leaf = fieldPath.split(".").at(-1);
4
+ for (const value of Object.values(schema)) {
5
+ if (!value || typeof value !== "object" || Array.isArray(value))
6
+ continue;
7
+ for (const entry of Object.values(value)) {
8
+ if (entry &&
9
+ typeof entry === "object" &&
10
+ !Array.isArray(entry) &&
11
+ String(entry.field ?? "") === leaf) {
12
+ return entry;
13
+ }
14
+ }
15
+ }
16
+ return null;
17
+ }
18
+ function valuesFromValidation(entry) {
19
+ if (!entry || !Array.isArray(entry.validation))
20
+ return undefined;
21
+ for (const raw of entry.validation) {
22
+ const match = /Must be one of:\s*(.+)$/i.exec(String(raw));
23
+ if (match)
24
+ return match[1]
25
+ .split(",")
26
+ .map((v) => v.trim())
27
+ .filter(Boolean);
28
+ }
29
+ return undefined;
30
+ }
31
+ export function projectedFields(spec, validator = new ArtifactSchemaValidator()) {
32
+ const schema = validator.loadSchema(spec.artifact);
33
+ if (!schema)
34
+ return spec.fields;
35
+ return spec.fields.map((field) => {
36
+ const entry = schemaEntry(schema, field.field);
37
+ return {
38
+ ...field,
39
+ required: field.required ?? Boolean(entry?.required),
40
+ validValues: field.validValues ?? valuesFromValidation(entry),
41
+ description: field.description ?? (entry?.description ? String(entry.description) : undefined),
42
+ };
43
+ });
44
+ }
45
+ export function schemaBudget(artifact, validator = new ArtifactSchemaValidator()) {
46
+ const schema = validator.loadSchema(artifact);
47
+ const result = {};
48
+ if (!schema ||
49
+ !schema.BUDGET ||
50
+ typeof schema.BUDGET !== "object" ||
51
+ Array.isArray(schema.BUDGET))
52
+ return result;
53
+ for (const entry of Object.values(schema.BUDGET)) {
54
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
55
+ continue;
56
+ const scope = String(entry.scope ?? "");
57
+ const key = scope.includes("full_file") ? "full_file_max_words" : "per_entry_max_words";
58
+ result[key] = typeof entry.max_words === "number" ? entry.max_words : null;
59
+ }
60
+ return result;
61
+ }
@@ -0,0 +1,263 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { canonicalTerminologyJson, validateTerminologyProposal, } from "../../audit/terminologyDrift.js";
5
+ import { dumpYamlMapping, loadYamlMapping } from "../../core/yaml.js";
6
+ import { loadArtifactRecord, resolveArtifactPath, } from "../../registries/artifactRegistry.js";
7
+ import { GlossaryEntryBoundError, validateGlossaryEntry } from "../../registries/glossaryEntryContract.js";
8
+ import { unicodeCaselessExact } from "../../registries/glossaryTermIdentity.js";
9
+ import { containsGlossaryTerm } from "../../registries/glossaryTermOccurrence.js";
10
+ import { assertValidatedProjectRoot } from "../projectRoot.js";
11
+ import { reject } from "./errors.js";
12
+ import { withStateMutation } from "./mutation.js";
13
+ const REQUEST_VERSION = "agentera.glossaryPublicationRequest.v1";
14
+ const DOCUMENT_VERSION = "agentera.projectGlossary.v1";
15
+ const REQUEST_FIELDS = ["schema_version", "proposal", "confirmation"];
16
+ function mapping(value) {
17
+ return value !== null && typeof value === "object" && !Array.isArray(value);
18
+ }
19
+ function exactFields(value, allowed) {
20
+ return Object.keys(value).every((field) => allowed.includes(field));
21
+ }
22
+ function validTimestamp(value) {
23
+ if (typeof value !== "string")
24
+ return false;
25
+ const match = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-](\d{2}):(\d{2}))$/.exec(value);
26
+ if (!match || Number.isNaN(Date.parse(value)))
27
+ return false;
28
+ const [, year, month, day, hour, minute, second, offsetHour = "00", offsetMinute = "00"] = match;
29
+ const calendar = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day)));
30
+ return calendar.getUTCFullYear() === Number(year)
31
+ && calendar.getUTCMonth() + 1 === Number(month)
32
+ && calendar.getUTCDate() === Number(day)
33
+ && Number(hour) <= 23
34
+ && Number(minute) <= 59
35
+ && Number(second) <= 59
36
+ && Number(offsetHour) <= 23
37
+ && Number(offsetMinute) <= 59;
38
+ }
39
+ function correction(message, classification = "schema_violation", recovery = "Rerun audit against current project files, obtain explicit user confirmation for the returned proposal_digest, and retry the same glossary publish command.") {
40
+ reject({
41
+ class: classification,
42
+ message,
43
+ recovery,
44
+ example: "agentera state glossary publish --input glossary-publication.yaml --format json",
45
+ });
46
+ }
47
+ function proposal(value) {
48
+ const validated = validateTerminologyProposal(value);
49
+ if (!validated.proposal) {
50
+ correction(`proposal is not canonical Audit output: ${validated.violations.join("; ")}`);
51
+ }
52
+ return validated.proposal;
53
+ }
54
+ function confirmation(value, digest) {
55
+ if (!mapping(value) || !exactFields(value, ["proposal_digest", "confirmed_by", "confirmed_at"])) {
56
+ correction("confirmation must contain only proposal_digest, confirmed_by, and confirmed_at");
57
+ }
58
+ if (value.confirmed_by !== "user") {
59
+ correction("confirmation.confirmed_by must be 'user'; generic consent or agent attribution is not approval");
60
+ }
61
+ if (!validTimestamp(value.confirmed_at)) {
62
+ correction("confirmation.confirmed_at must be a valid ISO 8601 timestamp with timezone");
63
+ }
64
+ if (value.proposal_digest !== digest) {
65
+ correction("confirmation.proposal_digest does not bind the submitted proposal");
66
+ }
67
+ return value;
68
+ }
69
+ function revalidateEvidence(root, proposalValue) {
70
+ const groups = [
71
+ { term: proposalValue.proposed_canonical_term, evidence: proposalValue.canonical_evidence },
72
+ ...proposalValue.variants,
73
+ ];
74
+ for (const group of groups) {
75
+ for (const record of group.evidence) {
76
+ assertValidatedProjectRoot(root);
77
+ const candidate = path.resolve(root.path, record.source_path);
78
+ let resolved;
79
+ try {
80
+ resolved = fs.realpathSync(candidate);
81
+ }
82
+ catch {
83
+ correction(`source evidence '${record.source_path}:${record.line}' is missing or unreadable`);
84
+ }
85
+ if (!resolved.startsWith(`${root.path}${path.sep}`) || !fs.statSync(resolved).isFile()) {
86
+ correction(`source evidence '${record.source_path}:${record.line}' escapes the project or is not a file`);
87
+ }
88
+ const canonicalPath = path.relative(root.path, resolved).split(path.sep).join(path.posix.sep);
89
+ if (canonicalPath !== record.source_path) {
90
+ correction(`source evidence '${record.source_path}:${record.line}' is not the canonical Audit-emitted project identity '${canonicalPath}:${record.line}'`);
91
+ }
92
+ const line = fs.readFileSync(resolved, "utf8").split(/\r?\n/)[record.line - 1];
93
+ const digest = line === undefined ? "" : crypto.createHash("sha256").update(line).digest("hex");
94
+ if (line === undefined || digest !== record.source_record_sha256 || !containsGlossaryTerm(line, group.term)) {
95
+ correction(`source evidence '${record.source_path}:${record.line}' is stale or no longer identifies '${group.term}'`);
96
+ }
97
+ }
98
+ }
99
+ }
100
+ function deriveEntry(proposalValue, confirmed) {
101
+ const source = proposalValue.canonical_evidence[0];
102
+ const date = confirmed.confirmed_at.slice(0, 10);
103
+ const entry = {
104
+ term: proposalValue.proposed_canonical_term,
105
+ meaning: proposalValue.concept,
106
+ confidence: proposalValue.confidence,
107
+ permanence: "stable",
108
+ temporal: { observed_at: date, last_confirmed_at: date },
109
+ provenance: {
110
+ kind: "project_file",
111
+ evidence: [{ source_path: source.source_path, source_record_sha256: source.source_record_sha256 }],
112
+ },
113
+ };
114
+ const violations = validateGlossaryEntry(entry, "project");
115
+ if (violations.length > 0)
116
+ correction(`derived project glossary entry is invalid: ${violations.join("; ")}`);
117
+ return entry;
118
+ }
119
+ function same(left, right) {
120
+ return canonicalTerminologyJson(left) === canonicalTerminologyJson(right);
121
+ }
122
+ function parseApproval(value, index) {
123
+ if (!mapping(value) || !exactFields(value, ["proposal_digest", "proposal", "confirmation"])) {
124
+ correction(`existing approvals[${index}] is malformed`, "conflict");
125
+ }
126
+ const proposed = proposal(value.proposal);
127
+ const confirmed = confirmation(value.confirmation, proposed.proposal_digest);
128
+ if (value.proposal_digest !== proposed.proposal_digest) {
129
+ correction(`existing approvals[${index}] has conflicting digest identity`, "conflict");
130
+ }
131
+ return {
132
+ approval: { proposal_digest: proposed.proposal_digest, proposal: proposed, confirmation: confirmed },
133
+ entry: deriveEntry(proposed, confirmed),
134
+ };
135
+ }
136
+ export function parseProjectGlossaryDocument(bytes, maxEntries = Number.POSITIVE_INFINITY) {
137
+ let value;
138
+ try {
139
+ value = loadYamlMapping(bytes);
140
+ }
141
+ catch (error) {
142
+ correction(`existing glossary document is malformed: ${error.message}`, "conflict");
143
+ }
144
+ if (!exactFields(value, ["schema_version", "approvals", "entries"]) || value.schema_version !== DOCUMENT_VERSION || !Array.isArray(value.approvals) || !Array.isArray(value.entries)) {
145
+ correction(`existing glossary document must use ${DOCUMENT_VERSION} with approvals and entries lists`, "conflict");
146
+ }
147
+ if (value.entries.length > maxEntries || value.approvals.length > maxEntries)
148
+ throw new GlossaryEntryBoundError("project glossary exceeds the consumer entry bound");
149
+ const approvals = value.approvals.map((item, index) => parseApproval(item, index));
150
+ const entries = value.entries;
151
+ if (entries.length !== approvals.length)
152
+ correction("existing glossary approvals and entries do not form complete publication pairs", "conflict");
153
+ const terminologyIdentities = [];
154
+ const digestIdentities = new Set();
155
+ for (const [index, item] of entries.entries()) {
156
+ if (!mapping(item))
157
+ correction(`existing entries[${index}] is malformed`, "conflict");
158
+ const violations = validateGlossaryEntry(item, "project");
159
+ if (violations.length > 0)
160
+ correction(`existing entries[${index}] is malformed: ${violations.join("; ")}`, "conflict");
161
+ if (!same(item, approvals[index].entry))
162
+ correction(`existing approval and entry at index ${index} do not match`, "conflict");
163
+ const canonical = String(item.term);
164
+ const digest = approvals[index].approval.proposal_digest;
165
+ if (digestIdentities.has(digest))
166
+ correction("existing glossary contains duplicate term or approval identity", "conflict");
167
+ digestIdentities.add(digest);
168
+ const terms = [canonical, ...approvals[index].approval.proposal.variants.map(({ term }) => term)];
169
+ for (const term of terms) {
170
+ const existing = terminologyIdentities.find((identity) => unicodeCaselessExact(identity.term, term));
171
+ if (existing) {
172
+ correction(`terminology identity collision for '${term}' between canonical sets '${existing.canonical}' and '${canonical}'`, "conflict", `Choose distinct canonical and variant terms for '${existing.canonical}' and '${canonical}', rerun audit, obtain confirmation for the corrected proposal, and retry the same glossary publish command.`);
173
+ }
174
+ terminologyIdentities.push({ term, canonical });
175
+ }
176
+ }
177
+ return {
178
+ schema_version: DOCUMENT_VERSION,
179
+ approvals: approvals.map(({ approval }) => approval),
180
+ entries: entries,
181
+ };
182
+ }
183
+ function validateCandidateBytes(bytes) {
184
+ return parseProjectGlossaryDocument(bytes);
185
+ }
186
+ export function loadProjectGlossaryDocument(projectRoot) {
187
+ const record = loadArtifactRecord("glossary");
188
+ if (!record)
189
+ correction("registered glossary artifact is unavailable");
190
+ const target = resolveArtifactPath(record, projectRoot);
191
+ if (!fs.existsSync(target))
192
+ return null;
193
+ return { path: target, document: parseProjectGlossaryDocument(fs.readFileSync(target, "utf8")) };
194
+ }
195
+ export function publishGlossary(req, root, options = {}) {
196
+ if (!req.input || !exactFields(req.input, REQUEST_FIELDS) || req.input.schema_version !== REQUEST_VERSION) {
197
+ correction(`publication request must use ${REQUEST_VERSION} and contain only proposal and confirmation`);
198
+ }
199
+ const proposed = proposal(req.input.proposal);
200
+ const confirmed = confirmation(req.input.confirmation, proposed.proposal_digest);
201
+ const entry = deriveEntry(proposed, confirmed);
202
+ const approval = {
203
+ proposal_digest: proposed.proposal_digest,
204
+ proposal: proposed,
205
+ confirmation: confirmed,
206
+ };
207
+ const record = loadArtifactRecord("glossary");
208
+ if (!record)
209
+ correction("registered glossary artifact is unavailable");
210
+ return withStateMutation(root.path, (transaction) => {
211
+ assertValidatedProjectRoot(root);
212
+ const target = resolveArtifactPath(record, root.path, { strictWrite: true });
213
+ const relativePath = path.relative(root.path, target).split(path.sep).join("/");
214
+ revalidateEvidence(root, proposed);
215
+ const previousBytes = fs.existsSync(target) ? fs.readFileSync(target, "utf8") : "";
216
+ const current = previousBytes
217
+ ? parseProjectGlossaryDocument(previousBytes)
218
+ : { schema_version: DOCUMENT_VERSION, approvals: [], entries: [] };
219
+ const approvalIndex = current.approvals.findIndex((item) => item.proposal_digest === proposed.proposal_digest);
220
+ const termIndex = current.entries.findIndex((item) => unicodeCaselessExact(String(item.term), proposed.proposed_canonical_term));
221
+ if (approvalIndex >= 0 || termIndex >= 0) {
222
+ if (approvalIndex === termIndex && approvalIndex >= 0 && same(current.approvals[approvalIndex], approval) && same(current.entries[termIndex], entry)) {
223
+ return {
224
+ schemaVersion: "agentera.stateWrite.v1",
225
+ status: "pass",
226
+ command: "state glossary publish",
227
+ artifact: "glossary",
228
+ path: relativePath,
229
+ operation: { dry_run: req.dryRun, changed: false, idempotent_replay: true },
230
+ candidate: current,
231
+ };
232
+ }
233
+ correction(`confirmed term '${proposed.proposed_canonical_term}' conflicts with existing approval or entry state`, "conflict");
234
+ }
235
+ const candidate = {
236
+ schema_version: DOCUMENT_VERSION,
237
+ approvals: [...current.approvals, approval],
238
+ entries: [...current.entries, entry],
239
+ };
240
+ const bytes = dumpYamlMapping(candidate);
241
+ validateCandidateBytes(bytes);
242
+ if (!req.dryRun) {
243
+ const stage = transaction.stageProjection(target, bytes);
244
+ try {
245
+ transaction.syncStaged(stage);
246
+ assertValidatedProjectRoot(root);
247
+ transaction.publishProjection(stage, target, previousBytes);
248
+ }
249
+ finally {
250
+ transaction.removeStage(stage);
251
+ }
252
+ }
253
+ return {
254
+ schemaVersion: "agentera.stateWrite.v1",
255
+ status: "pass",
256
+ command: "state glossary publish",
257
+ artifact: "glossary",
258
+ path: relativePath,
259
+ operation: { dry_run: req.dryRun, changed: true, idempotent_replay: false },
260
+ candidate,
261
+ };
262
+ }, options, root);
263
+ }