agentera 3.0.0-dev.7 → 3.0.0-dev.72
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.
- package/LICENSE +201 -0
- package/README.md +118 -22
- package/bundle/CHANGELOG.md +1361 -0
- package/bundle/DESIGN.md +229 -0
- package/bundle/LICENSE +201 -0
- package/bundle/README.md +143 -0
- package/bundle/UPGRADE.md +252 -0
- package/bundle/extract-corpus-parity.json +2 -4
- package/bundle/fixtures/routing/hybrid-corpus.yaml +154 -0
- package/bundle/references/adapters/package-publication.json +488 -0
- package/bundle/references/adapters/package-registry.yaml +435 -188
- package/bundle/references/adapters/package-surface-characterization.md +66 -34
- package/bundle/references/adapters/runtime-lifecycle-adapters.yaml +74 -0
- package/bundle/references/adapters/runtime-lifecycle-authority.yaml +62 -0
- package/bundle/references/adapters/runtime-lifecycle-operation-contract.yaml +84 -0
- package/bundle/references/adapters/runtime-retired-resources.yaml +333 -0
- package/bundle/references/analysis/evidence-tier-authority.yaml +518 -0
- package/bundle/references/analysis/verification-policy.yaml +266 -0
- package/bundle/references/artifacts/artifact-registry-interface-model.yaml +17 -8
- package/bundle/references/artifacts/glossary-entry-contract.yaml +1254 -0
- package/bundle/references/artifacts/state-storage-authority.yaml +3061 -0
- package/bundle/references/artifacts/verbosity-budget-authority.yaml +42 -0
- package/bundle/references/cli/app-lifecycle-vocabulary.yaml +3 -4
- package/bundle/references/cli/capability-instruction-contract.yaml +11 -14
- package/bundle/references/cli/hybrid-route-contract.yaml +438 -0
- package/bundle/references/cli/routing-model.md +152 -93
- package/bundle/references/cli/trigger-schema-enrichment.md +57 -46
- package/bundle/references/cli/update-channels.yaml +4 -2
- package/bundle/references/cli/vocabulary-index.yaml +5 -7
- package/bundle/references/cli/vocabulary.md +51 -93
- package/bundle/references/meta/retained-reference-authority.yaml +151 -0
- package/bundle/skills/agentera/SKILL.md +183 -63
- package/bundle/skills/agentera/capabilities/audit/schemas/artifacts.yaml +27 -19
- package/bundle/skills/agentera/capabilities/audit/schemas/exit.yaml +2 -2
- package/bundle/skills/agentera/capabilities/audit/schemas/triggers.yaml +13 -35
- package/bundle/skills/agentera/capabilities/audit/schemas/validation.yaml +30 -11
- package/bundle/skills/agentera/capabilities/build/schemas/artifacts.yaml +44 -21
- package/bundle/skills/agentera/capabilities/build/schemas/exit.yaml +8 -6
- package/bundle/skills/agentera/capabilities/build/schemas/triggers.yaml +14 -36
- package/bundle/skills/agentera/capabilities/build/schemas/validation.yaml +95 -21
- package/bundle/skills/agentera/capabilities/design/schemas/artifacts.yaml +6 -6
- package/bundle/skills/agentera/capabilities/design/schemas/exit.yaml +5 -5
- package/bundle/skills/agentera/capabilities/design/schemas/triggers.yaml +5 -34
- package/bundle/skills/agentera/capabilities/design/schemas/validation.yaml +2 -2
- package/bundle/skills/agentera/capabilities/discuss/schemas/artifacts.yaml +17 -13
- package/bundle/skills/agentera/capabilities/discuss/schemas/exit.yaml +2 -2
- package/bundle/skills/agentera/capabilities/discuss/schemas/triggers.yaml +6 -40
- package/bundle/skills/agentera/capabilities/discuss/schemas/validation.yaml +72 -5
- package/bundle/skills/agentera/capabilities/document/schemas/artifacts.yaml +24 -17
- package/bundle/skills/agentera/capabilities/document/schemas/triggers.yaml +5 -35
- package/bundle/skills/agentera/capabilities/document/schemas/validation.yaml +13 -13
- package/bundle/skills/agentera/capabilities/optimize/schemas/artifacts.yaml +10 -10
- package/bundle/skills/agentera/capabilities/optimize/schemas/exit.yaml +2 -2
- package/bundle/skills/agentera/capabilities/optimize/schemas/triggers.yaml +4 -35
- package/bundle/skills/agentera/capabilities/optimize/schemas/validation.yaml +3 -3
- package/bundle/skills/agentera/capabilities/orchestrate/schemas/artifacts.yaml +34 -22
- package/bundle/skills/agentera/capabilities/orchestrate/schemas/exit.yaml +9 -7
- package/bundle/skills/agentera/capabilities/orchestrate/schemas/triggers.yaml +5 -37
- package/bundle/skills/agentera/capabilities/orchestrate/schemas/validation.yaml +38 -37
- package/bundle/skills/agentera/capabilities/plan/schemas/artifacts.yaml +20 -16
- package/bundle/skills/agentera/capabilities/plan/schemas/triggers.yaml +8 -31
- package/bundle/skills/agentera/capabilities/plan/schemas/validation.yaml +66 -6
- package/bundle/skills/agentera/capabilities/profile/schemas/artifacts.yaml +9 -4
- package/bundle/skills/agentera/capabilities/profile/schemas/exit.yaml +4 -4
- package/bundle/skills/agentera/capabilities/profile/schemas/triggers.yaml +8 -37
- package/bundle/skills/agentera/capabilities/profile/schemas/validation.yaml +61 -3
- package/bundle/skills/agentera/capabilities/research/schemas/artifacts.yaml +6 -6
- package/bundle/skills/agentera/capabilities/research/schemas/triggers.yaml +5 -29
- package/bundle/skills/agentera/capabilities/status/schemas/artifacts.yaml +13 -12
- package/bundle/skills/agentera/capabilities/status/schemas/triggers.yaml +7 -49
- package/bundle/skills/agentera/capabilities/vision/schemas/artifacts.yaml +8 -8
- package/bundle/skills/agentera/capabilities/vision/schemas/exit.yaml +7 -6
- package/bundle/skills/agentera/capabilities/vision/schemas/triggers.yaml +7 -39
- package/bundle/skills/agentera/capabilities/vision/schemas/validation.yaml +14 -16
- package/bundle/skills/agentera/capability_schema_contract.yaml +32 -32
- package/bundle/skills/agentera/protocol.yaml +4 -4
- package/bundle/skills/agentera/route-phrases.yaml +81 -0
- package/bundle/skills/agentera/schemas/artifacts/changelog.yaml +1 -0
- package/bundle/skills/agentera/schemas/artifacts/decisions.yaml +30 -12
- package/bundle/skills/agentera/schemas/artifacts/design.yaml +1 -0
- package/bundle/skills/agentera/schemas/artifacts/docs.yaml +7 -12
- package/bundle/skills/agentera/schemas/artifacts/experiments.yaml +140 -9
- package/bundle/skills/agentera/schemas/artifacts/glossary.yaml +82 -0
- package/bundle/skills/agentera/schemas/artifacts/health.yaml +56 -19
- package/bundle/skills/agentera/schemas/artifacts/objective.yaml +18 -4
- package/bundle/skills/agentera/schemas/artifacts/plan.yaml +457 -32
- package/bundle/skills/agentera/schemas/artifacts/progress.yaml +131 -18
- package/bundle/skills/agentera/schemas/artifacts/todo.yaml +302 -7
- package/dist/analytics/extractCorpus/cli.js +52 -11
- package/dist/analytics/extractCorpus/copilotSessions.js +6 -4
- package/dist/analytics/extractCorpus/core.js +40 -12
- package/dist/analytics/extractCorpus/corpus.js +39 -17
- package/dist/analytics/extractCorpus/coverageAudit.js +44 -45
- package/dist/analytics/extractCorpus/cursorSessions.js +6 -4
- package/dist/analytics/extractCorpus/evidenceTiers.js +603 -0
- package/dist/analytics/extractCorpus/extractCorpusParity.js +4 -4
- package/dist/analytics/extractCorpus/filesystemSources.js +1 -5
- package/dist/analytics/extractCorpus/index.js +3 -1
- package/dist/analytics/extractCorpus/jsonlSessions.js +24 -5
- package/dist/analytics/extractCorpus/sqliteCaps.js +0 -1
- package/dist/analytics/extractCorpus/sqliteSessions.js +0 -1
- package/dist/analytics/extractCorpus/tierReader.js +108 -0
- package/dist/analytics/extractCorpus.js +0 -1
- package/dist/analytics/glossaryAdviceResolution.js +166 -0
- package/dist/analytics/glossaryInputAcquisition.js +319 -0
- package/dist/analytics/personalGlossaryAdmission.js +133 -0
- package/dist/analytics/personalGlossaryProfile.js +219 -0
- package/dist/analytics/profileSignals.js +211 -0
- package/dist/analytics/usageStats.js +150 -23
- package/dist/audit/terminologyDrift.js +281 -0
- package/dist/bin/agentera.js +3 -2
- package/dist/capabilities/audit/instructions.js +16 -6
- package/dist/capabilities/build/instructions.js +59 -6
- package/dist/capabilities/design/instructions.js +3 -4
- package/dist/capabilities/discuss/instructions.js +29 -6
- package/dist/capabilities/document/instructions.js +11 -6
- package/dist/capabilities/index.js +16 -14
- package/dist/capabilities/optimize/instructions.js +14 -6
- package/dist/capabilities/orchestrate/instructions.js +42 -6
- package/dist/capabilities/plan/instructions.js +30 -3
- package/dist/capabilities/profile/instructions.js +70 -6
- package/dist/capabilities/research/instructions.js +4 -5
- package/dist/capabilities/status/instructions.js +15 -6
- package/dist/capabilities/status/startupInstructions.js +34 -0
- package/dist/capabilities/vision/instructions.js +3 -5
- package/dist/cli/appContext.js +14 -7
- package/dist/cli/argvalidate.js +0 -1
- package/dist/cli/capabilityContext/benchmark.js +5 -4
- package/dist/cli/capabilityContext/bespoke.js +14 -6
- package/dist/cli/capabilityContext/build.js +116 -42
- package/dist/cli/capabilityContext/closeout.js +30 -27
- package/dist/cli/capabilityContext/contract.js +18 -27
- package/dist/cli/capabilityContext/evidence.js +84 -77
- package/dist/cli/capabilityContext/index.js +0 -1
- package/dist/cli/capabilityContext/orchestration.js +42 -18
- package/dist/cli/capabilityContext/planState.js +89 -96
- package/dist/cli/capabilityContext/progress.js +51 -12
- package/dist/cli/capabilityContext/projectVerification.js +409 -0
- package/dist/cli/capabilityContext/shared.js +9 -20
- package/dist/cli/capabilityContext/slim.js +52 -8
- package/dist/cli/capabilityContext/startup.js +51 -114
- package/dist/cli/capabilityContext/startupAggregation.js +68 -0
- package/dist/cli/capabilityContext/types.js +26 -10
- package/dist/cli/capabilityContext.js +0 -1
- package/dist/cli/commands/appHome.js +0 -1
- package/dist/cli/commands/capability.js +2 -2
- package/dist/cli/commands/compact.js +163 -13
- package/dist/cli/commands/doctor.js +117 -11
- package/dist/cli/commands/durability.js +81 -0
- package/dist/cli/commands/glossaryAdvice.js +138 -0
- package/dist/cli/commands/lint.js +22 -8
- package/dist/cli/commands/personalGlossary.js +176 -0
- package/dist/cli/commands/prime/briefOrientation.js +746 -0
- package/dist/cli/commands/prime/buildExecutionRequest.js +165 -0
- package/dist/cli/commands/prime/bundleStatus.js +54 -4
- package/dist/cli/commands/prime/collectEntityOrientation.js +326 -0
- package/dist/cli/commands/prime/collectOrientationState.js +126 -63
- package/dist/cli/commands/prime/orientationOutput.js +267 -56
- package/dist/cli/commands/prime/types.js +0 -1
- package/dist/cli/commands/prime/v1Migration.js +0 -1
- package/dist/cli/commands/prime.js +76 -11
- package/dist/cli/commands/profileGrounding.js +55 -0
- package/dist/cli/commands/query.js +74 -52
- package/dist/cli/commands/report.js +73 -19
- package/dist/cli/commands/route.js +142 -0
- package/dist/cli/commands/schema.js +257 -138
- package/dist/cli/commands/state/decisions.js +40 -56
- package/dist/cli/commands/state/docs.js +58 -85
- package/dist/cli/commands/state/experimentRecords.js +151 -0
- package/dist/cli/commands/state/experiments.js +11 -65
- package/dist/cli/commands/state/get.js +129 -0
- package/dist/cli/commands/state/health.js +11 -113
- package/dist/cli/commands/state/index.js +6 -41
- package/dist/cli/commands/state/list.js +194 -0
- package/dist/cli/commands/state/objective.js +21 -65
- package/dist/cli/commands/state/plan.js +11 -170
- package/dist/cli/commands/state/planTasks.js +154 -0
- package/dist/cli/commands/state/plans.js +154 -0
- package/dist/cli/commands/state/progress.js +11 -45
- package/dist/cli/commands/state/shared.js +0 -1
- package/dist/cli/commands/state/todo.js +28 -107
- package/dist/cli/commands/state/write.js +433 -0
- package/dist/cli/commands/upgrade.js +146 -5
- package/dist/cli/commands/upgradeVerify.js +118 -0
- package/dist/cli/commands/validate.js +235 -136
- package/dist/cli/commands/verify.js +23 -8
- package/dist/cli/contracts/bundleStatus.js +0 -1
- package/dist/cli/contracts/orientationState.js +0 -1
- package/dist/cli/dispatch/argvParser.js +0 -1
- package/dist/cli/dispatch/check.js +84 -40
- package/dist/cli/dispatch/commands.js +3 -3
- package/dist/cli/dispatch/index.js +77 -52
- package/dist/cli/dispatch/lifecycle.js +117 -62
- package/dist/cli/dispatch/prime.js +37 -2
- package/dist/cli/dispatch/projections.js +17 -0
- package/dist/cli/dispatch/shared.js +1 -2
- package/dist/cli/dispatch/state.js +62 -66
- package/dist/cli/dispatch.js +0 -1
- package/dist/cli/errors.js +16 -17
- package/dist/cli/help.js +358 -39
- package/dist/cli/migrationRequired.js +122 -0
- package/dist/cli/orientation/attention.js +19 -19
- package/dist/cli/orientation/corpusCoverage.js +32 -1
- package/dist/cli/orientation.js +346 -129
- package/dist/cli/planArtifacts.js +350 -0
- package/dist/cli/planEvidence.js +157 -0
- package/dist/cli/planLifecycleState.js +36 -0
- package/dist/cli/planTaskIndex.js +11 -0
- package/dist/cli/preCutoverCommand.js +32 -0
- package/dist/cli/prime-blob.js +71 -3
- package/dist/cli/profileAcquisition.js +167 -0
- package/dist/cli/startupCompletenessContract.js +11 -8
- package/dist/cli/stateQuery.js +47 -12
- package/dist/cli/structured.js +0 -1
- package/dist/cli/todoMarkdown.js +25 -12
- package/dist/cli/todoReadinessSelection.js +192 -0
- package/dist/cli/todoSeverity.js +0 -1
- package/dist/core/atomicWriter.js +20 -0
- package/dist/core/developmentChannel.js +1 -0
- package/dist/core/developmentInvocation.js +374 -0
- package/dist/core/difflib.js +0 -1
- package/dist/core/envPaths.js +0 -1
- package/dist/core/jsonValue.js +0 -1
- package/dist/core/paths.js +0 -1
- package/dist/core/pyjson.js +0 -1
- package/dist/core/shell.js +4 -0
- package/dist/core/skillIdentity.js +23 -0
- package/dist/core/sourceRoot.js +9 -12
- package/dist/core/text.js +10 -0
- package/dist/core/toml.js +0 -1
- package/dist/core/yaml.js +8 -1
- package/dist/eval/evalSkills.js +13 -14
- package/dist/eval/hybridRouteEvaluation.js +155 -0
- package/dist/eval/semanticEval.js +0 -1
- package/dist/eval/semanticFixtures.js +0 -1
- package/dist/hooks/common.js +3 -56
- package/dist/hooks/compaction/apply.js +224 -47
- package/dist/hooks/compaction/dryRun.js +2 -1
- package/dist/hooks/compaction/index.js +5 -6
- package/dist/hooks/compaction/parse.js +73 -6
- package/dist/hooks/compaction/retention.js +28 -25
- package/dist/hooks/compaction/status.js +145 -26
- package/dist/hooks/compaction/types.js +0 -1
- package/dist/hooks/validateArtifact/agentFacing.js +0 -1
- package/dist/hooks/validateArtifact/index.js +6 -65
- package/dist/hooks/validateArtifact/markdown.js +9 -10
- package/dist/hooks/validateArtifact/schema.js +96 -9
- package/dist/hooks/validateArtifact/traversal.js +12 -11
- package/dist/hooks/validateArtifact/violations.js +5 -3
- package/dist/migrate/v2HandoffManifest.js +8 -3
- package/dist/registries/activationContract.js +2 -0
- package/dist/registries/activationTuples.js +108 -0
- package/dist/registries/artifactProtocolIds.js +2 -1
- package/dist/registries/artifactRegistry.js +207 -60
- package/dist/registries/artifactSchemaProjection.js +45 -0
- package/dist/registries/capabilityContract.js +5 -21
- package/dist/registries/evaluatorHandoffContract.js +0 -1
- package/dist/registries/evidenceTierContract.js +371 -0
- package/dist/registries/glossaryAdviceContract.js +79 -0
- package/dist/registries/glossaryCaveatContract.js +67 -0
- package/dist/registries/glossaryConsumerContractValidation.js +787 -0
- package/dist/registries/glossaryEntryContract.js +757 -0
- package/dist/registries/glossaryTermIdentity.js +17 -0
- package/dist/registries/glossaryTermOccurrence.js +20 -0
- package/dist/registries/hybridRoute.js +274 -0
- package/dist/registries/hybridRouteReceipt.js +221 -0
- package/dist/registries/packagePublication.js +273 -0
- package/dist/registries/packageRegistry.js +184 -209
- package/dist/registries/todoReadinessContract.js +448 -0
- package/dist/registries/triggerLoader.js +7 -44
- package/dist/registries/verbosityBudgetContract.js +205 -0
- package/dist/release/releaseMetadata.js +155 -5
- package/dist/runtime/lifecycleAdapterContract.js +457 -0
- package/dist/runtime/lifecycleAdapters.js +777 -0
- package/dist/runtime/lifecycleAuthority.js +453 -0
- package/dist/runtime/lifecycleOperationContract.js +123 -0
- package/dist/runtime/lifecycleOperations.js +634 -0
- package/dist/runtime/lifecycleOwnershipJournal.js +622 -0
- package/dist/runtime/lifecyclePublication.js +415 -0
- package/dist/runtime/lifecycleSnapshot.js +438 -0
- package/dist/runtime/nativeResourceCleanup.js +502 -0
- package/dist/setup/opencode.js +20 -13
- package/dist/setup/opencodeConstants.js +1 -0
- package/dist/setup/sharedSkill.js +45 -0
- package/dist/setup/smokeChecks.js +14 -75
- package/dist/state/archiveDiscovery.js +580 -0
- package/dist/state/archivePublication.js +225 -0
- package/dist/state/archiveRecovery.js +237 -0
- package/dist/state/archiveReplay.js +53 -0
- package/dist/state/canonicalMigrationRecord.js +36 -0
- package/dist/state/changelog.js +221 -0
- package/dist/state/decisionEntities.js +367 -0
- package/dist/state/decisionLegacyValidation.js +215 -0
- package/dist/state/decisionMigrationProvenance.js +199 -0
- package/dist/state/decisionOverlay.js +254 -0
- package/dist/state/decisionRevision.js +256 -0
- package/dist/state/decisionRevisionMigration.js +89 -0
- package/dist/state/directRetrieval.js +323 -0
- package/dist/state/durability.js +324 -0
- package/dist/state/entityCutover.js +459 -0
- package/dist/state/entityCutoverGit.js +127 -0
- package/dist/state/entityGlossaryAuthority.js +13 -0
- package/dist/state/entityListProjection.js +187 -0
- package/dist/state/entityListRuntimeRegistry.js +85 -0
- package/dist/state/entityMigrationCausality.js +97 -0
- package/dist/state/entityMigrationIdentity.js +5 -0
- package/dist/state/entityMigrationPreview.js +840 -0
- package/dist/state/entityMigrationTodo.js +133 -0
- package/dist/state/entityPublicationContext.js +859 -0
- package/dist/state/entityRetrievalHelp.js +506 -0
- package/dist/state/entityStorage.js +899 -0
- package/dist/state/exactReplacementRecovery.js +18 -0
- package/dist/state/experimentArchive.js +63 -0
- package/dist/state/experimentIdentity.js +202 -0
- package/dist/state/healthEntities.js +262 -0
- package/dist/state/healthEntityValidation.js +18 -0
- package/dist/state/healthRepair.js +69 -0
- package/dist/state/installRoot.js +15 -7
- package/dist/state/legacyEntityCutoverEvidence.js +65 -0
- package/dist/state/legacyIdentity.js +47 -0
- package/dist/state/legacySummaryRecord.js +6 -0
- package/dist/state/listAccounting.js +54 -0
- package/dist/state/listClassification.js +17 -0
- package/dist/state/listCursor.js +42 -0
- package/dist/state/listRetrieval.js +781 -0
- package/dist/state/migrationSourceBinding.js +30 -0
- package/dist/state/objectiveExperimentEntities.js +322 -0
- package/dist/state/planEntities.js +1027 -0
- package/dist/state/planIdentity.js +47 -0
- package/dist/state/planLineageValidation.js +52 -0
- package/dist/state/planReplacementTransaction.js +475 -0
- package/dist/state/planRetrieval.js +313 -0
- package/dist/state/planTaskRetrieval.js +294 -0
- package/dist/state/progressEntities.js +512 -0
- package/dist/state/progressGlossaryCaveat.js +168 -0
- package/dist/state/progressPublicationOrder.js +19 -0
- package/dist/state/progressWritePolicy.js +33 -0
- package/dist/state/projectRoot.js +62 -0
- package/dist/state/projectionPolicy.js +190 -0
- package/dist/state/retrievalAuthority.js +156 -0
- package/dist/state/safeProjectFile.js +155 -0
- package/dist/state/startupAnalysis/benchmark.js +70 -9
- package/dist/state/startupAnalysis/contract.js +44 -10
- package/dist/state/startupAnalysis/helpers.js +1 -2
- package/dist/state/startupAnalysis/index.js +0 -1
- package/dist/state/startupAnalysis/metrics.js +0 -1
- package/dist/state/startupAnalysis/records.js +0 -1
- package/dist/state/startupAnalysis/report.js +0 -1
- package/dist/state/startupAnalysis/threshold.js +13 -1
- package/dist/state/startupAnalysis.js +0 -1
- package/dist/state/startupProjection.js +499 -0
- package/dist/state/stateMode.js +222 -0
- package/dist/state/stateStorageAuthority.js +47 -0
- package/dist/state/summaryEntityRead.js +25 -0
- package/dist/state/summaryMigrationProvenance.js +66 -0
- package/dist/state/summarySourceRowAuthority.js +36 -0
- package/dist/state/todoActivationSafety.js +58 -0
- package/dist/state/todoDocsEntities.js +1124 -0
- package/dist/state/todoDocsEntityValidation.js +158 -0
- package/dist/state/todoMarkdownProjection.js +51 -0
- package/dist/state/todoReconciliationActivation.js +182 -0
- package/dist/state/todoReconciliationInspection.js +171 -0
- package/dist/state/todoReconciliationRepair.js +318 -0
- package/dist/state/todoReconciliationTransaction.js +595 -0
- package/dist/state/write/assign.js +20 -0
- package/dist/state/write/candidateMutation.js +269 -0
- package/dist/state/write/errors.js +11 -0
- package/dist/state/write/experimentPublication.js +192 -0
- package/dist/state/write/explain.js +377 -0
- package/dist/state/write/fields.js +61 -0
- package/dist/state/write/glossaryPublication.js +263 -0
- package/dist/state/write/grammar.js +285 -0
- package/dist/state/write/helpers.js +29 -0
- package/dist/state/write/index.js +12 -0
- package/dist/state/write/input.js +391 -0
- package/dist/state/write/lock.js +837 -0
- package/dist/state/write/mutation.js +234 -0
- package/dist/state/write/operations.js +170 -0
- package/dist/state/write/planEvaluation.js +128 -0
- package/dist/state/write/planPublication.js +179 -0
- package/dist/state/write/runtimeOperations.js +146 -0
- package/dist/state/write/serialize.js +1 -0
- package/dist/state/write/transaction.js +57 -0
- package/dist/state/write/validate.js +7 -0
- package/dist/upgrade/appContentRefresh.js +77 -36
- package/dist/upgrade/appModel.js +0 -1
- package/dist/upgrade/atomicWriter.js +1 -0
- package/dist/upgrade/bundleEvidence.js +0 -1
- package/dist/upgrade/channels.js +6 -9
- package/dist/upgrade/compatibility.js +43 -17
- package/dist/upgrade/doctor.js +55 -32
- package/dist/upgrade/doctorClassifier.js +11 -1
- package/dist/upgrade/installedHooksRetirement.js +46 -40
- package/dist/upgrade/legacyAgentCleanup.js +187 -21
- package/dist/upgrade/lifecycleUpgrade.js +113 -0
- package/dist/upgrade/migrateArtifactsV2ToV3.js +334 -64
- package/dist/upgrade/migrationPublication.js +122 -0
- package/dist/upgrade/nextMajorDoctor.js +0 -1
- package/dist/upgrade/npxPlatformStatus.js +0 -1
- package/dist/upgrade/projectIntegration.js +121 -159
- package/dist/upgrade/projectIntegrationDecision.js +42 -85
- package/dist/upgrade/retiredResourceDiagnostics.js +117 -0
- package/dist/upgrade/runtimeMigration.js +262 -453
- package/dist/upgrade/upgradeCommands.js +14 -1
- package/dist/upgrade/upgradeLock.js +85 -0
- package/dist/upgrade/upgradeOrchestrator.js +263 -59
- package/dist/upgrade/v3CapabilitySurface.js +2 -3
- package/dist/upgrade/versionResolution.js +0 -1
- package/dist/validate/activationArtifactEvidence.js +852 -0
- package/dist/validate/activationArtifactEvidenceTypes.js +12 -0
- package/dist/validate/activationConjunction.js +816 -0
- package/dist/validate/activationEvidenceManifest.js +531 -0
- package/dist/validate/activationPackageSemantics.js +29 -0
- package/dist/validate/appHomeContract.js +1 -7
- package/dist/validate/bootstrapAuthority.js +44 -0
- package/dist/validate/capability.js +11 -3
- package/dist/validate/crossCapability.js +14 -9
- package/dist/validate/retainedReferenceAuthority.js +879 -0
- package/dist/validate/selfAudit.js +39 -45
- package/dist/validate/v1LegacyCruft.js +131 -0
- package/dist/validate/vocabularyAuthority.js +8 -8
- package/package.json +41 -13
- package/bundle/references/adapters/cursor.md +0 -214
- package/bundle/references/adapters/opencode.md +0 -530
- package/bundle/references/adapters/package-manifest-interface-model.yaml +0 -337
- package/bundle/references/adapters/runtime-adapter-characterization.md +0 -79
- package/bundle/references/adapters/runtime-adapter-interface-model.yaml +0 -200
- package/bundle/references/adapters/runtime-adapter-registry.yaml +0 -554
- package/bundle/references/adapters/runtime-feature-parity.md +0 -189
- package/bundle/references/analysis/benchmark.md +0 -267
- package/bundle/references/analysis/startup-measurement-contract.yaml +0 -424
- package/bundle/references/cli/agent-ready-state-contract.yaml +0 -953
- package/bundle/references/cli/audience-namespace-cli-migration.yaml +0 -369
- package/bundle/references/cli/bundle-skill-vocabulary.yaml +0 -250
- package/bundle/references/cli/capability-tool-classification.yaml +0 -53
- package/bundle/references/cli/coexistence-probe.yaml +0 -13
- package/bundle/references/cli/parity-expected-actual-template.md +0 -30
- package/bundle/references/cli/routing-execution-vocabulary.yaml +0 -281
- package/bundle/references/cli/single-name-protocol.yaml +0 -42
- package/bundle/references/cli/upgrade-repair-wording.md +0 -45
- package/bundle/references/cli/v3-handoff-manifest.schema.yaml +0 -98
- package/bundle/references/meta/documentation-inventory.md +0 -49
- package/bundle/skills/agentera/.claude-plugin/plugin.json +0 -27
- package/bundle/skills/agentera/agents/audit.toml +0 -6
- package/bundle/skills/agentera/agents/build.toml +0 -6
- package/bundle/skills/agentera/agents/design.toml +0 -6
- package/bundle/skills/agentera/agents/discuss.toml +0 -6
- package/bundle/skills/agentera/agents/document.toml +0 -6
- package/bundle/skills/agentera/agents/optimize.toml +0 -6
- package/bundle/skills/agentera/agents/orchestrate.toml +0 -6
- package/bundle/skills/agentera/agents/plan.toml +0 -6
- package/bundle/skills/agentera/agents/profile.toml +0 -6
- package/bundle/skills/agentera/agents/research.toml +0 -6
- package/bundle/skills/agentera/agents/status.toml +0 -6
- package/bundle/skills/agentera/agents/vision.toml +0 -6
- package/bundle/skills/agentera/references/contract.md +0 -1048
- package/dist/analytics/extractCorpus/cli.js.map +0 -1
- package/dist/analytics/extractCorpus/copilotSessions.js.map +0 -1
- package/dist/analytics/extractCorpus/core.js.map +0 -1
- package/dist/analytics/extractCorpus/corpus.js.map +0 -1
- package/dist/analytics/extractCorpus/coverageAudit.js.map +0 -1
- package/dist/analytics/extractCorpus/cursorSessions.js.map +0 -1
- package/dist/analytics/extractCorpus/extractCorpusParity.js.map +0 -1
- package/dist/analytics/extractCorpus/filesystemSources.js.map +0 -1
- package/dist/analytics/extractCorpus/index.js.map +0 -1
- package/dist/analytics/extractCorpus/jsonlSessions.js.map +0 -1
- package/dist/analytics/extractCorpus/sqliteCaps.js.map +0 -1
- package/dist/analytics/extractCorpus/sqliteSessions.js.map +0 -1
- package/dist/analytics/extractCorpus.js.map +0 -1
- package/dist/analytics/usageStats.js.map +0 -1
- package/dist/bin/agentera.js.map +0 -1
- package/dist/capabilities/audit/instructions.js.map +0 -1
- package/dist/capabilities/build/instructions.js.map +0 -1
- package/dist/capabilities/design/instructions.js.map +0 -1
- package/dist/capabilities/discuss/instructions.js.map +0 -1
- package/dist/capabilities/document/instructions.js.map +0 -1
- package/dist/capabilities/dokumentera/instructions.js +0 -6
- package/dist/capabilities/dokumentera/instructions.js.map +0 -1
- package/dist/capabilities/hej/instructions.js +0 -6
- package/dist/capabilities/hej/instructions.js.map +0 -1
- package/dist/capabilities/index.js.map +0 -1
- package/dist/capabilities/inspektera/instructions.js +0 -6
- package/dist/capabilities/inspektera/instructions.js.map +0 -1
- package/dist/capabilities/inspirera/instructions.js +0 -6
- package/dist/capabilities/inspirera/instructions.js.map +0 -1
- package/dist/capabilities/optimera/instructions.js +0 -6
- package/dist/capabilities/optimera/instructions.js.map +0 -1
- package/dist/capabilities/optimize/instructions.js.map +0 -1
- package/dist/capabilities/orchestrate/instructions.js.map +0 -1
- package/dist/capabilities/orkestrera/instructions.js +0 -6
- package/dist/capabilities/orkestrera/instructions.js.map +0 -1
- package/dist/capabilities/plan/instructions.js.map +0 -1
- package/dist/capabilities/planera/instructions.js +0 -6
- package/dist/capabilities/planera/instructions.js.map +0 -1
- package/dist/capabilities/profile/instructions.js.map +0 -1
- package/dist/capabilities/profilera/instructions.js +0 -6
- package/dist/capabilities/profilera/instructions.js.map +0 -1
- package/dist/capabilities/realisera/instructions.js +0 -6
- package/dist/capabilities/realisera/instructions.js.map +0 -1
- package/dist/capabilities/research/instructions.js.map +0 -1
- package/dist/capabilities/resonera/instructions.js +0 -6
- package/dist/capabilities/resonera/instructions.js.map +0 -1
- package/dist/capabilities/status/instructions.js.map +0 -1
- package/dist/capabilities/vision/instructions.js.map +0 -1
- package/dist/capabilities/visionera/instructions.js +0 -6
- package/dist/capabilities/visionera/instructions.js.map +0 -1
- package/dist/capabilities/visualisera/instructions.js +0 -5
- package/dist/capabilities/visualisera/instructions.js.map +0 -1
- package/dist/cli/appContext.js.map +0 -1
- package/dist/cli/argvalidate.js.map +0 -1
- package/dist/cli/capabilityContext/benchmark.js.map +0 -1
- package/dist/cli/capabilityContext/bespoke.js.map +0 -1
- package/dist/cli/capabilityContext/build.js.map +0 -1
- package/dist/cli/capabilityContext/closeout.js.map +0 -1
- package/dist/cli/capabilityContext/contract.js.map +0 -1
- package/dist/cli/capabilityContext/evidence.js.map +0 -1
- package/dist/cli/capabilityContext/index.js.map +0 -1
- package/dist/cli/capabilityContext/orchestration.js.map +0 -1
- package/dist/cli/capabilityContext/planState.js.map +0 -1
- package/dist/cli/capabilityContext/progress.js.map +0 -1
- package/dist/cli/capabilityContext/realisera.js +0 -174
- package/dist/cli/capabilityContext/realisera.js.map +0 -1
- package/dist/cli/capabilityContext/shared.js.map +0 -1
- package/dist/cli/capabilityContext/slim.js.map +0 -1
- package/dist/cli/capabilityContext/startup.js.map +0 -1
- package/dist/cli/capabilityContext/types.js.map +0 -1
- package/dist/cli/capabilityContext.js.map +0 -1
- package/dist/cli/commands/appHome.js.map +0 -1
- package/dist/cli/commands/backfill.js +0 -84
- package/dist/cli/commands/backfill.js.map +0 -1
- package/dist/cli/commands/capability.js.map +0 -1
- package/dist/cli/commands/compact.js.map +0 -1
- package/dist/cli/commands/doctor.js.map +0 -1
- package/dist/cli/commands/lint.js.map +0 -1
- package/dist/cli/commands/prime/bundleStatus.js.map +0 -1
- package/dist/cli/commands/prime/collectOrientationState.js.map +0 -1
- package/dist/cli/commands/prime/orientationOutput.js.map +0 -1
- package/dist/cli/commands/prime/routeOutput.js +0 -50
- package/dist/cli/commands/prime/routeOutput.js.map +0 -1
- package/dist/cli/commands/prime/types.js.map +0 -1
- package/dist/cli/commands/prime/v1Migration.js.map +0 -1
- package/dist/cli/commands/prime.js.map +0 -1
- package/dist/cli/commands/query.js.map +0 -1
- package/dist/cli/commands/report.js.map +0 -1
- package/dist/cli/commands/schema.js.map +0 -1
- package/dist/cli/commands/state/decisions.js.map +0 -1
- package/dist/cli/commands/state/docs.js.map +0 -1
- package/dist/cli/commands/state/experiments.js.map +0 -1
- package/dist/cli/commands/state/health.js.map +0 -1
- package/dist/cli/commands/state/index.js.map +0 -1
- package/dist/cli/commands/state/objective.js.map +0 -1
- package/dist/cli/commands/state/plan.js.map +0 -1
- package/dist/cli/commands/state/progress.js.map +0 -1
- package/dist/cli/commands/state/shared.js.map +0 -1
- package/dist/cli/commands/state/todo.js.map +0 -1
- package/dist/cli/commands/state.js +0 -1023
- package/dist/cli/commands/state.js.map +0 -1
- package/dist/cli/commands/upgrade.js.map +0 -1
- package/dist/cli/commands/validate.js.map +0 -1
- package/dist/cli/commands/verify.js.map +0 -1
- package/dist/cli/contracts/bundleStatus.js.map +0 -1
- package/dist/cli/contracts/orientationState.js.map +0 -1
- package/dist/cli/dispatch/argvParser.js.map +0 -1
- package/dist/cli/dispatch/check.js.map +0 -1
- package/dist/cli/dispatch/commands.js.map +0 -1
- package/dist/cli/dispatch/index.js.map +0 -1
- package/dist/cli/dispatch/lifecycle.js.map +0 -1
- package/dist/cli/dispatch/prime.js.map +0 -1
- package/dist/cli/dispatch/shared.js.map +0 -1
- package/dist/cli/dispatch/state.js.map +0 -1
- package/dist/cli/dispatch.js.map +0 -1
- package/dist/cli/errors.js.map +0 -1
- package/dist/cli/help.js.map +0 -1
- package/dist/cli/orientation/attention.js.map +0 -1
- package/dist/cli/orientation/corpusCoverage.js.map +0 -1
- package/dist/cli/orientation.js.map +0 -1
- package/dist/cli/prime-blob.js.map +0 -1
- package/dist/cli/startupCompletenessContract.js.map +0 -1
- package/dist/cli/stateQuery.js.map +0 -1
- package/dist/cli/structured.js.map +0 -1
- package/dist/cli/todoMarkdown.js.map +0 -1
- package/dist/cli/todoSeverity.js.map +0 -1
- package/dist/core/difflib.js.map +0 -1
- package/dist/core/envPaths.js.map +0 -1
- package/dist/core/git.js +0 -43
- package/dist/core/git.js.map +0 -1
- package/dist/core/jsonValue.js.map +0 -1
- package/dist/core/paths.js.map +0 -1
- package/dist/core/pyjson.js.map +0 -1
- package/dist/core/sourceRoot.js.map +0 -1
- package/dist/core/toml.js.map +0 -1
- package/dist/core/yaml.js.map +0 -1
- package/dist/eval/evalSkills.js.map +0 -1
- package/dist/eval/semanticEval.js.map +0 -1
- package/dist/eval/semanticFixtures.js.map +0 -1
- package/dist/hooks/common.js.map +0 -1
- package/dist/hooks/compaction/apply.js.map +0 -1
- package/dist/hooks/compaction/dryRun.js.map +0 -1
- package/dist/hooks/compaction/index.js.map +0 -1
- package/dist/hooks/compaction/parse.js.map +0 -1
- package/dist/hooks/compaction/retention.js.map +0 -1
- package/dist/hooks/compaction/status.js.map +0 -1
- package/dist/hooks/compaction/todoResolved.js +0 -137
- package/dist/hooks/compaction/todoResolved.js.map +0 -1
- package/dist/hooks/compaction/types.js.map +0 -1
- package/dist/hooks/compaction.js +0 -935
- package/dist/hooks/compaction.js.map +0 -1
- package/dist/hooks/cursorPreToolUse.js +0 -19
- package/dist/hooks/cursorPreToolUse.js.map +0 -1
- package/dist/hooks/cursorSessionStart.js +0 -79
- package/dist/hooks/cursorSessionStart.js.map +0 -1
- package/dist/hooks/sessionStart.js +0 -216
- package/dist/hooks/sessionStart.js.map +0 -1
- package/dist/hooks/sessionStop.js +0 -206
- package/dist/hooks/sessionStop.js.map +0 -1
- package/dist/hooks/todoLayout.js +0 -177
- package/dist/hooks/todoLayout.js.map +0 -1
- package/dist/hooks/validateArtifact/agentFacing.js.map +0 -1
- package/dist/hooks/validateArtifact/index.js.map +0 -1
- package/dist/hooks/validateArtifact/markdown.js.map +0 -1
- package/dist/hooks/validateArtifact/runtime.js +0 -86
- package/dist/hooks/validateArtifact/runtime.js.map +0 -1
- package/dist/hooks/validateArtifact/schema.js.map +0 -1
- package/dist/hooks/validateArtifact/traversal.js.map +0 -1
- package/dist/hooks/validateArtifact/violations.js.map +0 -1
- package/dist/hooks/validateArtifact.js +0 -924
- package/dist/hooks/validateArtifact.js.map +0 -1
- package/dist/migrate/v2HandoffManifest.js.map +0 -1
- package/dist/registries/artifactProtocolIds.js.map +0 -1
- package/dist/registries/artifactRegistry.js.map +0 -1
- package/dist/registries/capabilityContract.js.map +0 -1
- package/dist/registries/evaluatorHandoffContract.js.map +0 -1
- package/dist/registries/packageRegistry.js.map +0 -1
- package/dist/registries/runtimeAdapterRegistry.js +0 -316
- package/dist/registries/runtimeAdapterRegistry.js.map +0 -1
- package/dist/registries/triggerLoader.js.map +0 -1
- package/dist/release/releaseMetadata.js.map +0 -1
- package/dist/routing/index.js +0 -2
- package/dist/routing/index.js.map +0 -1
- package/dist/routing/routeEngine.js +0 -189
- package/dist/routing/routeEngine.js.map +0 -1
- package/dist/setup/codex/agents.js +0 -96
- package/dist/setup/codex/agents.js.map +0 -1
- package/dist/setup/codex/cli.js +0 -161
- package/dist/setup/codex/cli.js.map +0 -1
- package/dist/setup/codex/configToml.js +0 -639
- package/dist/setup/codex/configToml.js.map +0 -1
- package/dist/setup/codex/constants.js +0 -29
- package/dist/setup/codex/constants.js.map +0 -1
- package/dist/setup/codex/installRoot.js +0 -64
- package/dist/setup/codex/installRoot.js.map +0 -1
- package/dist/setup/codex/state.js +0 -270
- package/dist/setup/codex/state.js.map +0 -1
- package/dist/setup/codex.js +0 -12
- package/dist/setup/codex.js.map +0 -1
- package/dist/setup/copilot.js +0 -227
- package/dist/setup/copilot.js.map +0 -1
- package/dist/setup/cursor.js +0 -129
- package/dist/setup/cursor.js.map +0 -1
- package/dist/setup/cursorSurfaces.js +0 -67
- package/dist/setup/cursorSurfaces.js.map +0 -1
- package/dist/setup/doctor/core.js +0 -300
- package/dist/setup/doctor/core.js.map +0 -1
- package/dist/setup/doctor/diagnostics.js +0 -240
- package/dist/setup/doctor/diagnostics.js.map +0 -1
- package/dist/setup/doctor/opencode.js +0 -313
- package/dist/setup/doctor/opencode.js.map +0 -1
- package/dist/setup/doctor/report.js +0 -425
- package/dist/setup/doctor/report.js.map +0 -1
- package/dist/setup/doctor.js +0 -10
- package/dist/setup/doctor.js.map +0 -1
- package/dist/setup/opencode.js.map +0 -1
- package/dist/setup/smokeChecks.js.map +0 -1
- package/dist/state/installRoot.js.map +0 -1
- package/dist/state/progressCommit.js +0 -289
- package/dist/state/progressCommit.js.map +0 -1
- package/dist/state/startupAnalysis/benchmark.js.map +0 -1
- package/dist/state/startupAnalysis/contract.js.map +0 -1
- package/dist/state/startupAnalysis/helpers.js.map +0 -1
- package/dist/state/startupAnalysis/index.js.map +0 -1
- package/dist/state/startupAnalysis/metrics.js.map +0 -1
- package/dist/state/startupAnalysis/records.js.map +0 -1
- package/dist/state/startupAnalysis/report.js.map +0 -1
- package/dist/state/startupAnalysis/threshold.js.map +0 -1
- package/dist/state/startupAnalysis.js.map +0 -1
- package/dist/upgrade/appContentRefresh.js.map +0 -1
- package/dist/upgrade/appModel.js.map +0 -1
- package/dist/upgrade/bundleEvidence.js.map +0 -1
- package/dist/upgrade/channels.js.map +0 -1
- package/dist/upgrade/cliProbe.js +0 -22
- package/dist/upgrade/cliProbe.js.map +0 -1
- package/dist/upgrade/coexistenceProbe.js +0 -107
- package/dist/upgrade/coexistenceProbe.js.map +0 -1
- package/dist/upgrade/compatibility.js.map +0 -1
- package/dist/upgrade/doctor.js.map +0 -1
- package/dist/upgrade/doctorClassifier.js.map +0 -1
- package/dist/upgrade/installedHooksRetirement.js.map +0 -1
- package/dist/upgrade/legacyAgentCleanup.js.map +0 -1
- package/dist/upgrade/migrateArtifactsV1ToV2.js +0 -570
- package/dist/upgrade/migrateArtifactsV1ToV2.js.map +0 -1
- package/dist/upgrade/migrateArtifactsV2ToV3.js.map +0 -1
- package/dist/upgrade/nextMajorDoctor.js.map +0 -1
- package/dist/upgrade/npxPlatformStatus.js.map +0 -1
- package/dist/upgrade/projectIntegration.js.map +0 -1
- package/dist/upgrade/projectIntegrationDecision.js.map +0 -1
- package/dist/upgrade/runtimeMigration.js.map +0 -1
- package/dist/upgrade/upgradeCommands.js.map +0 -1
- package/dist/upgrade/upgradeOrchestrator.js.map +0 -1
- package/dist/upgrade/v3CapabilitySurface.js.map +0 -1
- package/dist/upgrade/versionResolution.js.map +0 -1
- package/dist/validate/appHomeContract.js.map +0 -1
- package/dist/validate/capability.js.map +0 -1
- package/dist/validate/crossCapability.js.map +0 -1
- package/dist/validate/lifecycleAdapters/legacyPythonParity.js +0 -93
- package/dist/validate/lifecycleAdapters/legacyPythonParity.js.map +0 -1
- package/dist/validate/lifecycleAdapters/nodeFormChecks.js +0 -488
- package/dist/validate/lifecycleAdapters/nodeFormChecks.js.map +0 -1
- package/dist/validate/lifecycleAdapters/shared.js +0 -198
- package/dist/validate/lifecycleAdapters/shared.js.map +0 -1
- package/dist/validate/lifecycleAdapters.js +0 -62
- package/dist/validate/lifecycleAdapters.js.map +0 -1
- package/dist/validate/selfAudit.js.map +0 -1
- package/dist/validate/vocabularyAuthority.js.map +0 -1
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { resolveSourceRoot } from "../core/sourceRoot.js";
|
|
3
|
+
import { loadStateStorageAuthority } from "./stateStorageAuthority.js";
|
|
4
|
+
const EXPECTED_AUTHORITY_SCHEMA = "agentera.stateStorageAuthority.v1";
|
|
5
|
+
function mapping(value) {
|
|
6
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
7
|
+
? value
|
|
8
|
+
: {};
|
|
9
|
+
}
|
|
10
|
+
function requiredString(value, field) {
|
|
11
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
12
|
+
throw new Error(`state storage authority field '${field}' must be a non-empty string`);
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function requiredList(value, field) {
|
|
17
|
+
if (!Array.isArray(value) ||
|
|
18
|
+
value.some((item) => typeof item !== "string" || item.length === 0)) {
|
|
19
|
+
throw new Error(`state storage authority field '${field}' must be a list of non-empty strings`);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function readAuthority(sourceRoot) {
|
|
24
|
+
const authority = loadStateStorageAuthority(sourceRoot).document;
|
|
25
|
+
if (authority.schema_version !== EXPECTED_AUTHORITY_SCHEMA) {
|
|
26
|
+
throw new Error("state storage authority schema_version is unsupported");
|
|
27
|
+
}
|
|
28
|
+
if (authority.status !== "active_authority") {
|
|
29
|
+
throw new Error("state storage authority must be active_authority");
|
|
30
|
+
}
|
|
31
|
+
return authority;
|
|
32
|
+
}
|
|
33
|
+
function overlayCrossCheck(authority) {
|
|
34
|
+
const overlays = mapping(authority.overlays);
|
|
35
|
+
const identityKey = requiredString(overlays.identity_key, "overlays.identity_key");
|
|
36
|
+
const identityPrefix = identityKey.split(":")[0];
|
|
37
|
+
if (!identityPrefix || identityKey !== `${identityPrefix}:<decision-number>`) {
|
|
38
|
+
throw new Error("state storage authority overlays.identity_key is unsupported");
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
identityPrefix,
|
|
42
|
+
mutablePaths: requiredList(overlays.mutable_paths, "overlays.mutable_paths"),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function decisionRevisionContract(sourceRoot = resolveSourceRoot()) {
|
|
46
|
+
const authority = readAuthority(sourceRoot);
|
|
47
|
+
const revisions = mapping(authority.revisions);
|
|
48
|
+
if (Object.keys(revisions).length === 0) {
|
|
49
|
+
throw new Error("state storage authority revisions section is required");
|
|
50
|
+
}
|
|
51
|
+
const location = requiredString(revisions.location, "revisions.location");
|
|
52
|
+
if (path.isAbsolute(location) || location.split(/[\\/]/).some((part) => part === "..")) {
|
|
53
|
+
throw new Error("state storage authority revisions location must be project-relative");
|
|
54
|
+
}
|
|
55
|
+
const identityKey = requiredString(revisions.identity_key, "revisions.identity_key");
|
|
56
|
+
const identityPrefix = identityKey.split(":")[0];
|
|
57
|
+
if (!identityPrefix || identityKey !== `${identityPrefix}:<decision-number>`) {
|
|
58
|
+
throw new Error("state storage authority revisions identity_key is unsupported");
|
|
59
|
+
}
|
|
60
|
+
const overlay = overlayCrossCheck(authority);
|
|
61
|
+
if (identityPrefix !== overlay.identityPrefix) {
|
|
62
|
+
throw new Error("state storage authority revisions identity_key prefix must match the overlay identity");
|
|
63
|
+
}
|
|
64
|
+
const amendablePaths = requiredList(revisions.amendable_paths, "revisions.amendable_paths");
|
|
65
|
+
const legacyAmendablePaths = requiredList(revisions.legacy_amendable_paths, "revisions.legacy_amendable_paths");
|
|
66
|
+
const migrationAmendablePaths = requiredList(revisions.migration_amendable_paths, "revisions.migration_amendable_paths");
|
|
67
|
+
const identityPaths = requiredList(revisions.identity_paths, "revisions.identity_paths");
|
|
68
|
+
const temporalPaths = requiredList(revisions.temporal_paths, "revisions.temporal_paths");
|
|
69
|
+
const reserved = new Set([...identityPaths, ...temporalPaths]);
|
|
70
|
+
for (const [field, paths] of [["amendable_paths", amendablePaths], ["legacy_amendable_paths", legacyAmendablePaths], ["migration_amendable_paths", migrationAmendablePaths]]) {
|
|
71
|
+
for (const amendable of paths) {
|
|
72
|
+
if (reserved.has(amendable)) {
|
|
73
|
+
throw new Error(`state storage authority revisions.${field} must not include identity or temporal path '${amendable}'`);
|
|
74
|
+
}
|
|
75
|
+
if (overlay.mutablePaths.some((mutable) => amendable === mutable || amendable.startsWith(`${mutable}.`))) {
|
|
76
|
+
throw new Error(`state storage authority revisions.${field} must not overlap overlay mutable path '${amendable}'`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
location,
|
|
82
|
+
legacySourceState: requiredString(revisions.legacy_source_state, "revisions.legacy_source_state"),
|
|
83
|
+
schemaVersion: requiredString(revisions.schema_version, "revisions.schema_version"),
|
|
84
|
+
identityKey,
|
|
85
|
+
identityPrefix,
|
|
86
|
+
amendablePaths,
|
|
87
|
+
legacyAmendablePaths,
|
|
88
|
+
migrationAmendablePaths,
|
|
89
|
+
currentConfidenceVocabulary: requiredList(mapping(mapping(authority.compatibility).legacy_label_coexistence).current_vocabulary, "compatibility.legacy_label_coexistence.current_vocabulary"),
|
|
90
|
+
knownLegacyConfidenceValues: requiredList(mapping(mapping(authority.compatibility).legacy_label_coexistence).known_legacy_examples, "compatibility.legacy_label_coexistence.known_legacy_examples"),
|
|
91
|
+
identityPaths,
|
|
92
|
+
temporalPaths,
|
|
93
|
+
separationFromOverlay: requiredString(revisions.separation_from_overlay, "revisions.separation_from_overlay"),
|
|
94
|
+
immutability: requiredString(revisions.immutability, "revisions.immutability"),
|
|
95
|
+
provenance: requiredString(revisions.provenance, "revisions.provenance"),
|
|
96
|
+
publicationOrder: requiredList(revisions.publication_order, "revisions.publication_order"),
|
|
97
|
+
applyState: requiredString(revisions.apply_state, "revisions.apply_state"),
|
|
98
|
+
applyStateNote: requiredString(revisions.apply_state_note, "revisions.apply_state_note"),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export function legacyLabelCoexistence(sourceRoot = resolveSourceRoot()) {
|
|
102
|
+
const authority = readAuthority(sourceRoot);
|
|
103
|
+
const compatibility = mapping(authority.compatibility);
|
|
104
|
+
const coexistence = mapping(compatibility.legacy_label_coexistence);
|
|
105
|
+
if (Object.keys(coexistence).length === 0) {
|
|
106
|
+
throw new Error("state storage authority compatibility.legacy_label_coexistence section is required");
|
|
107
|
+
}
|
|
108
|
+
const currentVocabulary = requiredList(coexistence.current_vocabulary, "compatibility.legacy_label_coexistence.current_vocabulary");
|
|
109
|
+
if (currentVocabulary.length === 0) {
|
|
110
|
+
throw new Error("state storage authority legacy_label_coexistence.current_vocabulary must be non-empty");
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
dimensions: requiredList(coexistence.dimensions, "compatibility.legacy_label_coexistence.dimensions"),
|
|
114
|
+
currentVocabulary,
|
|
115
|
+
currentVocabularyRef: requiredString(coexistence.current_vocabulary_ref, "compatibility.legacy_label_coexistence.current_vocabulary_ref"),
|
|
116
|
+
knownLegacyExamples: requiredList(coexistence.known_legacy_examples, "compatibility.legacy_label_coexistence.known_legacy_examples"),
|
|
117
|
+
classificationRule: requiredString(coexistence.classification_rule, "compatibility.legacy_label_coexistence.classification_rule"),
|
|
118
|
+
noSilentNormalization: requiredString(coexistence.no_silent_normalization, "compatibility.legacy_label_coexistence.no_silent_normalization"),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export function classifyConfidenceLabel(contract, value, touched) {
|
|
122
|
+
const vocabulary = contract.currentVocabulary.join(", ");
|
|
123
|
+
if (contract.currentVocabulary.includes(value)) {
|
|
124
|
+
return { classification: "current", allowed: true, caveat: "" };
|
|
125
|
+
}
|
|
126
|
+
if (!touched) {
|
|
127
|
+
return {
|
|
128
|
+
classification: "explicit_legacy",
|
|
129
|
+
allowed: true,
|
|
130
|
+
caveat: `inherited unsupported confidence label '${value}' is explicit legacy state; current vocabulary is ${vocabulary}`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
classification: "rejected",
|
|
135
|
+
allowed: false,
|
|
136
|
+
caveat: `confidence label '${value}' requires current vocabulary (${vocabulary}) for new or amended content`,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
export const REVISION_PROVENANCE_VALUES = ["historical_revision", "degraded_projection"];
|
|
140
|
+
const REVISION_META_KEYS = new Set(["date", "provenance", "base_sha256"]);
|
|
141
|
+
const FORBIDDEN_REVISION_PROVENANCE = "historical_archive";
|
|
142
|
+
function isRecord(value) {
|
|
143
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
144
|
+
}
|
|
145
|
+
function decisionNumberFromId(id, contract) {
|
|
146
|
+
const prefix = `${contract.identityPrefix}:`;
|
|
147
|
+
if (!id.startsWith(prefix))
|
|
148
|
+
return null;
|
|
149
|
+
const number = id.slice(prefix.length);
|
|
150
|
+
if (!/^[1-9][0-9]*$/.test(number))
|
|
151
|
+
return null;
|
|
152
|
+
const parsed = Number(number);
|
|
153
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : null;
|
|
154
|
+
}
|
|
155
|
+
export function decisionRevisionViolations(document, contract = decisionRevisionContract()) {
|
|
156
|
+
if (!isRecord(document)) {
|
|
157
|
+
return ["decision revision root must be a mapping keyed by stable decision ID"];
|
|
158
|
+
}
|
|
159
|
+
const amendable = new Set(contract.legacyAmendablePaths);
|
|
160
|
+
const allowed = new Set([...REVISION_META_KEYS, ...contract.legacyAmendablePaths]);
|
|
161
|
+
const violations = [];
|
|
162
|
+
for (const [stableId, value] of Object.entries(document)) {
|
|
163
|
+
if (decisionNumberFromId(stableId, contract) === null) {
|
|
164
|
+
violations.push(`${stableId} is not a valid ${contract.identityKey} key`);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (!Array.isArray(value)) {
|
|
168
|
+
violations.push(`${stableId} must be an ordered list of revision records`);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
value.forEach((revision, index) => {
|
|
172
|
+
violations.push(...decisionRevisionRecordViolations(revision, `${stableId}[${index}]`, contract, allowed, amendable, contract.legacyAmendablePaths, true));
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return violations;
|
|
176
|
+
}
|
|
177
|
+
function decisionRevisionRecordViolations(revision, label, contract, allowed = new Set([...REVISION_META_KEYS, ...contract.amendablePaths, ...contract.migrationAmendablePaths]), amendable = new Set([...contract.amendablePaths, ...contract.migrationAmendablePaths]), amendablePaths = [...contract.amendablePaths, ...contract.migrationAmendablePaths], legacy = false, allowLegacyConfidence = false) {
|
|
178
|
+
if (!isRecord(revision))
|
|
179
|
+
return [`${label} must be a mapping of amendable fields and revision provenance`];
|
|
180
|
+
const violations = [];
|
|
181
|
+
for (const key of Object.keys(revision)) {
|
|
182
|
+
if (!allowed.has(key))
|
|
183
|
+
violations.push(`${label} carries '${key}' which is not an amendable content path or revision meta key`);
|
|
184
|
+
}
|
|
185
|
+
if ("alternatives" in revision && ("alternatives.chosen" in revision || "alternatives.rejected" in revision)) {
|
|
186
|
+
violations.push(`${label} must not mix migration-only alternatives replacement with granular alternative changes`);
|
|
187
|
+
}
|
|
188
|
+
for (const key of amendable) {
|
|
189
|
+
if (!(key in revision))
|
|
190
|
+
continue;
|
|
191
|
+
const value = revision[key];
|
|
192
|
+
if (key === "alternatives") {
|
|
193
|
+
const alternatives = Array.isArray(value) ? value : [];
|
|
194
|
+
const malformed = !Array.isArray(value)
|
|
195
|
+
|| alternatives.length === 0
|
|
196
|
+
|| alternatives.some((entry) => {
|
|
197
|
+
const candidate = isRecord(entry) ? entry : {};
|
|
198
|
+
return typeof candidate.name !== "string"
|
|
199
|
+
|| candidate.name.length === 0
|
|
200
|
+
|| !["chosen", "rejected"].includes(String(candidate.status));
|
|
201
|
+
})
|
|
202
|
+
|| alternatives.filter((entry) => isRecord(entry) && entry.status === "chosen").length !== 1;
|
|
203
|
+
if (malformed) {
|
|
204
|
+
violations.push(`${label}.alternatives must be a non-empty list with exactly one named chosen alternative and zero or more named rejected alternatives`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else if (key === "alternatives.rejected") {
|
|
208
|
+
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string" || entry.length === 0)) {
|
|
209
|
+
violations.push(`${label}.alternatives.rejected must be a list of non-empty strings`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else if (typeof value !== "string" || value.length === 0) {
|
|
213
|
+
violations.push(`${label}.${key} must be a non-empty string`);
|
|
214
|
+
}
|
|
215
|
+
else if (key === "confidence" && !legacy && !contract.currentConfidenceVocabulary.includes(value) && !(allowLegacyConfidence && contract.knownLegacyConfidenceValues.includes(value))) {
|
|
216
|
+
violations.push(`${label}.confidence '${value}' is not one of: ${contract.currentConfidenceVocabulary.join(", ")}`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const provenance = revision.provenance;
|
|
220
|
+
if (provenance !== undefined) {
|
|
221
|
+
if (typeof provenance !== "string")
|
|
222
|
+
violations.push(`${label}.provenance must be a string`);
|
|
223
|
+
else if (provenance === FORBIDDEN_REVISION_PROVENANCE)
|
|
224
|
+
violations.push(`${label}.provenance must never claim historical_archive provenance`);
|
|
225
|
+
else if (!REVISION_PROVENANCE_VALUES.includes(provenance)) {
|
|
226
|
+
violations.push(`${label}.provenance '${provenance}' is not one of: ${REVISION_PROVENANCE_VALUES.join(", ")}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const baseSha = revision.base_sha256;
|
|
230
|
+
if (baseSha !== undefined && (typeof baseSha !== "string" || !/^[0-9a-f]{64}$/.test(baseSha))) {
|
|
231
|
+
violations.push(`${label}.base_sha256 must be a 64-character sha256 hex digest`);
|
|
232
|
+
}
|
|
233
|
+
const date = revision.date;
|
|
234
|
+
if (date !== undefined && (typeof date !== "string" || date.length === 0)) {
|
|
235
|
+
violations.push(`${label}.date must be a non-empty string`);
|
|
236
|
+
}
|
|
237
|
+
if (!Object.keys(revision).some((key) => amendable.has(key))) {
|
|
238
|
+
violations.push(`${label} must amend at least one content field (${amendablePaths.join(", ")})`);
|
|
239
|
+
}
|
|
240
|
+
return violations;
|
|
241
|
+
}
|
|
242
|
+
export function decisionRevisionEntityViolations(record, contract = decisionRevisionContract(), allowLegacyConfidence = false) {
|
|
243
|
+
if (!isRecord(record.changes))
|
|
244
|
+
return ["decision revision changes must be a mapping of amendable fields"];
|
|
245
|
+
const amendable = new Set([...contract.amendablePaths, ...contract.migrationAmendablePaths]);
|
|
246
|
+
const violations = Object.keys(record.changes)
|
|
247
|
+
.filter((key) => !amendable.has(key))
|
|
248
|
+
.map((key) => `decision revision changes carries '${key}' which is not an amendable content path`);
|
|
249
|
+
violations.push(...decisionRevisionRecordViolations({
|
|
250
|
+
...record.changes,
|
|
251
|
+
date: record.date,
|
|
252
|
+
provenance: record.provenance,
|
|
253
|
+
base_sha256: record.base_sha256,
|
|
254
|
+
}, "decision revision", contract, undefined, undefined, undefined, false, allowLegacyConfidence));
|
|
255
|
+
return violations;
|
|
256
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { canonicalRecordJson, validateStateRecord } from "./archiveDiscovery.js";
|
|
3
|
+
import { canonicalMigrationRecord } from "./canonicalMigrationRecord.js";
|
|
4
|
+
import { applyDecisionChanges } from "./decisionEntities.js";
|
|
5
|
+
import { classifyCompleteDecisionConfidence, decisionLegacyCoexistence } from "./decisionLegacyValidation.js";
|
|
6
|
+
function mapping(value) {
|
|
7
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
8
|
+
}
|
|
9
|
+
function hash(value) {
|
|
10
|
+
return createHash("sha256").update(value).digest("hex");
|
|
11
|
+
}
|
|
12
|
+
function refuse(entry, recovery) {
|
|
13
|
+
entry.classification = "corrupt";
|
|
14
|
+
entry.detail_availability = "unavailable";
|
|
15
|
+
entry.compatibility = "degraded";
|
|
16
|
+
entry.proposed_target = null;
|
|
17
|
+
entry.target_sha256 = null;
|
|
18
|
+
entry.recovery = recovery;
|
|
19
|
+
}
|
|
20
|
+
function changesFrom(source) {
|
|
21
|
+
const changes = mapping(source.changes);
|
|
22
|
+
return structuredClone(changes ?? Object.fromEntries(Object.entries(source).filter(([field]) => !["decision", "date", "provenance", "base_sha256"].includes(field))));
|
|
23
|
+
}
|
|
24
|
+
export function migrateDecisionRevisionEntries(entries, decisions, legacyDecisions, sourceRoot, forbiddenAliases, sourceFingerprint) {
|
|
25
|
+
const coexistence = decisionLegacyCoexistence(sourceRoot);
|
|
26
|
+
const grouped = new Map();
|
|
27
|
+
for (const entry of entries.filter(({ boundary }) => boundary === "decision_revision")) {
|
|
28
|
+
const decision = entry.relationships.find(({ field }) => field === "decision")?.target_id ?? "";
|
|
29
|
+
grouped.set(decision, [...(grouped.get(decision) ?? []), entry]);
|
|
30
|
+
}
|
|
31
|
+
for (const [decision, revisions] of grouped) {
|
|
32
|
+
let effective = structuredClone(decisions.get(decision) ?? {});
|
|
33
|
+
const legacyBase = legacyDecisions.get(decision);
|
|
34
|
+
let legacyEffective = structuredClone(legacyBase ?? {});
|
|
35
|
+
const legacyBaseSha256 = legacyBase ? hash(canonicalRecordJson(legacyBase)) : null;
|
|
36
|
+
let chainValid = decisions.has(decision) && legacyBaseSha256 !== null;
|
|
37
|
+
for (const entry of revisions.sort((left, right) => left.source_identity.localeCompare(right.source_identity, undefined, { numeric: true }))) {
|
|
38
|
+
if (!entry.proposed_target) {
|
|
39
|
+
chainValid = false;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const source = entry.record;
|
|
43
|
+
const changes = changesFrom(source);
|
|
44
|
+
const expectedBase = hash(canonicalRecordJson(effective));
|
|
45
|
+
const claimedBase = typeof source.base_sha256 === "string" ? source.base_sha256 : null;
|
|
46
|
+
if (!chainValid || (claimedBase !== null && claimedBase !== legacyBaseSha256)) {
|
|
47
|
+
refuse(entry, claimedBase !== null && claimedBase !== legacyBaseSha256
|
|
48
|
+
? `Legacy revision '${entry.source_identity}' claims base ${claimedBase}, but the immutable legacy base is ${legacyBaseSha256}; preserve the source and reconcile the stale hash before migration.`
|
|
49
|
+
: `Legacy revision '${entry.source_identity}' follows an invalid or unavailable revision base; preserve the source and repair the ordered chain before migration.`);
|
|
50
|
+
chainValid = false;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const legacyProjected = { ...legacyEffective, ...structuredClone(changes) };
|
|
54
|
+
const assessment = classifyCompleteDecisionConfidence(legacyProjected, coexistence, (candidate) => validateStateRecord(sourceRoot, "decisions", candidate), "active");
|
|
55
|
+
if (assessment.status === "invalid") {
|
|
56
|
+
refuse(entry, `Legacy revision '${entry.source_identity}' produces an invalid effective decision (${assessment.violations.join("; ")}); preserve the source and repair the revision before migration.`);
|
|
57
|
+
chainValid = false;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const projected = applyDecisionChanges(effective, changes);
|
|
61
|
+
const expectedProjection = canonicalMigrationRecord("decision", legacyProjected, forbiddenAliases);
|
|
62
|
+
if (canonicalRecordJson(projected) !== canonicalRecordJson(expectedProjection)) {
|
|
63
|
+
refuse(entry, `Legacy revision '${entry.source_identity}' cannot be represented by canonical decision changes without altering its effective value; preserve the source and repair the revision before migration.`);
|
|
64
|
+
chainValid = false;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
entry.record = {
|
|
68
|
+
decision,
|
|
69
|
+
...(typeof source.date === "string" ? { date: source.date } : {}),
|
|
70
|
+
provenance: typeof source.provenance === "string" ? source.provenance : "historical_revision",
|
|
71
|
+
base_sha256: expectedBase,
|
|
72
|
+
changes,
|
|
73
|
+
};
|
|
74
|
+
if (typeof changes.confidence === "string" && coexistence.knownLegacyExamples.includes(changes.confidence)) {
|
|
75
|
+
entry.canonical_migration_provenance = {
|
|
76
|
+
kind: "inherited_decision_revision_confidence",
|
|
77
|
+
source: "revision_document",
|
|
78
|
+
source_path: entry.source_paths[0],
|
|
79
|
+
source_identity: entry.source_identity,
|
|
80
|
+
source_fingerprint: sourceFingerprint,
|
|
81
|
+
source_record_sha256: entry.content_sha256 ?? hash(canonicalRecordJson(source)),
|
|
82
|
+
confidence: changes.confidence,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
effective = projected;
|
|
86
|
+
legacyEffective = legacyProjected;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { loadYamlMapping } from "../core/yaml.js";
|
|
3
|
+
import { resolveSourceRoot } from "../core/sourceRoot.js";
|
|
4
|
+
import { canonicalRecordJson, decisionOverlayContract, numberedArchiveArtifacts, numberedArchiveContract, readNumberedArchiveEntry, stateCurrentProjectionPath, validateStateRecord, } from "./archiveDiscovery.js";
|
|
5
|
+
import { composeDecisionOverlay, decisionOverlayPath, loadDecisionOverlay } from "./decisionOverlay.js";
|
|
6
|
+
import { decisionContextEntry } from "../cli/commands/state/decisions.js";
|
|
7
|
+
import { assertRealpathBoundary } from "../registries/artifactRegistry.js";
|
|
8
|
+
import { legacyEntryNumber, legacyIdentity } from "./legacyIdentity.js";
|
|
9
|
+
export class StateRetrievalFailure extends Error {
|
|
10
|
+
body;
|
|
11
|
+
exitCode;
|
|
12
|
+
constructor(body, exitCode) {
|
|
13
|
+
super(body.error.message);
|
|
14
|
+
this.body = body;
|
|
15
|
+
this.exitCode = exitCode;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function isMapping(value) {
|
|
19
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
function stateSyntax(artifactId = "<artifact-id>") {
|
|
22
|
+
return `agentera state ${artifactId} get --number N --format json`;
|
|
23
|
+
}
|
|
24
|
+
function stateExample(artifactId, entryNumber = null) {
|
|
25
|
+
return `agentera state ${artifactId} get --number ${entryNumber ?? 1} --format json`;
|
|
26
|
+
}
|
|
27
|
+
function failure(exitCode, className, message, options) {
|
|
28
|
+
const artifactId = options.artifactId;
|
|
29
|
+
const entryNumber = options.entryNumber;
|
|
30
|
+
const stableId = artifactId && entryNumber ? `${artifactId}:${entryNumber}` : undefined;
|
|
31
|
+
return new StateRetrievalFailure({
|
|
32
|
+
schemaVersion: "agentera.stateFailure.v1",
|
|
33
|
+
status: "fail",
|
|
34
|
+
error: {
|
|
35
|
+
class: className,
|
|
36
|
+
message,
|
|
37
|
+
syntax: stateSyntax(artifactId),
|
|
38
|
+
example: artifactId ? stateExample(artifactId, entryNumber ?? null) : stateExample("progress"),
|
|
39
|
+
recovery: options.recovery,
|
|
40
|
+
...(artifactId ? { artifact_id: artifactId } : {}),
|
|
41
|
+
...(entryNumber ? { entry_number: entryNumber } : {}),
|
|
42
|
+
...(stableId ? { stable_id: stableId } : {}),
|
|
43
|
+
...(options.validValues ? { valid_values: options.validValues } : {}),
|
|
44
|
+
...(options.details ? { details: options.details } : {}),
|
|
45
|
+
},
|
|
46
|
+
}, exitCode);
|
|
47
|
+
}
|
|
48
|
+
function inspectCurrentProjection(projectRoot, artifactId, entryNumber, contract, sourceRoot) {
|
|
49
|
+
const projectionPath = stateCurrentProjectionPath(projectRoot, artifactId, sourceRoot);
|
|
50
|
+
try {
|
|
51
|
+
assertRealpathBoundary(projectRoot, projectionPath, `${artifactId} projection`);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
throw failure(1, "corrupt", `current ${artifactId} projection path is unsafe`, {
|
|
55
|
+
artifactId,
|
|
56
|
+
entryNumber,
|
|
57
|
+
recovery: "Preserve the project state, repair the unsafe projection path, then retry the direct get command.",
|
|
58
|
+
details: { path: projectionPath, reason: error.message },
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
let projectionStat;
|
|
62
|
+
try {
|
|
63
|
+
projectionStat = fs.lstatSync(projectionPath);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error.code === "ENOENT")
|
|
67
|
+
return { path: projectionPath, state: "missing" };
|
|
68
|
+
throw failure(1, "corrupt", `cannot read current ${artifactId} projection`, {
|
|
69
|
+
artifactId,
|
|
70
|
+
entryNumber,
|
|
71
|
+
recovery: "Preserve the current projection for diagnostics, repair its file permissions or path, then retry the direct get command.",
|
|
72
|
+
details: { path: projectionPath, reason: error.message },
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (projectionStat.isSymbolicLink() || !projectionStat.isFile()) {
|
|
76
|
+
throw failure(1, "corrupt", `current ${artifactId} projection is not a regular file`, {
|
|
77
|
+
artifactId,
|
|
78
|
+
entryNumber,
|
|
79
|
+
recovery: "Restore the declared current projection as a regular project-local file, then retry the direct get command.",
|
|
80
|
+
details: { path: projectionPath },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
let document;
|
|
84
|
+
try {
|
|
85
|
+
document = loadYamlMapping(fs.readFileSync(projectionPath, "utf8"));
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
throw failure(1, "corrupt", `cannot parse current ${artifactId} projection: ${error.message}`, {
|
|
89
|
+
artifactId,
|
|
90
|
+
entryNumber,
|
|
91
|
+
recovery: "Preserve the current projection for diagnostics, repair its YAML, then retry the direct get command.",
|
|
92
|
+
details: { path: projectionPath },
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const active = document[contract.entryCollection];
|
|
96
|
+
if (!Array.isArray(active)) {
|
|
97
|
+
throw failure(1, "corrupt", `current ${artifactId} projection is missing its '${contract.entryCollection}' collection`, {
|
|
98
|
+
artifactId,
|
|
99
|
+
entryNumber,
|
|
100
|
+
recovery: "Restore a valid current projection with its declared entry collection, then retry the direct get command.",
|
|
101
|
+
details: { path: projectionPath, collection: contract.entryCollection },
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
let matchingActive;
|
|
105
|
+
for (const candidate of active) {
|
|
106
|
+
if (!isMapping(candidate))
|
|
107
|
+
continue;
|
|
108
|
+
if (legacyEntryNumber(candidate, artifactId, contract.entryNumberField) !== entryNumber)
|
|
109
|
+
continue;
|
|
110
|
+
if (matchingActive) {
|
|
111
|
+
throw failure(1, "ambiguous", `current ${artifactId} projection contains duplicate identity ${artifactId}:${entryNumber}`, {
|
|
112
|
+
artifactId,
|
|
113
|
+
entryNumber,
|
|
114
|
+
recovery: "Preserve the duplicate current entries, remove the identity conflict according to the artifact schema, then retry.",
|
|
115
|
+
details: { path: projectionPath, collection: contract.entryCollection },
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
matchingActive = candidate;
|
|
119
|
+
}
|
|
120
|
+
if (matchingActive) {
|
|
121
|
+
try {
|
|
122
|
+
const violations = validateStateRecord(sourceRoot, artifactId, matchingActive);
|
|
123
|
+
return {
|
|
124
|
+
path: projectionPath,
|
|
125
|
+
state: violations.length === 0 ? "full" : "summary",
|
|
126
|
+
identity: legacyIdentity(matchingActive, artifactId, contract.entryNumberField).kind,
|
|
127
|
+
record: matchingActive,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw failure(1, "unsupported_state", `current ${artifactId} projection could not be validated: ${error.message}`, {
|
|
132
|
+
artifactId,
|
|
133
|
+
entryNumber,
|
|
134
|
+
recovery: "Use a state schema supported by the storage authority, repair the current projection, then retry.",
|
|
135
|
+
details: { path: projectionPath },
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const archive = document.archive;
|
|
140
|
+
if (Array.isArray(archive)) {
|
|
141
|
+
for (const candidate of archive) {
|
|
142
|
+
if (legacyEntryNumber(candidate, artifactId, contract.entryNumberField) !== entryNumber)
|
|
143
|
+
continue;
|
|
144
|
+
return {
|
|
145
|
+
path: projectionPath,
|
|
146
|
+
state: "summary",
|
|
147
|
+
identity: legacyIdentity(candidate, artifactId, contract.entryNumberField).kind,
|
|
148
|
+
record: isMapping(candidate) ? candidate : { summary: candidate },
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return { path: projectionPath, state: "absent" };
|
|
153
|
+
}
|
|
154
|
+
function overlayFor(projectRoot, sourceRoot, artifactId, entryNumber, record) {
|
|
155
|
+
if (artifactId !== "decisions")
|
|
156
|
+
return { record, applied: false, fields: [], path: "" };
|
|
157
|
+
const contract = decisionOverlayContract(sourceRoot);
|
|
158
|
+
const overlayPath = decisionOverlayPath(projectRoot, sourceRoot);
|
|
159
|
+
let overlay;
|
|
160
|
+
try {
|
|
161
|
+
overlay = loadDecisionOverlay(projectRoot, sourceRoot);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
throw failure(1, "corrupt", `cannot read decision overlay: ${error.message}`, {
|
|
165
|
+
artifactId,
|
|
166
|
+
entryNumber,
|
|
167
|
+
recovery: "Preserve the decision overlay for diagnostics, repair its YAML and whitelisted fields, then retry.",
|
|
168
|
+
details: { path: overlayPath },
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const stableId = `decisions:${entryNumber}`;
|
|
172
|
+
const selected = overlay[stableId];
|
|
173
|
+
const fields = selected
|
|
174
|
+
? contract.mutablePaths.filter((field) => {
|
|
175
|
+
let value = selected;
|
|
176
|
+
for (const part of field.split(".")) {
|
|
177
|
+
if (!isMapping(value))
|
|
178
|
+
return false;
|
|
179
|
+
value = value[part];
|
|
180
|
+
}
|
|
181
|
+
return value !== undefined;
|
|
182
|
+
})
|
|
183
|
+
: [];
|
|
184
|
+
const composed = composeDecisionOverlay(record, selected, contract);
|
|
185
|
+
return {
|
|
186
|
+
record: decisionContextEntry(composed, { inferOutcome: false }),
|
|
187
|
+
applied: fields.length > 0,
|
|
188
|
+
fields,
|
|
189
|
+
path: overlayPath,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function compose(projectRoot, sourceRoot, artifactId, entryNumber, current, archivePath, archiveRecord, archiveHash) {
|
|
193
|
+
const record = archiveRecord ?? current.record;
|
|
194
|
+
if (!record) {
|
|
195
|
+
throw failure(1, "incomplete", `state ${artifactId}:${entryNumber} has no complete record available`, {
|
|
196
|
+
artifactId,
|
|
197
|
+
entryNumber,
|
|
198
|
+
recovery: "Restore or publish the validated numbered archive for this ID before retrying; missing fields are not reconstructed.",
|
|
199
|
+
details: { current_projection_path: current.path, archive_path: archivePath, current_representation: current.state },
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (!archiveRecord && current.state === "summary" && current.identity !== "explicit_decision_shorthand") {
|
|
203
|
+
throw failure(1, "incomplete", `state ${artifactId}:${entryNumber} is represented only by an irrecoverable legacy summary`, {
|
|
204
|
+
artifactId,
|
|
205
|
+
entryNumber,
|
|
206
|
+
recovery: "Restore or publish the validated numbered archive for this ID before retrying; missing fields are not reconstructed.",
|
|
207
|
+
details: { current_projection_path: current.path, archive_path: archivePath, current_representation: current.state },
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
const complete = archiveRecord !== undefined || current.state === "full";
|
|
211
|
+
const overlay = complete ? overlayFor(projectRoot, sourceRoot, artifactId, entryNumber, record) : { record, applied: false, fields: [], path: "" };
|
|
212
|
+
const source = archiveRecord ? "archive" : current.state === "summary" ? "legacy_summary" : "legacy_full";
|
|
213
|
+
const compatibility = archiveRecord ? "complete" : "degraded";
|
|
214
|
+
return {
|
|
215
|
+
stable_id: `${artifactId}:${entryNumber}`,
|
|
216
|
+
artifact_id: artifactId,
|
|
217
|
+
entry_number: entryNumber,
|
|
218
|
+
record: overlay.record,
|
|
219
|
+
source,
|
|
220
|
+
detail_availability: complete ? "full" : "summary",
|
|
221
|
+
compatibility,
|
|
222
|
+
provenance: {
|
|
223
|
+
archive: {
|
|
224
|
+
path: archivePath,
|
|
225
|
+
available: archiveRecord !== undefined,
|
|
226
|
+
verified: archiveRecord !== undefined,
|
|
227
|
+
...(archiveHash ? { record_sha256: archiveHash } : {}),
|
|
228
|
+
},
|
|
229
|
+
current_projection: {
|
|
230
|
+
path: current.path,
|
|
231
|
+
present: current.state !== "missing" && current.state !== "absent",
|
|
232
|
+
representation: current.state,
|
|
233
|
+
},
|
|
234
|
+
...(artifactId === "decisions" && complete
|
|
235
|
+
? {
|
|
236
|
+
overlay: { path: overlay.path, applied: overlay.applied, fields: overlay.fields },
|
|
237
|
+
}
|
|
238
|
+
: {}),
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
export function retrieveStateEntry(projectRoot, artifactId, entryNumber, options = {}) {
|
|
243
|
+
const sourceRoot = options.sourceRoot ?? resolveSourceRoot();
|
|
244
|
+
const artifacts = numberedArchiveArtifacts(sourceRoot);
|
|
245
|
+
if (!artifacts.includes(artifactId)) {
|
|
246
|
+
throw failure(2, "unsupported_artifact", `unsupported state artifact '${artifactId}'`, {
|
|
247
|
+
recovery: "Use a supported numbered state artifact and retry the direct get command.",
|
|
248
|
+
validValues: artifacts,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
const contract = numberedArchiveContract(artifactId, sourceRoot);
|
|
252
|
+
let current;
|
|
253
|
+
try {
|
|
254
|
+
current = inspectCurrentProjection(projectRoot, artifactId, entryNumber, contract, sourceRoot);
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
if (error instanceof StateRetrievalFailure)
|
|
258
|
+
throw error;
|
|
259
|
+
throw failure(1, "unsupported_state", `state authority could not read ${artifactId}:${entryNumber}: ${error.message}`, {
|
|
260
|
+
artifactId,
|
|
261
|
+
entryNumber,
|
|
262
|
+
recovery: "Use a state format supported by the storage authority, then retry the direct get command.",
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
const lookup = readNumberedArchiveEntry(projectRoot, artifactId, entryNumber, { sourceRoot });
|
|
266
|
+
if (lookup.rejection) {
|
|
267
|
+
const unsupported = lookup.rejection.class === "unsupported_artifact" ||
|
|
268
|
+
lookup.rejection.reason === "unsupported_artifact" ||
|
|
269
|
+
(lookup.rejection.reason === "invalid_envelope" && lookup.rejection.message.startsWith("schemaVersion must be"));
|
|
270
|
+
throw failure(1, unsupported ? "unsupported_state" : "corrupt", lookup.rejection.message, {
|
|
271
|
+
artifactId,
|
|
272
|
+
entryNumber,
|
|
273
|
+
recovery: unsupported
|
|
274
|
+
? "Use a numbered archive schema supported by the storage authority, then retry the direct get command."
|
|
275
|
+
: "Preserve the affected archive bytes for diagnostics, repair the numbered record, then retry the direct get command.",
|
|
276
|
+
details: { archive_path: lookup.path, rejection: lookup.rejection.reason },
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
const archiveRecord = lookup.entry?.record;
|
|
280
|
+
if (!archiveRecord && current.state === "missing") {
|
|
281
|
+
throw failure(1, "not_found", `state ${artifactId}:${entryNumber} was not found in the current projection or numbered archive`, {
|
|
282
|
+
artifactId,
|
|
283
|
+
entryNumber,
|
|
284
|
+
recovery: "Use an existing stable ID or restore/publish this numbered record before retrying.",
|
|
285
|
+
details: { current_projection_path: current.path, archive_path: lookup.path },
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (!archiveRecord && current.state === "absent") {
|
|
289
|
+
throw failure(1, "not_found", `state ${artifactId}:${entryNumber} was not found in the current projection or numbered archive`, {
|
|
290
|
+
artifactId,
|
|
291
|
+
entryNumber,
|
|
292
|
+
recovery: "Use an existing stable ID or restore/publish this numbered record before retrying.",
|
|
293
|
+
details: { current_projection_path: current.path, archive_path: lookup.path },
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
if (archiveRecord && current.record && current.state === "full") {
|
|
297
|
+
try {
|
|
298
|
+
if (canonicalRecordJson(archiveRecord) !== canonicalRecordJson(current.record)) {
|
|
299
|
+
throw failure(1, "immutable_conflict", `state ${artifactId}:${entryNumber} differs between archive and current projection`, {
|
|
300
|
+
artifactId,
|
|
301
|
+
entryNumber,
|
|
302
|
+
recovery: "Preserve the immutable archive bytes and reconcile the conflicting current record before retrying.",
|
|
303
|
+
details: { current_projection_path: current.path, archive_path: lookup.path },
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
if (error instanceof StateRetrievalFailure)
|
|
309
|
+
throw error;
|
|
310
|
+
throw failure(1, "corrupt", `state ${artifactId}:${entryNumber} could not be compared safely`, {
|
|
311
|
+
artifactId,
|
|
312
|
+
entryNumber,
|
|
313
|
+
recovery: "Preserve both records for diagnostics, repair their serialized state, then retry.",
|
|
314
|
+
details: { current_projection_path: current.path, archive_path: lookup.path },
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
command: `state ${artifactId} get`,
|
|
320
|
+
status: "ok",
|
|
321
|
+
entry: compose(projectRoot, sourceRoot, artifactId, entryNumber, current, lookup.path, archiveRecord, lookup.entry?.recordSha256),
|
|
322
|
+
};
|
|
323
|
+
}
|