onto-mcp 0.3.2 → 0.4.0
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/.onto/processes/reconstruct/actionable-ontology-seed-recomposition-design.md +447 -0
- package/.onto/processes/reconstruct/foundry-style-ontology-seed-contract.md +934 -0
- package/.onto/processes/reconstruct/reconstruct-boundary-contract.md +303 -725
- package/.onto/processes/reconstruct/reconstruct-contract-registry.yaml +1645 -0
- package/.onto/processes/reconstruct/reconstruct-execution-ux-contract.md +26 -22
- package/.onto/processes/reconstruct/source-profile-contract.md +49 -23
- package/.onto/processes/reconstruct/source-profiles/code.md +6 -3
- package/.onto/processes/reconstruct/source-profiles/database.md +5 -2
- package/.onto/processes/reconstruct/source-profiles/document.md +5 -2
- package/.onto/processes/reconstruct/source-profiles/spreadsheet.md +5 -4
- package/.onto/processes/review/review-execution-ux-contract.md +40 -0
- package/.onto/processes/shared/pipeline-execution-ledger-contract.md +26 -10
- package/.onto/processes/shared/target-material-kind-contract.md +29 -16
- package/AGENTS.md +6 -4
- package/README.md +135 -76
- package/dist/cli.js +8 -8
- package/dist/core-api/reconstruct-api.js +117 -31
- package/dist/core-api/review-api.js +47 -0
- package/dist/core-runtime/cli/codex-review-unit-executor.js +39 -2
- package/dist/core-runtime/cli/complete-review-session.js +2 -2
- package/dist/core-runtime/cli/mock-review-unit-executor.js +1 -1
- package/dist/core-runtime/cli/review-invoke.js +9 -9
- package/dist/core-runtime/cli/run-review-prompt-execution.js +39 -5
- package/dist/core-runtime/cli/spawn-watcher.js +266 -47
- package/dist/core-runtime/cli/start-review-session.js +3 -3
- package/dist/core-runtime/llm/llm-caller.js +11 -0
- package/dist/core-runtime/llm/llm-tool-loop.js +2 -0
- package/dist/core-runtime/observability/runtime-stream-observation.js +118 -0
- package/dist/core-runtime/onboard/cli-host.js +149 -0
- package/dist/core-runtime/onboard/host-target.js +22 -0
- package/dist/core-runtime/onboard/json-config-host.js +122 -0
- package/dist/core-runtime/onboard/path-scan.js +26 -0
- package/dist/core-runtime/onboard/prompt.js +51 -0
- package/dist/core-runtime/onboard/register.js +207 -0
- package/dist/core-runtime/onboard/types.js +27 -0
- package/dist/core-runtime/reconstruct/actionable-seed-validation.js +1777 -0
- package/dist/core-runtime/reconstruct/artifact-types.js +10 -4
- package/dist/core-runtime/reconstruct/contract-registry.js +623 -0
- package/dist/core-runtime/reconstruct/domain-id.js +10 -0
- package/dist/core-runtime/reconstruct/governing-snapshot.js +716 -0
- package/dist/core-runtime/reconstruct/material-profile-validation.js +191 -0
- package/dist/core-runtime/reconstruct/materialize-preparation.js +49 -11
- package/dist/core-runtime/reconstruct/pipeline-execution-ledger.js +269 -79
- package/dist/core-runtime/reconstruct/post-seed-validation.js +1194 -51
- package/dist/core-runtime/reconstruct/record.js +104 -20
- package/dist/core-runtime/reconstruct/run.js +2107 -413
- package/dist/core-runtime/reconstruct/seed-claim-projections.js +268 -0
- package/dist/core-runtime/reconstruct/source-profiles.js +93 -4
- package/dist/core-runtime/reconstruct/terminal-validation.js +807 -0
- package/dist/core-runtime/review/review-invocation-runner.js +4 -4
- package/dist/mcp/server.js +110 -38
- package/dist/mcp/tool-schemas.js +20 -6
- package/package.json +8 -17
- package/scripts/onto-review-watch.sh +486 -0
- package/scripts/onto-runtime-watch.sh +122 -0
- package/scripts/postinstall-hint.js +22 -0
- package/.onto/processes/reconstruct/top-level-concept-discovery-contract.md +0 -387
- package/dist/core-runtime/cli/bootstrap-review-binding.js +0 -186
- package/dist/core-runtime/cli/codex-nested-dispatch.test.js +0 -390
- package/dist/core-runtime/cli/codex-nested-teamlead-executor.test.js +0 -335
- package/dist/core-runtime/cli/coordinator-helpers.js +0 -583
- package/dist/core-runtime/cli/coordinator-state-machine-deliberation.test.js +0 -167
- package/dist/core-runtime/cli/coordinator-state-machine.js +0 -794
- package/dist/core-runtime/cli/e2e-codex-multi-agent-fixes.test.js +0 -615
- package/dist/core-runtime/cli/e2e-start-review-session.test.js +0 -312
- package/dist/core-runtime/cli/health.js +0 -44
- package/dist/core-runtime/cli/inline-http-review-unit-executor.test.js +0 -567
- package/dist/core-runtime/cli/materialize-review-execution-preparation.js +0 -104
- package/dist/core-runtime/cli/migrate-session-roots.js +0 -118
- package/dist/core-runtime/cli/repo-layout-migration-replace.smoke.test.js +0 -106
- package/dist/core-runtime/cli/review-invoke-auto-resolution.test.js +0 -268
- package/dist/core-runtime/cli/review-invoke-coordinator-topology.test.js +0 -136
- package/dist/core-runtime/cli/review-invoke-resolver-caching.test.js +0 -201
- package/dist/core-runtime/cli/review-invoke-topology-dispatch.test.js +0 -192
- package/dist/core-runtime/cli/session-root-guard.js +0 -168
- package/dist/core-runtime/cli/spawn-watcher.test.js +0 -457
- package/dist/core-runtime/cli/strip-wrapping-code-fence.test.js +0 -79
- package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.js +0 -412
- package/dist/core-runtime/cli/teamcreate-lens-deliberation-executor.test.js +0 -351
- package/dist/core-runtime/cli/topology-executor-mapping.js +0 -139
- package/dist/core-runtime/cli/topology-executor-mapping.test.js +0 -173
- package/dist/core-runtime/cli/write-review-interpretation.js +0 -81
- package/dist/core-runtime/config/onto-config-cli.js +0 -278
- package/dist/core-runtime/config/onto-config-key-path.js +0 -288
- package/dist/core-runtime/config/onto-config-key-path.test.js +0 -195
- package/dist/core-runtime/config/onto-config-preview.js +0 -108
- package/dist/core-runtime/config/onto-config-preview.test.js +0 -132
- package/dist/core-runtime/discovery/config-chain.js +0 -118
- package/dist/core-runtime/discovery/config-chain.test.js +0 -103
- package/dist/core-runtime/discovery/config-profile.js +0 -199
- package/dist/core-runtime/discovery/config-profile.test.js +0 -233
- package/dist/core-runtime/discovery/host-detection.test.js +0 -186
- package/dist/core-runtime/discovery/installation-paths.test.js +0 -65
- package/dist/core-runtime/discovery/lens-registry.test.js +0 -81
- package/dist/core-runtime/discovery/path-normalization.test.js +0 -22
- package/dist/core-runtime/discovery/plugin-path.js +0 -72
- package/dist/core-runtime/discovery/plugin-path.test.js +0 -95
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.js +0 -344
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile-defense.test.js +0 -915
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile.js +0 -564
- package/dist/core-runtime/evolve/adapters/code-product/compile/compile.test.js +0 -708
- package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.js +0 -165
- package/dist/core-runtime/evolve/adapters/code-product/parsers/brief-parser.test.js +0 -227
- package/dist/core-runtime/evolve/adapters/code-product/validators/validate.js +0 -59
- package/dist/core-runtime/evolve/adapters/code-product/validators/validate.test.js +0 -205
- package/dist/core-runtime/evolve/adapters/methodology/adapter.js +0 -16
- package/dist/core-runtime/evolve/adapters/methodology/adapter.test.js +0 -9
- package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.js +0 -298
- package/dist/core-runtime/evolve/adapters/methodology/perspectives/authority-consistency.test.js +0 -70
- package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.js +0 -46
- package/dist/core-runtime/evolve/adapters/methodology/scope-types/process.test.js +0 -73
- package/dist/core-runtime/evolve/adapters/registry.js +0 -47
- package/dist/core-runtime/evolve/adapters/registry.test.js +0 -67
- package/dist/core-runtime/evolve/cli.js +0 -256
- package/dist/core-runtime/evolve/commands/align.js +0 -194
- package/dist/core-runtime/evolve/commands/align.test.js +0 -82
- package/dist/core-runtime/evolve/commands/apply.js +0 -161
- package/dist/core-runtime/evolve/commands/apply.test.js +0 -138
- package/dist/core-runtime/evolve/commands/close.js +0 -39
- package/dist/core-runtime/evolve/commands/close.test.js +0 -99
- package/dist/core-runtime/evolve/commands/defer.js +0 -40
- package/dist/core-runtime/evolve/commands/defer.test.js +0 -134
- package/dist/core-runtime/evolve/commands/draft.js +0 -323
- package/dist/core-runtime/evolve/commands/draft.test.js +0 -178
- package/dist/core-runtime/evolve/commands/e2e-evolve-full-cycle.test.js +0 -208
- package/dist/core-runtime/evolve/commands/error-messages.js +0 -125
- package/dist/core-runtime/evolve/commands/error-messages.test.js +0 -167
- package/dist/core-runtime/evolve/commands/propose-align.js +0 -222
- package/dist/core-runtime/evolve/commands/propose-align.test.js +0 -136
- package/dist/core-runtime/evolve/commands/reconstruct.js +0 -330
- package/dist/core-runtime/evolve/commands/reconstruct.test.js +0 -278
- package/dist/core-runtime/evolve/commands/shared.js +0 -22
- package/dist/core-runtime/evolve/commands/stale-check.js +0 -103
- package/dist/core-runtime/evolve/commands/stale-check.test.js +0 -84
- package/dist/core-runtime/evolve/commands/start.js +0 -887
- package/dist/core-runtime/evolve/commands/start.test.js +0 -396
- package/dist/core-runtime/evolve/config/project-config.js +0 -99
- package/dist/core-runtime/evolve/config/project-config.test.js +0 -170
- package/dist/core-runtime/evolve/renderers/align-packet.js +0 -280
- package/dist/core-runtime/evolve/renderers/align-packet.test.js +0 -332
- package/dist/core-runtime/evolve/renderers/draft-packet.js +0 -303
- package/dist/core-runtime/evolve/renderers/draft-packet.test.js +0 -377
- package/dist/core-runtime/evolve/renderers/format.js +0 -5
- package/dist/core-runtime/evolve/renderers/scope-md.js +0 -237
- package/dist/core-runtime/evolve/renderers/scope-md.test.js +0 -306
- package/dist/core-runtime/govern/cli.js +0 -369
- package/dist/core-runtime/govern/cli.test.js +0 -314
- package/dist/core-runtime/govern/drift-engine.js +0 -103
- package/dist/core-runtime/govern/drift-engine.test.js +0 -319
- package/dist/core-runtime/govern/promote-principle.js +0 -206
- package/dist/core-runtime/govern/promote-principle.test.js +0 -368
- package/dist/core-runtime/govern/queue.js +0 -81
- package/dist/core-runtime/govern/types.js +0 -16
- package/dist/core-runtime/install/cli.js +0 -530
- package/dist/core-runtime/install/detect.js +0 -128
- package/dist/core-runtime/install/detect.test.js +0 -155
- package/dist/core-runtime/install/gitignore-update.js +0 -74
- package/dist/core-runtime/install/gitignore-update.test.js +0 -64
- package/dist/core-runtime/install/install-integration.test.js +0 -373
- package/dist/core-runtime/install/prompts.js +0 -389
- package/dist/core-runtime/install/prompts.test.js +0 -293
- package/dist/core-runtime/install/types.js +0 -26
- package/dist/core-runtime/install/validation.js +0 -295
- package/dist/core-runtime/install/validation.test.js +0 -313
- package/dist/core-runtime/install/writer.js +0 -254
- package/dist/core-runtime/install/writer.test.js +0 -218
- package/dist/core-runtime/learning/extractor.js +0 -461
- package/dist/core-runtime/learning/feedback.js +0 -179
- package/dist/core-runtime/learning/health-report.js +0 -165
- package/dist/core-runtime/learning/health-report.test.js +0 -169
- package/dist/core-runtime/learning/loader.js +0 -388
- package/dist/core-runtime/learning/loader.test.js +0 -102
- package/dist/core-runtime/learning/promote/apply-state.js +0 -240
- package/dist/core-runtime/learning/promote/audit-obligation.js +0 -195
- package/dist/core-runtime/learning/promote/collector.js +0 -432
- package/dist/core-runtime/learning/promote/degraded-state.js +0 -125
- package/dist/core-runtime/learning/promote/domain-doc-proposer.js +0 -166
- package/dist/core-runtime/learning/promote/e2e-promote.test.js +0 -6385
- package/dist/core-runtime/learning/promote/health-snapshot.js +0 -150
- package/dist/core-runtime/learning/promote/insight-reclassifier.js +0 -544
- package/dist/core-runtime/learning/promote/judgment-auditor.js +0 -517
- package/dist/core-runtime/learning/promote/panel-reviewer.js +0 -1158
- package/dist/core-runtime/learning/promote/promote-executor.js +0 -1675
- package/dist/core-runtime/learning/promote/promoter.js +0 -307
- package/dist/core-runtime/learning/promote/retirement.js +0 -122
- package/dist/core-runtime/learning/promote/types.js +0 -23
- package/dist/core-runtime/learning/prompt-sections.js +0 -51
- package/dist/core-runtime/learning/shared/artifact-registry-init.js +0 -45
- package/dist/core-runtime/learning/shared/artifact-registry.js +0 -254
- package/dist/core-runtime/learning/shared/audit-obligation-kernel.js +0 -73
- package/dist/core-runtime/learning/shared/audit-state.js +0 -99
- package/dist/core-runtime/learning/shared/duplicate-check.js +0 -28
- package/dist/core-runtime/learning/shared/llm-caller.js +0 -831
- package/dist/core-runtime/learning/shared/llm-caller.test.js +0 -601
- package/dist/core-runtime/learning/shared/llm-tool-loop.js +0 -393
- package/dist/core-runtime/learning/shared/mode.js +0 -25
- package/dist/core-runtime/learning/shared/paths.js +0 -84
- package/dist/core-runtime/learning/shared/paths.test.js +0 -79
- package/dist/core-runtime/learning/shared/patterns.js +0 -37
- package/dist/core-runtime/learning/shared/recoverability.js +0 -355
- package/dist/core-runtime/learning/shared/recovery-context.js +0 -374
- package/dist/core-runtime/learning/shared/scope.js +0 -1
- package/dist/core-runtime/learning/shared/semantic-classifier.js +0 -94
- package/dist/core-runtime/learning/shared/specs/apply-execution-state-spec.js +0 -42
- package/dist/core-runtime/learning/shared/specs/audit-state-spec.js +0 -37
- package/dist/core-runtime/learning/shared/specs/backup-metadata-spec.js +0 -39
- package/dist/core-runtime/learning/shared/specs/emergency-log-spec.js +0 -41
- package/dist/core-runtime/learning/shared/specs/layout-version-spec.js +0 -38
- package/dist/core-runtime/learning/shared/specs/promote-decisions-spec.js +0 -43
- package/dist/core-runtime/learning/shared/specs/promote-report-spec.js +0 -113
- package/dist/core-runtime/learning/shared/specs/prune-log-spec.js +0 -36
- package/dist/core-runtime/learning/shared/specs/recovery-resolution-spec.js +0 -48
- package/dist/core-runtime/learning/shared/specs/restore-manifest-spec.js +0 -43
- package/dist/core-runtime/learning/shared/specs/spec-helpers.js +0 -64
- package/dist/core-runtime/learning/usage-tracker.js +0 -190
- package/dist/core-runtime/learning/usage-tracker.test.js +0 -176
- package/dist/core-runtime/onboard/detect-review-axes.js +0 -122
- package/dist/core-runtime/onboard/detect-review-axes.test.js +0 -127
- package/dist/core-runtime/onboard/write-review-block.js +0 -188
- package/dist/core-runtime/onboard/write-review-block.test.js +0 -240
- package/dist/core-runtime/readers/brownfield-builder.js +0 -150
- package/dist/core-runtime/readers/brownfield-builder.test.js +0 -136
- package/dist/core-runtime/readers/code-chunk-collector.js +0 -53
- package/dist/core-runtime/readers/code-chunk-collector.test.js +0 -136
- package/dist/core-runtime/readers/file-utils.js +0 -240
- package/dist/core-runtime/readers/file-utils.test.js +0 -146
- package/dist/core-runtime/readers/lexicon-citation-check.js +0 -93
- package/dist/core-runtime/readers/lexicon-citation-check.test.js +0 -77
- package/dist/core-runtime/readers/mcp-figma.js +0 -30
- package/dist/core-runtime/readers/mcp-figma.test.js +0 -82
- package/dist/core-runtime/readers/mcp-generic.js +0 -31
- package/dist/core-runtime/readers/mcp-generic.test.js +0 -76
- package/dist/core-runtime/readers/ontology-index.js +0 -148
- package/dist/core-runtime/readers/ontology-index.test.js +0 -245
- package/dist/core-runtime/readers/ontology-query.js +0 -168
- package/dist/core-runtime/readers/ontology-query.test.js +0 -311
- package/dist/core-runtime/readers/ontology-resolve.js +0 -48
- package/dist/core-runtime/readers/ontology-resolve.test.js +0 -48
- package/dist/core-runtime/readers/patterns/index.js +0 -7
- package/dist/core-runtime/readers/review-log.js +0 -213
- package/dist/core-runtime/readers/review-log.test.js +0 -313
- package/dist/core-runtime/readers/scan-local.js +0 -102
- package/dist/core-runtime/readers/scan-local.test.js +0 -102
- package/dist/core-runtime/readers/scan-tarball.js +0 -121
- package/dist/core-runtime/readers/scan-tarball.test.js +0 -283
- package/dist/core-runtime/readers/scan-vault.js +0 -34
- package/dist/core-runtime/readers/scan-vault.test.js +0 -81
- package/dist/core-runtime/readers/types.js +0 -42
- package/dist/core-runtime/readers/types.test.js +0 -94
- package/dist/core-runtime/readers/viewpoint-collectors.js +0 -229
- package/dist/core-runtime/reconstruct/seed-candidate-validation.js +0 -385
- package/dist/core-runtime/review/citation-audit.test.js +0 -165
- package/dist/core-runtime/review/execution-plan-resolver.js +0 -247
- package/dist/core-runtime/review/execution-plan-resolver.test.js +0 -243
- package/dist/core-runtime/review/execution-topology-resolver-axis-first.test.js +0 -246
- package/dist/core-runtime/review/execution-topology-resolver.js +0 -401
- package/dist/core-runtime/review/execution-topology-resolver.test.js +0 -315
- package/dist/core-runtime/review/inline-context-embedder.test.js +0 -154
- package/dist/core-runtime/review/legacy-mode-policy.js +0 -88
- package/dist/core-runtime/review/materializers-effort-persist.test.js +0 -79
- package/dist/core-runtime/review/ontology-path-classifier.js +0 -179
- package/dist/core-runtime/review/ontology-path-classifier.test.js +0 -216
- package/dist/core-runtime/review/packet-boundary-policy.test.js +0 -107
- package/dist/core-runtime/review/participating-lens-paths.test.js +0 -73
- package/dist/core-runtime/review/review-config-legacy-translate.js +0 -244
- package/dist/core-runtime/review/review-config-legacy-translate.test.js +0 -161
- package/dist/core-runtime/review/review-config-validator.js +0 -289
- package/dist/core-runtime/review/review-config-validator.test.js +0 -236
- package/dist/core-runtime/review/shape-pipeline-audit.test.js +0 -311
- package/dist/core-runtime/review/shape-to-topology-id.js +0 -117
- package/dist/core-runtime/review/shape-to-topology-id.test.js +0 -132
- package/dist/core-runtime/review/topology-shape-derivation.js +0 -155
- package/dist/core-runtime/review/topology-shape-derivation.test.js +0 -195
- package/dist/core-runtime/scope-runtime/constants.js +0 -12
- package/dist/core-runtime/scope-runtime/constraint-pool.js +0 -166
- package/dist/core-runtime/scope-runtime/constraint-pool.test.js +0 -674
- package/dist/core-runtime/scope-runtime/domain-validation-log.js +0 -135
- package/dist/core-runtime/scope-runtime/domain-validation-log.test.js +0 -156
- package/dist/core-runtime/scope-runtime/eval-persistence.js +0 -65
- package/dist/core-runtime/scope-runtime/eval-persistence.test.js +0 -84
- package/dist/core-runtime/scope-runtime/event-pipeline.js +0 -64
- package/dist/core-runtime/scope-runtime/event-pipeline.test.js +0 -450
- package/dist/core-runtime/scope-runtime/event-store.js +0 -39
- package/dist/core-runtime/scope-runtime/event-store.test.js +0 -95
- package/dist/core-runtime/scope-runtime/gate-guard.js +0 -348
- package/dist/core-runtime/scope-runtime/gate-guard.test.js +0 -1047
- package/dist/core-runtime/scope-runtime/hash.js +0 -4
- package/dist/core-runtime/scope-runtime/hash.test.js +0 -33
- package/dist/core-runtime/scope-runtime/id.js +0 -4
- package/dist/core-runtime/scope-runtime/id.test.js +0 -17
- package/dist/core-runtime/scope-runtime/reducer.js +0 -297
- package/dist/core-runtime/scope-runtime/reducer.test.js +0 -759
- package/dist/core-runtime/scope-runtime/scope-manager.js +0 -161
- package/dist/core-runtime/scope-runtime/state-machine.js +0 -309
- package/dist/core-runtime/scope-runtime/state-machine.test.js +0 -704
- package/dist/core-runtime/scope-runtime/types.js +0 -116
- package/dist/core-runtime/scope-runtime/types.test.js +0 -69
- package/dist/core-runtime/translate/render-for-user.js +0 -169
- package/dist/core-runtime/translate/render-for-user.test.js +0 -122
- package/dist/providers/capability-contract.js +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
1
2
|
import fs from "node:fs/promises";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
@@ -5,29 +6,224 @@ import { callLlm } from "../llm/llm-caller.js";
|
|
|
5
6
|
import { loadCoreLensRegistry } from "../discovery/lens-registry.js";
|
|
6
7
|
import { writeSourceObservationDirectiveValidationArtifact } from "./directive-validation.js";
|
|
7
8
|
import { materializeReconstructPreparationArtifacts } from "./materialize-preparation.js";
|
|
8
|
-
import {
|
|
9
|
+
import { writeTargetMaterialProfileValidationArtifact } from "./material-profile-validation.js";
|
|
10
|
+
import { ANSWER_STATUSES, validateFinalOutputProvenance, writeClaimRealizationMapValidationForOntologySeedArtifact, writeCompetencyQuestionAssessmentValidationArtifact, writeCompetencyQuestionsValidationForOntologySeedArtifact, writeFailureClassificationValidationArtifact, writeRevisionProposalValidationArtifact, writeSeedConfirmationValidationForOntologySeedArtifact, } from "./post-seed-validation.js";
|
|
9
11
|
import { assembleReconstructRecord } from "./record.js";
|
|
10
|
-
import {
|
|
12
|
+
import { writeActionableOntologySeedValidationArtifact, writeCandidateDispositionValidationArtifact, } from "./actionable-seed-validation.js";
|
|
13
|
+
import { loadReconstructContractRegistry, } from "./contract-registry.js";
|
|
14
|
+
import { buildReconstructRunGoverningSnapshot } from "./governing-snapshot.js";
|
|
15
|
+
import { writeHandoffDecisionValidationArtifact, writeReconstructRunManifestValidationArtifact, } from "./terminal-validation.js";
|
|
16
|
+
import { ontologySeedAnswerabilitySummary, ontologySeedClaimProjections, ontologySeedExcludedClaimIds, } from "./seed-claim-projections.js";
|
|
11
17
|
function isoNow() {
|
|
12
18
|
return new Date().toISOString();
|
|
13
19
|
}
|
|
20
|
+
function isRecord(value) {
|
|
21
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22
|
+
}
|
|
23
|
+
function stableJson(value) {
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
return `[${value.map(stableJson).join(",")}]`;
|
|
26
|
+
}
|
|
27
|
+
if (isRecord(value)) {
|
|
28
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
|
|
29
|
+
}
|
|
30
|
+
return JSON.stringify(value);
|
|
31
|
+
}
|
|
32
|
+
function sha256Text(text) {
|
|
33
|
+
return crypto.createHash("sha256").update(text).digest("hex");
|
|
34
|
+
}
|
|
35
|
+
async function sha256File(filePath) {
|
|
36
|
+
return crypto.createHash("sha256").update(await fs.readFile(filePath)).digest("hex");
|
|
37
|
+
}
|
|
14
38
|
async function writeYamlDocument(filePath, value) {
|
|
15
39
|
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
16
40
|
await fs.writeFile(filePath, stringifyYaml(value), "utf8");
|
|
17
41
|
}
|
|
42
|
+
function validationViolationSummary(violations) {
|
|
43
|
+
if (!Array.isArray(violations) || violations.length === 0) {
|
|
44
|
+
return "no violation details recorded";
|
|
45
|
+
}
|
|
46
|
+
return violations.slice(0, 8).map((violation, index) => {
|
|
47
|
+
if (violation === null || typeof violation !== "object" || Array.isArray(violation)) {
|
|
48
|
+
return `${index + 1}. ${String(violation)}`;
|
|
49
|
+
}
|
|
50
|
+
const record = violation;
|
|
51
|
+
const code = typeof record.code === "string" ? record.code : "unknown";
|
|
52
|
+
const message = typeof record.message === "string" ? record.message : JSON.stringify(record);
|
|
53
|
+
const subject = typeof record.subject_id === "string"
|
|
54
|
+
? record.subject_id
|
|
55
|
+
: typeof record.claim_id === "string"
|
|
56
|
+
? record.claim_id
|
|
57
|
+
: typeof record.candidate_id === "string"
|
|
58
|
+
? record.candidate_id
|
|
59
|
+
: null;
|
|
60
|
+
return `${index + 1}. ${code}${subject ? ` (${subject})` : ""}: ${message}`;
|
|
61
|
+
}).join("; ");
|
|
62
|
+
}
|
|
63
|
+
function validationDetailSummary(validation) {
|
|
64
|
+
if (Array.isArray(validation.violations) && validation.violations.length > 0) {
|
|
65
|
+
return validationViolationSummary(validation.violations);
|
|
66
|
+
}
|
|
67
|
+
if (Array.isArray(validation.rejected_frontier_refs) &&
|
|
68
|
+
validation.rejected_frontier_refs.length > 0) {
|
|
69
|
+
return validation.rejected_frontier_refs.slice(0, 8).map((item, index) => {
|
|
70
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) {
|
|
71
|
+
return `${index + 1}. ${String(item)}`;
|
|
72
|
+
}
|
|
73
|
+
const record = item;
|
|
74
|
+
return `${index + 1}. ${String(record.reason ?? "rejected_frontier_ref")}: ${String(record.source_ref ?? record.frontier_ref_id ?? "unknown")}`;
|
|
75
|
+
}).join("; ");
|
|
76
|
+
}
|
|
77
|
+
return "no validation details recorded";
|
|
78
|
+
}
|
|
79
|
+
function assertRuntimeValidationValid(args) {
|
|
80
|
+
if (args.validation.validation_status === "valid")
|
|
81
|
+
return;
|
|
82
|
+
throw new Error(`${args.artifactName} validation failed at ${args.artifactRef}: ${validationDetailSummary(args.validation)}`);
|
|
83
|
+
}
|
|
18
84
|
async function readYamlDocument(filePath) {
|
|
19
85
|
return parseYaml(await fs.readFile(filePath, "utf8"));
|
|
20
86
|
}
|
|
21
|
-
function
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
87
|
+
function isMissingFile(error) {
|
|
88
|
+
return (typeof error === "object" &&
|
|
89
|
+
error !== null &&
|
|
90
|
+
"code" in error &&
|
|
91
|
+
error.code === "ENOENT");
|
|
92
|
+
}
|
|
93
|
+
async function readYamlDocumentIfPresent(filePath) {
|
|
94
|
+
try {
|
|
95
|
+
return await readYamlDocument(filePath);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (isMissingFile(error))
|
|
99
|
+
return null;
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function readTextIfPresent(filePath) {
|
|
104
|
+
try {
|
|
105
|
+
return await fs.readFile(filePath, "utf8");
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (isMissingFile(error))
|
|
109
|
+
return null;
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function exists(filePath) {
|
|
114
|
+
try {
|
|
115
|
+
await fs.access(filePath);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (isMissingFile(error))
|
|
120
|
+
return false;
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function authoredArtifactProvenancePath(filePath) {
|
|
125
|
+
return `${filePath}.reuse-provenance.yaml`;
|
|
126
|
+
}
|
|
127
|
+
function compatibilityHash(compatibility) {
|
|
128
|
+
return sha256Text(stableJson(compatibility));
|
|
129
|
+
}
|
|
130
|
+
function authoredArtifactCompatibility(args) {
|
|
131
|
+
return {
|
|
132
|
+
session_id: args.sessionId,
|
|
133
|
+
intent_sha256: sha256Text(args.intent),
|
|
134
|
+
target_refs_sha256: sha256Text(stableJson(args.targetRefs.map((ref) => path.resolve(ref)).sort())),
|
|
135
|
+
target_material_profile_sha256: sha256Text(stableJson({
|
|
136
|
+
target_refs: args.targetMaterialProfile.target_refs.map((ref) => path.resolve(ref)).sort(),
|
|
137
|
+
target_material_kind: args.targetMaterialProfile.target_material_kind,
|
|
138
|
+
target_material_kind_candidates: args.targetMaterialProfile.target_material_kind_candidates,
|
|
139
|
+
support_status: args.targetMaterialProfile.support_status,
|
|
140
|
+
selected_source_profiles: args.targetMaterialProfile.selected_source_profiles,
|
|
141
|
+
detection: args.targetMaterialProfile.detection.per_ref.map((item) => ({
|
|
142
|
+
ref: path.resolve(item.ref),
|
|
143
|
+
exists: item.exists,
|
|
144
|
+
kind: item.kind,
|
|
145
|
+
confidence: item.confidence,
|
|
146
|
+
})),
|
|
147
|
+
})),
|
|
148
|
+
source_inventory_sha256: sha256Text(stableJson(args.sourceInventory.inventory_units.map((unit) => ({
|
|
149
|
+
ref: path.resolve(unit.ref),
|
|
150
|
+
exists: unit.exists,
|
|
151
|
+
target_material_kind: unit.target_material_kind,
|
|
152
|
+
inventory_unit: unit.inventory_unit,
|
|
153
|
+
profile_ref: unit.profile_ref ? path.resolve(unit.profile_ref) : null,
|
|
154
|
+
scan_status: unit.scan_status,
|
|
155
|
+
skip_reason: unit.skip_reason,
|
|
156
|
+
})))),
|
|
157
|
+
source_observations_sha256: sha256Text(stableJson({
|
|
158
|
+
observations: args.sourceObservations.observations.map((observation) => ({
|
|
159
|
+
observation_id: observation.observation_id,
|
|
160
|
+
target_material_kind: observation.target_material_kind,
|
|
161
|
+
adapter_id: observation.adapter_id,
|
|
162
|
+
source_ref: path.resolve(observation.source_ref),
|
|
163
|
+
location: path.resolve(observation.location),
|
|
164
|
+
structural_data: {
|
|
165
|
+
path_kind: observation.structural_data.path_kind ?? null,
|
|
166
|
+
size_bytes: observation.structural_data.size_bytes ?? null,
|
|
167
|
+
line_count: observation.structural_data.line_count ?? null,
|
|
168
|
+
char_count: observation.structural_data.char_count ?? null,
|
|
169
|
+
content_sha256: observation.structural_data.content_sha256 ?? null,
|
|
170
|
+
excerpt_truncated: observation.structural_data.excerpt_truncated ?? null,
|
|
171
|
+
},
|
|
172
|
+
})),
|
|
173
|
+
skipped_refs: args.sourceObservations.skipped_refs.map((skipped) => ({
|
|
174
|
+
ref: path.resolve(skipped.ref),
|
|
175
|
+
target_material_kind: skipped.target_material_kind,
|
|
176
|
+
reason: skipped.reason,
|
|
177
|
+
})),
|
|
178
|
+
})),
|
|
179
|
+
governing_snapshot_sha256: sha256Text(stableJson(args.governingSnapshot)),
|
|
180
|
+
requested_domain_ids: args.governingSnapshot.requested_domain_ids,
|
|
181
|
+
semantic_author_realization: args.semanticAuthorRealization,
|
|
182
|
+
confirmation_provider_realization: args.confirmationProviderRealization,
|
|
183
|
+
directive_author_id: args.directiveAuthor.authorId,
|
|
184
|
+
confirmation_provider_id: args.confirmationProvider.providerId,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
async function writeFreshAuthoredYamlDocument(filePath, artifactName, create, options = {}) {
|
|
188
|
+
const currentCompatibilityHash = options.compatibility
|
|
189
|
+
? compatibilityHash(options.compatibility)
|
|
190
|
+
: null;
|
|
191
|
+
if (await exists(filePath)) {
|
|
192
|
+
if (options.reuseExisting) {
|
|
193
|
+
const provenancePath = authoredArtifactProvenancePath(filePath);
|
|
194
|
+
const provenance = await readYamlDocumentIfPresent(provenancePath);
|
|
195
|
+
if (!provenance) {
|
|
196
|
+
throw new Error(`${artifactName} already exists at ${filePath}, but ${provenancePath} is missing; explicit resume cannot prove authored artifact compatibility.`);
|
|
197
|
+
}
|
|
198
|
+
if (currentCompatibilityHash &&
|
|
199
|
+
provenance.compatibility_hash !== currentCompatibilityHash) {
|
|
200
|
+
throw new Error(`${artifactName} resume provenance mismatch at ${provenancePath}; existing authored artifact was produced for compatibility_hash=${provenance.compatibility_hash}, current compatibility_hash=${currentCompatibilityHash}.`);
|
|
201
|
+
}
|
|
202
|
+
const currentArtifactSha256 = await sha256File(filePath);
|
|
203
|
+
if (provenance.artifact_sha256 !== currentArtifactSha256) {
|
|
204
|
+
throw new Error(`${artifactName} artifact hash mismatch at ${filePath}; expected ${provenance.artifact_sha256}, got ${currentArtifactSha256}.`);
|
|
205
|
+
}
|
|
206
|
+
return readYamlDocument(filePath);
|
|
207
|
+
}
|
|
208
|
+
throw new Error(`${artifactName} already exists at ${filePath}; explicit resume or supersession is required before rewriting authored semantic artifacts.`);
|
|
209
|
+
}
|
|
210
|
+
const created = await create();
|
|
211
|
+
await writeYamlDocument(filePath, created);
|
|
212
|
+
if (options.compatibility && currentCompatibilityHash) {
|
|
213
|
+
await writeYamlDocument(authoredArtifactProvenancePath(filePath), {
|
|
214
|
+
schema_version: "1",
|
|
215
|
+
artifact_name: artifactName,
|
|
216
|
+
artifact_ref: filePath,
|
|
217
|
+
artifact_sha256: await sha256File(filePath),
|
|
218
|
+
created_at: isoNow(),
|
|
219
|
+
compatibility_hash: currentCompatibilityHash,
|
|
220
|
+
compatibility: options.compatibility,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return created;
|
|
224
|
+
}
|
|
225
|
+
function ontologyClaims(ontologySeed) {
|
|
226
|
+
return ontologySeedClaimProjections(ontologySeed);
|
|
31
227
|
}
|
|
32
228
|
function compactStatement(statement) {
|
|
33
229
|
const limit = 240;
|
|
@@ -36,19 +232,9 @@ function compactStatement(statement) {
|
|
|
36
232
|
function sourceBasename(sourceRef) {
|
|
37
233
|
return path.basename(sourceRef) || sourceRef;
|
|
38
234
|
}
|
|
39
|
-
function
|
|
40
|
-
|
|
41
|
-
["purpose", [seedCandidate.purpose]],
|
|
42
|
-
["non_goal", seedCandidate.non_goals],
|
|
43
|
-
["entity", seedCandidate.entities],
|
|
44
|
-
["relation", seedCandidate.relations],
|
|
45
|
-
["action", seedCandidate.actions],
|
|
46
|
-
["property", seedCandidate.properties],
|
|
47
|
-
["rule", seedCandidate.rules],
|
|
48
|
-
];
|
|
49
|
-
return groups.flatMap(([claimKind, claims]) => claims.map((claim) => ({
|
|
235
|
+
function claimRealizationTargets(claims) {
|
|
236
|
+
return claims.map((claim) => ({
|
|
50
237
|
claim_id: claim.claim_id,
|
|
51
|
-
claim_kind: claimKind,
|
|
52
238
|
name: claim.name,
|
|
53
239
|
statement: compactStatement(claim.statement),
|
|
54
240
|
evidence_observation_ids: [
|
|
@@ -57,7 +243,20 @@ function summarizeSeedClaimsForConfirmation(seedCandidate) {
|
|
|
57
243
|
evidence_source_basenames: [
|
|
58
244
|
...new Set(claim.evidence_refs.map((ref) => sourceBasename(ref.source_ref))),
|
|
59
245
|
],
|
|
60
|
-
}))
|
|
246
|
+
}));
|
|
247
|
+
}
|
|
248
|
+
function answerabilitySummary(ontologySeed) {
|
|
249
|
+
return ontologySeedAnswerabilitySummary(ontologySeed);
|
|
250
|
+
}
|
|
251
|
+
function ontologySeedSummaryLines(ontologySeed) {
|
|
252
|
+
const claims = ontologyClaims(ontologySeed);
|
|
253
|
+
const summary = ontologySeedAnswerabilitySummary(ontologySeed);
|
|
254
|
+
return [
|
|
255
|
+
`- Ontology seed projected claims: ${claims.length}`,
|
|
256
|
+
`- Coverage axes: ${summary.declared_question_count}`,
|
|
257
|
+
`- Action types: ${summary.supported_action_count + summary.unsupported_action_count}`,
|
|
258
|
+
`- Limited action types: ${summary.unsupported_action_count}`,
|
|
259
|
+
];
|
|
61
260
|
}
|
|
62
261
|
function countBy(values, selected) {
|
|
63
262
|
const counts = Object.fromEntries(values.map((value) => [value, 0]));
|
|
@@ -66,6 +265,15 @@ function countBy(values, selected) {
|
|
|
66
265
|
}
|
|
67
266
|
return counts;
|
|
68
267
|
}
|
|
268
|
+
function stopDecisionAllowedDecisions(input) {
|
|
269
|
+
const materialFailureCount = input.failureClassification.failures.filter((failure) => failure.materiality === "material").length;
|
|
270
|
+
const hasUnresolvedWork = input.metrics.unresolved_question_count > 0 ||
|
|
271
|
+
materialFailureCount > 0 ||
|
|
272
|
+
input.metrics.confirmation_state_counts.rejected > 0 ||
|
|
273
|
+
input.metrics.confirmation_state_counts.partial > 0 ||
|
|
274
|
+
input.metrics.confirmation_state_counts.deferred > 0;
|
|
275
|
+
return hasUnresolvedWork ? ["continue", "ask_user"] : ["stop", "continue", "ask_user"];
|
|
276
|
+
}
|
|
69
277
|
const CLAIM_REALIZATION_STANCES = [
|
|
70
278
|
"observed_runtime_behavior",
|
|
71
279
|
"declared_design_intent",
|
|
@@ -74,13 +282,6 @@ const CLAIM_REALIZATION_STANCES = [
|
|
|
74
282
|
"deferred_or_non_goal",
|
|
75
283
|
"unknown",
|
|
76
284
|
];
|
|
77
|
-
const ANSWER_STATUSES = [
|
|
78
|
-
"answered",
|
|
79
|
-
"partially_answered",
|
|
80
|
-
"not_answered",
|
|
81
|
-
"needs_evidence",
|
|
82
|
-
"out_of_scope",
|
|
83
|
-
];
|
|
84
285
|
const FAILURE_KINDS = [
|
|
85
286
|
"unsupported_claim",
|
|
86
287
|
"unanswered_question",
|
|
@@ -112,10 +313,26 @@ function requireFirstObservation(sourceObservations) {
|
|
|
112
313
|
}
|
|
113
314
|
return observation;
|
|
114
315
|
}
|
|
316
|
+
function assertSemanticAuthoringHasObservedEvidence(args) {
|
|
317
|
+
if (args.sourceObservations.observations.length > 0)
|
|
318
|
+
return;
|
|
319
|
+
const skipped = args.sourceInventory.inventory_units
|
|
320
|
+
.filter((unit) => unit.scan_status === "skipped")
|
|
321
|
+
.map((unit) => `${path.basename(unit.ref)}:${unit.target_material_kind}:${unit.skip_reason ?? "skipped"}`);
|
|
322
|
+
throw new Error([
|
|
323
|
+
"reconstruct semantic authoring requires at least one runtime source observation",
|
|
324
|
+
`target_material_kind=${args.targetMaterialProfile.target_material_kind}`,
|
|
325
|
+
`support_status=${args.targetMaterialProfile.support_status}`,
|
|
326
|
+
`unsupported_reason=${args.targetMaterialProfile.unsupported_reason ?? "none"}`,
|
|
327
|
+
`skipped_refs=${skipped.join(", ") || "none"}`,
|
|
328
|
+
].join("; "));
|
|
329
|
+
}
|
|
115
330
|
function calculateMetrics(args) {
|
|
116
331
|
const validationStatus = {
|
|
332
|
+
target_material_profile: args.targetMaterialProfileValidation.validation_status,
|
|
117
333
|
source_observation_directive: args.sourceObservationDirectiveValidation.validation_status,
|
|
118
|
-
|
|
334
|
+
candidate_disposition: args.candidateDispositionValidation.validation_status,
|
|
335
|
+
ontology_seed: args.ontologySeedValidation.validation_status,
|
|
119
336
|
seed_confirmation: args.seedConfirmation.confirmation_status,
|
|
120
337
|
claim_realization: args.claimRealizationMapValidation.validation_status,
|
|
121
338
|
seed_confirmation_validation: args.seedConfirmationValidation.validation_status,
|
|
@@ -129,7 +346,9 @@ function calculateMetrics(args) {
|
|
|
129
346
|
const deferredClaimCount = args.seedConfirmationValidation.deferred_claim_ids.length;
|
|
130
347
|
const invalidGateCount = [
|
|
131
348
|
validationStatus.source_observation_directive,
|
|
132
|
-
validationStatus.
|
|
349
|
+
validationStatus.target_material_profile,
|
|
350
|
+
validationStatus.candidate_disposition,
|
|
351
|
+
validationStatus.ontology_seed,
|
|
133
352
|
validationStatus.claim_realization,
|
|
134
353
|
validationStatus.seed_confirmation_validation,
|
|
135
354
|
validationStatus.competency_questions,
|
|
@@ -139,20 +358,22 @@ function calculateMetrics(args) {
|
|
|
139
358
|
].filter((status) => status !== "valid").length;
|
|
140
359
|
const unresolvedQuestionCount = rejectedClaimCount +
|
|
141
360
|
partialClaimCount +
|
|
361
|
+
args.sourceObservations.skipped_refs.length +
|
|
142
362
|
args.failureClassificationValidation.material_failure_count +
|
|
143
363
|
args.competencyQuestions.open_questions.length +
|
|
144
364
|
invalidGateCount;
|
|
145
365
|
const competencyQuestionCount = args.competencyQuestions.questions.length;
|
|
146
366
|
const passedQuestions = Math.max(0, competencyQuestionCount - unresolvedQuestionCount);
|
|
147
367
|
const answerStatusCounts = args.competencyQuestionAssessmentValidation.answer_status_counts;
|
|
368
|
+
const projectedOntologyClaims = ontologyClaims(args.ontologySeed);
|
|
148
369
|
return {
|
|
149
370
|
schema_version: "1",
|
|
150
371
|
session_id: args.sessionId,
|
|
151
372
|
created_at: isoNow(),
|
|
152
373
|
source_observation_count: args.sourceObservations.observations.length,
|
|
153
374
|
selected_observation_count: args.sourceObservationDirectiveValidation.selected_observation_count,
|
|
154
|
-
semantic_claim_count:
|
|
155
|
-
evidence_ref_count: args.
|
|
375
|
+
semantic_claim_count: projectedOntologyClaims.length,
|
|
376
|
+
evidence_ref_count: args.ontologySeedValidation.evidence_ref_count,
|
|
156
377
|
confirmed_claim_count: args.seedConfirmationValidation.accepted_claim_ids.length,
|
|
157
378
|
rejected_claim_count: rejectedClaimCount,
|
|
158
379
|
partial_claim_count: partialClaimCount,
|
|
@@ -161,8 +382,9 @@ function calculateMetrics(args) {
|
|
|
161
382
|
competency_question_assessment_count: args.competencyQuestionAssessmentValidation.assessment_count,
|
|
162
383
|
unresolved_question_count: unresolvedQuestionCount,
|
|
163
384
|
deferred_count: deferredClaimCount +
|
|
164
|
-
answerStatusCounts.
|
|
385
|
+
answerStatusCounts.deferred +
|
|
165
386
|
args.failureClassificationValidation.failure_kind_counts.deferred_scope,
|
|
387
|
+
answerability_summary: answerabilitySummary(args.ontologySeed),
|
|
166
388
|
claim_realization_stance_counts: args.claimRealizationMapValidation.stance_counts,
|
|
167
389
|
confirmation_state_counts: {
|
|
168
390
|
accepted: args.seedConfirmationValidation.accepted_claim_ids.length,
|
|
@@ -182,6 +404,7 @@ function calculateMetrics(args) {
|
|
|
182
404
|
function artifactRefsWithDefaults(args) {
|
|
183
405
|
return {
|
|
184
406
|
target_material_profile: args.refs.target_material_profile ?? null,
|
|
407
|
+
target_material_profile_validation: args.refs.target_material_profile_validation ?? null,
|
|
185
408
|
source_inventory: args.refs.source_inventory ?? null,
|
|
186
409
|
initial_source_frontier: args.refs.initial_source_frontier ?? null,
|
|
187
410
|
source_observations: args.refs.source_observations ?? null,
|
|
@@ -191,10 +414,11 @@ function artifactRefsWithDefaults(args) {
|
|
|
191
414
|
exploration_synthesis: args.refs.exploration_synthesis ?? null,
|
|
192
415
|
source_frontier: args.refs.source_frontier ?? null,
|
|
193
416
|
source_frontier_validation: args.refs.source_frontier_validation ?? null,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
417
|
+
candidate_inventory: args.refs.candidate_inventory ?? null,
|
|
418
|
+
candidate_disposition: args.refs.candidate_disposition ?? null,
|
|
419
|
+
candidate_disposition_validation: args.refs.candidate_disposition_validation ?? null,
|
|
420
|
+
ontology_seed: args.refs.ontology_seed ?? null,
|
|
421
|
+
ontology_seed_validation: args.refs.ontology_seed_validation ?? null,
|
|
198
422
|
claim_realization_map: args.refs.claim_realization_map ?? null,
|
|
199
423
|
claim_realization_map_validation: args.refs.claim_realization_map_validation ?? null,
|
|
200
424
|
seed_confirmation: args.refs.seed_confirmation ?? null,
|
|
@@ -209,7 +433,11 @@ function artifactRefsWithDefaults(args) {
|
|
|
209
433
|
revision_proposal_validation: args.refs.revision_proposal_validation ?? null,
|
|
210
434
|
reconstruct_metrics: args.refs.reconstruct_metrics ?? null,
|
|
211
435
|
stop_decision: args.refs.stop_decision ?? null,
|
|
436
|
+
pre_handoff_run_manifest_validation: args.refs.pre_handoff_run_manifest_validation ?? null,
|
|
437
|
+
post_publication_run_manifest_validation: args.refs.post_publication_run_manifest_validation ?? null,
|
|
438
|
+
handoff_decision_validation: args.refs.handoff_decision_validation ?? null,
|
|
212
439
|
final_output: args.refs.final_output ?? null,
|
|
440
|
+
final_output_provenance_validation: args.refs.final_output_provenance_validation ?? null,
|
|
213
441
|
reconstruct_run_manifest: args.refs.reconstruct_run_manifest ?? null,
|
|
214
442
|
};
|
|
215
443
|
}
|
|
@@ -255,6 +483,13 @@ function confirmationProviderPerformer(confirmationProvider) {
|
|
|
255
483
|
};
|
|
256
484
|
}
|
|
257
485
|
function createRunManifest(args) {
|
|
486
|
+
const artifactRefs = args.terminalArtifactsCompleted
|
|
487
|
+
? args.artifactRefs
|
|
488
|
+
: {
|
|
489
|
+
...args.artifactRefs,
|
|
490
|
+
handoff_decision_validation: null,
|
|
491
|
+
final_output: null,
|
|
492
|
+
};
|
|
258
493
|
return {
|
|
259
494
|
schema_version: "1",
|
|
260
495
|
session_id: args.sessionId,
|
|
@@ -279,12 +514,16 @@ function createRunManifest(args) {
|
|
|
279
514
|
: "Runtime completed the live integral reconstruct path for the produced and explicitly skipped artifacts.",
|
|
280
515
|
},
|
|
281
516
|
artifact_refs: {
|
|
282
|
-
...
|
|
283
|
-
reconstruct_record: args.
|
|
517
|
+
...artifactRefs,
|
|
518
|
+
reconstruct_record: args.terminalArtifactsCompleted
|
|
519
|
+
? args.reconstructRecordPath
|
|
520
|
+
: null,
|
|
284
521
|
},
|
|
522
|
+
governing_snapshot: args.governingSnapshot,
|
|
285
523
|
happy_path_scope: {
|
|
286
524
|
implemented_artifacts: [
|
|
287
525
|
"target_material_profile",
|
|
526
|
+
"target_material_profile_validation",
|
|
288
527
|
"source_inventory",
|
|
289
528
|
"initial_source_frontier",
|
|
290
529
|
"source_observations",
|
|
@@ -294,8 +533,11 @@ function createRunManifest(args) {
|
|
|
294
533
|
"exploration_synthesis",
|
|
295
534
|
"source_frontier",
|
|
296
535
|
"source_frontier_validation",
|
|
297
|
-
"
|
|
298
|
-
"
|
|
536
|
+
"candidate_inventory",
|
|
537
|
+
"candidate_disposition",
|
|
538
|
+
"candidate_disposition_validation",
|
|
539
|
+
"ontology_seed",
|
|
540
|
+
"ontology_seed_validation",
|
|
299
541
|
"claim_realization_map",
|
|
300
542
|
"claim_realization_map_validation",
|
|
301
543
|
"seed_confirmation",
|
|
@@ -310,21 +552,31 @@ function createRunManifest(args) {
|
|
|
310
552
|
"revision_proposal_validation",
|
|
311
553
|
"reconstruct_metrics",
|
|
312
554
|
"stop_decision",
|
|
313
|
-
"
|
|
555
|
+
"pre_handoff_run_manifest_validation",
|
|
556
|
+
"handoff_decision_validation",
|
|
314
557
|
"reconstruct_run_manifest",
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
558
|
+
...(args.terminalArtifactsCompleted
|
|
559
|
+
? [
|
|
560
|
+
"final_output",
|
|
561
|
+
"final_output_provenance_validation",
|
|
562
|
+
"post_publication_run_manifest_validation",
|
|
563
|
+
"reconstruct_record",
|
|
564
|
+
]
|
|
565
|
+
: []),
|
|
320
566
|
],
|
|
321
|
-
|
|
567
|
+
deferred_artifacts: [],
|
|
568
|
+
deferred_reason: args.governingSnapshot.requested_domain_ids.length > 0
|
|
569
|
+
? "Domain competency admission is recorded in governing_snapshot; no separate domain competency selection artifact is active."
|
|
570
|
+
: "No reconstruct artifacts are deferred by the active runtime contract.",
|
|
322
571
|
},
|
|
323
572
|
steps: [
|
|
324
573
|
completedStep("invocation_binding", "runtime", runtimePerformer(), []),
|
|
325
574
|
completedStep("target_material_profile", "runtime", runtimePerformer(), [
|
|
326
575
|
args.artifactRefs.target_material_profile,
|
|
327
576
|
].filter((ref) => ref !== null)),
|
|
577
|
+
completedStep("target_material_profile_validation", "runtime", runtimePerformer(), [
|
|
578
|
+
args.artifactRefs.target_material_profile_validation,
|
|
579
|
+
].filter((ref) => ref !== null)),
|
|
328
580
|
completedStep("source_inventory", "runtime", runtimePerformer(), [
|
|
329
581
|
args.artifactRefs.source_inventory,
|
|
330
582
|
].filter((ref) => ref !== null)),
|
|
@@ -348,12 +600,17 @@ function createRunManifest(args) {
|
|
|
348
600
|
completedStep("source_frontier_validation", "runtime", runtimePerformer(), [
|
|
349
601
|
args.artifactRefs.source_frontier_validation,
|
|
350
602
|
].filter((ref) => ref !== null)),
|
|
351
|
-
|
|
352
|
-
skippedStep("domain_context_selection_validation", "runtime", runtimePerformer(), "domain context selection was skipped.", "Runtime cannot validate domain snapshot identity for this run."),
|
|
353
|
-
completedStep("seed_candidate", "host_llm", directiveAuthorPerformer(args.directiveAuthor), [args.artifactRefs.seed_candidate]
|
|
603
|
+
completedStep("candidate_inventory", "host_llm", directiveAuthorPerformer(args.directiveAuthor), [args.artifactRefs.candidate_inventory]
|
|
354
604
|
.filter((ref) => ref !== null)),
|
|
355
|
-
completedStep("
|
|
356
|
-
|
|
605
|
+
completedStep("candidate_disposition", "host_llm", directiveAuthorPerformer(args.directiveAuthor), [args.artifactRefs.candidate_disposition]
|
|
606
|
+
.filter((ref) => ref !== null)),
|
|
607
|
+
completedStep("candidate_disposition_validation", "runtime", runtimePerformer(), [
|
|
608
|
+
args.artifactRefs.candidate_disposition_validation,
|
|
609
|
+
].filter((ref) => ref !== null)),
|
|
610
|
+
completedStep("ontology_seed", "host_llm", directiveAuthorPerformer(args.directiveAuthor), [args.artifactRefs.ontology_seed]
|
|
611
|
+
.filter((ref) => ref !== null)),
|
|
612
|
+
completedStep("ontology_seed_validation", "runtime", runtimePerformer(), [
|
|
613
|
+
args.artifactRefs.ontology_seed_validation,
|
|
357
614
|
].filter((ref) => ref !== null)),
|
|
358
615
|
completedStep("claim_realization", "host_llm", directiveAuthorPerformer(args.directiveAuthor), [args.artifactRefs.claim_realization_map]
|
|
359
616
|
.filter((ref) => ref !== null)),
|
|
@@ -390,11 +647,29 @@ function createRunManifest(args) {
|
|
|
390
647
|
].filter((ref) => ref !== null)),
|
|
391
648
|
completedStep("stop_decision", "host_llm", directiveAuthorPerformer(args.directiveAuthor), [args.artifactRefs.stop_decision]
|
|
392
649
|
.filter((ref) => ref !== null)),
|
|
393
|
-
completedStep("
|
|
394
|
-
.
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
650
|
+
completedStep("pre_handoff_run_manifest_validation", "runtime", runtimePerformer(), [
|
|
651
|
+
args.artifactRefs.pre_handoff_run_manifest_validation,
|
|
652
|
+
].filter((ref) => ref !== null)),
|
|
653
|
+
args.terminalArtifactsCompleted
|
|
654
|
+
? completedStep("handoff_decision_validation", "runtime", runtimePerformer(), [
|
|
655
|
+
args.artifactRefs.handoff_decision_validation,
|
|
656
|
+
].filter((ref) => ref !== null))
|
|
657
|
+
: skippedStep("handoff_decision_validation", "runtime", runtimePerformer(), "handoff-decision-validation.yaml is emitted after pre-handoff manifest validation.", "Pre-handoff manifest validation must not certify future handoff validation."),
|
|
658
|
+
args.terminalArtifactsCompleted
|
|
659
|
+
? completedStep("final_output", "host_llm", directiveAuthorPerformer(args.directiveAuthor), [args.artifactRefs.final_output]
|
|
660
|
+
.filter((ref) => ref !== null))
|
|
661
|
+
: skippedStep("final_output", "host_llm", directiveAuthorPerformer(args.directiveAuthor), "final-output.md is emitted after handoff validation.", "Pre-handoff manifest validation must not certify future final output."),
|
|
662
|
+
args.terminalArtifactsCompleted
|
|
663
|
+
? completedStep("final_output_provenance_validation", "runtime", runtimePerformer(), [args.artifactRefs.final_output_provenance_validation]
|
|
664
|
+
.filter((ref) => ref !== null))
|
|
665
|
+
: skippedStep("final_output_provenance_validation", "runtime", runtimePerformer(), "final-output-provenance-validation.yaml is emitted after final output.", "Pre-handoff manifest validation must not certify future final-output provenance."),
|
|
666
|
+
args.terminalArtifactsCompleted
|
|
667
|
+
? completedStep("record_assembly", "runtime", runtimePerformer(), [args.reconstructRecordPath])
|
|
668
|
+
: skippedStep("record_assembly", "runtime", runtimePerformer(), "reconstruct-record.yaml is assembled after final output provenance validation.", "Pre-handoff manifest validation must not certify future record assembly."),
|
|
669
|
+
args.terminalArtifactsCompleted
|
|
670
|
+
? completedStep("post_publication_run_manifest_validation", "runtime", runtimePerformer(), [args.artifactRefs.post_publication_run_manifest_validation]
|
|
671
|
+
.filter((ref) => ref !== null))
|
|
672
|
+
: skippedStep("post_publication_run_manifest_validation", "runtime", runtimePerformer(), "post-publication run-manifest validation is emitted after final output and record refs exist.", "Pre-handoff manifest validation must not certify future post-publication audit."),
|
|
398
673
|
],
|
|
399
674
|
runtime_boundary: {
|
|
400
675
|
semantic_generation: "not_performed",
|
|
@@ -454,6 +729,59 @@ function stringArray(value, fieldName) {
|
|
|
454
729
|
throw new Error(`${fieldName} must be an array.`);
|
|
455
730
|
return value.map((item, index) => stringValue(item, `${fieldName}[${index}]`));
|
|
456
731
|
}
|
|
732
|
+
function downstreamEffectForAnswerStatus(answerStatus) {
|
|
733
|
+
switch (answerStatus) {
|
|
734
|
+
case "answerable":
|
|
735
|
+
return "ready";
|
|
736
|
+
case "partially_answerable":
|
|
737
|
+
return "limited";
|
|
738
|
+
case "deferred":
|
|
739
|
+
return "blocked_by_missing_source_or_confirmation";
|
|
740
|
+
case "not_applicable":
|
|
741
|
+
return "not_applicable";
|
|
742
|
+
case "unsupported":
|
|
743
|
+
case "contradicted":
|
|
744
|
+
return "blocks_handoff";
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
function recordValue(value, fieldName) {
|
|
748
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
749
|
+
throw new Error(`${fieldName} must be an object.`);
|
|
750
|
+
}
|
|
751
|
+
return value;
|
|
752
|
+
}
|
|
753
|
+
function enumString(value, allowed, fieldName) {
|
|
754
|
+
const raw = stringValue(value, fieldName);
|
|
755
|
+
if (!allowed.includes(raw)) {
|
|
756
|
+
throw new Error(`${fieldName} must be one of: ${allowed.join(", ")}.`);
|
|
757
|
+
}
|
|
758
|
+
return raw;
|
|
759
|
+
}
|
|
760
|
+
function enumChoices(values) {
|
|
761
|
+
return values.join("|");
|
|
762
|
+
}
|
|
763
|
+
const ACTIONABLE_ONTOLOGY_SEED_JSON_SHAPE = [
|
|
764
|
+
"Return exactly one JSON object with these root fields:",
|
|
765
|
+
"seed_identity={schema_version,seed_id,title,target_refs,generated_at,authoring_profile}",
|
|
766
|
+
"purpose={declared_purpose,intended_decisions,intended_actions,non_goals,evidence_refs}",
|
|
767
|
+
"decision_context={principal_user,downstream_use,decision_boundary,risk_notes}",
|
|
768
|
+
"conceptual_frame={concepts:[{concept_id,name,definition,purpose_role,evidence_refs,confidence}],associations:[{association_id,source_concept_id,target_concept_id,association_kind,statement,evidence_refs}]}",
|
|
769
|
+
"semantic_layer={object_types:[{object_type_id,name,object_kind,description,primary_key:{property_id,name,value_type,evidence_refs},properties:[{property_id,name,value_type,nullable,description,constraints,evidence_refs}],backing_source_refs,evidence_refs,status}],link_types:[{link_type_id,source_object_type_id,target_object_type_id,cardinality,business_meaning,evidence_refs}],value_types:[{value_type_id,name,representation,constraints,evidence_refs}],constraints:[{constraint_id,target_ref,constraint_kind,statement,evidence_refs}]}",
|
|
770
|
+
"kinetic_layer={action_types:[{action_type_id,name,description,actor_type_ids,target_object_type_ids,affected_object_type_ids,parameters:[{parameter_id,name,value_source,value_type,required}],preconditions:[{precondition_id,statement,evidence_refs}],postconditions:[{postcondition_id,statement,evidence_refs}],side_effects:[{side_effect_id,statement,failure_behavior,evidence_refs}],writeback_behavior:{writes,writeback_source_refs,rationale},evidence_refs,status}],functions:[{function_id,name,input_type_refs,return_type_ref,purity,evidence_refs}],workflows:[{workflow_id,name,ordered_action_type_ids,trigger,terminal_state,evidence_refs}]}",
|
|
771
|
+
"dynamic_layer={actor_types:[{actor_type_id,name,actor_kind,role_refs,description,evidence_refs}],actor_roles:[{role_id,name,holder_actor_type_ids,authority_scope_refs,evidence_refs}],permission_policies:[{policy_id,actor_type_id,action_type_id,object_type_id,permission_kind,condition,evidence_refs}],state_models:[{state_model_id,object_type_id,states,transitions:[{transition_id,from_state,to_state,action_type_id,evidence_refs}]}],lifecycle_rules:[{rule_id,target_ref,statement,evidence_refs}]}",
|
|
772
|
+
"data_binding_layer={source_bindings:[{binding_id,seed_ref,source_ref,binding_kind,statement,evidence_refs}],read_models:[{read_model_id,name,object_type_ids,source_refs,transformation_summary,evidence_refs}],writebacks:[{writeback_id,action_type_id,target_source_refs,write_mode,evidence_refs}],provenance_bindings:[{provenance_id,seed_ref,source_ref,author_or_system,timestamp_ref,evidence_refs}]}",
|
|
773
|
+
"validation_layer={question_authority_ref:{authority_scope,projection_policy},coverage_axes,unsupported_question_candidates:[{candidate_id,question,unsupported_reason,needed_source_or_confirmation}],runtime_validation_refs:[{authority_scope,projection_policy}]}",
|
|
774
|
+
"candidate_disposition_authority_ref={authority_scope,projection_policy}",
|
|
775
|
+
"ontology_handoff={readiness_claim,classification_mapping,entity_identity_mapping,instance_assertion_mapping,terminology_mapping,relation_type_mapping,constraint_mapping,modularity_boundary,reasoning_or_formalism_profile,application_context_mapping,metadata_mapping,provenance_mapping,change_tracking_mapping,competency_scope_mapping,alignment_mapping,modeling_concern_applicability,reference_standard_mapping,pattern_catalog_mapping,query_access_contract,visualization_contract,graph_exploration_contract,graph_connectivity,limitation_refs}",
|
|
776
|
+
"source_authority={evidence_scope,permission_scope,trust_boundary,instruction_authority,external_content_handling,included_source_refs,excluded_source_refs,restricted_source_refs,source_gaps,rationale}",
|
|
777
|
+
"handoff_limitations=[{limitation_id,limitation_kind,description,affected_refs,missing_source_refs,mitigation_or_next_action,evidence_refs}]",
|
|
778
|
+
"Every evidence_refs item must be an object copied from an observed source with observation_id,target_material_kind,source_ref,location. Do not use a bare observation id string in evidence_refs.",
|
|
779
|
+
"Use the exact *_id key names above. Do not use id, claim_id, or candidate_id as a substitute for concept_id, object_type_id, actor_type_id, action_type_id, workflow_id, limitation_id, etc.",
|
|
780
|
+
"data_binding_layer.source_bindings.source_ref, read_models.source_refs, writebacks.target_source_refs, provenance_bindings.source_ref, source_authority.included_source_refs, and source_authority.excluded_source_refs must use only observed_source_refs.",
|
|
781
|
+
"Do not put runtime artifact refs such as source-observations.yaml, candidate-disposition.yaml, validation files, or final-output.md into source_ref fields. Runtime artifacts may be named in timestamp_ref, authority_ref, rationale, or mapping text only.",
|
|
782
|
+
"Skipped or unsupported material refs must not appear in included_source_refs or excluded_source_refs; record them in source_authority.source_gaps or handoff_limitations.missing_source_refs instead.",
|
|
783
|
+
"Every semantic_layer.object_types[].object_type_id must be covered by at least one of source_bindings.seed_ref, read_models.object_type_ids, provenance_bindings.seed_ref, or handoff_limitations.affected_refs.",
|
|
784
|
+
].join("\n");
|
|
457
785
|
function evidenceRefByObservationId(sourceObservations) {
|
|
458
786
|
return new Map(sourceObservations.observations.map((observation) => [
|
|
459
787
|
observation.observation_id,
|
|
@@ -474,37 +802,545 @@ function evidenceRefsFromIds(args) {
|
|
|
474
802
|
}
|
|
475
803
|
return refs;
|
|
476
804
|
}
|
|
477
|
-
function
|
|
478
|
-
|
|
805
|
+
function candidateKindIds(registry) {
|
|
806
|
+
return registry.candidate_kind_registry.map((record) => record.candidate_kind_id);
|
|
807
|
+
}
|
|
808
|
+
function candidateDispositionIds(registry) {
|
|
809
|
+
return registry.candidate_disposition_registry.map((record) => record.disposition_id);
|
|
810
|
+
}
|
|
811
|
+
function coverageAxisIds(registry) {
|
|
812
|
+
return registry.coverage_axis_registry.map((record) => record.axis_id);
|
|
813
|
+
}
|
|
814
|
+
function facetIds(records) {
|
|
815
|
+
return records.map((record) => record.facet_id);
|
|
816
|
+
}
|
|
817
|
+
function modelingConcernIds(registry) {
|
|
818
|
+
return registry.modeling_concern_applicability_registry.map((record) => record.concern_id);
|
|
819
|
+
}
|
|
820
|
+
function proofContractIds(records) {
|
|
821
|
+
return records.map((record) => record.contract_ref_id);
|
|
822
|
+
}
|
|
823
|
+
function candidateInventoryItemFromLlm(args) {
|
|
824
|
+
const fieldName = `candidates[${args.index}]`;
|
|
825
|
+
const candidateId = stringValue(args.raw.candidate_id, `${fieldName}.candidate_id`);
|
|
479
826
|
return {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
827
|
+
candidate_id: candidateId,
|
|
828
|
+
candidate_kind: stringValue(args.raw.candidate_kind, `${fieldName}.candidate_kind`),
|
|
829
|
+
name: stringValue(args.raw.name, `${fieldName}.name`),
|
|
830
|
+
description: stringValue(args.raw.description, `${fieldName}.description`),
|
|
831
|
+
salience: enumString(args.raw.salience, ["high", "medium", "low"], `${fieldName}.salience`),
|
|
483
832
|
evidence_refs: evidenceRefsFromIds({
|
|
484
|
-
observationIds: stringArray(args.raw.evidence_observation_ids, `${
|
|
833
|
+
observationIds: stringArray(args.raw.evidence_observation_ids, `${fieldName}.evidence_observation_ids`),
|
|
485
834
|
sourceObservations: args.sourceObservations,
|
|
486
|
-
fieldName: `${
|
|
835
|
+
fieldName: `${fieldName}.evidence_observation_ids`,
|
|
487
836
|
}),
|
|
488
837
|
};
|
|
489
838
|
}
|
|
490
|
-
function
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
839
|
+
function candidateDispositionItemFromLlm(args) {
|
|
840
|
+
const fieldName = `dispositions[${args.index}]`;
|
|
841
|
+
return {
|
|
842
|
+
candidate_id: stringValue(args.raw.candidate_id, `${fieldName}.candidate_id`),
|
|
843
|
+
disposition_id: stringValue(args.raw.disposition_id, `${fieldName}.disposition_id`),
|
|
844
|
+
target_seed_refs: stringArray(args.raw.target_seed_refs, `${fieldName}.target_seed_refs`),
|
|
845
|
+
rationale: stringValue(args.raw.rationale, `${fieldName}.rationale`),
|
|
846
|
+
evidence_refs: evidenceRefsFromIds({
|
|
847
|
+
observationIds: stringArray(args.raw.evidence_observation_ids, `${fieldName}.evidence_observation_ids`),
|
|
848
|
+
sourceObservations: args.sourceObservations,
|
|
849
|
+
fieldName: `${fieldName}.evidence_observation_ids`,
|
|
850
|
+
}),
|
|
851
|
+
};
|
|
497
852
|
}
|
|
498
|
-
function
|
|
499
|
-
return
|
|
853
|
+
function firstEvidenceRef(sourceObservations) {
|
|
854
|
+
return evidenceRefFromObservation(requireFirstObservation(sourceObservations));
|
|
855
|
+
}
|
|
856
|
+
function mockCandidateInventory(args) {
|
|
857
|
+
const evidence = firstEvidenceRef(args.sourceObservations);
|
|
858
|
+
return {
|
|
859
|
+
schema_version: "1",
|
|
860
|
+
session_id: args.sessionId,
|
|
861
|
+
created_at: isoNow(),
|
|
862
|
+
source_observations_ref: "source-observations.yaml",
|
|
863
|
+
candidates: [
|
|
864
|
+
{
|
|
865
|
+
candidate_id: "candidate-observed-material",
|
|
866
|
+
candidate_kind: "object",
|
|
867
|
+
name: "Observed Material",
|
|
868
|
+
description: "The observed source material represented as a seed object.",
|
|
869
|
+
salience: "high",
|
|
870
|
+
evidence_refs: [evidence],
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
candidate_id: "candidate-reconstruct-user",
|
|
874
|
+
candidate_kind: "actor",
|
|
875
|
+
name: "Reconstruct User",
|
|
876
|
+
description: "The user who will consume the reconstructed seed.",
|
|
877
|
+
salience: "high",
|
|
878
|
+
evidence_refs: [evidence],
|
|
879
|
+
},
|
|
880
|
+
{
|
|
881
|
+
candidate_id: "candidate-explain-seed",
|
|
882
|
+
candidate_kind: "action",
|
|
883
|
+
name: "Explain Seed",
|
|
884
|
+
description: "The action of explaining the observed material through the seed.",
|
|
885
|
+
salience: "high",
|
|
886
|
+
evidence_refs: [evidence],
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
candidate_id: "candidate-observed-source",
|
|
890
|
+
candidate_kind: "data_source",
|
|
891
|
+
name: "Observed Source",
|
|
892
|
+
description: "The runtime-observed source ref used as evidence.",
|
|
893
|
+
salience: "high",
|
|
894
|
+
evidence_refs: [evidence],
|
|
895
|
+
},
|
|
896
|
+
],
|
|
897
|
+
directive_author: {
|
|
898
|
+
owner: "mock",
|
|
899
|
+
author_id: args.authorId,
|
|
900
|
+
},
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
function mockCandidateDisposition(args) {
|
|
904
|
+
const targetByCandidateId = new Map([
|
|
905
|
+
["candidate-observed-material", "object-observed-material"],
|
|
906
|
+
["candidate-reconstruct-user", "actor-reconstruct-user"],
|
|
907
|
+
["candidate-explain-seed", "action-explain-seed"],
|
|
908
|
+
["candidate-observed-source", "binding-observed-source"],
|
|
909
|
+
]);
|
|
910
|
+
return {
|
|
911
|
+
schema_version: "1",
|
|
912
|
+
session_id: args.sessionId,
|
|
913
|
+
created_at: isoNow(),
|
|
914
|
+
candidate_inventory_ref: "candidate-inventory.yaml",
|
|
915
|
+
dispositions: args.candidateInventory.candidates.map((candidate) => ({
|
|
916
|
+
candidate_id: candidate.candidate_id,
|
|
917
|
+
disposition_id: "promoted_to_seed_layer",
|
|
918
|
+
target_seed_refs: [
|
|
919
|
+
targetByCandidateId.get(candidate.candidate_id) ?? `seed-ref-${candidate.candidate_id}`,
|
|
920
|
+
],
|
|
921
|
+
rationale: `${candidate.name} is promoted into the mock actionable seed surface.`,
|
|
922
|
+
evidence_refs: candidate.evidence_refs,
|
|
923
|
+
})),
|
|
924
|
+
directive_author: {
|
|
925
|
+
owner: "mock",
|
|
926
|
+
author_id: args.authorId,
|
|
927
|
+
},
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
function mockOntologyHandoff() {
|
|
931
|
+
return {
|
|
932
|
+
readiness_claim: "ready",
|
|
933
|
+
classification_mapping: {
|
|
934
|
+
ontology_scope_kind: "application_ontology_seed",
|
|
935
|
+
classification_axis_policy: "object, actor, action, and data-binding layers",
|
|
936
|
+
classification_level_axis_refs: [
|
|
937
|
+
"object-observed-material",
|
|
938
|
+
"actor-reconstruct-user",
|
|
939
|
+
"action-explain-seed",
|
|
940
|
+
],
|
|
941
|
+
inheritance_model: "flat_seed_layer",
|
|
942
|
+
mece_status: "not_asserted",
|
|
943
|
+
seed_refs: [
|
|
944
|
+
"object-observed-material",
|
|
945
|
+
"actor-reconstruct-user",
|
|
946
|
+
"action-explain-seed",
|
|
947
|
+
],
|
|
948
|
+
limitation_refs: [],
|
|
949
|
+
},
|
|
950
|
+
entity_identity_mapping: {
|
|
951
|
+
entity_id_policy: "stable seed ids",
|
|
952
|
+
uri_or_iri_policy: "not_assigned",
|
|
953
|
+
canonical_identifier_refs: [
|
|
954
|
+
"object-observed-material",
|
|
955
|
+
"actor-reconstruct-user",
|
|
956
|
+
"action-explain-seed",
|
|
957
|
+
],
|
|
958
|
+
alias_identifier_refs: [],
|
|
959
|
+
primitive_vs_defined_status: "defined_by_seed_record",
|
|
960
|
+
definition_criteria_refs: ["object-observed-material"],
|
|
961
|
+
limitation_refs: [],
|
|
962
|
+
},
|
|
963
|
+
instance_assertion_mapping: {
|
|
964
|
+
instance_availability_status: "present",
|
|
965
|
+
instance_refs: ["object-observed-material"],
|
|
966
|
+
example_assertion_refs: ["action-explain-seed"],
|
|
967
|
+
abox_assertion_refs: [],
|
|
968
|
+
limitation_refs: [],
|
|
969
|
+
},
|
|
970
|
+
terminology_mapping: {
|
|
971
|
+
canonical_label_policy: "seed names are canonical labels",
|
|
972
|
+
alias_policy: "aliases are not asserted",
|
|
973
|
+
hidden_label_policy: "hidden labels are not asserted",
|
|
974
|
+
homonym_policy: "not assessed in mock path",
|
|
975
|
+
multilingual_label_policy: "single-language mock labels",
|
|
976
|
+
language_tag_policy: "und",
|
|
977
|
+
limitation_refs: [],
|
|
978
|
+
},
|
|
979
|
+
relation_type_mapping: {
|
|
980
|
+
relation_type_refs: [],
|
|
981
|
+
formal_relation_semantics: "No link types are asserted; action bindings express operational relations.",
|
|
982
|
+
domain_range_declaration_refs: ["action-explain-seed"],
|
|
983
|
+
relation_property_constraint_refs: [],
|
|
984
|
+
unsupported_relation_candidates: [],
|
|
985
|
+
limitation_refs: [],
|
|
986
|
+
},
|
|
987
|
+
constraint_mapping: {
|
|
988
|
+
constraint_refs: [],
|
|
989
|
+
tbox_constraint_refs: [],
|
|
990
|
+
abox_assertion_constraint_refs: [],
|
|
991
|
+
shape_or_validation_constraint_refs: ["runtime_seed_validator"],
|
|
992
|
+
policy_constraint_refs: ["policy-explain-seed"],
|
|
993
|
+
unsupported_constraint_candidates: [],
|
|
994
|
+
limitation_refs: [],
|
|
995
|
+
},
|
|
996
|
+
modularity_boundary: {
|
|
997
|
+
module_candidates: ["observed_material_seed_module"],
|
|
998
|
+
import_or_reuse_refs: [],
|
|
999
|
+
limitation_refs: [],
|
|
1000
|
+
},
|
|
1001
|
+
reasoning_or_formalism_profile: {
|
|
1002
|
+
representation_formalism: "informal_actionable_graph",
|
|
1003
|
+
vocabulary_systems: ["custom_controlled_vocabulary"],
|
|
1004
|
+
validation_formalisms: ["custom_runtime_validator"],
|
|
1005
|
+
ontology_type: "application_ontology",
|
|
1006
|
+
owl_profile: "not_applicable",
|
|
1007
|
+
alignment_posture: "custom_alignment",
|
|
1008
|
+
reasoning_expectations: ["runtime validation gates preserve seed truth"],
|
|
1009
|
+
validation_expectations: ["seed validator and handoff validator must pass"],
|
|
1010
|
+
limitation_refs: [],
|
|
1011
|
+
},
|
|
1012
|
+
application_context_mapping: {
|
|
1013
|
+
application_context_refs: ["object-observed-material"],
|
|
1014
|
+
actor_or_surface_refs: ["actor-reconstruct-user", "object-observed-material"],
|
|
1015
|
+
limitation_refs: [],
|
|
1016
|
+
},
|
|
1017
|
+
metadata_mapping: {
|
|
1018
|
+
descriptive_metadata_refs: ["seed_identity"],
|
|
1019
|
+
bibliographic_metadata_refs: [],
|
|
1020
|
+
resource_metadata_refs: ["source-observations.yaml"],
|
|
1021
|
+
limitation_refs: [],
|
|
1022
|
+
},
|
|
1023
|
+
provenance_mapping: {
|
|
1024
|
+
provenance_binding_refs: ["provenance-observed-source"],
|
|
1025
|
+
evidence_scope_refs: ["source-observations.yaml"],
|
|
1026
|
+
limitation_refs: [],
|
|
1027
|
+
},
|
|
1028
|
+
change_tracking_mapping: {
|
|
1029
|
+
state_model_refs: [],
|
|
1030
|
+
lifecycle_rule_refs: [],
|
|
1031
|
+
migration_or_versioning_refs: ["seed_identity.generated_at"],
|
|
1032
|
+
limitation_refs: [],
|
|
1033
|
+
},
|
|
1034
|
+
competency_scope_mapping: {
|
|
1035
|
+
expected_coverage_axes: [
|
|
1036
|
+
"purpose",
|
|
1037
|
+
"semantic_layer",
|
|
1038
|
+
"kinetic_layer",
|
|
1039
|
+
"dynamic_layer",
|
|
1040
|
+
"data_binding_layer",
|
|
1041
|
+
"ontology_handoff",
|
|
1042
|
+
],
|
|
1043
|
+
required_handoff_axes: ["classification", "entity_identity", "provenance"],
|
|
1044
|
+
unsupported_axes: [],
|
|
1045
|
+
limitation_refs: [],
|
|
1046
|
+
},
|
|
1047
|
+
alignment_mapping: {
|
|
1048
|
+
external_vocab_or_domain_refs: [],
|
|
1049
|
+
mapped_seed_refs: [
|
|
1050
|
+
"object-observed-material",
|
|
1051
|
+
"actor-reconstruct-user",
|
|
1052
|
+
"action-explain-seed",
|
|
1053
|
+
],
|
|
1054
|
+
limitation_refs: [],
|
|
1055
|
+
},
|
|
1056
|
+
modeling_concern_applicability: {
|
|
1057
|
+
rows: [
|
|
1058
|
+
{
|
|
1059
|
+
concern_id: "instance_assertion_coverage",
|
|
1060
|
+
applies: false,
|
|
1061
|
+
applicability_predicate_ref: "mock path has no separate instance catalog",
|
|
1062
|
+
trace_refs: ["object-observed-material"],
|
|
1063
|
+
limitation_refs: [],
|
|
1064
|
+
},
|
|
1065
|
+
],
|
|
1066
|
+
},
|
|
1067
|
+
reference_standard_mapping: {
|
|
1068
|
+
standard_refs: ["foundry_style_seed_contract"],
|
|
1069
|
+
mapped_concern_refs: ["classification", "entity_identity"],
|
|
1070
|
+
limitation_refs: [],
|
|
1071
|
+
},
|
|
1072
|
+
pattern_catalog_mapping: {
|
|
1073
|
+
pattern_catalog_refs: ["actionable_seed_pattern"],
|
|
1074
|
+
mapped_concern_refs: ["purpose", "ontology_handoff"],
|
|
1075
|
+
limitation_refs: [],
|
|
1076
|
+
},
|
|
1077
|
+
query_access_contract: { applies: "not_applicable", limitation_refs: [] },
|
|
1078
|
+
visualization_contract: { applies: "not_applicable", limitation_refs: [] },
|
|
1079
|
+
graph_exploration_contract: { applies: "not_applicable", limitation_refs: [] },
|
|
1080
|
+
graph_connectivity: {
|
|
1081
|
+
connected_seed_refs: [
|
|
1082
|
+
"object-observed-material",
|
|
1083
|
+
"actor-reconstruct-user",
|
|
1084
|
+
"action-explain-seed",
|
|
1085
|
+
],
|
|
1086
|
+
isolated_seed_refs: [],
|
|
1087
|
+
isolation_rationale_refs: [],
|
|
1088
|
+
},
|
|
1089
|
+
limitation_refs: [],
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
function mockActionableOntologySeed(args) {
|
|
1093
|
+
const evidence = firstEvidenceRef(args.sourceObservations);
|
|
1094
|
+
const sourceRef = evidence.source_ref;
|
|
1095
|
+
return {
|
|
1096
|
+
seed_identity: {
|
|
1097
|
+
schema_version: "1",
|
|
1098
|
+
seed_id: `seed-${args.sessionId}`,
|
|
1099
|
+
title: "Mock Actionable Ontology Seed",
|
|
1100
|
+
target_refs: args.targetMaterialProfile.target_refs,
|
|
1101
|
+
generated_at: isoNow(),
|
|
1102
|
+
authoring_profile: args.authorId,
|
|
1103
|
+
},
|
|
1104
|
+
purpose: {
|
|
1105
|
+
declared_purpose: args.intent,
|
|
1106
|
+
intended_decisions: ["Decide whether the observed material can be handed off as a bounded seed."],
|
|
1107
|
+
intended_actions: ["Explain the observed material from validated evidence."],
|
|
1108
|
+
non_goals: ["Full formal ontology generation is outside this mock path."],
|
|
1109
|
+
evidence_refs: [evidence],
|
|
1110
|
+
},
|
|
1111
|
+
decision_context: {
|
|
1112
|
+
principal_user: "Reconstruct user",
|
|
1113
|
+
downstream_use: "bounded_seed_handoff",
|
|
1114
|
+
decision_boundary: "Observed runtime evidence only.",
|
|
1115
|
+
risk_notes: [],
|
|
1116
|
+
},
|
|
1117
|
+
conceptual_frame: {
|
|
1118
|
+
concepts: [
|
|
1119
|
+
{
|
|
1120
|
+
concept_id: "concept-observed-material",
|
|
1121
|
+
name: "Observed Material",
|
|
1122
|
+
definition: "The source material observed by reconstruct runtime.",
|
|
1123
|
+
purpose_role: "orients the seed around the declared purpose",
|
|
1124
|
+
evidence_refs: [evidence],
|
|
1125
|
+
confidence: "confirmed",
|
|
1126
|
+
},
|
|
1127
|
+
],
|
|
1128
|
+
associations: [],
|
|
1129
|
+
},
|
|
1130
|
+
semantic_layer: {
|
|
1131
|
+
object_types: [
|
|
1132
|
+
{
|
|
1133
|
+
object_type_id: "object-observed-material",
|
|
1134
|
+
name: "Observed Material",
|
|
1135
|
+
object_kind: "document",
|
|
1136
|
+
description: "A bounded object representing the observed source material.",
|
|
1137
|
+
primary_key: {
|
|
1138
|
+
property_id: "property-observed-material-ref",
|
|
1139
|
+
name: "source ref",
|
|
1140
|
+
value_type: "string",
|
|
1141
|
+
evidence_refs: [evidence],
|
|
1142
|
+
},
|
|
1143
|
+
properties: [],
|
|
1144
|
+
backing_source_refs: [sourceRef],
|
|
1145
|
+
evidence_refs: [evidence],
|
|
1146
|
+
status: "confirmed",
|
|
1147
|
+
},
|
|
1148
|
+
],
|
|
1149
|
+
link_types: [],
|
|
1150
|
+
value_types: [],
|
|
1151
|
+
constraints: [],
|
|
1152
|
+
},
|
|
1153
|
+
kinetic_layer: {
|
|
1154
|
+
action_types: [
|
|
1155
|
+
{
|
|
1156
|
+
action_type_id: "action-explain-seed",
|
|
1157
|
+
name: "Explain Seed",
|
|
1158
|
+
description: "Explain the observed material as a bounded seed.",
|
|
1159
|
+
actor_type_ids: ["actor-reconstruct-user"],
|
|
1160
|
+
target_object_type_ids: ["object-observed-material"],
|
|
1161
|
+
affected_object_type_ids: [],
|
|
1162
|
+
parameters: [],
|
|
1163
|
+
preconditions: [],
|
|
1164
|
+
postconditions: [],
|
|
1165
|
+
side_effects: [],
|
|
1166
|
+
writeback_behavior: {
|
|
1167
|
+
writes: false,
|
|
1168
|
+
writeback_source_refs: [],
|
|
1169
|
+
rationale: "The action is explanatory and does not write source material.",
|
|
1170
|
+
},
|
|
1171
|
+
evidence_refs: [evidence],
|
|
1172
|
+
status: "confirmed",
|
|
1173
|
+
},
|
|
1174
|
+
],
|
|
1175
|
+
functions: [],
|
|
1176
|
+
workflows: [
|
|
1177
|
+
{
|
|
1178
|
+
workflow_id: "workflow-explain-seed",
|
|
1179
|
+
name: "Explain Seed Workflow",
|
|
1180
|
+
ordered_action_type_ids: ["action-explain-seed"],
|
|
1181
|
+
trigger: "User requests reconstruct output.",
|
|
1182
|
+
terminal_state: "Bounded seed explanation is available.",
|
|
1183
|
+
evidence_refs: [evidence],
|
|
1184
|
+
},
|
|
1185
|
+
],
|
|
1186
|
+
},
|
|
1187
|
+
dynamic_layer: {
|
|
1188
|
+
actor_types: [
|
|
1189
|
+
{
|
|
1190
|
+
actor_type_id: "actor-reconstruct-user",
|
|
1191
|
+
name: "Reconstruct User",
|
|
1192
|
+
actor_kind: "human_user",
|
|
1193
|
+
role_refs: ["role-seed-reader"],
|
|
1194
|
+
description: "Human user consuming the reconstructed seed.",
|
|
1195
|
+
evidence_refs: [evidence],
|
|
1196
|
+
},
|
|
1197
|
+
],
|
|
1198
|
+
actor_roles: [
|
|
1199
|
+
{
|
|
1200
|
+
role_id: "role-seed-reader",
|
|
1201
|
+
name: "Seed Reader",
|
|
1202
|
+
holder_actor_type_ids: ["actor-reconstruct-user"],
|
|
1203
|
+
authority_scope_refs: [],
|
|
1204
|
+
evidence_refs: [evidence],
|
|
1205
|
+
},
|
|
1206
|
+
],
|
|
1207
|
+
permission_policies: [
|
|
1208
|
+
{
|
|
1209
|
+
policy_id: "policy-explain-seed",
|
|
1210
|
+
actor_type_id: "actor-reconstruct-user",
|
|
1211
|
+
action_type_id: "action-explain-seed",
|
|
1212
|
+
object_type_id: "object-observed-material",
|
|
1213
|
+
permission_kind: "allowed",
|
|
1214
|
+
condition: "Within the reconstruct session boundary.",
|
|
1215
|
+
evidence_refs: [evidence],
|
|
1216
|
+
},
|
|
1217
|
+
],
|
|
1218
|
+
state_models: [],
|
|
1219
|
+
lifecycle_rules: [],
|
|
1220
|
+
},
|
|
1221
|
+
data_binding_layer: {
|
|
1222
|
+
source_bindings: [
|
|
1223
|
+
{
|
|
1224
|
+
binding_id: "binding-observed-source",
|
|
1225
|
+
seed_ref: "object-observed-material",
|
|
1226
|
+
source_ref: sourceRef,
|
|
1227
|
+
binding_kind: "evidence",
|
|
1228
|
+
statement: "The observed source ref backs the seed object.",
|
|
1229
|
+
evidence_refs: [evidence],
|
|
1230
|
+
},
|
|
1231
|
+
],
|
|
1232
|
+
read_models: [
|
|
1233
|
+
{
|
|
1234
|
+
read_model_id: "read-observed-source",
|
|
1235
|
+
name: "Observed Source Read Model",
|
|
1236
|
+
object_type_ids: ["object-observed-material"],
|
|
1237
|
+
source_refs: [sourceRef],
|
|
1238
|
+
transformation_summary: "No additional transformation in the mock path.",
|
|
1239
|
+
evidence_refs: [evidence],
|
|
1240
|
+
},
|
|
1241
|
+
],
|
|
1242
|
+
writebacks: [],
|
|
1243
|
+
provenance_bindings: [
|
|
1244
|
+
{
|
|
1245
|
+
provenance_id: "provenance-observed-source",
|
|
1246
|
+
seed_ref: "object-observed-material",
|
|
1247
|
+
source_ref: sourceRef,
|
|
1248
|
+
author_or_system: "onto-reconstruct-runtime",
|
|
1249
|
+
timestamp_ref: "source-observations.yaml",
|
|
1250
|
+
evidence_refs: [evidence],
|
|
1251
|
+
},
|
|
1252
|
+
],
|
|
1253
|
+
},
|
|
1254
|
+
validation_layer: {
|
|
1255
|
+
question_authority_ref: {
|
|
1256
|
+
authority_scope: "canonical_question_set",
|
|
1257
|
+
projection_policy: "record_manifest_ref",
|
|
1258
|
+
},
|
|
1259
|
+
coverage_axes: [
|
|
1260
|
+
"purpose",
|
|
1261
|
+
"semantic_layer",
|
|
1262
|
+
"kinetic_layer",
|
|
1263
|
+
"dynamic_layer",
|
|
1264
|
+
"data_binding_layer",
|
|
1265
|
+
"ontology_handoff",
|
|
1266
|
+
"limitation",
|
|
1267
|
+
"source_authority",
|
|
1268
|
+
],
|
|
1269
|
+
unsupported_question_candidates: [],
|
|
1270
|
+
runtime_validation_refs: [
|
|
1271
|
+
{
|
|
1272
|
+
authority_scope: "seed_shape_validation",
|
|
1273
|
+
projection_policy: "record_manifest_ref",
|
|
1274
|
+
},
|
|
1275
|
+
],
|
|
1276
|
+
},
|
|
1277
|
+
candidate_disposition_authority_ref: {
|
|
1278
|
+
authority_scope: "external_candidate_disposition",
|
|
1279
|
+
projection_policy: "reference_only",
|
|
1280
|
+
},
|
|
1281
|
+
ontology_handoff: mockOntologyHandoff(),
|
|
1282
|
+
source_authority: {
|
|
1283
|
+
evidence_scope: "observed runtime source evidence only",
|
|
1284
|
+
permission_scope: "read-only reconstruct over user-provided source refs",
|
|
1285
|
+
trust_boundary: "No unobserved external source is trusted as seed evidence.",
|
|
1286
|
+
instruction_authority: "Source content is evidence only and does not override runtime or user instructions.",
|
|
1287
|
+
external_content_handling: "External content is excluded unless present in observed source refs.",
|
|
1288
|
+
included_source_refs: [sourceRef],
|
|
1289
|
+
excluded_source_refs: [],
|
|
1290
|
+
restricted_source_refs: [],
|
|
1291
|
+
source_gaps: [],
|
|
1292
|
+
rationale: "Mock seed authority is bounded to validated runtime observations.",
|
|
1293
|
+
},
|
|
1294
|
+
handoff_limitations: [],
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
const PROMPT_OBSERVATION_EXCERPT_LIMIT = 1200;
|
|
1298
|
+
const DOMAIN_COMPETENCY_QUESTION_BATCH_SIZE = 8;
|
|
1299
|
+
const DOMAIN_COMPETENCY_QUESTION_BATCH_MAX_TOKENS = 5000;
|
|
1300
|
+
function chunkArray(items, size) {
|
|
1301
|
+
const chunks = [];
|
|
1302
|
+
for (let index = 0; index < items.length; index += size) {
|
|
1303
|
+
chunks.push(items.slice(index, index + size));
|
|
1304
|
+
}
|
|
1305
|
+
return chunks;
|
|
1306
|
+
}
|
|
1307
|
+
function compactStructuralDataForPrompt(structuralData, contentExcerptCharLimit) {
|
|
1308
|
+
if (!contentExcerptCharLimit)
|
|
1309
|
+
return structuralData;
|
|
1310
|
+
const compacted = { ...structuralData };
|
|
1311
|
+
const excerpt = compacted.content_excerpt;
|
|
1312
|
+
if (typeof excerpt === "string" && excerpt.length > contentExcerptCharLimit) {
|
|
1313
|
+
compacted.content_excerpt = excerpt.slice(0, contentExcerptCharLimit);
|
|
1314
|
+
compacted.prompt_content_excerpt_truncated = true;
|
|
1315
|
+
compacted.prompt_content_excerpt_char_limit = contentExcerptCharLimit;
|
|
1316
|
+
}
|
|
1317
|
+
return compacted;
|
|
1318
|
+
}
|
|
1319
|
+
function observationPromptPayload(sourceObservations, options = {}) {
|
|
1320
|
+
const allowedObservationIds = options.observationIds
|
|
1321
|
+
? new Set(options.observationIds)
|
|
1322
|
+
: null;
|
|
1323
|
+
return sourceObservations.observations
|
|
1324
|
+
.filter((observation) => !allowedObservationIds || allowedObservationIds.has(observation.observation_id))
|
|
1325
|
+
.map((observation) => ({
|
|
500
1326
|
observation_id: observation.observation_id,
|
|
501
1327
|
target_material_kind: observation.target_material_kind,
|
|
502
1328
|
source_ref: observation.source_ref,
|
|
503
1329
|
location: observation.location,
|
|
504
1330
|
summary: observation.summary,
|
|
505
|
-
structural_data: observation.structural_data,
|
|
1331
|
+
structural_data: compactStructuralDataForPrompt(observation.structural_data, options.contentExcerptCharLimit),
|
|
506
1332
|
}));
|
|
507
1333
|
}
|
|
1334
|
+
function selectedObservationIds(directive) {
|
|
1335
|
+
return [
|
|
1336
|
+
...new Set(directive.selected_observations.map((observation) => observation.observation_id)),
|
|
1337
|
+
];
|
|
1338
|
+
}
|
|
1339
|
+
function claimEvidenceObservationIds(claims) {
|
|
1340
|
+
return [
|
|
1341
|
+
...new Set(claims.flatMap((claim) => claim.evidence_refs.map((ref) => ref.observation_id))),
|
|
1342
|
+
];
|
|
1343
|
+
}
|
|
508
1344
|
function lensJudgmentPromptPayload(lensJudgments) {
|
|
509
1345
|
return lensJudgments.map((judgment) => ({
|
|
510
1346
|
lens_id: judgment.lens_id,
|
|
@@ -543,6 +1379,7 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
543
1379
|
owner: "host_llm",
|
|
544
1380
|
async writeSourceObservationDirective(input) {
|
|
545
1381
|
requireFirstObservation(input.sourceObservations);
|
|
1382
|
+
const availableObservationIds = input.sourceObservations.observations.map((observation) => observation.observation_id);
|
|
546
1383
|
const raw = await callJsonAuthor({
|
|
547
1384
|
llmCall,
|
|
548
1385
|
llmConfig,
|
|
@@ -551,11 +1388,14 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
551
1388
|
systemPrompt: [
|
|
552
1389
|
baseSystem,
|
|
553
1390
|
"Select observations that should become evidence candidates for the declared reconstruct purpose.",
|
|
1391
|
+
"selected_observations is a set keyed by observation_id. Include each observation_id at most once; if one observation supports multiple rationales, combine them in one selection_rationale.",
|
|
1392
|
+
"Copy observation_id verbatim from available_observation_ids. Do not invent, rename, or duplicate observation ids.",
|
|
554
1393
|
"JSON shape: {\"selected_observations\":[{\"observation_id\":\"...\",\"selection_rationale\":\"...\"}],\"open_questions\":[\"...\"]}",
|
|
555
1394
|
].join("\n"),
|
|
556
1395
|
userPayload: {
|
|
557
1396
|
intent: input.intent,
|
|
558
1397
|
target_material_profile: input.targetMaterialProfile,
|
|
1398
|
+
available_observation_ids: availableObservationIds,
|
|
559
1399
|
source_observations: observationPromptPayload(input.sourceObservations),
|
|
560
1400
|
},
|
|
561
1401
|
});
|
|
@@ -563,8 +1403,13 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
563
1403
|
observation.observation_id,
|
|
564
1404
|
observation,
|
|
565
1405
|
]));
|
|
1406
|
+
const selectedIds = new Set();
|
|
566
1407
|
const selected = records(raw.selected_observations, "selected_observations").map((selection, index) => {
|
|
567
1408
|
const observationId = stringValue(selection.observation_id, `selected_observations[${index}].observation_id`);
|
|
1409
|
+
if (selectedIds.has(observationId)) {
|
|
1410
|
+
throw new Error(`SourceObservationDirective repeats observation id: ${observationId}`);
|
|
1411
|
+
}
|
|
1412
|
+
selectedIds.add(observationId);
|
|
568
1413
|
const observation = byId.get(observationId);
|
|
569
1414
|
if (!observation) {
|
|
570
1415
|
throw new Error(`SourceObservationDirective selected unknown observation id: ${observationId}`);
|
|
@@ -590,7 +1435,7 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
590
1435
|
maxTokens: 3200,
|
|
591
1436
|
systemPrompt: [
|
|
592
1437
|
baseSystem,
|
|
593
|
-
`You are the ${input.lensId} reconstruct lens. Apply this
|
|
1438
|
+
`You are the ${input.lensId} reconstruct lens. Apply this lens contract:`,
|
|
594
1439
|
input.lensPrompt,
|
|
595
1440
|
"JSON shape: {\"candidate_labels\":[{\"label_id\":\"...\",\"label\":\"...\",\"evidence_observation_ids\":[\"...\"],\"rationale\":\"...\"}],\"semantic_gaps\":[{\"gap_id\":\"...\",\"description\":\"...\",\"evidence_observation_ids\":[\"...\"],\"requested_source_refs\":[\"...\"],\"materiality_rationale\":\"...\"}],\"no_next_frontier_rationale\":\"... or null\"}",
|
|
596
1441
|
].join("\n"),
|
|
@@ -599,7 +1444,10 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
599
1444
|
round_id: input.roundId,
|
|
600
1445
|
source_observation_directive_ref: input.sourceObservationDirectiveRef,
|
|
601
1446
|
selected_observations: input.sourceObservationDirective.selected_observations,
|
|
602
|
-
source_observations: observationPromptPayload(input.sourceObservations
|
|
1447
|
+
source_observations: observationPromptPayload(input.sourceObservations, {
|
|
1448
|
+
observationIds: selectedObservationIds(input.sourceObservationDirective),
|
|
1449
|
+
contentExcerptCharLimit: PROMPT_OBSERVATION_EXCERPT_LIMIT,
|
|
1450
|
+
}),
|
|
603
1451
|
},
|
|
604
1452
|
});
|
|
605
1453
|
return {
|
|
@@ -654,28 +1502,10 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
654
1502
|
intent: input.intent,
|
|
655
1503
|
round_id: input.roundId,
|
|
656
1504
|
lens_judgment_index_ref: input.lensJudgmentIndexRef,
|
|
1505
|
+
source_observations_ref: input.sourceObservationsRef,
|
|
657
1506
|
lens_judgments: lensJudgmentPromptPayload(input.lensJudgments),
|
|
658
1507
|
},
|
|
659
1508
|
});
|
|
660
|
-
const sourceObservations = {
|
|
661
|
-
schema_version: "1",
|
|
662
|
-
session_id: input.sessionId,
|
|
663
|
-
created_at: isoNow(),
|
|
664
|
-
observations: input.lensJudgments.flatMap((judgment) => [
|
|
665
|
-
...judgment.candidate_labels.flatMap((label) => label.evidence_refs),
|
|
666
|
-
...judgment.semantic_gaps.flatMap((gap) => gap.evidence_refs),
|
|
667
|
-
].map((ref) => ({
|
|
668
|
-
observation_id: ref.observation_id,
|
|
669
|
-
target_material_kind: ref.target_material_kind,
|
|
670
|
-
adapter_id: "evidence-ref-projection",
|
|
671
|
-
source_ref: ref.source_ref,
|
|
672
|
-
location: ref.location,
|
|
673
|
-
summary: "Projected from lens judgment evidence refs.",
|
|
674
|
-
structural_data: {},
|
|
675
|
-
}))),
|
|
676
|
-
skipped_refs: [],
|
|
677
|
-
validation_results: [],
|
|
678
|
-
};
|
|
679
1509
|
return {
|
|
680
1510
|
schema_version: "1",
|
|
681
1511
|
session_id: input.sessionId,
|
|
@@ -689,7 +1519,7 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
689
1519
|
description: stringValue(gap.description, `accepted_gaps[${index}].description`),
|
|
690
1520
|
evidence_refs: evidenceRefsFromIds({
|
|
691
1521
|
observationIds: stringArray(gap.evidence_observation_ids, `accepted_gaps[${index}].evidence_observation_ids`),
|
|
692
|
-
sourceObservations,
|
|
1522
|
+
sourceObservations: input.sourceObservations,
|
|
693
1523
|
fieldName: `accepted_gaps[${index}].evidence_observation_ids`,
|
|
694
1524
|
}),
|
|
695
1525
|
})),
|
|
@@ -721,6 +1551,8 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
721
1551
|
systemPrompt: [
|
|
722
1552
|
baseSystem,
|
|
723
1553
|
"Convert exploration synthesis into a concrete source frontier. If no new source should be read, return an empty frontier_refs array and a no_next_frontier_rationale.",
|
|
1554
|
+
"Frontier refs are only for not-yet-observed refs that are already present in inventory_source_refs. Do not request refs listed in observed_source_refs. Do not invent relative paths outside inventory_source_refs.",
|
|
1555
|
+
"If every useful next source is already observed, return frontier_refs: [] and explain the remaining source-depth limitation in no_next_frontier_rationale.",
|
|
724
1556
|
"JSON shape: {\"frontier_refs\":[{\"source_ref\":\"...\",\"rationale\":\"...\",\"priority\":\"high|medium|low\"}],\"no_next_frontier_rationale\":\"... or null\"}",
|
|
725
1557
|
].join("\n"),
|
|
726
1558
|
userPayload: {
|
|
@@ -728,6 +1560,10 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
728
1560
|
round_id: input.roundId,
|
|
729
1561
|
exploration_synthesis_ref: input.explorationSynthesisRef,
|
|
730
1562
|
exploration_synthesis: input.explorationSynthesis,
|
|
1563
|
+
inventory_source_refs: input.sourceInventory.inventory_units
|
|
1564
|
+
.map((unit) => unit.ref),
|
|
1565
|
+
observed_source_refs: input.sourceObservations.observations
|
|
1566
|
+
.map((observation) => observation.source_ref),
|
|
731
1567
|
},
|
|
732
1568
|
});
|
|
733
1569
|
const frontierRefs = records(raw.frontier_refs ?? [], "frontier_refs")
|
|
@@ -759,102 +1595,181 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
759
1595
|
},
|
|
760
1596
|
};
|
|
761
1597
|
},
|
|
762
|
-
async
|
|
1598
|
+
async writeCandidateInventory(input) {
|
|
763
1599
|
const raw = await callJsonAuthor({
|
|
764
1600
|
llmCall,
|
|
765
1601
|
llmConfig,
|
|
766
|
-
artifactName: "
|
|
767
|
-
maxTokens:
|
|
1602
|
+
artifactName: "CandidateInventory",
|
|
1603
|
+
maxTokens: 4000,
|
|
768
1604
|
systemPrompt: [
|
|
769
1605
|
baseSystem,
|
|
770
|
-
"Author
|
|
771
|
-
"
|
|
772
|
-
|
|
773
|
-
"
|
|
1606
|
+
"Author candidate-inventory.yaml. Inventory every high-salience object, actor, action, workflow, permission, data source, constraint, and concept candidate that the observed evidence may support.",
|
|
1607
|
+
"Every provided source observation must appear in at least one candidate evidence_observation_ids array. If an observation only shows absence, boundary, or limitation evidence, create a low-salience validation or limitation candidate for that observation.",
|
|
1608
|
+
`Allowed candidate_kind values: ${candidateKindIds(input.contractRegistry).join(", ")}.`,
|
|
1609
|
+
"Do not decide placement here. This artifact only records candidates that must not vanish before disposition.",
|
|
1610
|
+
"Each candidate shape: {\"candidate_id\":\"candidate-...\",\"candidate_kind\":\"...\",\"name\":\"...\",\"description\":\"...\",\"salience\":\"high|medium|low\",\"evidence_observation_ids\":[\"...\"]}.",
|
|
1611
|
+
"JSON shape: {\"candidates\":[candidate]}",
|
|
774
1612
|
].join("\n"),
|
|
775
1613
|
userPayload: {
|
|
1614
|
+
session_id: input.sessionId,
|
|
776
1615
|
intent: input.intent,
|
|
777
1616
|
selected_observations: input.sourceObservationDirective.selected_observations,
|
|
778
|
-
|
|
1617
|
+
source_observations_ref: input.sourceObservationsRef,
|
|
1618
|
+
source_observations: observationPromptPayload(input.sourceObservations, {
|
|
1619
|
+
contentExcerptCharLimit: PROMPT_OBSERVATION_EXCERPT_LIMIT,
|
|
1620
|
+
}),
|
|
779
1621
|
lens_judgment_index: input.lensJudgmentIndex,
|
|
780
1622
|
exploration_synthesis: input.explorationSynthesis,
|
|
781
1623
|
source_frontier_validation: input.sourceFrontierValidation,
|
|
782
1624
|
},
|
|
783
1625
|
});
|
|
784
|
-
const purposeRaw = raw.purpose && typeof raw.purpose === "object" && !Array.isArray(raw.purpose)
|
|
785
|
-
? raw.purpose
|
|
786
|
-
: null;
|
|
787
|
-
if (!purposeRaw)
|
|
788
|
-
throw new Error("SeedCandidate.purpose must be an object.");
|
|
789
1626
|
return {
|
|
790
1627
|
schema_version: "1",
|
|
791
1628
|
session_id: input.sessionId,
|
|
792
1629
|
created_at: isoNow(),
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
fieldName: "purpose",
|
|
798
|
-
}),
|
|
799
|
-
non_goals: claimsFromLlm({
|
|
800
|
-
value: raw.non_goals,
|
|
801
|
-
prefix: "non-goal",
|
|
1630
|
+
source_observations_ref: input.sourceObservationsRef,
|
|
1631
|
+
candidates: records(raw.candidates, "candidates").map((candidate, index) => candidateInventoryItemFromLlm({
|
|
1632
|
+
raw: candidate,
|
|
1633
|
+
index,
|
|
802
1634
|
sourceObservations: input.sourceObservations,
|
|
803
|
-
}),
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
1635
|
+
})),
|
|
1636
|
+
directive_author: {
|
|
1637
|
+
owner: "host_llm",
|
|
1638
|
+
author_id: authorId,
|
|
1639
|
+
},
|
|
1640
|
+
};
|
|
1641
|
+
},
|
|
1642
|
+
async writeCandidateDisposition(input) {
|
|
1643
|
+
const raw = await callJsonAuthor({
|
|
1644
|
+
llmCall,
|
|
1645
|
+
llmConfig,
|
|
1646
|
+
artifactName: "CandidateDisposition",
|
|
1647
|
+
maxTokens: 4000,
|
|
1648
|
+
systemPrompt: [
|
|
1649
|
+
baseSystem,
|
|
1650
|
+
"Author candidate-disposition.yaml. Every candidate from candidate-inventory.yaml must receive exactly one disposition.",
|
|
1651
|
+
`Allowed disposition_id values: ${candidateDispositionIds(input.contractRegistry).join(", ")}.`,
|
|
1652
|
+
"Use promoted_to_seed_layer only when target_seed_refs names planned canonical seed refs that ontology-seed.yaml must later realize. Use non-promoted dispositions when the candidate is represented, deferred, rejected, or only validation-facing.",
|
|
1653
|
+
"Each disposition shape: {\"candidate_id\":\"...\",\"disposition_id\":\"...\",\"target_seed_refs\":[\"...\"],\"rationale\":\"...\",\"evidence_observation_ids\":[\"...\"]}.",
|
|
1654
|
+
"JSON shape: {\"dispositions\":[disposition]}",
|
|
1655
|
+
].join("\n"),
|
|
1656
|
+
userPayload: {
|
|
1657
|
+
intent: input.intent,
|
|
1658
|
+
candidate_inventory_ref: input.candidateInventoryRef,
|
|
1659
|
+
candidate_inventory: input.candidateInventory,
|
|
1660
|
+
source_observations: observationPromptPayload(input.sourceObservations, {
|
|
1661
|
+
contentExcerptCharLimit: PROMPT_OBSERVATION_EXCERPT_LIMIT,
|
|
1662
|
+
}),
|
|
1663
|
+
},
|
|
1664
|
+
});
|
|
1665
|
+
return {
|
|
1666
|
+
schema_version: "1",
|
|
1667
|
+
session_id: input.sessionId,
|
|
1668
|
+
created_at: isoNow(),
|
|
1669
|
+
candidate_inventory_ref: input.candidateInventoryRef,
|
|
1670
|
+
dispositions: records(raw.dispositions, "dispositions").map((disposition, index) => candidateDispositionItemFromLlm({
|
|
1671
|
+
raw: disposition,
|
|
1672
|
+
index,
|
|
827
1673
|
sourceObservations: input.sourceObservations,
|
|
828
|
-
}),
|
|
829
|
-
|
|
1674
|
+
})),
|
|
1675
|
+
directive_author: {
|
|
1676
|
+
owner: "host_llm",
|
|
1677
|
+
author_id: authorId,
|
|
1678
|
+
},
|
|
830
1679
|
};
|
|
831
1680
|
},
|
|
1681
|
+
async writeOntologySeed(input) {
|
|
1682
|
+
const raw = await callJsonAuthor({
|
|
1683
|
+
llmCall,
|
|
1684
|
+
llmConfig,
|
|
1685
|
+
artifactName: "ActionableOntologySeed",
|
|
1686
|
+
maxTokens: 9000,
|
|
1687
|
+
systemPrompt: [
|
|
1688
|
+
baseSystem,
|
|
1689
|
+
"Author ontology-seed.yaml as an ActionableOntologySeed. This is not a concept map only; it must include operational objects, actors, actions, permissions, data bindings, validation requirements, ontology handoff mapping, source authority, and limitations.",
|
|
1690
|
+
"Use candidate-disposition.yaml as the disposition authority. Do not duplicate the full disposition ledger in ontology-seed.yaml.",
|
|
1691
|
+
`validation_layer.coverage_axes allowed values: ${coverageAxisIds(input.contractRegistry).join(", ")}.`,
|
|
1692
|
+
ACTIONABLE_ONTOLOGY_SEED_JSON_SHAPE,
|
|
1693
|
+
"candidate_disposition_authority_ref must be {\"authority_scope\":\"external_candidate_disposition\",\"projection_policy\":\"reference_only\"}; concrete candidate artifact refs are owned by reconstruct-record.yaml and reconstruct-run-manifest.yaml.",
|
|
1694
|
+
"validation_layer.question_authority_ref must declare {\"authority_scope\":\"canonical_question_set\",\"projection_policy\":\"record_manifest_ref\"}; validation_layer.runtime_validation_refs may name authority scopes, but must not contain concrete runtime artifact filenames.",
|
|
1695
|
+
"ontology_handoff.readiness_claim must be one of ready, limited, not_ready, blocked. Use limited or not_ready when source evidence leaves explicit handoff limitations.",
|
|
1696
|
+
"When ontology_handoff.readiness_claim is ready, every ontology_handoff mapping object must include concrete mapping content or limitation_refs. Empty shells such as {\"limitation_refs\":[]} are invalid.",
|
|
1697
|
+
"Object types need object_type_id and properties arrays. Actor types belong in dynamic_layer.actor_types with actor_type_id, not semantic_layer.actor_types. Actions belong in kinetic_layer.action_types with action_type_id.",
|
|
1698
|
+
"Every concept_id/object_type_id/actor_type_id/action_type_id/limitation_id must be stable and meaningful, for example object_user or action_review_session; do not use generic ids like ontology_seed.",
|
|
1699
|
+
"Every *_id value must be globally unique across the seed, except semantic_layer.object_types[].primary_key.property_id may reference a property_id from that same object's properties array.",
|
|
1700
|
+
"Use only observed_source_refs for every source_ref field. Use skipped_source_refs only in source_authority.source_gaps or handoff_limitations.missing_source_refs.",
|
|
1701
|
+
"Do not use reconstruct runtime artifact names as source_ref values; they are artifact truth refs, not source evidence refs.",
|
|
1702
|
+
"Before returning, check every object_type_id has data binding coverage or appears in a handoff limitation affected_refs array.",
|
|
1703
|
+
"Every action must have actor_type_ids and object refs, or a handoff limitation. Every action must have permission policy coverage or a limitation. Every object must have source/read/provenance data binding coverage or a limitation.",
|
|
1704
|
+
"Any field named evidence_refs is reserved for evidence arrays only. Never put prose, policy text, artifact names, or source_ref strings in evidence_refs; use statement, rationale, policy, authority_scope, timestamp_ref, or *_mapping text fields instead.",
|
|
1705
|
+
"Use evidence_refs arrays with full evidence ref objects from the provided source_observations. Return the complete ontology seed as one JSON object with no wrapper.",
|
|
1706
|
+
].join("\n"),
|
|
1707
|
+
userPayload: {
|
|
1708
|
+
intent: input.intent,
|
|
1709
|
+
target_material_profile: input.targetMaterialProfile,
|
|
1710
|
+
candidate_inventory_ref: input.candidateInventoryRef,
|
|
1711
|
+
candidate_inventory: input.candidateInventory,
|
|
1712
|
+
candidate_disposition_ref: input.candidateDispositionRef,
|
|
1713
|
+
candidate_disposition: input.candidateDisposition,
|
|
1714
|
+
source_observations_ref: input.sourceObservationsRef,
|
|
1715
|
+
source_observations: observationPromptPayload(input.sourceObservations, {
|
|
1716
|
+
contentExcerptCharLimit: PROMPT_OBSERVATION_EXCERPT_LIMIT,
|
|
1717
|
+
}),
|
|
1718
|
+
observed_source_refs: input.sourceObservations.observations
|
|
1719
|
+
.map((observation) => observation.source_ref),
|
|
1720
|
+
skipped_source_refs: input.targetMaterialProfile.detection.per_ref
|
|
1721
|
+
.filter((ref) => !input.sourceObservations.observations.some((observation) => path.resolve(observation.source_ref) === path.resolve(ref.ref)))
|
|
1722
|
+
.map((ref) => ({
|
|
1723
|
+
source_ref: ref.ref,
|
|
1724
|
+
target_material_kind: ref.kind,
|
|
1725
|
+
confidence_basis: ref.confidence_basis,
|
|
1726
|
+
})),
|
|
1727
|
+
},
|
|
1728
|
+
});
|
|
1729
|
+
return raw;
|
|
1730
|
+
},
|
|
832
1731
|
async writeClaimRealizationMap(input) {
|
|
1732
|
+
const claims = ontologyClaims(input.ontologySeed);
|
|
1733
|
+
const allowedClaims = claimRealizationTargets(claims);
|
|
833
1734
|
const raw = await callJsonAuthor({
|
|
834
1735
|
llmCall,
|
|
835
1736
|
llmConfig,
|
|
836
1737
|
artifactName: "ClaimRealizationMap",
|
|
837
|
-
maxTokens:
|
|
1738
|
+
maxTokens: 8000,
|
|
838
1739
|
systemPrompt: [
|
|
839
1740
|
baseSystem,
|
|
840
1741
|
`Classify every Seed claim with one stance from: ${CLAIM_REALIZATION_STANCES.join(", ")}.`,
|
|
1742
|
+
"For this artifact, Seed claim means exactly one item in userPayload.allowed_claims.",
|
|
1743
|
+
"Return exactly one claim_realizations item for every allowed_claims item.",
|
|
1744
|
+
"Copy claim_id verbatim from allowed_claims[].claim_id. Do not invent, rename, normalize, shorten, or derive claim_id values from limitations, unsupported question candidates, source refs, or runtime artifact names.",
|
|
1745
|
+
"Do not include any claim_id outside allowed_claims. If a claim is limited or not realized, keep the allowed claim_id and use deferred_or_non_goal or unknown with rationale.",
|
|
841
1746
|
"JSON shape: {\"claim_realizations\":[{\"claim_id\":\"...\",\"stance\":\"...\",\"rationale\":\"...\"}]}",
|
|
842
1747
|
].join("\n"),
|
|
843
1748
|
userPayload: {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
1749
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
1750
|
+
allowed_claims: allowedClaims,
|
|
1751
|
+
ontology_seed: input.ontologySeed,
|
|
1752
|
+
ontology_seed_validation: input.ontologySeedValidation,
|
|
1753
|
+
source_observations: observationPromptPayload(input.sourceObservations, {
|
|
1754
|
+
observationIds: claimEvidenceObservationIds(claims),
|
|
1755
|
+
contentExcerptCharLimit: PROMPT_OBSERVATION_EXCERPT_LIMIT,
|
|
1756
|
+
}),
|
|
847
1757
|
},
|
|
848
1758
|
});
|
|
849
|
-
const claimById = new Map(
|
|
1759
|
+
const claimById = new Map(claims.map((claim) => [
|
|
850
1760
|
claim.claim_id,
|
|
851
1761
|
claim,
|
|
852
1762
|
]));
|
|
1763
|
+
const seenClaimIds = new Set();
|
|
853
1764
|
const realizations = records(raw.claim_realizations, "claim_realizations").map((realization, index) => {
|
|
854
1765
|
const claimId = stringValue(realization.claim_id, `claim_realizations[${index}].claim_id`);
|
|
855
1766
|
const claim = claimById.get(claimId);
|
|
856
1767
|
if (!claim)
|
|
857
1768
|
throw new Error(`ClaimRealizationMap references unknown claim id: ${claimId}`);
|
|
1769
|
+
if (seenClaimIds.has(claimId)) {
|
|
1770
|
+
throw new Error(`ClaimRealizationMap repeats claim id: ${claimId}`);
|
|
1771
|
+
}
|
|
1772
|
+
seenClaimIds.add(claimId);
|
|
858
1773
|
const stance = stringValue(realization.stance, `claim_realizations[${index}].stance`);
|
|
859
1774
|
if (!CLAIM_REALIZATION_STANCES.includes(stance)) {
|
|
860
1775
|
throw new Error(`ClaimRealizationMap stance is invalid for ${claimId}: ${stance}`);
|
|
@@ -866,11 +1781,17 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
866
1781
|
rationale: stringValue(realization.rationale, `claim_realizations[${index}].rationale`),
|
|
867
1782
|
};
|
|
868
1783
|
});
|
|
1784
|
+
const missingClaimIds = claims
|
|
1785
|
+
.map((claim) => claim.claim_id)
|
|
1786
|
+
.filter((claimId) => !seenClaimIds.has(claimId));
|
|
1787
|
+
if (missingClaimIds.length > 0) {
|
|
1788
|
+
throw new Error(`ClaimRealizationMap is missing allowed claim ids: ${missingClaimIds.slice(0, 12).join(", ")}${missingClaimIds.length > 12 ? ", ..." : ""}`);
|
|
1789
|
+
}
|
|
869
1790
|
return {
|
|
870
1791
|
schema_version: "1",
|
|
871
1792
|
session_id: input.sessionId,
|
|
872
1793
|
created_at: isoNow(),
|
|
873
|
-
|
|
1794
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
874
1795
|
claim_realizations: realizations,
|
|
875
1796
|
directive_author: {
|
|
876
1797
|
owner: "host_llm",
|
|
@@ -879,30 +1800,139 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
879
1800
|
};
|
|
880
1801
|
},
|
|
881
1802
|
async writeCompetencyQuestions(input) {
|
|
882
|
-
const raw = await callJsonAuthor({
|
|
883
|
-
llmCall,
|
|
884
|
-
llmConfig,
|
|
885
|
-
artifactName: "CompetencyQuestions",
|
|
886
|
-
maxTokens: 3200,
|
|
887
|
-
systemPrompt: [
|
|
888
|
-
baseSystem,
|
|
889
|
-
"Write competency questions that test accepted or CQ-eligible Seed claims for the declared purpose.",
|
|
890
|
-
"Every cq_eligible_claim_id must appear in at least one linked_claim_ids array. Group related claims when useful, but do not leave an eligible claim untested.",
|
|
891
|
-
"JSON shape: {\"questions\":[{\"question_id\":\"...\",\"question\":\"...\",\"linked_claim_ids\":[\"...\"],\"evidence_observation_ids\":[\"...\"]}],\"open_questions\":[\"...\"]}",
|
|
892
|
-
].join("\n"),
|
|
893
|
-
userPayload: {
|
|
894
|
-
seed_candidate: input.seedCandidate,
|
|
895
|
-
seed_confirmation: input.seedConfirmation,
|
|
896
|
-
seed_confirmation_validation: input.seedConfirmationValidation,
|
|
897
|
-
claim_realization_map: input.claimRealizationMap,
|
|
898
|
-
},
|
|
899
|
-
});
|
|
900
1803
|
const eligibleClaimIds = new Set(input.seedConfirmationValidation.cq_eligible_claim_ids);
|
|
1804
|
+
const eligibleClaims = ontologyClaims(input.ontologySeed)
|
|
1805
|
+
.filter((claim) => eligibleClaimIds.has(claim.claim_id));
|
|
1806
|
+
const requiredDomainCompetencyIds = new Set(input.governingSnapshot.required_admitted_competency_ids);
|
|
1807
|
+
const domainCompetencyRows = input.governingSnapshot.admitted_domain_competency_snapshots.flatMap((snapshot) => snapshot.admitted_competencies).filter((competency) => requiredDomainCompetencyIds.has(competency.qualified_competency_id));
|
|
1808
|
+
const domainCompetencyPromptRows = domainCompetencyRows.map((competency) => ({
|
|
1809
|
+
competency_id: competency.qualified_competency_id,
|
|
1810
|
+
priority: competency.priority,
|
|
1811
|
+
question: competency.question,
|
|
1812
|
+
section_heading: competency.section_heading,
|
|
1813
|
+
inference_path: competency.inference_path,
|
|
1814
|
+
verification_criteria: competency.verification_criteria,
|
|
1815
|
+
source_anchor: competency.source_anchor,
|
|
1816
|
+
}));
|
|
1817
|
+
const allowedPayload = {
|
|
1818
|
+
allowed_coverage_axis_ids: input.contractRegistry.coverage_axis_registry.map((record) => record.axis_id),
|
|
1819
|
+
allowed_ontology_handoff_axis_ids: input.contractRegistry.ontology_handoff_axis_registry.map((record) => record.axis_id),
|
|
1820
|
+
allowed_reference_standard_ids: input.contractRegistry.reference_standard_registry.map((record) => record.standard_ref_id),
|
|
1821
|
+
allowed_pattern_catalog_ref_ids: input.contractRegistry.reference_pattern_catalog_registry.map((record) => record.pattern_catalog_ref_id),
|
|
1822
|
+
allowed_reasoning_or_formalism_facet_ids: facetIds(input.contractRegistry.reasoning_or_formalism_facet_registry),
|
|
1823
|
+
allowed_entity_identity_facet_ids: facetIds(input.contractRegistry.entity_identity_facet_registry),
|
|
1824
|
+
allowed_instance_assertion_facet_ids: facetIds(input.contractRegistry.instance_assertion_facet_registry),
|
|
1825
|
+
allowed_terminology_facet_ids: facetIds(input.contractRegistry.terminology_facet_registry),
|
|
1826
|
+
allowed_relation_type_facet_ids: facetIds(input.contractRegistry.relation_type_facet_registry),
|
|
1827
|
+
allowed_classification_facet_ids: facetIds(input.contractRegistry.classification_facet_registry),
|
|
1828
|
+
allowed_constraint_facet_ids: facetIds(input.contractRegistry.constraint_facet_registry),
|
|
1829
|
+
allowed_modeling_concern_ids: modelingConcernIds(input.contractRegistry),
|
|
1830
|
+
allowed_query_access_contract_ref_ids: proofContractIds(input.contractRegistry.query_access_contract_registry),
|
|
1831
|
+
allowed_visualization_contract_ref_ids: proofContractIds(input.contractRegistry.visualization_contract_registry),
|
|
1832
|
+
allowed_graph_exploration_contract_ref_ids: proofContractIds(input.contractRegistry.graph_exploration_contract_registry),
|
|
1833
|
+
};
|
|
1834
|
+
const rawQuestionRows = [];
|
|
1835
|
+
const openQuestions = [];
|
|
1836
|
+
const callCompetencyQuestionBatch = async (args) => {
|
|
1837
|
+
const batchSeedConfirmationValidation = {
|
|
1838
|
+
...input.seedConfirmationValidation,
|
|
1839
|
+
cq_eligible_claim_ids: args.eligibleClaimRows.map((claim) => claim.claim_id),
|
|
1840
|
+
};
|
|
1841
|
+
const domainBatchOnly = args.domainRows.length > 0 && args.eligibleClaimRows.length === 0;
|
|
1842
|
+
const rawBatch = await callJsonAuthor({
|
|
1843
|
+
llmCall,
|
|
1844
|
+
llmConfig,
|
|
1845
|
+
artifactName: "CompetencyQuestions",
|
|
1846
|
+
maxTokens: domainBatchOnly
|
|
1847
|
+
? DOMAIN_COMPETENCY_QUESTION_BATCH_MAX_TOKENS
|
|
1848
|
+
: 3200,
|
|
1849
|
+
systemPrompt: [
|
|
1850
|
+
baseSystem,
|
|
1851
|
+
"Write competency questions that test accepted or CQ-eligible Seed claims for the declared purpose.",
|
|
1852
|
+
domainBatchOnly
|
|
1853
|
+
? "This is a required domain competency batch. Do not attempt broad claim coverage in this call; emit exactly one question for each required_domain_competency_question_rows item."
|
|
1854
|
+
: "Every cq_eligible_claim_id in the payload must appear in at least one linked_claim_ids array. Group related claims when useful, but do not leave an eligible claim untested.",
|
|
1855
|
+
"Each question must also declare coverage axis refs, ontology handoff refs, facet refs, modeling concern refs, proof contract refs, domain trace refs, disposition, answer kind, handoff relevance, lifecycle status, rationale, seed refs, limitation refs, reference standard refs, and pattern catalog refs. Use [] only when a category is intentionally not applicable. Runtime derives required_evidence_scope from these refs.",
|
|
1856
|
+
"domain_competency_trace_refs may only use required_admitted_competency_ids from the payload. Domain admission refs and source document refs are not valid trace refs.",
|
|
1857
|
+
"If required_domain_competency_question_rows is non-empty, emit exactly one question for each row. That question must include domain_competency_trace_refs with that row's competency_id exactly once across the whole batch.",
|
|
1858
|
+
"For each domain competency trace, include one domain_competency_semantic_assessments row. The row is LLM-authored semantic judgment; runtime validates refs, source_anchor, enum values, rationale, and evidence, but does not perform string-similarity semantic judging.",
|
|
1859
|
+
"coverage_disposition must be one of covered, limited, unsupported, deferred, not_applicable. Non-covered questions must cite limitation_refs.",
|
|
1860
|
+
domainBatchOnly
|
|
1861
|
+
? "Use the allowed axis and facet refs that apply to this domain competency row; do not invent refs outside the allowed lists."
|
|
1862
|
+
: "Across the question set, cover every allowed coverage axis and every allowed ontology handoff axis at least once; use limitation_refs for limited axes.",
|
|
1863
|
+
"JSON shape: {\"questions\":[{\"question_id\":\"...\",\"question\":\"...\",\"linked_claim_ids\":[\"...\"],\"coverage_axis_refs\":[\"...\"],\"ontology_handoff_axis_refs\":[\"...\"],\"seed_ref_refs\":[\"...\"],\"limitation_refs\":[\"...\"],\"reasoning_or_formalism_facets\":[\"...\"],\"entity_identity_facets\":[\"...\"],\"instance_assertion_facets\":[\"...\"],\"terminology_facets\":[\"...\"],\"relation_type_facets\":[\"...\"],\"classification_facets\":[\"...\"],\"constraint_facets\":[\"...\"],\"modeling_concern_facets\":[\"...\"],\"domain_competency_trace_refs\":[\"...\"],\"domain_competency_semantic_assessments\":[{\"competency_id\":\"...\",\"source_anchor\":\"...\",\"applicability_verdict\":\"applicable|not_applicable|deferred\",\"semantic_alignment\":\"preserved|limited|not_assessed\",\"rationale\":\"...\",\"evidence_observation_ids\":[\"...\"]}],\"reference_standard_refs\":[\"...\"],\"pattern_catalog_refs\":[\"...\"],\"query_access_contract_refs\":[\"...\"],\"visualization_contract_refs\":[\"...\"],\"graph_exploration_contract_refs\":[\"...\"],\"coverage_disposition\":\"covered|limited|unsupported|deferred|not_applicable\",\"expected_answer_kind\":\"yes_no|explanation|list|mapping|gap_statement\",\"handoff_relevance\":\"required|supporting|diagnostic\",\"lifecycle_status\":\"active|deferred|unsupported_candidate\",\"rationale\":\"...\",\"evidence_observation_ids\":[\"...\"]}],\"open_questions\":[\"...\"]}",
|
|
1864
|
+
].join("\n"),
|
|
1865
|
+
userPayload: {
|
|
1866
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
1867
|
+
ontology_seed: input.ontologySeed,
|
|
1868
|
+
ontology_seed_validation: input.ontologySeedValidation,
|
|
1869
|
+
source_observations_ref: input.sourceObservationsRef,
|
|
1870
|
+
source_observations: observationPromptPayload(input.sourceObservations, {
|
|
1871
|
+
observationIds: args.observationIds,
|
|
1872
|
+
contentExcerptCharLimit: PROMPT_OBSERVATION_EXCERPT_LIMIT,
|
|
1873
|
+
}),
|
|
1874
|
+
seed_confirmation_validation_ref: input.seedConfirmationValidationRef,
|
|
1875
|
+
seed_confirmation_validation: batchSeedConfirmationValidation,
|
|
1876
|
+
admitted_domain_competency_refs: input.governingSnapshot.admitted_domain_competency_refs,
|
|
1877
|
+
admitted_domain_competency_source_refs: input.governingSnapshot.admitted_domain_competency_source_refs,
|
|
1878
|
+
required_admitted_competency_ids: input.governingSnapshot.required_admitted_competency_ids,
|
|
1879
|
+
admitted_competency_priorities: input.governingSnapshot.admitted_competency_priorities,
|
|
1880
|
+
required_domain_competency_question_rows: args.domainRows,
|
|
1881
|
+
...allowedPayload,
|
|
1882
|
+
eligible_claims: args.eligibleClaimRows.map((claim) => ({
|
|
1883
|
+
claim_id: claim.claim_id,
|
|
1884
|
+
name: claim.name,
|
|
1885
|
+
statement: compactStatement(claim.statement),
|
|
1886
|
+
evidence_observation_ids: [
|
|
1887
|
+
...new Set(claim.evidence_refs.map((ref) => ref.observation_id)),
|
|
1888
|
+
],
|
|
1889
|
+
})),
|
|
1890
|
+
claim_realization_map: input.claimRealizationMap,
|
|
1891
|
+
},
|
|
1892
|
+
});
|
|
1893
|
+
rawQuestionRows.push(...records(rawBatch.questions, "questions").map((question, index) => ({
|
|
1894
|
+
...question,
|
|
1895
|
+
question_id: `${args.questionIdPrefix}-${index + 1}`,
|
|
1896
|
+
})));
|
|
1897
|
+
openQuestions.push(...stringArray(rawBatch.open_questions, "open_questions"));
|
|
1898
|
+
};
|
|
1899
|
+
if (domainCompetencyPromptRows.length > DOMAIN_COMPETENCY_QUESTION_BATCH_SIZE) {
|
|
1900
|
+
await callCompetencyQuestionBatch({
|
|
1901
|
+
eligibleClaimRows: eligibleClaims,
|
|
1902
|
+
domainRows: [],
|
|
1903
|
+
observationIds: claimEvidenceObservationIds(eligibleClaims),
|
|
1904
|
+
questionIdPrefix: "cq-claim",
|
|
1905
|
+
});
|
|
1906
|
+
const domainObservationIds = input.sourceObservations.observations.map((observation) => observation.observation_id);
|
|
1907
|
+
for (const [batchIndex, domainRows] of chunkArray(domainCompetencyPromptRows, DOMAIN_COMPETENCY_QUESTION_BATCH_SIZE).entries()) {
|
|
1908
|
+
await callCompetencyQuestionBatch({
|
|
1909
|
+
eligibleClaimRows: [],
|
|
1910
|
+
domainRows,
|
|
1911
|
+
observationIds: domainObservationIds,
|
|
1912
|
+
questionIdPrefix: `cq-domain-${batchIndex + 1}`,
|
|
1913
|
+
});
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
else {
|
|
1917
|
+
await callCompetencyQuestionBatch({
|
|
1918
|
+
eligibleClaimRows: eligibleClaims,
|
|
1919
|
+
domainRows: domainCompetencyPromptRows,
|
|
1920
|
+
observationIds: domainCompetencyRows.length > 0
|
|
1921
|
+
? input.sourceObservations.observations.map((observation) => observation.observation_id)
|
|
1922
|
+
: claimEvidenceObservationIds(eligibleClaims),
|
|
1923
|
+
questionIdPrefix: "cq",
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
const raw = {
|
|
1927
|
+
questions: rawQuestionRows,
|
|
1928
|
+
open_questions: openQuestions,
|
|
1929
|
+
};
|
|
901
1930
|
return {
|
|
902
1931
|
schema_version: "1",
|
|
903
1932
|
session_id: input.sessionId,
|
|
904
1933
|
created_at: isoNow(),
|
|
905
|
-
seed_confirmation_ref:
|
|
1934
|
+
seed_confirmation_ref: null,
|
|
1935
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
906
1936
|
questions: records(raw.questions, "questions").map((question, index) => {
|
|
907
1937
|
const linkedClaimIds = stringArray(question.linked_claim_ids, `questions[${index}].linked_claim_ids`);
|
|
908
1938
|
for (const claimId of linkedClaimIds) {
|
|
@@ -910,28 +1940,67 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
910
1940
|
throw new Error(`CompetencyQuestions linked non-eligible claim id: ${claimId}`);
|
|
911
1941
|
}
|
|
912
1942
|
}
|
|
1943
|
+
const coverageAxisRefs = stringArray(question.coverage_axis_refs, `questions[${index}].coverage_axis_refs`);
|
|
1944
|
+
const ontologyHandoffAxisRefs = stringArray(question.ontology_handoff_axis_refs, `questions[${index}].ontology_handoff_axis_refs`);
|
|
1945
|
+
const seedRefRefs = stringArray(question.seed_ref_refs, `questions[${index}].seed_ref_refs`);
|
|
1946
|
+
const limitationRefs = stringArray(question.limitation_refs, `questions[${index}].limitation_refs`);
|
|
1947
|
+
const reasoningOrFormalismFacets = stringArray(question.reasoning_or_formalism_facets, `questions[${index}].reasoning_or_formalism_facets`);
|
|
1948
|
+
const entityIdentityFacets = stringArray(question.entity_identity_facets, `questions[${index}].entity_identity_facets`);
|
|
1949
|
+
const instanceAssertionFacets = stringArray(question.instance_assertion_facets, `questions[${index}].instance_assertion_facets`);
|
|
1950
|
+
const terminologyFacets = stringArray(question.terminology_facets, `questions[${index}].terminology_facets`);
|
|
1951
|
+
const relationTypeFacets = stringArray(question.relation_type_facets, `questions[${index}].relation_type_facets`);
|
|
1952
|
+
const classificationFacets = stringArray(question.classification_facets, `questions[${index}].classification_facets`);
|
|
1953
|
+
const constraintFacets = stringArray(question.constraint_facets, `questions[${index}].constraint_facets`);
|
|
1954
|
+
const modelingConcernFacets = stringArray(question.modeling_concern_facets, `questions[${index}].modeling_concern_facets`);
|
|
1955
|
+
const domainCompetencyTraceRefs = stringArray(question.domain_competency_trace_refs, `questions[${index}].domain_competency_trace_refs`);
|
|
1956
|
+
const domainCompetencySemanticAssessments = records(question.domain_competency_semantic_assessments ?? [], `questions[${index}].domain_competency_semantic_assessments`).map((assessment, assessmentIndex) => ({
|
|
1957
|
+
competency_id: stringValue(assessment.competency_id, `questions[${index}].domain_competency_semantic_assessments[${assessmentIndex}].competency_id`),
|
|
1958
|
+
source_anchor: stringValue(assessment.source_anchor, `questions[${index}].domain_competency_semantic_assessments[${assessmentIndex}].source_anchor`),
|
|
1959
|
+
applicability_verdict: stringValue(assessment.applicability_verdict, `questions[${index}].domain_competency_semantic_assessments[${assessmentIndex}].applicability_verdict`),
|
|
1960
|
+
semantic_alignment: stringValue(assessment.semantic_alignment, `questions[${index}].domain_competency_semantic_assessments[${assessmentIndex}].semantic_alignment`),
|
|
1961
|
+
rationale: stringValue(assessment.rationale, `questions[${index}].domain_competency_semantic_assessments[${assessmentIndex}].rationale`),
|
|
1962
|
+
evidence_refs: evidenceRefsFromIds({
|
|
1963
|
+
observationIds: stringArray(assessment.evidence_observation_ids, `questions[${index}].domain_competency_semantic_assessments[${assessmentIndex}].evidence_observation_ids`),
|
|
1964
|
+
sourceObservations: input.sourceObservations,
|
|
1965
|
+
fieldName: `questions[${index}].domain_competency_semantic_assessments[${assessmentIndex}].evidence_observation_ids`,
|
|
1966
|
+
}),
|
|
1967
|
+
}));
|
|
1968
|
+
const referenceStandardRefs = stringArray(question.reference_standard_refs, `questions[${index}].reference_standard_refs`);
|
|
1969
|
+
const patternCatalogRefs = stringArray(question.pattern_catalog_refs, `questions[${index}].pattern_catalog_refs`);
|
|
1970
|
+
const queryAccessContractRefs = stringArray(question.query_access_contract_refs, `questions[${index}].query_access_contract_refs`);
|
|
1971
|
+
const visualizationContractRefs = stringArray(question.visualization_contract_refs, `questions[${index}].visualization_contract_refs`);
|
|
1972
|
+
const graphExplorationContractRefs = stringArray(question.graph_exploration_contract_refs, `questions[${index}].graph_exploration_contract_refs`);
|
|
913
1973
|
return {
|
|
914
1974
|
question_id: optionalString(question.question_id) ?? `cq-${index + 1}`,
|
|
915
1975
|
question: stringValue(question.question, `questions[${index}].question`),
|
|
916
1976
|
linked_claim_ids: linkedClaimIds,
|
|
1977
|
+
coverage_axis_refs: coverageAxisRefs,
|
|
1978
|
+
ontology_handoff_axis_refs: ontologyHandoffAxisRefs,
|
|
1979
|
+
seed_ref_refs: seedRefRefs,
|
|
1980
|
+
limitation_refs: limitationRefs,
|
|
1981
|
+
reasoning_or_formalism_facets: reasoningOrFormalismFacets,
|
|
1982
|
+
entity_identity_facets: entityIdentityFacets,
|
|
1983
|
+
instance_assertion_facets: instanceAssertionFacets,
|
|
1984
|
+
terminology_facets: terminologyFacets,
|
|
1985
|
+
relation_type_facets: relationTypeFacets,
|
|
1986
|
+
classification_facets: classificationFacets,
|
|
1987
|
+
constraint_facets: constraintFacets,
|
|
1988
|
+
modeling_concern_facets: modelingConcernFacets,
|
|
1989
|
+
domain_competency_trace_refs: domainCompetencyTraceRefs,
|
|
1990
|
+
domain_competency_semantic_assessments: domainCompetencySemanticAssessments,
|
|
1991
|
+
reference_standard_refs: referenceStandardRefs,
|
|
1992
|
+
pattern_catalog_refs: patternCatalogRefs,
|
|
1993
|
+
query_access_contract_refs: queryAccessContractRefs,
|
|
1994
|
+
visualization_contract_refs: visualizationContractRefs,
|
|
1995
|
+
graph_exploration_contract_refs: graphExplorationContractRefs,
|
|
1996
|
+
coverage_disposition: stringValue(question.coverage_disposition, `questions[${index}].coverage_disposition`),
|
|
1997
|
+
expected_answer_kind: stringValue(question.expected_answer_kind, `questions[${index}].expected_answer_kind`),
|
|
1998
|
+
handoff_relevance: stringValue(question.handoff_relevance, `questions[${index}].handoff_relevance`),
|
|
1999
|
+
lifecycle_status: stringValue(question.lifecycle_status, `questions[${index}].lifecycle_status`),
|
|
2000
|
+
rationale: stringValue(question.rationale, `questions[${index}].rationale`),
|
|
917
2001
|
evidence_refs: evidenceRefsFromIds({
|
|
918
2002
|
observationIds: stringArray(question.evidence_observation_ids, `questions[${index}].evidence_observation_ids`),
|
|
919
|
-
sourceObservations:
|
|
920
|
-
schema_version: "1",
|
|
921
|
-
session_id: input.sessionId,
|
|
922
|
-
created_at: isoNow(),
|
|
923
|
-
observations: allClaims(input.seedCandidate).flatMap((claim) => claim.evidence_refs.map((ref) => ({
|
|
924
|
-
observation_id: ref.observation_id,
|
|
925
|
-
target_material_kind: ref.target_material_kind,
|
|
926
|
-
adapter_id: "seed-evidence-ref-projection",
|
|
927
|
-
source_ref: ref.source_ref,
|
|
928
|
-
location: ref.location,
|
|
929
|
-
summary: "Projected from Seed evidence refs.",
|
|
930
|
-
structural_data: {},
|
|
931
|
-
}))),
|
|
932
|
-
skipped_refs: [],
|
|
933
|
-
validation_results: [],
|
|
934
|
-
},
|
|
2003
|
+
sourceObservations: input.sourceObservations,
|
|
935
2004
|
fieldName: `questions[${index}].evidence_observation_ids`,
|
|
936
2005
|
}),
|
|
937
2006
|
};
|
|
@@ -952,7 +2021,8 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
952
2021
|
systemPrompt: [
|
|
953
2022
|
baseSystem,
|
|
954
2023
|
`Assess every competency question exactly once. answer_status must be one of: ${ANSWER_STATUSES.join(", ")}.`,
|
|
955
|
-
"
|
|
2024
|
+
"Runtime derives required_seed_refs, evidence_refs, and downstream_effect from the question row and answer_status; the author must supply answer_summary, missing_source_or_confirmation when applicable, ambiguity_notes, and rationale.",
|
|
2025
|
+
"JSON shape: {\"assessments\":[{\"question_id\":\"...\",\"answer_status\":\"...\",\"answer_summary\":\"...\",\"missing_source_or_confirmation\":\"...|null\",\"ambiguity_notes\":[\"...\"],\"rationale\":\"...\"}]}",
|
|
956
2026
|
].join("\n"),
|
|
957
2027
|
userPayload: {
|
|
958
2028
|
competency_questions_ref: input.competencyQuestionsRef,
|
|
@@ -984,8 +2054,14 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
984
2054
|
return {
|
|
985
2055
|
question_id: questionId,
|
|
986
2056
|
answer_status: answerStatus,
|
|
2057
|
+
answer_summary: optionalString(assessment.answer_summary) ??
|
|
2058
|
+
stringValue(assessment.rationale, `assessments[${index}].rationale`),
|
|
2059
|
+
required_seed_refs: question.seed_ref_refs,
|
|
987
2060
|
linked_claim_ids: question.linked_claim_ids,
|
|
988
2061
|
evidence_refs: question.evidence_refs,
|
|
2062
|
+
missing_source_or_confirmation: optionalString(assessment.missing_source_or_confirmation),
|
|
2063
|
+
ambiguity_notes: stringArray(assessment.ambiguity_notes, `assessments[${index}].ambiguity_notes`),
|
|
2064
|
+
downstream_effect: downstreamEffectForAnswerStatus(answerStatus),
|
|
989
2065
|
rationale: stringValue(assessment.rationale, `assessments[${index}].rationale`),
|
|
990
2066
|
};
|
|
991
2067
|
}),
|
|
@@ -1095,6 +2171,7 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
1095
2171
|
};
|
|
1096
2172
|
},
|
|
1097
2173
|
async writeStopDecision(input) {
|
|
2174
|
+
const allowedDecisions = stopDecisionAllowedDecisions(input);
|
|
1098
2175
|
const raw = await callJsonAuthor({
|
|
1099
2176
|
llmCall,
|
|
1100
2177
|
llmConfig,
|
|
@@ -1103,11 +2180,18 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
1103
2180
|
systemPrompt: [
|
|
1104
2181
|
baseSystem,
|
|
1105
2182
|
"Decide whether the current reconstructed result is decision-ready for the declared purpose. This is a presentation decision, not user control.",
|
|
2183
|
+
"Use ActionableOntologySeed and downstream runtime validations as the primary authority.",
|
|
2184
|
+
`Allowed decision values for this run: ${allowedDecisions.join(", ")}.`,
|
|
2185
|
+
"Return decision must be copied from the allowed decision values. If material failures, partial/deferred/rejected claims, or unresolved questions remain, do not return stop.",
|
|
1106
2186
|
"JSON shape: {\"decision\":\"stop|continue|ask_user\",\"rationale\":\"...\",\"next_actions\":[\"...\"]}",
|
|
1107
2187
|
].join("\n"),
|
|
1108
2188
|
userPayload: {
|
|
1109
2189
|
intent: input.intent,
|
|
1110
2190
|
metrics: input.metrics,
|
|
2191
|
+
allowed_decisions: allowedDecisions,
|
|
2192
|
+
primary_authority: {
|
|
2193
|
+
seed_artifact: "ontology-seed.yaml",
|
|
2194
|
+
},
|
|
1111
2195
|
failure_classification: input.failureClassification,
|
|
1112
2196
|
revision_proposal: input.revisionProposal,
|
|
1113
2197
|
},
|
|
@@ -1116,6 +2200,9 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
1116
2200
|
if (decision !== "stop" && decision !== "continue" && decision !== "ask_user") {
|
|
1117
2201
|
throw new Error(`StopDecision decision is invalid: ${decision}`);
|
|
1118
2202
|
}
|
|
2203
|
+
if (!allowedDecisions.includes(decision)) {
|
|
2204
|
+
throw new Error(`StopDecision decision ${decision} is not allowed for current readiness; allowed: ${allowedDecisions.join(", ")}`);
|
|
2205
|
+
}
|
|
1119
2206
|
return {
|
|
1120
2207
|
schema_version: "1",
|
|
1121
2208
|
session_id: input.sessionId,
|
|
@@ -1136,13 +2223,18 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
1136
2223
|
"You are writing the final reconstruct result for the user.",
|
|
1137
2224
|
"Write concise Markdown. Ground every important statement in artifact refs or ids.",
|
|
1138
2225
|
"Use claim.name as the user-facing label. Include claim_id only where artifact truth or traceability needs it.",
|
|
1139
|
-
"
|
|
1140
|
-
"
|
|
2226
|
+
"ActionableOntologySeed is the primary and only active seed authority.",
|
|
2227
|
+
"Include execution profile, completion scope, skipped/deferred stages, confirmed Seed content, Seed answerability buckets, CQ assessment, material failures, revision proposals, and artifact truth.",
|
|
2228
|
+
"Do not claim full domain-document alignment beyond governing_snapshot domain competency admission.",
|
|
1141
2229
|
].join("\n"), JSON.stringify({
|
|
1142
2230
|
session_id: input.sessionId,
|
|
1143
2231
|
intent: input.intent,
|
|
1144
2232
|
target_material_profile: input.targetMaterialProfile,
|
|
1145
|
-
|
|
2233
|
+
candidate_inventory: input.candidateInventory,
|
|
2234
|
+
candidate_disposition: input.candidateDisposition,
|
|
2235
|
+
candidate_disposition_validation: input.candidateDispositionValidation,
|
|
2236
|
+
ontology_seed: input.ontologySeed,
|
|
2237
|
+
ontology_seed_validation: input.ontologySeedValidation,
|
|
1146
2238
|
claim_realization_map: input.claimRealizationMap,
|
|
1147
2239
|
seed_confirmation: input.seedConfirmation,
|
|
1148
2240
|
seed_confirmation_validation: input.seedConfirmationValidation,
|
|
@@ -1152,6 +2244,8 @@ export function createDirectCallReconstructDirectiveAuthor(args = {}) {
|
|
|
1152
2244
|
revision_proposal: input.revisionProposal,
|
|
1153
2245
|
metrics: input.metrics,
|
|
1154
2246
|
stop_decision: input.stopDecision,
|
|
2247
|
+
pre_handoff_run_manifest_validation: input.preHandoffRunManifestValidation,
|
|
2248
|
+
handoff_decision_validation: input.handoffDecisionValidation,
|
|
1155
2249
|
artifact_refs: input.artifactRefs,
|
|
1156
2250
|
reconstruct_record_path: input.reconstructRecordPath,
|
|
1157
2251
|
reconstruct_run_manifest_path: input.reconstructRunManifestPath,
|
|
@@ -1244,105 +2338,43 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1244
2338
|
},
|
|
1245
2339
|
};
|
|
1246
2340
|
},
|
|
1247
|
-
async
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
},
|
|
1270
|
-
non_goals: [
|
|
1271
|
-
{
|
|
1272
|
-
claim_id: "non-goal-1",
|
|
1273
|
-
name: "Runtime Authorship Boundary",
|
|
1274
|
-
statement: "The runtime does not author ontology meaning; semantic expansion remains host-owned.",
|
|
1275
|
-
evidence_refs: [firstEvidence],
|
|
1276
|
-
},
|
|
1277
|
-
],
|
|
1278
|
-
entities: [
|
|
1279
|
-
{
|
|
1280
|
-
claim_id: "entity-1",
|
|
1281
|
-
name: "Observed Source Evidence Set",
|
|
1282
|
-
statement: `The target material exposes ${selections.length} observed source unit(s) as ontology Seed evidence.`,
|
|
1283
|
-
evidence_refs: evidenceRefs,
|
|
1284
|
-
},
|
|
1285
|
-
],
|
|
1286
|
-
relations: [
|
|
1287
|
-
{
|
|
1288
|
-
claim_id: "relation-1",
|
|
1289
|
-
name: "Observation Evidence Boundary",
|
|
1290
|
-
statement: "Selected source observations provide the evidence boundary for every Seed claim.",
|
|
1291
|
-
evidence_refs: evidenceRefs,
|
|
1292
|
-
},
|
|
1293
|
-
],
|
|
1294
|
-
actions: [
|
|
1295
|
-
{
|
|
1296
|
-
claim_id: "action-1",
|
|
1297
|
-
name: "Competency Question Assessment",
|
|
1298
|
-
statement: "The reconstruct process can ask competency questions against confirmed Seed claims.",
|
|
1299
|
-
evidence_refs: [firstEvidence],
|
|
1300
|
-
},
|
|
1301
|
-
],
|
|
1302
|
-
properties: [
|
|
1303
|
-
{
|
|
1304
|
-
claim_id: "property-1",
|
|
1305
|
-
name: "Target Material Kind",
|
|
1306
|
-
statement: `The target material kind is ${selections[0]?.target_material_kind ?? "unknown"} for at least one selected evidence unit.`,
|
|
1307
|
-
evidence_refs: [firstEvidence],
|
|
1308
|
-
},
|
|
1309
|
-
],
|
|
1310
|
-
rules: [
|
|
1311
|
-
{
|
|
1312
|
-
claim_id: "rule-1",
|
|
1313
|
-
name: "Artifact Truth Rule",
|
|
1314
|
-
statement: "Any final output must cite artifact truth rather than becoming a second ontology authority.",
|
|
1315
|
-
evidence_refs: [firstEvidence],
|
|
1316
|
-
},
|
|
1317
|
-
],
|
|
1318
|
-
open_questions: [
|
|
1319
|
-
...(input.sourceObservationDirectiveValidation.validation_status === "valid"
|
|
1320
|
-
? []
|
|
1321
|
-
: ["Source observation directive needs revision before Seed use."]),
|
|
1322
|
-
...(materialKinds.size > 1
|
|
1323
|
-
? [
|
|
1324
|
-
"Mixed target material requires a host-authored mapping from each selected observation to ontology terms before expanding beyond the bounded Seed purpose.",
|
|
1325
|
-
]
|
|
1326
|
-
: []),
|
|
1327
|
-
],
|
|
1328
|
-
};
|
|
2341
|
+
async writeCandidateInventory(input) {
|
|
2342
|
+
return mockCandidateInventory({
|
|
2343
|
+
sessionId: input.sessionId,
|
|
2344
|
+
sourceObservations: input.sourceObservations,
|
|
2345
|
+
authorId,
|
|
2346
|
+
});
|
|
2347
|
+
},
|
|
2348
|
+
async writeCandidateDisposition(input) {
|
|
2349
|
+
return mockCandidateDisposition({
|
|
2350
|
+
sessionId: input.sessionId,
|
|
2351
|
+
candidateInventory: input.candidateInventory,
|
|
2352
|
+
authorId,
|
|
2353
|
+
});
|
|
2354
|
+
},
|
|
2355
|
+
async writeOntologySeed(input) {
|
|
2356
|
+
return mockActionableOntologySeed({
|
|
2357
|
+
sessionId: input.sessionId,
|
|
2358
|
+
intent: input.intent,
|
|
2359
|
+
targetMaterialProfile: input.targetMaterialProfile,
|
|
2360
|
+
sourceObservations: input.sourceObservations,
|
|
2361
|
+
authorId,
|
|
2362
|
+
});
|
|
1329
2363
|
},
|
|
1330
2364
|
async writeClaimRealizationMap(input) {
|
|
1331
|
-
const claims =
|
|
2365
|
+
const claims = ontologyClaims(input.ontologySeed);
|
|
1332
2366
|
return {
|
|
1333
2367
|
schema_version: "1",
|
|
1334
2368
|
session_id: input.sessionId,
|
|
1335
2369
|
created_at: isoNow(),
|
|
1336
|
-
|
|
1337
|
-
claim_realizations: claims.map((claim
|
|
1338
|
-
const stance =
|
|
2370
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
2371
|
+
claim_realizations: claims.map((claim) => {
|
|
2372
|
+
const stance = "observed_runtime_behavior";
|
|
1339
2373
|
return {
|
|
1340
2374
|
claim_id: claim.claim_id,
|
|
1341
2375
|
stance,
|
|
1342
2376
|
evidence_refs: claim.evidence_refs,
|
|
1343
|
-
rationale:
|
|
1344
|
-
? "Mock author treats this claim as directly supported by runtime observations."
|
|
1345
|
-
: `Mock author records ${stance} so downstream gates exercise non-happy-path evidence states.`,
|
|
2377
|
+
rationale: "Mock author treats this claim as directly supported by runtime observations.",
|
|
1346
2378
|
};
|
|
1347
2379
|
}),
|
|
1348
2380
|
directive_author: {
|
|
@@ -1352,25 +2384,98 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1352
2384
|
};
|
|
1353
2385
|
},
|
|
1354
2386
|
async writeCompetencyQuestions(input) {
|
|
1355
|
-
const
|
|
1356
|
-
const
|
|
1357
|
-
.filter((claim) =>
|
|
1358
|
-
.map((claim, index) =>
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
2387
|
+
const eligibleClaims = new Set(input.seedConfirmationValidation.cq_eligible_claim_ids);
|
|
2388
|
+
const claimQuestions = ontologyClaims(input.ontologySeed)
|
|
2389
|
+
.filter((claim) => eligibleClaims.has(claim.claim_id))
|
|
2390
|
+
.map((claim, index) => {
|
|
2391
|
+
const question = {
|
|
2392
|
+
question_id: `cq-${index + 1}`,
|
|
2393
|
+
question: `Can the reconstructed Seed explain claim ${claim.claim_id} for its declared purpose?`,
|
|
2394
|
+
linked_claim_ids: [claim.claim_id],
|
|
2395
|
+
coverage_axis_refs: input.contractRegistry.coverage_axis_registry.map((record) => record.axis_id),
|
|
2396
|
+
ontology_handoff_axis_refs: input.contractRegistry.ontology_handoff_axis_registry.map((record) => record.axis_id),
|
|
2397
|
+
seed_ref_refs: [claim.claim_id],
|
|
2398
|
+
limitation_refs: [],
|
|
2399
|
+
reasoning_or_formalism_facets: facetIds(input.contractRegistry.reasoning_or_formalism_facet_registry),
|
|
2400
|
+
entity_identity_facets: facetIds(input.contractRegistry.entity_identity_facet_registry),
|
|
2401
|
+
instance_assertion_facets: facetIds(input.contractRegistry.instance_assertion_facet_registry),
|
|
2402
|
+
terminology_facets: facetIds(input.contractRegistry.terminology_facet_registry),
|
|
2403
|
+
relation_type_facets: facetIds(input.contractRegistry.relation_type_facet_registry),
|
|
2404
|
+
classification_facets: facetIds(input.contractRegistry.classification_facet_registry),
|
|
2405
|
+
constraint_facets: facetIds(input.contractRegistry.constraint_facet_registry),
|
|
2406
|
+
modeling_concern_facets: modelingConcernIds(input.contractRegistry),
|
|
2407
|
+
domain_competency_trace_refs: [],
|
|
2408
|
+
domain_competency_semantic_assessments: [],
|
|
2409
|
+
reference_standard_refs: [],
|
|
2410
|
+
pattern_catalog_refs: [],
|
|
2411
|
+
query_access_contract_refs: [],
|
|
2412
|
+
visualization_contract_refs: [],
|
|
2413
|
+
graph_exploration_contract_refs: [],
|
|
2414
|
+
coverage_disposition: "covered",
|
|
2415
|
+
expected_answer_kind: "yes_no",
|
|
2416
|
+
handoff_relevance: "required",
|
|
2417
|
+
lifecycle_status: "active",
|
|
2418
|
+
rationale: `Mock competency question covers claim ${claim.claim_id} and all registry-required happy-path axes.`,
|
|
2419
|
+
evidence_refs: claim.evidence_refs,
|
|
2420
|
+
};
|
|
2421
|
+
return question;
|
|
2422
|
+
});
|
|
2423
|
+
const requiredDomainCompetencyIds = new Set(input.governingSnapshot.required_admitted_competency_ids);
|
|
2424
|
+
const admittedDomainCompetencies = input.governingSnapshot.admitted_domain_competency_snapshots.flatMap((snapshot) => snapshot.admitted_competencies).filter((competency) => requiredDomainCompetencyIds.has(competency.qualified_competency_id));
|
|
2425
|
+
const domainEvidenceRef = input.sourceObservations.observations[0]
|
|
2426
|
+
? evidenceRefFromObservation(input.sourceObservations.observations[0])
|
|
2427
|
+
: null;
|
|
2428
|
+
const domainCompetencyQuestions = admittedDomainCompetencies.map((competency, index) => {
|
|
2429
|
+
const question = {
|
|
2430
|
+
question_id: `domain-cq-${index + 1}`,
|
|
2431
|
+
question: `Can the reconstructed Seed answer ${competency.qualified_competency_id}: ${competency.question}`,
|
|
2432
|
+
linked_claim_ids: [],
|
|
2433
|
+
coverage_axis_refs: [],
|
|
2434
|
+
ontology_handoff_axis_refs: [],
|
|
2435
|
+
seed_ref_refs: [],
|
|
2436
|
+
limitation_refs: [],
|
|
2437
|
+
reasoning_or_formalism_facets: [],
|
|
2438
|
+
entity_identity_facets: [],
|
|
2439
|
+
instance_assertion_facets: [],
|
|
2440
|
+
terminology_facets: [],
|
|
2441
|
+
relation_type_facets: [],
|
|
2442
|
+
classification_facets: [],
|
|
2443
|
+
constraint_facets: [],
|
|
2444
|
+
modeling_concern_facets: [],
|
|
2445
|
+
domain_competency_trace_refs: [competency.qualified_competency_id],
|
|
2446
|
+
domain_competency_semantic_assessments: [
|
|
2447
|
+
{
|
|
2448
|
+
competency_id: competency.qualified_competency_id,
|
|
2449
|
+
source_anchor: competency.source_anchor,
|
|
2450
|
+
applicability_verdict: "applicable",
|
|
2451
|
+
semantic_alignment: "preserved",
|
|
2452
|
+
rationale: `Mock semantic assessment preserves admitted domain competency ${competency.qualified_competency_id}.`,
|
|
2453
|
+
evidence_refs: domainEvidenceRef ? [domainEvidenceRef] : [],
|
|
2454
|
+
},
|
|
2455
|
+
],
|
|
2456
|
+
reference_standard_refs: [],
|
|
2457
|
+
pattern_catalog_refs: [],
|
|
2458
|
+
query_access_contract_refs: [],
|
|
2459
|
+
visualization_contract_refs: [],
|
|
2460
|
+
graph_exploration_contract_refs: [],
|
|
2461
|
+
coverage_disposition: "covered",
|
|
2462
|
+
expected_answer_kind: "gap_statement",
|
|
2463
|
+
handoff_relevance: "diagnostic",
|
|
2464
|
+
lifecycle_status: "active",
|
|
2465
|
+
rationale: `Mock domain competency disposition row for ${competency.qualified_competency_id}. Verification criteria: ${competency.verification_criteria}`,
|
|
2466
|
+
evidence_refs: domainEvidenceRef ? [domainEvidenceRef] : [],
|
|
2467
|
+
};
|
|
2468
|
+
return question;
|
|
2469
|
+
});
|
|
2470
|
+
const questions = [...claimQuestions, ...domainCompetencyQuestions];
|
|
1364
2471
|
return {
|
|
1365
2472
|
schema_version: "1",
|
|
1366
2473
|
session_id: input.sessionId,
|
|
1367
2474
|
created_at: isoNow(),
|
|
1368
|
-
seed_confirmation_ref:
|
|
2475
|
+
seed_confirmation_ref: null,
|
|
2476
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
1369
2477
|
questions,
|
|
1370
|
-
open_questions: [
|
|
1371
|
-
...input.seedCandidate.open_questions,
|
|
1372
|
-
...input.seedConfirmation.notes,
|
|
1373
|
-
],
|
|
2478
|
+
open_questions: [],
|
|
1374
2479
|
directive_author: {
|
|
1375
2480
|
owner: "mock",
|
|
1376
2481
|
author_id: authorId,
|
|
@@ -1392,20 +2497,27 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1392
2497
|
const firstClaimId = question.linked_claim_ids[0] ?? null;
|
|
1393
2498
|
const stance = firstClaimId
|
|
1394
2499
|
? realizationByClaim.get(firstClaimId)?.stance ?? "unknown"
|
|
1395
|
-
:
|
|
2500
|
+
: question.domain_competency_trace_refs.length > 0
|
|
2501
|
+
? "schema_or_contract_presence"
|
|
2502
|
+
: "unknown";
|
|
1396
2503
|
const answerStatus = stance === "observed_runtime_behavior" ||
|
|
1397
2504
|
stance === "schema_or_contract_presence"
|
|
1398
|
-
? "
|
|
2505
|
+
? "answerable"
|
|
1399
2506
|
: stance === "declared_design_intent"
|
|
1400
|
-
? "
|
|
2507
|
+
? "partially_answerable"
|
|
1401
2508
|
: stance === "deferred_or_non_goal"
|
|
1402
|
-
? "
|
|
1403
|
-
: "
|
|
2509
|
+
? "deferred"
|
|
2510
|
+
: "unsupported";
|
|
1404
2511
|
return {
|
|
1405
2512
|
question_id: question.question_id,
|
|
1406
2513
|
answer_status: answerStatus,
|
|
2514
|
+
answer_summary: `Mock assessment maps claim realization stance ${stance} to answer status ${answerStatus}.`,
|
|
2515
|
+
required_seed_refs: question.seed_ref_refs,
|
|
1407
2516
|
linked_claim_ids: question.linked_claim_ids,
|
|
1408
2517
|
evidence_refs: question.evidence_refs,
|
|
2518
|
+
missing_source_or_confirmation: answerStatus === "answerable" ? null : `Mock unresolved stance: ${stance}`,
|
|
2519
|
+
ambiguity_notes: [],
|
|
2520
|
+
downstream_effect: downstreamEffectForAnswerStatus(answerStatus),
|
|
1409
2521
|
rationale: `Mock assessment maps claim realization stance ${stance} to answer status ${answerStatus}.`,
|
|
1410
2522
|
};
|
|
1411
2523
|
}),
|
|
@@ -1417,13 +2529,16 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1417
2529
|
},
|
|
1418
2530
|
async writeFailureClassification(input) {
|
|
1419
2531
|
const failures = input.competencyQuestionAssessment.assessments
|
|
1420
|
-
.filter((assessment) => assessment.answer_status !== "
|
|
2532
|
+
.filter((assessment) => assessment.answer_status !== "answerable")
|
|
2533
|
+
.filter((assessment) => assessment.answer_status !== "not_applicable")
|
|
1421
2534
|
.map((assessment, index) => {
|
|
1422
|
-
const failureKind = assessment.answer_status === "
|
|
2535
|
+
const failureKind = assessment.answer_status === "deferred"
|
|
1423
2536
|
? "deferred_scope"
|
|
1424
|
-
: assessment.answer_status === "
|
|
2537
|
+
: assessment.answer_status === "partially_answerable"
|
|
1425
2538
|
? "insufficient_evidence"
|
|
1426
|
-
: "
|
|
2539
|
+
: assessment.answer_status === "contradicted"
|
|
2540
|
+
? "contradicted_evidence"
|
|
2541
|
+
: "unsupported_claim";
|
|
1427
2542
|
return {
|
|
1428
2543
|
failure_id: `failure-${index + 1}`,
|
|
1429
2544
|
failure_kind: failureKind,
|
|
@@ -1472,8 +2587,11 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1472
2587
|
};
|
|
1473
2588
|
},
|
|
1474
2589
|
async writeStopDecision(input) {
|
|
1475
|
-
const
|
|
1476
|
-
|
|
2590
|
+
const allowedDecisions = stopDecisionAllowedDecisions(input);
|
|
2591
|
+
const shouldStop = allowedDecisions.includes("stop") &&
|
|
2592
|
+
input.metrics.validation_status.source_observation_directive === "valid" &&
|
|
2593
|
+
input.metrics.validation_status.candidate_disposition === "valid" &&
|
|
2594
|
+
input.metrics.validation_status.ontology_seed === "valid" &&
|
|
1477
2595
|
input.metrics.validation_status.seed_confirmation_validation === "valid" &&
|
|
1478
2596
|
input.metrics.unresolved_question_count === 0;
|
|
1479
2597
|
return {
|
|
@@ -1484,7 +2602,7 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1484
2602
|
declared_purpose: input.intent,
|
|
1485
2603
|
metrics_ref: input.metricsRef,
|
|
1486
2604
|
rationale: shouldStop
|
|
1487
|
-
? "All happy-path runtime gates passed and the
|
|
2605
|
+
? "All happy-path runtime gates passed and the primary ontology seed was accepted."
|
|
1488
2606
|
: "One or more reconstruct gates remains unresolved.",
|
|
1489
2607
|
next_actions: shouldStop
|
|
1490
2608
|
? []
|
|
@@ -1496,10 +2614,10 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1496
2614
|
};
|
|
1497
2615
|
},
|
|
1498
2616
|
async writeFinalOutput(input) {
|
|
1499
|
-
const confirmedClaims =
|
|
2617
|
+
const confirmedClaims = ontologyClaims(input.ontologySeed).filter((claim) => input.seedConfirmationValidation.accepted_claim_ids.includes(claim.claim_id));
|
|
1500
2618
|
const claimLines = confirmedClaims.length === 0
|
|
1501
2619
|
? ["- No Seed claims were confirmed."]
|
|
1502
|
-
: confirmedClaims.map((claim) => `- ${claim.name} (${claim.claim_id}): ${claim.statement} (seed
|
|
2620
|
+
: confirmedClaims.map((claim) => `- ${claim.name} (${claim.claim_id}): ${claim.statement} (ontology-seed.yaml, seed-confirmation-validation.yaml)`);
|
|
1503
2621
|
const realizationLines = input.claimRealizationMap.claim_realizations.map((realization) => `- ${realization.claim_id}: ${realization.stance} (claim-realization-map.yaml)`);
|
|
1504
2622
|
const assessmentLines = input.competencyQuestionAssessment.assessments.length === 0
|
|
1505
2623
|
? ["- No competency question assessments recorded."]
|
|
@@ -1511,12 +2629,12 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1511
2629
|
? ["- No revision proposals recorded."]
|
|
1512
2630
|
: input.revisionProposal.proposals.map((proposal) => `- ${proposal.proposal_id}: ${proposal.action} ${proposal.target_type} ${proposal.target_id} (revision-proposal.yaml)`);
|
|
1513
2631
|
const unresolvedQuestions = [
|
|
1514
|
-
...input.seedCandidate.open_questions,
|
|
1515
2632
|
...input.competencyQuestions.open_questions,
|
|
1516
2633
|
];
|
|
1517
2634
|
const unresolvedLines = unresolvedQuestions.length === 0
|
|
1518
2635
|
? ["- None recorded."]
|
|
1519
2636
|
: unresolvedQuestions.map((question) => `- ${question}`);
|
|
2637
|
+
const answerabilityLines = ontologySeedSummaryLines(input.ontologySeed);
|
|
1520
2638
|
const skippedLines = input.sourceObservations.skipped_refs.length === 0
|
|
1521
2639
|
? ["- None recorded."]
|
|
1522
2640
|
: input.sourceObservations.skipped_refs.map((skipped) => `- ${skipped.ref} (${skipped.target_material_kind}): ${skipped.reason}`);
|
|
@@ -1545,6 +2663,12 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1545
2663
|
`- Material failures: ${input.failureClassificationValidation.material_failure_count}`,
|
|
1546
2664
|
`- Revision proposals: ${input.revisionProposalValidation.proposal_count}`,
|
|
1547
2665
|
`- Pass rate: ${input.metrics.pass_rate}`,
|
|
2666
|
+
`- Handoff readiness: ${input.handoffDecisionValidation.readiness_projection}`,
|
|
2667
|
+
`- Handoff decision validation: ${input.handoffDecisionValidation.validation_status}`,
|
|
2668
|
+
"",
|
|
2669
|
+
"## Seed Answerability",
|
|
2670
|
+
"",
|
|
2671
|
+
...answerabilityLines,
|
|
1548
2672
|
"",
|
|
1549
2673
|
"## Claim Realization Summary",
|
|
1550
2674
|
"",
|
|
@@ -1576,12 +2700,15 @@ export function createMockReconstructDirectiveAuthor() {
|
|
|
1576
2700
|
"",
|
|
1577
2701
|
"## Artifact Truth",
|
|
1578
2702
|
"",
|
|
1579
|
-
`-
|
|
2703
|
+
`- Ontology seed: ${input.artifactRefs.ontology_seed}`,
|
|
2704
|
+
`- Ontology seed validation: ${input.artifactRefs.ontology_seed_validation}`,
|
|
1580
2705
|
`- Claim realization map: ${input.artifactRefs.claim_realization_map}`,
|
|
1581
2706
|
`- Seed confirmation validation: ${input.artifactRefs.seed_confirmation_validation}`,
|
|
1582
2707
|
`- Competency question assessment: ${input.artifactRefs.competency_question_assessment}`,
|
|
1583
2708
|
`- Failure classification: ${input.artifactRefs.failure_classification}`,
|
|
1584
2709
|
`- Revision proposal: ${input.artifactRefs.revision_proposal}`,
|
|
2710
|
+
`- Pre-handoff run manifest validation: ${input.artifactRefs.pre_handoff_run_manifest_validation}`,
|
|
2711
|
+
`- Handoff decision validation: ${input.artifactRefs.handoff_decision_validation}`,
|
|
1585
2712
|
`- Reconstruct record: ${input.reconstructRecordPath}`,
|
|
1586
2713
|
`- Reconstruct run manifest: ${input.reconstructRunManifestPath}`,
|
|
1587
2714
|
`- Record stage at final output authoring: ${input.record.record_stage}`,
|
|
@@ -1596,29 +2723,45 @@ export function createAutoAcceptReconstructConfirmationProvider() {
|
|
|
1596
2723
|
return {
|
|
1597
2724
|
providerId,
|
|
1598
2725
|
owner: "mock",
|
|
1599
|
-
async
|
|
1600
|
-
const claims =
|
|
1601
|
-
const canAccept = input.
|
|
1602
|
-
const
|
|
1603
|
-
const
|
|
1604
|
-
|
|
1605
|
-
|
|
2726
|
+
async confirmOntologySeed(input) {
|
|
2727
|
+
const claims = ontologyClaims(input.ontologySeed);
|
|
2728
|
+
const canAccept = input.ontologySeedValidation.validation_status === "valid";
|
|
2729
|
+
const excludedClaimIds = ontologySeedExcludedClaimIds(input.ontologySeed);
|
|
2730
|
+
const acceptedClaims = canAccept
|
|
2731
|
+
? claims.filter((claim) => !excludedClaimIds.has(claim.claim_id))
|
|
2732
|
+
: [];
|
|
2733
|
+
const partialClaims = [];
|
|
2734
|
+
const deferredClaims = canAccept
|
|
2735
|
+
? claims.filter((claim) => excludedClaimIds.has(claim.claim_id))
|
|
2736
|
+
: [];
|
|
2737
|
+
const classifiedClaimIds = new Set([
|
|
2738
|
+
...acceptedClaims.map((claim) => claim.claim_id),
|
|
2739
|
+
...partialClaims.map((claim) => claim.claim_id),
|
|
2740
|
+
...deferredClaims.map((claim) => claim.claim_id),
|
|
2741
|
+
]);
|
|
2742
|
+
const rejectedClaims = canAccept
|
|
2743
|
+
? claims.filter((claim) => !classifiedClaimIds.has(claim.claim_id))
|
|
2744
|
+
: claims;
|
|
1606
2745
|
return {
|
|
1607
2746
|
schema_version: "1",
|
|
1608
2747
|
session_id: input.sessionId,
|
|
1609
2748
|
created_at: isoNow(),
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
confirmation_status:
|
|
2749
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
2750
|
+
ontology_seed_validation_ref: input.ontologySeedValidationRef,
|
|
2751
|
+
confirmation_status: rejectedClaims.length === 0 && partialClaims.length === 0 && deferredClaims.length === 0
|
|
2752
|
+
? "accepted"
|
|
2753
|
+
: canAccept
|
|
2754
|
+
? "partial"
|
|
2755
|
+
: "rejected",
|
|
1613
2756
|
confirmed_claim_ids: acceptedClaims.map((claim) => claim.claim_id),
|
|
1614
2757
|
rejected_claim_ids: rejectedClaims.map((claim) => claim.claim_id),
|
|
1615
2758
|
partial_claim_ids: partialClaims.map((claim) => claim.claim_id),
|
|
1616
2759
|
deferred_claim_ids: deferredClaims.map((claim) => claim.claim_id),
|
|
1617
2760
|
notes: canAccept
|
|
1618
2761
|
? [
|
|
1619
|
-
"Mock confirmation
|
|
2762
|
+
"Mock confirmation accepts ontology seed claims before competency-question authoring.",
|
|
1620
2763
|
]
|
|
1621
|
-
: ["
|
|
2764
|
+
: ["Ontology seed validation failed; confirmation rejected by provider."],
|
|
1622
2765
|
confirmation_provider: {
|
|
1623
2766
|
owner: "mock",
|
|
1624
2767
|
provider_id: providerId,
|
|
@@ -1634,20 +2777,32 @@ export function createDirectCallReconstructConfirmationProvider(args = {}) {
|
|
|
1634
2777
|
return {
|
|
1635
2778
|
providerId,
|
|
1636
2779
|
owner: "host_or_user",
|
|
1637
|
-
async
|
|
1638
|
-
const claimSummaries =
|
|
2780
|
+
async confirmOntologySeed(input) {
|
|
2781
|
+
const claimSummaries = ontologyClaims(input.ontologySeed).map((claim) => ({
|
|
2782
|
+
claim_id: claim.claim_id,
|
|
2783
|
+
claim_kind: "ontology_seed_claim",
|
|
2784
|
+
name: claim.name,
|
|
2785
|
+
statement: compactStatement(claim.statement),
|
|
2786
|
+
evidence_observation_ids: [
|
|
2787
|
+
...new Set(claim.evidence_refs.map((ref) => ref.observation_id)),
|
|
2788
|
+
],
|
|
2789
|
+
evidence_source_basenames: [
|
|
2790
|
+
...new Set(claim.evidence_refs.map((ref) => sourceBasename(ref.source_ref))),
|
|
2791
|
+
],
|
|
2792
|
+
}));
|
|
1639
2793
|
const result = await llmCall([
|
|
1640
2794
|
"You are mediating reconstruct Seed confirmation for a non-interactive host.",
|
|
1641
2795
|
"Return only valid JSON. Do not wrap in Markdown.",
|
|
1642
2796
|
"Classify every Seed claim summary into confirmed, rejected, partial, or deferred for the declared purpose.",
|
|
1643
2797
|
"Use the claim id, claim kind, short statement, validation status, and evidence observation ids. Do not invent new claim ids.",
|
|
1644
|
-
"
|
|
2798
|
+
"Deferred or unsupported answerability summaries confirm boundary disclosure only; they do not make a claim eligible for competency-question testing.",
|
|
2799
|
+
"Do not re-author Seed content or assess competency-question answerability. This step only assigns seed-claim confirmation state before competency questions are authored.",
|
|
1645
2800
|
"JSON shape: {\"confirmation_status\":\"accepted|rejected|partial|deferred\",\"confirmed_claim_ids\":[\"...\"],\"rejected_claim_ids\":[\"...\"],\"partial_claim_ids\":[\"...\"],\"deferred_claim_ids\":[\"...\"],\"notes\":[\"...\"]}",
|
|
1646
2801
|
].join("\n"), JSON.stringify({
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
2802
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
2803
|
+
ontology_seed_validation_status: input.ontologySeedValidation.validation_status,
|
|
2804
|
+
ontology_seed_validation_results: input.ontologySeedValidation.validation_results,
|
|
2805
|
+
ontology_seed_validation_violation_count: input.ontologySeedValidation.violations.length,
|
|
1651
2806
|
claim_summaries: claimSummaries,
|
|
1652
2807
|
}, null, 2), { ...llmConfig, max_tokens: 2400 });
|
|
1653
2808
|
const raw = parseLlmJsonObject(result.text, "SeedConfirmation");
|
|
@@ -1659,8 +2814,8 @@ export function createDirectCallReconstructConfirmationProvider(args = {}) {
|
|
|
1659
2814
|
schema_version: "1",
|
|
1660
2815
|
session_id: input.sessionId,
|
|
1661
2816
|
created_at: isoNow(),
|
|
1662
|
-
|
|
1663
|
-
|
|
2817
|
+
ontology_seed_ref: input.ontologySeedRef,
|
|
2818
|
+
ontology_seed_validation_ref: input.ontologySeedValidationRef,
|
|
1664
2819
|
confirmation_status: confirmationStatus,
|
|
1665
2820
|
confirmed_claim_ids: stringArray(raw.confirmed_claim_ids, "confirmed_claim_ids"),
|
|
1666
2821
|
rejected_claim_ids: stringArray(raw.rejected_claim_ids, "rejected_claim_ids"),
|
|
@@ -1679,6 +2834,9 @@ async function readLensPrompt(args) {
|
|
|
1679
2834
|
const ontoRoot = path.resolve(args.profilesRoot, "..", "..", "..");
|
|
1680
2835
|
return fs.readFile(path.join(ontoRoot, "roles", `${args.lensId}.md`), "utf8");
|
|
1681
2836
|
}
|
|
2837
|
+
function reconstructContractRegistryPathFromProfilesRoot(profilesRoot) {
|
|
2838
|
+
return path.join(path.dirname(path.resolve(profilesRoot)), "reconstruct-contract-registry.yaml");
|
|
2839
|
+
}
|
|
1682
2840
|
function validateSourceFrontier(args) {
|
|
1683
2841
|
const inventoryRefs = new Set(args.sourceInventory.inventory_units.map((unit) => path.resolve(unit.ref)));
|
|
1684
2842
|
const observedRefs = new Set(args.sourceObservations.observations.map((observation) => path.resolve(observation.source_ref)));
|
|
@@ -1717,7 +2875,16 @@ function validateSourceFrontier(args) {
|
|
|
1717
2875
|
const noNextFrontierAccepted = args.sourceFrontier.frontier_refs.length === 0 &&
|
|
1718
2876
|
typeof args.sourceFrontier.no_next_frontier_rationale === "string" &&
|
|
1719
2877
|
args.sourceFrontier.no_next_frontier_rationale.length > 0;
|
|
1720
|
-
const
|
|
2878
|
+
const upstreamValid = args.targetMaterialProfileValidation.validation_status === "valid";
|
|
2879
|
+
if (!upstreamValid) {
|
|
2880
|
+
rejected.push({
|
|
2881
|
+
frontier_ref_id: null,
|
|
2882
|
+
source_ref: null,
|
|
2883
|
+
reason: "target_material_profile_validation_invalid",
|
|
2884
|
+
});
|
|
2885
|
+
}
|
|
2886
|
+
const valid = upstreamValid &&
|
|
2887
|
+
rejected.length === 0 &&
|
|
1721
2888
|
(accepted.length > 0 || noNextFrontierAccepted);
|
|
1722
2889
|
return {
|
|
1723
2890
|
schema_version: "1",
|
|
@@ -1727,35 +2894,259 @@ function validateSourceFrontier(args) {
|
|
|
1727
2894
|
source_frontier_ref: args.sourceFrontierRef,
|
|
1728
2895
|
source_inventory_ref: args.sourceInventoryRef,
|
|
1729
2896
|
source_observations_ref: args.sourceObservationsRef,
|
|
2897
|
+
target_material_profile_validation_ref: args.targetMaterialProfileValidationRef,
|
|
2898
|
+
upstream_validation_statuses: {
|
|
2899
|
+
target_material_profile: args.targetMaterialProfileValidation.validation_status,
|
|
2900
|
+
},
|
|
1730
2901
|
validation_status: valid ? "valid" : "invalid",
|
|
1731
2902
|
accepted_frontier_ref_ids: accepted,
|
|
1732
2903
|
rejected_frontier_refs: rejected,
|
|
1733
2904
|
no_next_frontier_accepted: noNextFrontierAccepted,
|
|
1734
2905
|
validation_results: [
|
|
1735
2906
|
...(valid ? ["source_frontier_boundary_valid"] : []),
|
|
2907
|
+
...(upstreamValid ? ["target_material_profile_validation_valid"] : []),
|
|
1736
2908
|
...(noNextFrontierAccepted ? ["no_next_frontier_rationale_present"] : []),
|
|
1737
2909
|
],
|
|
1738
2910
|
};
|
|
1739
2911
|
}
|
|
1740
2912
|
function appendFinalOutputProvenanceFooter(finalOutputText, requiredFragments) {
|
|
1741
|
-
const
|
|
1742
|
-
|
|
2913
|
+
const heading = "## Runtime Artifact Truth Footer";
|
|
2914
|
+
const footer = [
|
|
2915
|
+
heading,
|
|
2916
|
+
"",
|
|
2917
|
+
...requiredFragments.map((fragment) => `- ${fragment}`),
|
|
2918
|
+
"",
|
|
2919
|
+
].join("\n");
|
|
2920
|
+
if (finalOutputText.includes(heading)) {
|
|
2921
|
+
const lines = finalOutputText.split(/\r?\n/);
|
|
2922
|
+
const start = lines.findIndex((line) => line.trim() === heading);
|
|
2923
|
+
let end = lines.length;
|
|
2924
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
2925
|
+
if (/^##\s+/.test(lines[index]?.trim() ?? "")) {
|
|
2926
|
+
end = index;
|
|
2927
|
+
break;
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
return [
|
|
2931
|
+
...lines.slice(0, start),
|
|
2932
|
+
footer.trimEnd(),
|
|
2933
|
+
...lines.slice(end),
|
|
2934
|
+
].join("\n");
|
|
2935
|
+
}
|
|
2936
|
+
return [
|
|
2937
|
+
finalOutputText.trimEnd(),
|
|
2938
|
+
"",
|
|
2939
|
+
footer,
|
|
2940
|
+
].join("\n");
|
|
2941
|
+
}
|
|
2942
|
+
function appendFinalOutputProvenanceBindingsSection(finalOutputText, sectionBindings) {
|
|
2943
|
+
const heading = "## Runtime Provenance Bindings";
|
|
2944
|
+
const content = [
|
|
2945
|
+
heading,
|
|
2946
|
+
"",
|
|
2947
|
+
...sectionBindings.flatMap((binding) => [
|
|
2948
|
+
`- ${binding.section_id}: ${binding.claim_summary}`,
|
|
2949
|
+
` - section: ${binding.heading}`,
|
|
2950
|
+
` - authority_refs: ${binding.authority_refs.join(", ")}`,
|
|
2951
|
+
` - validation_refs: ${binding.validation_refs.join(", ")}`,
|
|
2952
|
+
]),
|
|
2953
|
+
"",
|
|
2954
|
+
].join("\n");
|
|
2955
|
+
if (!finalOutputText.includes(heading)) {
|
|
2956
|
+
return [
|
|
2957
|
+
finalOutputText.trimEnd(),
|
|
2958
|
+
"",
|
|
2959
|
+
content,
|
|
2960
|
+
].join("\n");
|
|
2961
|
+
}
|
|
2962
|
+
const lines = finalOutputText.split(/\r?\n/);
|
|
2963
|
+
const start = lines.findIndex((line) => line.trim() === heading);
|
|
2964
|
+
if (start < 0)
|
|
2965
|
+
return finalOutputText;
|
|
2966
|
+
let end = lines.length;
|
|
2967
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
2968
|
+
if (/^##\s+/.test(lines[index]?.trim() ?? "")) {
|
|
2969
|
+
end = index;
|
|
2970
|
+
break;
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
return [
|
|
2974
|
+
...lines.slice(0, start),
|
|
2975
|
+
content.trimEnd(),
|
|
2976
|
+
...lines.slice(end),
|
|
2977
|
+
].join("\n");
|
|
2978
|
+
}
|
|
2979
|
+
function appendFinalOutputAnswerabilitySection(finalOutputText, ontologySeed) {
|
|
2980
|
+
if (finalOutputText.includes("## Seed Answerability"))
|
|
1743
2981
|
return finalOutputText;
|
|
1744
2982
|
return [
|
|
1745
2983
|
finalOutputText.trimEnd(),
|
|
1746
2984
|
"",
|
|
1747
|
-
"##
|
|
2985
|
+
"## Seed Answerability",
|
|
1748
2986
|
"",
|
|
1749
|
-
...
|
|
2987
|
+
...ontologySeedSummaryLines(ontologySeed),
|
|
1750
2988
|
"",
|
|
1751
2989
|
].join("\n");
|
|
1752
2990
|
}
|
|
2991
|
+
function appendFinalOutputArtifactTruthSection(finalOutputText, args) {
|
|
2992
|
+
const heading = "## Artifact Truth";
|
|
2993
|
+
const content = [
|
|
2994
|
+
heading,
|
|
2995
|
+
"",
|
|
2996
|
+
`- Ontology seed: ${args.ontologySeedPath}`,
|
|
2997
|
+
`- Ontology seed validation: ${args.ontologySeedValidationPath}`,
|
|
2998
|
+
`- Claim realization map: ${args.claimRealizationMapPath}`,
|
|
2999
|
+
`- Seed confirmation validation: ${args.seedConfirmationValidationPath}`,
|
|
3000
|
+
`- Competency question assessment: ${args.competencyQuestionAssessmentPath}`,
|
|
3001
|
+
`- Failure classification: ${args.failureClassificationPath}`,
|
|
3002
|
+
`- Revision proposal: ${args.revisionProposalPath}`,
|
|
3003
|
+
`- Pre-handoff run manifest: ${args.preHandoffManifestPath}`,
|
|
3004
|
+
`- Pre-handoff run manifest validation: ${args.preHandoffRunManifestValidationPath}`,
|
|
3005
|
+
`- Handoff decision validation: ${args.handoffDecisionValidationPath}`,
|
|
3006
|
+
`- Reconstruct record: ${args.recordPath}`,
|
|
3007
|
+
`- Reconstruct run manifest: ${args.manifestPath}`,
|
|
3008
|
+
"",
|
|
3009
|
+
].join("\n");
|
|
3010
|
+
if (!finalOutputText.includes(heading)) {
|
|
3011
|
+
return [
|
|
3012
|
+
finalOutputText.trimEnd(),
|
|
3013
|
+
"",
|
|
3014
|
+
content,
|
|
3015
|
+
].join("\n");
|
|
3016
|
+
}
|
|
3017
|
+
const lines = finalOutputText.split(/\r?\n/);
|
|
3018
|
+
const start = lines.findIndex((line) => line.trim() === heading);
|
|
3019
|
+
if (start < 0)
|
|
3020
|
+
return finalOutputText;
|
|
3021
|
+
let end = lines.length;
|
|
3022
|
+
for (let index = start + 1; index < lines.length; index += 1) {
|
|
3023
|
+
if (/^##\s+/.test(lines[index]?.trim() ?? "")) {
|
|
3024
|
+
end = index;
|
|
3025
|
+
break;
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
return [
|
|
3029
|
+
...lines.slice(0, start),
|
|
3030
|
+
content.trimEnd(),
|
|
3031
|
+
...lines.slice(end),
|
|
3032
|
+
].join("\n");
|
|
3033
|
+
}
|
|
3034
|
+
async function writeFinalOutputProvenanceValidationArtifact(args) {
|
|
3035
|
+
const finalOutputText = await fs.readFile(args.finalOutputPath, "utf8");
|
|
3036
|
+
const requiredFragments = [
|
|
3037
|
+
...new Set(args.sectionBindings.flatMap((binding) => binding.required_fragments)),
|
|
3038
|
+
];
|
|
3039
|
+
const violations = validateFinalOutputProvenance({
|
|
3040
|
+
finalOutputText,
|
|
3041
|
+
sectionBindings: args.sectionBindings,
|
|
3042
|
+
});
|
|
3043
|
+
const violationSubjects = new Set(violations.map((item) => item.subject_id).filter((item) => item !== null));
|
|
3044
|
+
const artifact = {
|
|
3045
|
+
schema_version: "1",
|
|
3046
|
+
session_id: args.sessionId,
|
|
3047
|
+
created_at: isoNow(),
|
|
3048
|
+
final_output_ref: args.finalOutputPath,
|
|
3049
|
+
validation_status: violations.length === 0 ? "valid" : "invalid",
|
|
3050
|
+
required_fragments: requiredFragments,
|
|
3051
|
+
section_bindings: args.sectionBindings.map((binding) => {
|
|
3052
|
+
const missing = binding.required_fragments.some((fragment) => violationSubjects.has(`${binding.section_id}:${fragment}`)) || violationSubjects.has(binding.section_id);
|
|
3053
|
+
return {
|
|
3054
|
+
section_id: binding.section_id,
|
|
3055
|
+
heading: binding.heading,
|
|
3056
|
+
claim_summary: binding.claim_summary,
|
|
3057
|
+
authority_refs: binding.authority_refs,
|
|
3058
|
+
validation_refs: binding.validation_refs,
|
|
3059
|
+
required_fragments: binding.required_fragments,
|
|
3060
|
+
binding_status: missing
|
|
3061
|
+
? "missing"
|
|
3062
|
+
: "present",
|
|
3063
|
+
trust_status: missing
|
|
3064
|
+
? "unbound"
|
|
3065
|
+
: "grounded",
|
|
3066
|
+
};
|
|
3067
|
+
}),
|
|
3068
|
+
validation_results: violations.length === 0
|
|
3069
|
+
? ["final_output_provenance_valid"]
|
|
3070
|
+
: ["final_output_provenance_invalid"],
|
|
3071
|
+
violations,
|
|
3072
|
+
};
|
|
3073
|
+
await writeYamlDocument(args.outputPath, artifact);
|
|
3074
|
+
return artifact;
|
|
3075
|
+
}
|
|
3076
|
+
function finalOutputProvenanceSectionBindings(args) {
|
|
3077
|
+
return [
|
|
3078
|
+
{
|
|
3079
|
+
section_id: "seed-answerability",
|
|
3080
|
+
heading: "Seed Answerability",
|
|
3081
|
+
claim_summary: "Seed answerability is grounded in the seed and competency-question artifacts.",
|
|
3082
|
+
authority_refs: [args.ontologySeedPath, args.competencyQuestionsPath],
|
|
3083
|
+
validation_refs: [
|
|
3084
|
+
args.ontologySeedValidationPath,
|
|
3085
|
+
args.competencyQuestionsValidationPath,
|
|
3086
|
+
],
|
|
3087
|
+
required_fragments: ["Ontology seed projected claims", "Coverage axes"],
|
|
3088
|
+
},
|
|
3089
|
+
{
|
|
3090
|
+
section_id: "artifact-truth",
|
|
3091
|
+
heading: "Artifact Truth",
|
|
3092
|
+
claim_summary: "Terminal artifact truth is grounded in the pre-handoff manifest validation, handoff readiness validation, final output provenance, and planned terminal record paths.",
|
|
3093
|
+
authority_refs: [args.recordPath, args.manifestPath, args.preHandoffManifestPath],
|
|
3094
|
+
validation_refs: [
|
|
3095
|
+
args.preHandoffRunManifestValidationPath,
|
|
3096
|
+
args.handoffDecisionValidationPath,
|
|
3097
|
+
args.finalOutputProvenanceValidationPath,
|
|
3098
|
+
],
|
|
3099
|
+
required_fragments: [
|
|
3100
|
+
args.ontologySeedPath,
|
|
3101
|
+
args.ontologySeedValidationPath,
|
|
3102
|
+
args.claimRealizationMapPath,
|
|
3103
|
+
args.seedConfirmationValidationPath,
|
|
3104
|
+
args.competencyQuestionAssessmentPath,
|
|
3105
|
+
args.failureClassificationPath,
|
|
3106
|
+
args.revisionProposalPath,
|
|
3107
|
+
args.preHandoffManifestPath,
|
|
3108
|
+
args.preHandoffRunManifestValidationPath,
|
|
3109
|
+
args.handoffDecisionValidationPath,
|
|
3110
|
+
args.recordPath,
|
|
3111
|
+
args.manifestPath,
|
|
3112
|
+
],
|
|
3113
|
+
},
|
|
3114
|
+
{
|
|
3115
|
+
section_id: "runtime-artifact-truth-footer",
|
|
3116
|
+
heading: "Runtime Artifact Truth Footer",
|
|
3117
|
+
claim_summary: "The runtime footer enumerates all required provenance fragments for audit.",
|
|
3118
|
+
authority_refs: [args.manifestPath, args.recordPath],
|
|
3119
|
+
validation_refs: [args.finalOutputProvenanceValidationPath],
|
|
3120
|
+
required_fragments: args.finalFragments,
|
|
3121
|
+
},
|
|
3122
|
+
{
|
|
3123
|
+
section_id: "runtime-provenance-bindings",
|
|
3124
|
+
heading: "Runtime Provenance Bindings",
|
|
3125
|
+
claim_summary: "The runtime-emitted provenance binding section lists section-to-authority bindings.",
|
|
3126
|
+
authority_refs: [args.finalOutputProvenanceValidationPath],
|
|
3127
|
+
validation_refs: [args.finalOutputProvenanceValidationPath],
|
|
3128
|
+
required_fragments: [
|
|
3129
|
+
"seed-answerability",
|
|
3130
|
+
"artifact-truth",
|
|
3131
|
+
"runtime-artifact-truth-footer",
|
|
3132
|
+
],
|
|
3133
|
+
},
|
|
3134
|
+
];
|
|
3135
|
+
}
|
|
1753
3136
|
export async function runReconstruct(params) {
|
|
1754
3137
|
const projectRoot = path.resolve(params.projectRoot);
|
|
1755
3138
|
const sessionRoot = path.resolve(params.sessionRoot);
|
|
1756
3139
|
const sessionId = path.basename(sessionRoot);
|
|
1757
3140
|
const targetRefs = params.targetRefs.map((targetRef) => path.resolve(targetRef));
|
|
1758
3141
|
const { directiveAuthor, confirmationProvider } = params;
|
|
3142
|
+
const reuseExistingAuthoredArtifacts = params.resumeMode === "reuse_existing_authored_artifacts";
|
|
3143
|
+
let currentAuthoredArtifactCompatibility = null;
|
|
3144
|
+
const writeAuthoredYamlDocument = (filePath, artifactName, create) => writeFreshAuthoredYamlDocument(filePath, artifactName, create, {
|
|
3145
|
+
reuseExisting: reuseExistingAuthoredArtifacts,
|
|
3146
|
+
...(currentAuthoredArtifactCompatibility
|
|
3147
|
+
? { compatibility: currentAuthoredArtifactCompatibility }
|
|
3148
|
+
: {}),
|
|
3149
|
+
});
|
|
1759
3150
|
if (params.semanticAuthorRealization !== "mock" &&
|
|
1760
3151
|
params.semanticAuthorRealization !== "direct_call") {
|
|
1761
3152
|
throw new Error(`Unsupported reconstruct semanticAuthorRealization: ${params.semanticAuthorRealization}`);
|
|
@@ -1782,20 +3173,67 @@ export async function runReconstruct(params) {
|
|
|
1782
3173
|
const targetMaterialProfile = await readYamlDocument(preparationRefs.target_material_profile);
|
|
1783
3174
|
const sourceObservations = await readYamlDocument(preparationRefs.source_observations);
|
|
1784
3175
|
const sourceInventory = await readYamlDocument(preparationRefs.source_inventory);
|
|
1785
|
-
const
|
|
1786
|
-
const
|
|
3176
|
+
const contractRegistryPath = reconstructContractRegistryPathFromProfilesRoot(params.profilesRoot);
|
|
3177
|
+
const contractRegistry = await loadReconstructContractRegistry({
|
|
3178
|
+
registryPath: contractRegistryPath,
|
|
3179
|
+
});
|
|
3180
|
+
const manifestPath = path.join(sessionRoot, "reconstruct-run-manifest.yaml");
|
|
3181
|
+
const targetMaterialProfileValidationPath = path.join(sessionRoot, "target-material-profile-validation.yaml");
|
|
3182
|
+
const targetMaterialProfileValidation = await writeTargetMaterialProfileValidationArtifact({
|
|
3183
|
+
targetMaterialProfilePath: preparationRefs.target_material_profile,
|
|
3184
|
+
registryPath: contractRegistryPath,
|
|
3185
|
+
outputPath: targetMaterialProfileValidationPath,
|
|
3186
|
+
});
|
|
3187
|
+
assertRuntimeValidationValid({
|
|
3188
|
+
artifactName: "target-material-profile",
|
|
3189
|
+
artifactRef: targetMaterialProfileValidationPath,
|
|
3190
|
+
validation: targetMaterialProfileValidation,
|
|
3191
|
+
});
|
|
3192
|
+
assertSemanticAuthoringHasObservedEvidence({
|
|
3193
|
+
targetMaterialProfile,
|
|
3194
|
+
sourceInventory,
|
|
3195
|
+
sourceObservations,
|
|
3196
|
+
});
|
|
3197
|
+
const lensIds = loadCoreLensRegistry().full_review_lens_ids;
|
|
3198
|
+
const governingSnapshot = await buildReconstructRunGoverningSnapshot({
|
|
3199
|
+
projectRoot,
|
|
3200
|
+
registryPath: contractRegistryPath,
|
|
3201
|
+
contractRegistry,
|
|
3202
|
+
selectedSourceProfiles: targetMaterialProfile.selected_source_profiles,
|
|
3203
|
+
lensIds,
|
|
3204
|
+
admittedDomainIds: params.domain ? [params.domain] : [],
|
|
3205
|
+
});
|
|
3206
|
+
currentAuthoredArtifactCompatibility = authoredArtifactCompatibility({
|
|
1787
3207
|
sessionId,
|
|
1788
3208
|
intent: params.intent,
|
|
3209
|
+
targetRefs,
|
|
1789
3210
|
targetMaterialProfile,
|
|
3211
|
+
sourceInventory,
|
|
1790
3212
|
sourceObservations,
|
|
3213
|
+
governingSnapshot,
|
|
3214
|
+
semanticAuthorRealization: params.semanticAuthorRealization,
|
|
3215
|
+
confirmationProviderRealization: params.confirmationProviderRealization,
|
|
3216
|
+
directiveAuthor,
|
|
3217
|
+
confirmationProvider,
|
|
1791
3218
|
});
|
|
1792
|
-
|
|
3219
|
+
const sourceObservationDirectivePath = path.join(sessionRoot, "source-observation-directive.yaml");
|
|
3220
|
+
const sourceObservationDirective = await writeAuthoredYamlDocument(sourceObservationDirectivePath, "source-observation-directive.yaml", () => directiveAuthor.writeSourceObservationDirective({
|
|
3221
|
+
sessionId,
|
|
3222
|
+
intent: params.intent,
|
|
3223
|
+
targetMaterialProfile,
|
|
3224
|
+
sourceObservations,
|
|
3225
|
+
}));
|
|
1793
3226
|
const sourceObservationDirectiveValidationPath = path.join(sessionRoot, "source-observation-directive-validation.yaml");
|
|
1794
3227
|
const sourceObservationDirectiveValidation = await writeSourceObservationDirectiveValidationArtifact({
|
|
1795
3228
|
directivePath: sourceObservationDirectivePath,
|
|
1796
3229
|
sourceObservationsPath: preparationRefs.source_observations,
|
|
1797
3230
|
outputPath: sourceObservationDirectiveValidationPath,
|
|
1798
3231
|
});
|
|
3232
|
+
assertRuntimeValidationValid({
|
|
3233
|
+
artifactName: "source-observation-directive",
|
|
3234
|
+
artifactRef: sourceObservationDirectiveValidationPath,
|
|
3235
|
+
validation: sourceObservationDirectiveValidation,
|
|
3236
|
+
});
|
|
1799
3237
|
const roundId = "round-1";
|
|
1800
3238
|
const roundRoot = path.join(sessionRoot, "rounds", roundId);
|
|
1801
3239
|
const roundObservationDirectivePath = path.join(roundRoot, "source-observation-directive.yaml");
|
|
@@ -1803,7 +3241,6 @@ export async function runReconstruct(params) {
|
|
|
1803
3241
|
await writeYamlDocument(roundObservationDirectivePath, sourceObservationDirective);
|
|
1804
3242
|
await writeYamlDocument(roundObservationDirectiveValidationPath, sourceObservationDirectiveValidation);
|
|
1805
3243
|
const lensJudgmentRoot = path.join(roundRoot, "lens-judgments");
|
|
1806
|
-
const lensIds = loadCoreLensRegistry().full_review_lens_ids;
|
|
1807
3244
|
const lensJudgments = [];
|
|
1808
3245
|
const lensJudgmentRefs = [];
|
|
1809
3246
|
for (const lensId of lensIds) {
|
|
@@ -1811,7 +3248,8 @@ export async function runReconstruct(params) {
|
|
|
1811
3248
|
profilesRoot: path.resolve(params.profilesRoot),
|
|
1812
3249
|
lensId,
|
|
1813
3250
|
});
|
|
1814
|
-
const
|
|
3251
|
+
const lensJudgmentPath = path.join(lensJudgmentRoot, `${lensId}.yaml`);
|
|
3252
|
+
const lensJudgment = await writeAuthoredYamlDocument(lensJudgmentPath, `lens judgment ${lensId}`, () => directiveAuthor.writeLensJudgment({
|
|
1815
3253
|
sessionId,
|
|
1816
3254
|
intent: params.intent,
|
|
1817
3255
|
roundId,
|
|
@@ -1820,9 +3258,7 @@ export async function runReconstruct(params) {
|
|
|
1820
3258
|
sourceObservations,
|
|
1821
3259
|
sourceObservationDirective,
|
|
1822
3260
|
sourceObservationDirectiveRef: roundObservationDirectivePath,
|
|
1823
|
-
});
|
|
1824
|
-
const lensJudgmentPath = path.join(lensJudgmentRoot, `${lensId}.yaml`);
|
|
1825
|
-
await writeYamlDocument(lensJudgmentPath, lensJudgment);
|
|
3261
|
+
}));
|
|
1826
3262
|
lensJudgments.push(lensJudgment);
|
|
1827
3263
|
lensJudgmentRefs.push({
|
|
1828
3264
|
lens_id: lensId,
|
|
@@ -1839,23 +3275,25 @@ export async function runReconstruct(params) {
|
|
|
1839
3275
|
};
|
|
1840
3276
|
await writeYamlDocument(lensJudgmentIndexPath, lensJudgmentIndex);
|
|
1841
3277
|
const explorationSynthesisPath = path.join(roundRoot, "exploration-synthesis.yaml");
|
|
1842
|
-
const explorationSynthesis = await directiveAuthor.writeExplorationSynthesis({
|
|
3278
|
+
const explorationSynthesis = await writeAuthoredYamlDocument(explorationSynthesisPath, "exploration-synthesis.yaml", () => directiveAuthor.writeExplorationSynthesis({
|
|
1843
3279
|
sessionId,
|
|
1844
3280
|
intent: params.intent,
|
|
1845
3281
|
roundId,
|
|
1846
3282
|
lensJudgments,
|
|
1847
3283
|
lensJudgmentIndexRef: lensJudgmentIndexPath,
|
|
1848
|
-
|
|
1849
|
-
|
|
3284
|
+
sourceObservations,
|
|
3285
|
+
sourceObservationsRef: preparationRefs.source_observations,
|
|
3286
|
+
}));
|
|
1850
3287
|
const sourceFrontierPath = path.join(roundRoot, "source-frontier.yaml");
|
|
1851
|
-
const sourceFrontier = await directiveAuthor.writeSourceFrontier({
|
|
3288
|
+
const sourceFrontier = await writeAuthoredYamlDocument(sourceFrontierPath, "source-frontier.yaml", () => directiveAuthor.writeSourceFrontier({
|
|
1852
3289
|
sessionId,
|
|
1853
3290
|
intent: params.intent,
|
|
1854
3291
|
roundId,
|
|
1855
3292
|
explorationSynthesis,
|
|
1856
3293
|
explorationSynthesisRef: explorationSynthesisPath,
|
|
1857
|
-
|
|
1858
|
-
|
|
3294
|
+
sourceInventory,
|
|
3295
|
+
sourceObservations,
|
|
3296
|
+
}));
|
|
1859
3297
|
const sourceFrontierValidationPath = path.join(roundRoot, "source-frontier-validation.yaml");
|
|
1860
3298
|
const sourceFrontierValidation = validateSourceFrontier({
|
|
1861
3299
|
sessionId,
|
|
@@ -1866,102 +3304,181 @@ export async function runReconstruct(params) {
|
|
|
1866
3304
|
sourceInventoryRef: preparationRefs.source_inventory,
|
|
1867
3305
|
sourceObservations,
|
|
1868
3306
|
sourceObservationsRef: preparationRefs.source_observations,
|
|
3307
|
+
targetMaterialProfileValidation,
|
|
3308
|
+
targetMaterialProfileValidationRef: targetMaterialProfileValidationPath,
|
|
1869
3309
|
});
|
|
1870
3310
|
await writeYamlDocument(sourceFrontierValidationPath, sourceFrontierValidation);
|
|
1871
|
-
|
|
1872
|
-
|
|
3311
|
+
assertRuntimeValidationValid({
|
|
3312
|
+
artifactName: "source-frontier",
|
|
3313
|
+
artifactRef: sourceFrontierValidationPath,
|
|
3314
|
+
validation: sourceFrontierValidation,
|
|
3315
|
+
});
|
|
3316
|
+
if (sourceFrontierValidation.accepted_frontier_ref_ids.length > 0) {
|
|
3317
|
+
throw new Error([
|
|
3318
|
+
"source-frontier accepted new source refs, but this runner has no multi-round observation loop yet.",
|
|
3319
|
+
"Use no_next_frontier_rationale for terminal frontier or implement observation of accepted refs before semantic authoring.",
|
|
3320
|
+
`accepted_frontier_ref_ids=${sourceFrontierValidation.accepted_frontier_ref_ids.join(",")}`,
|
|
3321
|
+
].join(" "));
|
|
3322
|
+
}
|
|
3323
|
+
const candidateInventoryPath = path.join(sessionRoot, "candidate-inventory.yaml");
|
|
3324
|
+
const candidateInventory = await writeAuthoredYamlDocument(candidateInventoryPath, "candidate-inventory.yaml", () => directiveAuthor.writeCandidateInventory({
|
|
1873
3325
|
sessionId,
|
|
1874
3326
|
intent: params.intent,
|
|
1875
3327
|
sourceObservations,
|
|
3328
|
+
sourceObservationsRef: preparationRefs.source_observations,
|
|
1876
3329
|
sourceObservationDirective,
|
|
1877
|
-
sourceObservationDirectiveValidation,
|
|
1878
3330
|
lensJudgmentIndex,
|
|
1879
3331
|
explorationSynthesis,
|
|
1880
3332
|
sourceFrontierValidation,
|
|
3333
|
+
contractRegistry,
|
|
3334
|
+
}));
|
|
3335
|
+
const candidateDispositionPath = path.join(sessionRoot, "candidate-disposition.yaml");
|
|
3336
|
+
const candidateDisposition = await writeAuthoredYamlDocument(candidateDispositionPath, "candidate-disposition.yaml", () => directiveAuthor.writeCandidateDisposition({
|
|
3337
|
+
sessionId,
|
|
3338
|
+
intent: params.intent,
|
|
3339
|
+
candidateInventory,
|
|
3340
|
+
candidateInventoryRef: candidateInventoryPath,
|
|
3341
|
+
sourceObservations,
|
|
3342
|
+
contractRegistry,
|
|
3343
|
+
}));
|
|
3344
|
+
const candidateDispositionValidationPath = path.join(sessionRoot, "candidate-disposition-validation.yaml");
|
|
3345
|
+
const candidateDispositionValidation = await writeCandidateDispositionValidationArtifact({
|
|
3346
|
+
candidateInventoryPath,
|
|
3347
|
+
candidateDispositionPath,
|
|
3348
|
+
sourceObservationsPath: preparationRefs.source_observations,
|
|
3349
|
+
registryPath: contractRegistryPath,
|
|
3350
|
+
outputPath: candidateDispositionValidationPath,
|
|
3351
|
+
});
|
|
3352
|
+
assertRuntimeValidationValid({
|
|
3353
|
+
artifactName: "candidate-disposition",
|
|
3354
|
+
artifactRef: candidateDispositionValidationPath,
|
|
3355
|
+
validation: candidateDispositionValidation,
|
|
1881
3356
|
});
|
|
1882
|
-
|
|
1883
|
-
const
|
|
1884
|
-
|
|
1885
|
-
|
|
3357
|
+
const ontologySeedPath = path.join(sessionRoot, "ontology-seed.yaml");
|
|
3358
|
+
const ontologySeed = await writeAuthoredYamlDocument(ontologySeedPath, "ontology-seed.yaml", () => directiveAuthor.writeOntologySeed({
|
|
3359
|
+
sessionId,
|
|
3360
|
+
intent: params.intent,
|
|
3361
|
+
targetMaterialProfile,
|
|
3362
|
+
candidateInventory,
|
|
3363
|
+
candidateInventoryRef: candidateInventoryPath,
|
|
3364
|
+
candidateDisposition,
|
|
3365
|
+
candidateDispositionRef: candidateDispositionPath,
|
|
3366
|
+
sourceObservations,
|
|
3367
|
+
sourceObservationsRef: preparationRefs.source_observations,
|
|
3368
|
+
contractRegistry,
|
|
3369
|
+
}));
|
|
3370
|
+
const ontologySeedValidationPath = path.join(sessionRoot, "ontology-seed-validation.yaml");
|
|
3371
|
+
const ontologySeedValidation = await writeActionableOntologySeedValidationArtifact({
|
|
3372
|
+
ontologySeedPath,
|
|
3373
|
+
candidateDispositionPath,
|
|
1886
3374
|
sourceObservationsPath: preparationRefs.source_observations,
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
3375
|
+
registryPath: contractRegistryPath,
|
|
3376
|
+
outputPath: ontologySeedValidationPath,
|
|
3377
|
+
});
|
|
3378
|
+
assertRuntimeValidationValid({
|
|
3379
|
+
artifactName: "ontology-seed",
|
|
3380
|
+
artifactRef: ontologySeedValidationPath,
|
|
3381
|
+
validation: ontologySeedValidation,
|
|
1890
3382
|
});
|
|
1891
3383
|
const claimRealizationMapPath = path.join(sessionRoot, "claim-realization-map.yaml");
|
|
1892
|
-
const claimRealizationMap = await directiveAuthor.writeClaimRealizationMap({
|
|
3384
|
+
const claimRealizationMap = await writeAuthoredYamlDocument(claimRealizationMapPath, "claim-realization-map.yaml", () => directiveAuthor.writeClaimRealizationMap({
|
|
1893
3385
|
sessionId,
|
|
1894
|
-
|
|
1895
|
-
|
|
3386
|
+
ontologySeed,
|
|
3387
|
+
ontologySeedRef: ontologySeedPath,
|
|
3388
|
+
ontologySeedValidation,
|
|
1896
3389
|
sourceObservations,
|
|
1897
|
-
});
|
|
1898
|
-
await writeYamlDocument(claimRealizationMapPath, claimRealizationMap);
|
|
3390
|
+
}));
|
|
1899
3391
|
const claimRealizationMapValidationPath = path.join(sessionRoot, "claim-realization-map-validation.yaml");
|
|
1900
|
-
const claimRealizationMapValidation = await
|
|
3392
|
+
const claimRealizationMapValidation = await writeClaimRealizationMapValidationForOntologySeedArtifact({
|
|
1901
3393
|
claimRealizationMapPath,
|
|
1902
|
-
|
|
3394
|
+
ontologySeedPath,
|
|
1903
3395
|
sourceObservationsPath: preparationRefs.source_observations,
|
|
1904
3396
|
outputPath: claimRealizationMapValidationPath,
|
|
1905
3397
|
});
|
|
3398
|
+
assertRuntimeValidationValid({
|
|
3399
|
+
artifactName: "claim-realization-map",
|
|
3400
|
+
artifactRef: claimRealizationMapValidationPath,
|
|
3401
|
+
validation: claimRealizationMapValidation,
|
|
3402
|
+
});
|
|
1906
3403
|
const seedConfirmationPath = path.join(sessionRoot, "seed-confirmation.yaml");
|
|
1907
|
-
const seedConfirmation = await confirmationProvider.
|
|
3404
|
+
const seedConfirmation = await writeAuthoredYamlDocument(seedConfirmationPath, "seed-confirmation.yaml", () => confirmationProvider.confirmOntologySeed({
|
|
1908
3405
|
sessionId,
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
});
|
|
1914
|
-
await writeYamlDocument(seedConfirmationPath, seedConfirmation);
|
|
3406
|
+
ontologySeed,
|
|
3407
|
+
ontologySeedRef: ontologySeedPath,
|
|
3408
|
+
ontologySeedValidation,
|
|
3409
|
+
ontologySeedValidationRef: ontologySeedValidationPath,
|
|
3410
|
+
}));
|
|
1915
3411
|
const seedConfirmationValidationPath = path.join(sessionRoot, "seed-confirmation-validation.yaml");
|
|
1916
|
-
const seedConfirmationValidation = await
|
|
3412
|
+
const seedConfirmationValidation = await writeSeedConfirmationValidationForOntologySeedArtifact({
|
|
1917
3413
|
seedConfirmationPath,
|
|
1918
|
-
|
|
1919
|
-
|
|
3414
|
+
ontologySeedPath,
|
|
3415
|
+
ontologySeedValidationPath,
|
|
1920
3416
|
outputPath: seedConfirmationValidationPath,
|
|
1921
3417
|
});
|
|
3418
|
+
assertRuntimeValidationValid({
|
|
3419
|
+
artifactName: "seed-confirmation",
|
|
3420
|
+
artifactRef: seedConfirmationValidationPath,
|
|
3421
|
+
validation: seedConfirmationValidation,
|
|
3422
|
+
});
|
|
1922
3423
|
const competencyQuestionsPath = path.join(sessionRoot, "competency-questions.yaml");
|
|
1923
|
-
const competencyQuestions = await directiveAuthor.writeCompetencyQuestions({
|
|
3424
|
+
const competencyQuestions = await writeAuthoredYamlDocument(competencyQuestionsPath, "competency-questions.yaml", () => directiveAuthor.writeCompetencyQuestions({
|
|
1924
3425
|
sessionId,
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
3426
|
+
ontologySeed,
|
|
3427
|
+
ontologySeedRef: ontologySeedPath,
|
|
3428
|
+
ontologySeedValidation,
|
|
1928
3429
|
seedConfirmationValidation,
|
|
1929
3430
|
seedConfirmationValidationRef: seedConfirmationValidationPath,
|
|
1930
3431
|
claimRealizationMap,
|
|
1931
|
-
|
|
1932
|
-
|
|
3432
|
+
sourceObservations,
|
|
3433
|
+
sourceObservationsRef: preparationRefs.source_observations,
|
|
3434
|
+
contractRegistry,
|
|
3435
|
+
governingSnapshot,
|
|
3436
|
+
}));
|
|
1933
3437
|
const competencyQuestionsValidationPath = path.join(sessionRoot, "competency-questions-validation.yaml");
|
|
1934
|
-
const competencyQuestionsValidation = await
|
|
3438
|
+
const competencyQuestionsValidation = await writeCompetencyQuestionsValidationForOntologySeedArtifact({
|
|
1935
3439
|
competencyQuestionsPath,
|
|
3440
|
+
ontologySeedPath,
|
|
3441
|
+
ontologySeedValidationPath,
|
|
1936
3442
|
seedConfirmationValidationPath,
|
|
1937
3443
|
sourceObservationsPath: preparationRefs.source_observations,
|
|
3444
|
+
registryPath: contractRegistryPath,
|
|
3445
|
+
reconstructRunManifestPath: manifestPath,
|
|
3446
|
+
governingSnapshot,
|
|
1938
3447
|
outputPath: competencyQuestionsValidationPath,
|
|
1939
3448
|
});
|
|
3449
|
+
assertRuntimeValidationValid({
|
|
3450
|
+
artifactName: "competency-questions",
|
|
3451
|
+
artifactRef: competencyQuestionsValidationPath,
|
|
3452
|
+
validation: competencyQuestionsValidation,
|
|
3453
|
+
});
|
|
1940
3454
|
const competencyQuestionAssessmentPath = path.join(sessionRoot, "competency-question-assessment.yaml");
|
|
1941
|
-
const competencyQuestionAssessment = await directiveAuthor.writeCompetencyQuestionAssessment({
|
|
3455
|
+
const competencyQuestionAssessment = await writeAuthoredYamlDocument(competencyQuestionAssessmentPath, "competency-question-assessment.yaml", () => directiveAuthor.writeCompetencyQuestionAssessment({
|
|
1942
3456
|
sessionId,
|
|
1943
3457
|
competencyQuestions,
|
|
1944
3458
|
competencyQuestionsRef: competencyQuestionsPath,
|
|
1945
3459
|
competencyQuestionsValidation,
|
|
1946
3460
|
competencyQuestionsValidationRef: competencyQuestionsValidationPath,
|
|
1947
3461
|
claimRealizationMap,
|
|
1948
|
-
});
|
|
1949
|
-
await writeYamlDocument(competencyQuestionAssessmentPath, competencyQuestionAssessment);
|
|
3462
|
+
}));
|
|
1950
3463
|
const competencyQuestionAssessmentValidationPath = path.join(sessionRoot, "competency-question-assessment-validation.yaml");
|
|
1951
3464
|
const competencyQuestionAssessmentValidation = await writeCompetencyQuestionAssessmentValidationArtifact({
|
|
1952
3465
|
competencyQuestionAssessmentPath,
|
|
1953
3466
|
competencyQuestionsPath,
|
|
1954
3467
|
outputPath: competencyQuestionAssessmentValidationPath,
|
|
1955
3468
|
});
|
|
3469
|
+
assertRuntimeValidationValid({
|
|
3470
|
+
artifactName: "competency-question-assessment",
|
|
3471
|
+
artifactRef: competencyQuestionAssessmentValidationPath,
|
|
3472
|
+
validation: competencyQuestionAssessmentValidation,
|
|
3473
|
+
});
|
|
1956
3474
|
const failureClassificationPath = path.join(sessionRoot, "failure-classification.yaml");
|
|
1957
|
-
const failureClassification = await directiveAuthor.writeFailureClassification({
|
|
3475
|
+
const failureClassification = await writeAuthoredYamlDocument(failureClassificationPath, "failure-classification.yaml", () => directiveAuthor.writeFailureClassification({
|
|
1958
3476
|
sessionId,
|
|
1959
3477
|
competencyQuestionAssessment,
|
|
1960
3478
|
competencyQuestionAssessmentRef: competencyQuestionAssessmentPath,
|
|
1961
3479
|
competencyQuestionAssessmentValidation,
|
|
1962
3480
|
seedConfirmationValidation,
|
|
1963
|
-
});
|
|
1964
|
-
await writeYamlDocument(failureClassificationPath, failureClassification);
|
|
3481
|
+
}));
|
|
1965
3482
|
const failureClassificationValidationPath = path.join(sessionRoot, "failure-classification-validation.yaml");
|
|
1966
3483
|
const failureClassificationValidation = await writeFailureClassificationValidationArtifact({
|
|
1967
3484
|
failureClassificationPath,
|
|
@@ -1969,26 +3486,38 @@ export async function runReconstruct(params) {
|
|
|
1969
3486
|
seedConfirmationValidationPath,
|
|
1970
3487
|
outputPath: failureClassificationValidationPath,
|
|
1971
3488
|
});
|
|
3489
|
+
assertRuntimeValidationValid({
|
|
3490
|
+
artifactName: "failure-classification",
|
|
3491
|
+
artifactRef: failureClassificationValidationPath,
|
|
3492
|
+
validation: failureClassificationValidation,
|
|
3493
|
+
});
|
|
1972
3494
|
const revisionProposalPath = path.join(sessionRoot, "revision-proposal.yaml");
|
|
1973
|
-
const revisionProposal = await directiveAuthor.writeRevisionProposal({
|
|
3495
|
+
const revisionProposal = await writeAuthoredYamlDocument(revisionProposalPath, "revision-proposal.yaml", () => directiveAuthor.writeRevisionProposal({
|
|
1974
3496
|
sessionId,
|
|
1975
3497
|
failureClassification,
|
|
1976
3498
|
failureClassificationRef: failureClassificationPath,
|
|
1977
3499
|
failureClassificationValidation,
|
|
1978
|
-
});
|
|
1979
|
-
await writeYamlDocument(revisionProposalPath, revisionProposal);
|
|
3500
|
+
}));
|
|
1980
3501
|
const revisionProposalValidationPath = path.join(sessionRoot, "revision-proposal-validation.yaml");
|
|
1981
3502
|
const revisionProposalValidation = await writeRevisionProposalValidationArtifact({
|
|
1982
3503
|
revisionProposalPath,
|
|
1983
3504
|
failureClassificationPath,
|
|
1984
3505
|
outputPath: revisionProposalValidationPath,
|
|
1985
3506
|
});
|
|
3507
|
+
assertRuntimeValidationValid({
|
|
3508
|
+
artifactName: "revision-proposal",
|
|
3509
|
+
artifactRef: revisionProposalValidationPath,
|
|
3510
|
+
validation: revisionProposalValidation,
|
|
3511
|
+
});
|
|
1986
3512
|
const metricsPath = path.join(sessionRoot, "reconstruct-metrics.yaml");
|
|
1987
3513
|
const metrics = calculateMetrics({
|
|
1988
3514
|
sessionId,
|
|
1989
3515
|
sourceObservations,
|
|
3516
|
+
targetMaterialProfileValidation,
|
|
1990
3517
|
sourceObservationDirectiveValidation,
|
|
1991
|
-
|
|
3518
|
+
candidateDispositionValidation,
|
|
3519
|
+
ontologySeed,
|
|
3520
|
+
ontologySeedValidation,
|
|
1992
3521
|
claimRealizationMapValidation,
|
|
1993
3522
|
seedConfirmation,
|
|
1994
3523
|
seedConfirmationValidation,
|
|
@@ -2000,21 +3529,26 @@ export async function runReconstruct(params) {
|
|
|
2000
3529
|
});
|
|
2001
3530
|
await writeYamlDocument(metricsPath, metrics);
|
|
2002
3531
|
const stopDecisionPath = path.join(sessionRoot, "stop-decision.yaml");
|
|
2003
|
-
const stopDecision = await directiveAuthor.writeStopDecision({
|
|
3532
|
+
const stopDecision = await writeAuthoredYamlDocument(stopDecisionPath, "stop-decision.yaml", () => directiveAuthor.writeStopDecision({
|
|
2004
3533
|
sessionId,
|
|
2005
3534
|
intent: params.intent,
|
|
2006
3535
|
metrics,
|
|
2007
3536
|
metricsRef: metricsPath,
|
|
2008
3537
|
failureClassification,
|
|
2009
3538
|
revisionProposal,
|
|
2010
|
-
});
|
|
2011
|
-
await writeYamlDocument(stopDecisionPath, stopDecision);
|
|
3539
|
+
}));
|
|
2012
3540
|
const finalOutputPath = path.join(sessionRoot, "final-output.md");
|
|
2013
|
-
const
|
|
3541
|
+
const finalOutputProvenanceValidationPath = path.join(sessionRoot, "final-output-provenance-validation.yaml");
|
|
3542
|
+
const preHandoffManifestPath = path.join(sessionRoot, "reconstruct-run-manifest.pre-handoff.yaml");
|
|
3543
|
+
const preHandoffRunManifestValidationPath = path.join(sessionRoot, "reconstruct-run-manifest.pre-handoff-validation.yaml");
|
|
3544
|
+
const postPublicationRunManifestValidationPath = path.join(sessionRoot, "reconstruct-run-manifest.post-publication-validation.yaml");
|
|
3545
|
+
const handoffDecisionValidationPath = path.join(sessionRoot, "handoff-decision-validation.yaml");
|
|
2014
3546
|
const recordPath = path.join(sessionRoot, "reconstruct-record.yaml");
|
|
3547
|
+
const prePublicationRecordPath = path.join(sessionRoot, "reconstruct-record.pre-publication.yaml");
|
|
2015
3548
|
const artifactRefs = artifactRefsWithDefaults({
|
|
2016
3549
|
refs: {
|
|
2017
3550
|
target_material_profile: preparationRefs.target_material_profile,
|
|
3551
|
+
target_material_profile_validation: targetMaterialProfileValidationPath,
|
|
2018
3552
|
source_inventory: preparationRefs.source_inventory,
|
|
2019
3553
|
initial_source_frontier: preparationRefs.initial_source_frontier,
|
|
2020
3554
|
source_observations: preparationRefs.source_observations,
|
|
@@ -2024,8 +3558,11 @@ export async function runReconstruct(params) {
|
|
|
2024
3558
|
exploration_synthesis: explorationSynthesisPath,
|
|
2025
3559
|
source_frontier: sourceFrontierPath,
|
|
2026
3560
|
source_frontier_validation: sourceFrontierValidationPath,
|
|
2027
|
-
|
|
2028
|
-
|
|
3561
|
+
candidate_inventory: candidateInventoryPath,
|
|
3562
|
+
candidate_disposition: candidateDispositionPath,
|
|
3563
|
+
candidate_disposition_validation: candidateDispositionValidationPath,
|
|
3564
|
+
ontology_seed: ontologySeedPath,
|
|
3565
|
+
ontology_seed_validation: ontologySeedValidationPath,
|
|
2029
3566
|
claim_realization_map: claimRealizationMapPath,
|
|
2030
3567
|
claim_realization_map_validation: claimRealizationMapValidationPath,
|
|
2031
3568
|
seed_confirmation: seedConfirmationPath,
|
|
@@ -2040,11 +3577,26 @@ export async function runReconstruct(params) {
|
|
|
2040
3577
|
revision_proposal_validation: revisionProposalValidationPath,
|
|
2041
3578
|
reconstruct_metrics: metricsPath,
|
|
2042
3579
|
stop_decision: stopDecisionPath,
|
|
3580
|
+
pre_handoff_run_manifest_validation: preHandoffRunManifestValidationPath,
|
|
3581
|
+
post_publication_run_manifest_validation: postPublicationRunManifestValidationPath,
|
|
3582
|
+
handoff_decision_validation: handoffDecisionValidationPath,
|
|
2043
3583
|
final_output: finalOutputPath,
|
|
3584
|
+
final_output_provenance_validation: finalOutputProvenanceValidationPath,
|
|
2044
3585
|
reconstruct_run_manifest: manifestPath,
|
|
2045
3586
|
},
|
|
2046
3587
|
});
|
|
2047
|
-
const
|
|
3588
|
+
const preHandoffArtifactRefs = artifactRefsWithDefaults({
|
|
3589
|
+
refs: {
|
|
3590
|
+
...artifactRefs,
|
|
3591
|
+
pre_handoff_run_manifest_validation: preHandoffRunManifestValidationPath,
|
|
3592
|
+
post_publication_run_manifest_validation: null,
|
|
3593
|
+
handoff_decision_validation: null,
|
|
3594
|
+
final_output: null,
|
|
3595
|
+
final_output_provenance_validation: null,
|
|
3596
|
+
reconstruct_run_manifest: preHandoffManifestPath,
|
|
3597
|
+
},
|
|
3598
|
+
});
|
|
3599
|
+
const preHandoffRunManifest = createRunManifest({
|
|
2048
3600
|
sessionId,
|
|
2049
3601
|
targetRefs,
|
|
2050
3602
|
intent: params.intent,
|
|
@@ -2052,20 +3604,63 @@ export async function runReconstruct(params) {
|
|
|
2052
3604
|
confirmationProviderRealization: params.confirmationProviderRealization,
|
|
2053
3605
|
directiveAuthor,
|
|
2054
3606
|
confirmationProvider,
|
|
2055
|
-
artifactRefs,
|
|
3607
|
+
artifactRefs: preHandoffArtifactRefs,
|
|
2056
3608
|
reconstructRecordPath: recordPath,
|
|
3609
|
+
governingSnapshot,
|
|
3610
|
+
terminalArtifactsCompleted: false,
|
|
3611
|
+
});
|
|
3612
|
+
await writeYamlDocument(preHandoffManifestPath, preHandoffRunManifest);
|
|
3613
|
+
const preHandoffRunManifestValidation = await writeReconstructRunManifestValidationArtifact({
|
|
3614
|
+
manifestPath: preHandoffManifestPath,
|
|
3615
|
+
projectRoot,
|
|
3616
|
+
registryPath: contractRegistryPath,
|
|
3617
|
+
targetMaterialProfilePath: preparationRefs.target_material_profile,
|
|
3618
|
+
lensIds,
|
|
3619
|
+
admittedDomainIds: params.domain ? [params.domain] : [],
|
|
3620
|
+
outputPath: preHandoffRunManifestValidationPath,
|
|
3621
|
+
});
|
|
3622
|
+
assertRuntimeValidationValid({
|
|
3623
|
+
artifactName: "reconstruct-run-manifest",
|
|
3624
|
+
artifactRef: preHandoffRunManifestValidationPath,
|
|
3625
|
+
validation: preHandoffRunManifestValidation,
|
|
3626
|
+
});
|
|
3627
|
+
const handoffDecisionValidation = await writeHandoffDecisionValidationArtifact({
|
|
3628
|
+
stopDecisionPath,
|
|
3629
|
+
manifestValidationPath: preHandoffRunManifestValidationPath,
|
|
3630
|
+
metricsPath,
|
|
3631
|
+
targetMaterialProfileValidationPath,
|
|
3632
|
+
sourceObservationDirectiveValidationPath,
|
|
3633
|
+
sourceFrontierValidationPath,
|
|
3634
|
+
candidateDispositionValidationPath,
|
|
3635
|
+
ontologySeedValidationPath,
|
|
3636
|
+
claimRealizationMapValidationPath,
|
|
3637
|
+
competencyQuestionsValidationPath,
|
|
3638
|
+
competencyQuestionAssessmentValidationPath,
|
|
3639
|
+
seedConfirmationValidationPath,
|
|
3640
|
+
failureClassificationValidationPath,
|
|
3641
|
+
revisionProposalValidationPath,
|
|
3642
|
+
registryPath: contractRegistryPath,
|
|
3643
|
+
outputPath: handoffDecisionValidationPath,
|
|
3644
|
+
});
|
|
3645
|
+
assertRuntimeValidationValid({
|
|
3646
|
+
artifactName: "handoff-decision",
|
|
3647
|
+
artifactRef: handoffDecisionValidationPath,
|
|
3648
|
+
validation: handoffDecisionValidation,
|
|
2057
3649
|
});
|
|
2058
|
-
await writeYamlDocument(manifestPath, reconstructRunManifest);
|
|
2059
3650
|
const interimRecord = await assembleReconstructRecord({
|
|
2060
3651
|
sessionRoot,
|
|
2061
3652
|
artifactRefs,
|
|
2062
|
-
outputPath:
|
|
3653
|
+
outputPath: prePublicationRecordPath,
|
|
2063
3654
|
});
|
|
2064
3655
|
const authoredFinalOutputText = await directiveAuthor.writeFinalOutput({
|
|
2065
3656
|
sessionId,
|
|
2066
3657
|
intent: params.intent,
|
|
2067
3658
|
targetMaterialProfile,
|
|
2068
|
-
|
|
3659
|
+
candidateInventory,
|
|
3660
|
+
candidateDisposition,
|
|
3661
|
+
candidateDispositionValidation,
|
|
3662
|
+
ontologySeed,
|
|
3663
|
+
ontologySeedValidation,
|
|
2069
3664
|
claimRealizationMap,
|
|
2070
3665
|
claimRealizationMapValidation,
|
|
2071
3666
|
seedConfirmation,
|
|
@@ -2080,35 +3675,134 @@ export async function runReconstruct(params) {
|
|
|
2080
3675
|
revisionProposalValidation,
|
|
2081
3676
|
metrics,
|
|
2082
3677
|
stopDecision,
|
|
3678
|
+
preHandoffRunManifestValidation,
|
|
3679
|
+
handoffDecisionValidation,
|
|
2083
3680
|
sourceObservations,
|
|
2084
3681
|
artifactRefs,
|
|
2085
3682
|
reconstructRecordPath: recordPath,
|
|
2086
|
-
reconstructRunManifestPath:
|
|
2087
|
-
reconstructRunManifest,
|
|
3683
|
+
reconstructRunManifestPath: preHandoffManifestPath,
|
|
3684
|
+
reconstructRunManifest: preHandoffRunManifest,
|
|
2088
3685
|
record: interimRecord,
|
|
2089
3686
|
});
|
|
2090
3687
|
const requiredFinalOutputFragments = [
|
|
2091
3688
|
recordPath,
|
|
2092
3689
|
manifestPath,
|
|
2093
|
-
|
|
3690
|
+
candidateInventoryPath,
|
|
3691
|
+
candidateDispositionPath,
|
|
3692
|
+
candidateDispositionValidationPath,
|
|
3693
|
+
ontologySeedPath,
|
|
3694
|
+
ontologySeedValidationPath,
|
|
2094
3695
|
claimRealizationMapPath,
|
|
2095
3696
|
seedConfirmationValidationPath,
|
|
2096
3697
|
competencyQuestionAssessmentPath,
|
|
2097
3698
|
failureClassificationPath,
|
|
2098
3699
|
revisionProposalPath,
|
|
3700
|
+
preHandoffManifestPath,
|
|
3701
|
+
preHandoffRunManifestValidationPath,
|
|
3702
|
+
handoffDecisionValidationPath,
|
|
3703
|
+
finalOutputProvenanceValidationPath,
|
|
3704
|
+
preHandoffRunManifestValidation.validation_status,
|
|
3705
|
+
handoffDecisionValidation.readiness_projection,
|
|
3706
|
+
handoffDecisionValidation.validation_status,
|
|
2099
3707
|
...seedConfirmationValidation.accepted_claim_ids,
|
|
3708
|
+
...candidateDispositionValidation.violations.map((violation) => violation.code),
|
|
3709
|
+
...ontologySeedValidation.violations.map((violation) => violation.code),
|
|
2100
3710
|
...failureClassification.failures.map((failure) => failure.failure_id),
|
|
2101
3711
|
...revisionProposal.proposals.map((proposal) => proposal.proposal_id),
|
|
2102
3712
|
];
|
|
2103
|
-
const
|
|
3713
|
+
const requiredFinalOutputSectionBindings = finalOutputProvenanceSectionBindings({
|
|
3714
|
+
ontologySeedPath,
|
|
3715
|
+
ontologySeedValidationPath,
|
|
3716
|
+
claimRealizationMapPath,
|
|
3717
|
+
claimRealizationMapValidationPath,
|
|
3718
|
+
seedConfirmationValidationPath,
|
|
3719
|
+
competencyQuestionsPath,
|
|
3720
|
+
competencyQuestionsValidationPath,
|
|
3721
|
+
competencyQuestionAssessmentPath,
|
|
3722
|
+
competencyQuestionAssessmentValidationPath,
|
|
3723
|
+
failureClassificationPath,
|
|
3724
|
+
failureClassificationValidationPath,
|
|
3725
|
+
revisionProposalPath,
|
|
3726
|
+
revisionProposalValidationPath,
|
|
3727
|
+
metricsPath,
|
|
3728
|
+
stopDecisionPath,
|
|
3729
|
+
preHandoffManifestPath,
|
|
3730
|
+
preHandoffRunManifestValidationPath,
|
|
3731
|
+
handoffDecisionValidationPath,
|
|
3732
|
+
recordPath,
|
|
3733
|
+
manifestPath,
|
|
3734
|
+
finalOutputProvenanceValidationPath,
|
|
3735
|
+
finalFragments: requiredFinalOutputFragments,
|
|
3736
|
+
});
|
|
3737
|
+
const finalOutputWithAnswerability = appendFinalOutputAnswerabilitySection(authoredFinalOutputText, ontologySeed);
|
|
3738
|
+
const finalOutputWithArtifactTruth = appendFinalOutputArtifactTruthSection(finalOutputWithAnswerability, {
|
|
3739
|
+
ontologySeedPath,
|
|
3740
|
+
ontologySeedValidationPath,
|
|
3741
|
+
claimRealizationMapPath,
|
|
3742
|
+
seedConfirmationValidationPath,
|
|
3743
|
+
competencyQuestionAssessmentPath,
|
|
3744
|
+
failureClassificationPath,
|
|
3745
|
+
revisionProposalPath,
|
|
3746
|
+
preHandoffManifestPath,
|
|
3747
|
+
preHandoffRunManifestValidationPath,
|
|
3748
|
+
handoffDecisionValidationPath,
|
|
3749
|
+
recordPath,
|
|
3750
|
+
manifestPath,
|
|
3751
|
+
});
|
|
3752
|
+
let finalOutputText = appendFinalOutputProvenanceFooter(finalOutputWithArtifactTruth, requiredFinalOutputFragments);
|
|
3753
|
+
finalOutputText = appendFinalOutputProvenanceBindingsSection(finalOutputText, requiredFinalOutputSectionBindings);
|
|
2104
3754
|
const finalOutputViolations = validateFinalOutputProvenance({
|
|
2105
3755
|
finalOutputText,
|
|
2106
|
-
|
|
3756
|
+
sectionBindings: requiredFinalOutputSectionBindings,
|
|
2107
3757
|
});
|
|
2108
3758
|
if (finalOutputViolations.length > 0) {
|
|
2109
3759
|
throw new Error(`final-output.md failed provenance validation: ${finalOutputViolations.map((item) => item.message).join("; ")}`);
|
|
2110
3760
|
}
|
|
2111
3761
|
await fs.writeFile(finalOutputPath, finalOutputText, "utf8");
|
|
3762
|
+
const finalOutputProvenanceValidation = await writeFinalOutputProvenanceValidationArtifact({
|
|
3763
|
+
sessionId,
|
|
3764
|
+
finalOutputPath,
|
|
3765
|
+
sectionBindings: requiredFinalOutputSectionBindings,
|
|
3766
|
+
outputPath: finalOutputProvenanceValidationPath,
|
|
3767
|
+
});
|
|
3768
|
+
assertRuntimeValidationValid({
|
|
3769
|
+
artifactName: "final-output-provenance",
|
|
3770
|
+
artifactRef: finalOutputProvenanceValidationPath,
|
|
3771
|
+
validation: finalOutputProvenanceValidation,
|
|
3772
|
+
});
|
|
3773
|
+
await assembleReconstructRecord({
|
|
3774
|
+
sessionRoot,
|
|
3775
|
+
artifactRefs,
|
|
3776
|
+
outputPath: recordPath,
|
|
3777
|
+
});
|
|
3778
|
+
const reconstructRunManifest = createRunManifest({
|
|
3779
|
+
sessionId,
|
|
3780
|
+
targetRefs,
|
|
3781
|
+
intent: params.intent,
|
|
3782
|
+
semanticAuthorRealization: params.semanticAuthorRealization,
|
|
3783
|
+
confirmationProviderRealization: params.confirmationProviderRealization,
|
|
3784
|
+
directiveAuthor,
|
|
3785
|
+
confirmationProvider,
|
|
3786
|
+
artifactRefs,
|
|
3787
|
+
reconstructRecordPath: recordPath,
|
|
3788
|
+
governingSnapshot,
|
|
3789
|
+
terminalArtifactsCompleted: true,
|
|
3790
|
+
});
|
|
3791
|
+
await writeYamlDocument(manifestPath, reconstructRunManifest);
|
|
3792
|
+
const postPublicationRunManifestValidation = await writeReconstructRunManifestValidationArtifact({
|
|
3793
|
+
manifestPath,
|
|
3794
|
+
projectRoot,
|
|
3795
|
+
registryPath: contractRegistryPath,
|
|
3796
|
+
targetMaterialProfilePath: preparationRefs.target_material_profile,
|
|
3797
|
+
lensIds,
|
|
3798
|
+
admittedDomainIds: params.domain ? [params.domain] : [],
|
|
3799
|
+
outputPath: postPublicationRunManifestValidationPath,
|
|
3800
|
+
});
|
|
3801
|
+
assertRuntimeValidationValid({
|
|
3802
|
+
artifactName: "reconstruct-run-manifest",
|
|
3803
|
+
artifactRef: postPublicationRunManifestValidationPath,
|
|
3804
|
+
validation: postPublicationRunManifestValidation,
|
|
3805
|
+
});
|
|
2112
3806
|
const finalRecord = await assembleReconstructRecord({
|
|
2113
3807
|
sessionRoot,
|
|
2114
3808
|
artifactRefs,
|