@mnstry/atelier 0.2.0-alpha.12 → 0.2.0-alpha.14
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/CHANGELOG.md +894 -0
- package/README.md +159 -6
- package/contracts/atelier-adoption-policy.v2.schema.json +55 -0
- package/contracts/atelier-architecture.v1.schema.json +258 -0
- package/contracts/atelier-boundary-delegations.v1.schema.json +161 -0
- package/contracts/atelier-boundary-owner-keys.v1.schema.json +98 -0
- package/contracts/atelier-build.v1.schema.json +1076 -0
- package/contracts/atelier-capability.v1.schema.json +1252 -0
- package/contracts/atelier-coordination.v1.schema.json +1050 -0
- package/contracts/atelier-evidence-navigation.v1.schema.json +603 -0
- package/contracts/atelier-harness.v1.schema.json +234 -0
- package/contracts/atelier-ingestion.v1.schema.json +806 -0
- package/contracts/atelier-inquiry.v1.schema.json +1772 -0
- package/contracts/atelier-instruction-adoption.v1.schema.json +490 -0
- package/contracts/atelier-interaction.v1.schema.json +553 -0
- package/contracts/atelier-judgment.v1.schema.json +690 -0
- package/contracts/atelier-knowledge.v1.schema.json +1512 -0
- package/contracts/atelier-learning.v1.schema.json +1095 -0
- package/contracts/atelier-migration.v3.schema.json +64 -0
- package/contracts/atelier-personal-workspace-manifest.v1.schema.json +87 -0
- package/contracts/atelier-personal-workspace-overlay.v1.schema.json +299 -0
- package/contracts/atelier-template-adoption.v1.schema.json +223 -0
- package/contracts/atelier-template-profile.v1.schema.json +1168 -0
- package/contracts/atelier-trackable.v1.schema.json +781 -0
- package/contracts/atelier-upgrade-plan.v3.schema.json +532 -0
- package/docs/architecture.md +89 -0
- package/docs/assurance-controls.md +2 -2
- package/docs/blocks/capability-stewardship.md +17 -0
- package/docs/blocks/claims.md +16 -3
- package/docs/blocks/inquiry-harnesses.md +19 -0
- package/docs/blocks/learning-harnesses.md +17 -0
- package/docs/capability-stewardship.md +267 -0
- package/docs/coordination.md +51 -0
- package/docs/decision-practices.md +111 -0
- package/docs/decisions.md +29 -0
- package/docs/evidence-navigation.md +237 -0
- package/docs/exact-upgrades.md +3 -2
- package/docs/ingestion.md +181 -0
- package/docs/inquiry-harnesses.md +210 -0
- package/docs/install.md +80 -3
- package/docs/intake-and-guides.md +5 -0
- package/docs/integration-contract-decisions.md +24 -2
- package/docs/interaction-and-reflection.md +72 -0
- package/docs/knowledge-graph.md +20 -0
- package/docs/knowledge-health/api.md +30 -0
- package/docs/knowledge-health/assessment/api.md +96 -0
- package/docs/knowledge-health/assessment/capabilities.md +40 -0
- package/docs/knowledge-health/assessment/evaluation.md +27 -0
- package/docs/knowledge-health/assessment/facilitator.md +30 -0
- package/docs/knowledge-health/assessment/quickstart.md +61 -0
- package/docs/knowledge-health/assessment/troubleshooting.md +23 -0
- package/docs/knowledge-health/devday/facilitator.md +16 -0
- package/docs/knowledge-health/devday/participant-response.md +22 -0
- package/docs/knowledge-health/devday/public-default.md +107 -0
- package/docs/knowledge-health/devday/quickstart.md +18 -0
- package/docs/knowledge-health/devday/support.md +22 -0
- package/docs/knowledge-health/exercise.md +17 -0
- package/docs/knowledge-health/facilitator.md +20 -0
- package/docs/knowledge-health/quickstart.md +94 -0
- package/docs/knowledge-health/readme.md +15 -0
- package/docs/knowledge-health/support.md +34 -0
- package/docs/knowledge-setup.md +248 -0
- package/docs/knowledge-workspace.md +264 -0
- package/docs/learning-harnesses.md +237 -0
- package/docs/learning.md +215 -0
- package/docs/local-services.md +223 -19
- package/docs/obsidian-contract.md +246 -15
- package/docs/obsidian-plugin.md +252 -7
- package/docs/obsidian.md +874 -52
- package/docs/optional-ingestion.md +83 -0
- package/docs/personal-workspace.md +266 -0
- package/docs/practical-judgment.md +92 -0
- package/docs/progressive-ingestion-acceptance.md +89 -0
- package/docs/progressive-ingestion.md +235 -0
- package/docs/project-command-inventory.md +1 -0
- package/docs/release-engineering.md +50 -0
- package/docs/repo-boundary-guard.md +120 -3
- package/docs/research-starter-quickstart.md +66 -0
- package/docs/research-starter.md +114 -0
- package/docs/semantic-ingestion.md +198 -0
- package/docs/semantic-operation.md +318 -0
- package/docs/skill-steward.md +6 -0
- package/docs/template-profile.md +164 -0
- package/docs/template-upgrades.md +114 -0
- package/docs/trackables.md +111 -0
- package/docs/upgrade.md +219 -2
- package/fixtures/atelier-architecture/binding/invalid/document.json +19 -0
- package/fixtures/atelier-architecture/binding/valid/document.json +19 -0
- package/fixtures/atelier-architecture/catalog/invalid/document.json +290 -0
- package/fixtures/atelier-architecture/catalog/valid/document.json +343 -0
- package/fixtures/atelier-build-contract/attempt/invalid/document.json +20 -0
- package/fixtures/atelier-build-contract/attempt/valid/document.json +19 -0
- package/fixtures/atelier-build-contract/candidate/invalid/document.json +24 -0
- package/fixtures/atelier-build-contract/candidate/valid/document.json +23 -0
- package/fixtures/atelier-build-contract/decision/invalid/document.json +31 -0
- package/fixtures/atelier-build-contract/decision/valid/document.json +30 -0
- package/fixtures/atelier-build-contract/delivery/invalid/document.json +18 -0
- package/fixtures/atelier-build-contract/delivery/valid/document.json +17 -0
- package/fixtures/atelier-build-contract/gate/invalid/document.json +22 -0
- package/fixtures/atelier-build-contract/gate/valid/document.json +21 -0
- package/fixtures/atelier-build-contract/ledger/invalid/document.json +270 -0
- package/fixtures/atelier-build-contract/ledger/valid/document.json +269 -0
- package/fixtures/atelier-build-contract/objective/invalid/document.json +73 -0
- package/fixtures/atelier-build-contract/objective/valid/document.json +72 -0
- package/fixtures/atelier-build-contract/progress/invalid/document.json +18 -0
- package/fixtures/atelier-build-contract/progress/valid/document.json +17 -0
- package/fixtures/atelier-capability-contract/adoption/invalid/document.json +71 -0
- package/fixtures/atelier-capability-contract/adoption/valid/document.json +70 -0
- package/fixtures/atelier-capability-contract/event/invalid/document.json +18 -0
- package/fixtures/atelier-capability-contract/event/valid/document.json +17 -0
- package/fixtures/atelier-capability-contract/journal/invalid/document.json +382 -0
- package/fixtures/atelier-capability-contract/journal/valid/document.json +381 -0
- package/fixtures/atelier-capability-contract/notice/invalid/document.json +8 -0
- package/fixtures/atelier-capability-contract/notice/valid/document.json +7 -0
- package/fixtures/atelier-capability-contract/package/invalid/document.json +59 -0
- package/fixtures/atelier-capability-contract/package/valid/document.json +58 -0
- package/fixtures/atelier-capability-contract/plan/invalid/document.json +107 -0
- package/fixtures/atelier-capability-contract/plan/valid/document.json +106 -0
- package/fixtures/atelier-capability-contract/release/invalid/document.json +85 -0
- package/fixtures/atelier-capability-contract/release/valid/document.json +84 -0
- package/fixtures/atelier-capability-contract/state/invalid/document.json +316 -0
- package/fixtures/atelier-capability-contract/state/valid/document.json +315 -0
- package/fixtures/atelier-coordination/dependency/invalid/document.json +37 -0
- package/fixtures/atelier-coordination/dependency/valid/document.json +36 -0
- package/fixtures/atelier-coordination/directive/invalid/document.json +25 -0
- package/fixtures/atelier-coordination/directive/valid/document.json +24 -0
- package/fixtures/atelier-coordination/disposition/invalid/document.json +34 -0
- package/fixtures/atelier-coordination/disposition/valid/document.json +33 -0
- package/fixtures/atelier-coordination/outcome/invalid/document.json +39 -0
- package/fixtures/atelier-coordination/outcome/valid/document.json +38 -0
- package/fixtures/atelier-coordination/recovery/invalid/document.json +34 -0
- package/fixtures/atelier-coordination/recovery/valid/document.json +33 -0
- package/fixtures/atelier-harness-contract/handoff/invalid/document.json +25 -0
- package/fixtures/atelier-harness-contract/handoff/valid/document.json +24 -0
- package/fixtures/atelier-ingestion/invalid/authority.json +19 -0
- package/fixtures/atelier-ingestion/semantic-baseline.json +26 -0
- package/fixtures/atelier-ingestion/semantic-operation.json +75 -0
- package/fixtures/atelier-ingestion/valid/plan-input.json +18 -0
- package/fixtures/atelier-inquiry-contract/assessment/invalid/document.json +41 -0
- package/fixtures/atelier-inquiry-contract/assessment/valid/document.json +40 -0
- package/fixtures/atelier-inquiry-contract/bundle/invalid/document.json +51 -0
- package/fixtures/atelier-inquiry-contract/bundle/valid/document.json +50 -0
- package/fixtures/atelier-inquiry-contract/campaign/invalid/document.json +17 -0
- package/fixtures/atelier-inquiry-contract/campaign/valid/document.json +16 -0
- package/fixtures/atelier-inquiry-contract/decision/invalid/document.json +22 -0
- package/fixtures/atelier-inquiry-contract/decision/valid/document.json +21 -0
- package/fixtures/atelier-inquiry-contract/feedback/invalid/document.json +19 -0
- package/fixtures/atelier-inquiry-contract/feedback/valid/document.json +18 -0
- package/fixtures/atelier-inquiry-contract/handoff/invalid/document.json +92 -0
- package/fixtures/atelier-inquiry-contract/handoff/valid/document.json +91 -0
- package/fixtures/atelier-inquiry-contract/hypothesis/invalid/document.json +20 -0
- package/fixtures/atelier-inquiry-contract/hypothesis/valid/document.json +19 -0
- package/fixtures/atelier-inquiry-contract/ledger/invalid/document.json +680 -0
- package/fixtures/atelier-inquiry-contract/ledger/valid/document.json +679 -0
- package/fixtures/atelier-inquiry-contract/legacy-assessment/invalid/document.json +19 -0
- package/fixtures/atelier-inquiry-contract/legacy-assessment/valid/document.json +18 -0
- package/fixtures/atelier-inquiry-contract/request/invalid/document.json +50 -0
- package/fixtures/atelier-inquiry-contract/request/valid/document.json +49 -0
- package/fixtures/atelier-inquiry-contract/source/invalid/document.json +18 -0
- package/fixtures/atelier-inquiry-contract/source/valid/document.json +17 -0
- package/fixtures/atelier-inquiry-contract/withdrawal/invalid/document.json +16 -0
- package/fixtures/atelier-inquiry-contract/withdrawal/valid/document.json +15 -0
- package/fixtures/atelier-instruction-adoption/context-receipt/invalid/document.json +18 -0
- package/fixtures/atelier-instruction-adoption/context-receipt/valid/document.json +17 -0
- package/fixtures/atelier-instruction-adoption/plan/invalid/document.json +63 -0
- package/fixtures/atelier-instruction-adoption/plan/valid/document.json +62 -0
- package/fixtures/atelier-instruction-adoption/receipt/invalid/document.json +22 -0
- package/fixtures/atelier-instruction-adoption/receipt/valid/document.json +21 -0
- package/fixtures/atelier-instruction-adoption/state/invalid/document.json +30 -0
- package/fixtures/atelier-instruction-adoption/state/valid/document.json +29 -0
- package/fixtures/atelier-interaction/act/invalid/document.json +25 -0
- package/fixtures/atelier-interaction/act/valid/document.json +24 -0
- package/fixtures/atelier-interaction/assessment/invalid/document.json +32 -0
- package/fixtures/atelier-interaction/assessment/valid/document.json +31 -0
- package/fixtures/atelier-interaction/observation/invalid/document.json +22 -0
- package/fixtures/atelier-interaction/observation/valid/document.json +21 -0
- package/fixtures/atelier-interaction/policy/invalid/document.json +20 -0
- package/fixtures/atelier-interaction/policy/valid/document.json +19 -0
- package/fixtures/atelier-judgment/case/invalid/document.json +76 -0
- package/fixtures/atelier-judgment/case/valid/document.json +75 -0
- package/fixtures/atelier-judgment/decision/invalid/document.json +38 -0
- package/fixtures/atelier-judgment/decision/valid/document.json +37 -0
- package/fixtures/atelier-judgment/native-decision.md +3 -0
- package/fixtures/atelier-judgment/practice-reconsideration/definition.json +92 -0
- package/fixtures/atelier-judgment/practice-reconsideration/scenario.json +435 -0
- package/fixtures/atelier-knowledge-contract/activation/invalid/document.json +26 -0
- package/fixtures/atelier-knowledge-contract/activation/valid/document.json +25 -0
- package/fixtures/atelier-knowledge-contract/contribution/invalid/document.json +34 -0
- package/fixtures/atelier-knowledge-contract/contribution/valid/document.json +33 -0
- package/fixtures/atelier-knowledge-contract/domain/invalid/document.json +41 -0
- package/fixtures/atelier-knowledge-contract/domain/valid/document.json +40 -0
- package/fixtures/atelier-knowledge-contract/domain-revision/invalid/document.json +46 -0
- package/fixtures/atelier-knowledge-contract/domain-revision/valid/document.json +45 -0
- package/fixtures/atelier-knowledge-contract/evaluation/invalid/document.json +21 -0
- package/fixtures/atelier-knowledge-contract/evaluation/valid/document.json +20 -0
- package/fixtures/atelier-knowledge-contract/ledger/invalid/document.json +318 -0
- package/fixtures/atelier-knowledge-contract/ledger/valid/document.json +317 -0
- package/fixtures/atelier-knowledge-contract/relation/invalid/document.json +25 -0
- package/fixtures/atelier-knowledge-contract/relation/valid/document.json +24 -0
- package/fixtures/atelier-knowledge-contract/review/invalid/document.json +18 -0
- package/fixtures/atelier-knowledge-contract/review/valid/document.json +17 -0
- package/fixtures/atelier-knowledge-contract/withdrawal/invalid/document.json +16 -0
- package/fixtures/atelier-knowledge-contract/withdrawal/valid/document.json +15 -0
- package/fixtures/atelier-learning/invalid/authority.json +14 -0
- package/fixtures/atelier-learning/valid/capture.json +13 -0
- package/fixtures/atelier-personal-workspace-contract/manifest/invalid/authority-key.json +17 -0
- package/fixtures/atelier-personal-workspace-contract/manifest/invalid/nonempty-ext.json +25 -0
- package/fixtures/atelier-personal-workspace-contract/manifest/invalid/wrong-schema.json +22 -0
- package/fixtures/atelier-personal-workspace-contract/manifest/valid/manifest.json +22 -0
- package/fixtures/atelier-personal-workspace-contract/overlay/invalid/authority-key.json +25 -0
- package/fixtures/atelier-personal-workspace-contract/overlay/invalid/unknown-top-level-field.json +27 -0
- package/fixtures/atelier-personal-workspace-contract/overlay/invalid/wrong-schema.json +24 -0
- package/fixtures/atelier-trackable/definition/invalid/document.json +15 -0
- package/fixtures/atelier-trackable/definition/valid/document.json +14 -0
- package/fixtures/atelier-trackable/request/invalid/document.json +23 -0
- package/fixtures/atelier-trackable/request/valid/document.json +22 -0
- package/fixtures/boundary-delegations/invalid/authority-key.v1.json +30 -0
- package/fixtures/boundary-delegations/invalid/push-operation.v1.json +28 -0
- package/fixtures/boundary-delegations/invalid/unsigned.v1.json +25 -0
- package/fixtures/boundary-delegations/valid/empty.v1.json +4 -0
- package/fixtures/boundary-delegations/valid/signed-operator.v1.json +30 -0
- package/fixtures/boundary-owner-keys/invalid/wrong-algorithm.v1.json +15 -0
- package/fixtures/boundary-owner-keys/invalid/wrong-curve.v1.json +15 -0
- package/fixtures/boundary-owner-keys/valid/one-owner.v1.json +17 -0
- package/fixtures/capability-packages/adoption.example.json +70 -0
- package/fixtures/capability-packages/evidence-review/capability-package.json +58 -0
- package/fixtures/capability-packages/evidence-review/capability-release.json +84 -0
- package/fixtures/capability-packages/evidence-review/evaluation.md +15 -0
- package/fixtures/capability-packages/evidence-review/skills/evidence-review/SKILL.md +22 -0
- package/fixtures/capability-packages/evidence-review/skills/evidence-review/references/ledger.md +7 -0
- package/fixtures/capability-packages/research/capability-package.json +88 -0
- package/fixtures/capability-packages/research/capability-release.json +134 -0
- package/fixtures/capability-packages/research/evaluation.md +15 -0
- package/fixtures/capability-packages/research/skills/research-integrate/SKILL.md +29 -0
- package/fixtures/capability-packages/research/skills/research-integrate/references/integration.md +10 -0
- package/fixtures/capability-packages/research/skills/research-plan/SKILL.md +27 -0
- package/fixtures/capability-packages/research/skills/research-plan/references/inquiries.md +26 -0
- package/fixtures/capability-packages/research/skills/research-synthesize/SKILL.md +23 -0
- package/fixtures/capability-packages/research/skills/research-synthesize/references/synthesis.md +12 -0
- package/fixtures/evidence-navigation/invalid/duplicate-operation.json +16 -0
- package/fixtures/evidence-navigation/invalid/instruction-kind.json +36 -0
- package/fixtures/evidence-navigation/invalid/invalid-digest.json +36 -0
- package/fixtures/evidence-navigation/invalid/invalid-time.json +36 -0
- package/fixtures/evidence-navigation/invalid/missing-attribution.json +35 -0
- package/fixtures/evidence-navigation/invalid/reserved-extension.json +19 -0
- package/fixtures/evidence-navigation/invalid/unattributed-acceptance.json +36 -0
- package/fixtures/evidence-navigation/invalid/uncoerced-version.json +16 -0
- package/fixtures/evidence-navigation/invalid/unknown-currency.json +17 -0
- package/fixtures/evidence-navigation/invalid/unknown-selector-field.json +37 -0
- package/fixtures/evidence-navigation/invalid/unsupported-operation.json +15 -0
- package/fixtures/evidence-navigation/valid/claim.json +36 -0
- package/fixtures/evidence-navigation/valid/host.json +16 -0
- package/fixtures/evidence-navigation/valid/profile.json +16 -0
- package/fixtures/evidence-navigation/valid/snapshot.json +17 -0
- package/fixtures/harness-packages/build-harness/capability-package.json +61 -0
- package/fixtures/harness-packages/build-harness/capability-release.json +82 -0
- package/fixtures/harness-packages/build-harness/evaluation.md +3 -0
- package/fixtures/harness-packages/build-harness/skills/atelier-build-harness/SKILL.md +59 -0
- package/fixtures/harness-packages/knowledge-harness/capability-package.json +61 -0
- package/fixtures/harness-packages/knowledge-harness/capability-release.json +82 -0
- package/fixtures/harness-packages/knowledge-harness/evaluation.md +3 -0
- package/fixtures/harness-packages/knowledge-harness/skills/atelier-knowledge-harness/SKILL.md +60 -0
- package/fixtures/harnesses/learning-cycle.json +780 -0
- package/fixtures/inquiry/workshop.json +675 -0
- package/fixtures/inquiry-packages/discovery-harness/capability-package.json +61 -0
- package/fixtures/inquiry-packages/discovery-harness/capability-release.json +82 -0
- package/fixtures/inquiry-packages/discovery-harness/evaluation.md +3 -0
- package/fixtures/inquiry-packages/discovery-harness/skills/atelier-discovery-harness/SKILL.md +48 -0
- package/fixtures/inquiry-packages/research-harness/capability-package.json +61 -0
- package/fixtures/inquiry-packages/research-harness/capability-release.json +82 -0
- package/fixtures/inquiry-packages/research-harness/evaluation.md +3 -0
- package/fixtures/inquiry-packages/research-harness/skills/atelier-research-harness/SKILL.md +43 -0
- package/fixtures/knowledge-health/calibration-suite.json +26 -0
- package/fixtures/knowledge-health/calibration-trial.json +37 -0
- package/fixtures/knowledge-health/corrected/checklist.md +18 -0
- package/fixtures/knowledge-health/devday/participant-record.json +19 -0
- package/fixtures/knowledge-health/expected-summary.json +27 -0
- package/fixtures/knowledge-health/workshop/README.md +20 -0
- package/fixtures/knowledge-health/workshop/atelier.project.json +7 -0
- package/fixtures/knowledge-health/workshop/knowledge-plan.json +65 -0
- package/fixtures/knowledge-health/workshop/records/checklist.md +18 -0
- package/fixtures/knowledge-health/workshop/records/workshop.md +18 -0
- package/fixtures/knowledge-health/workshop/repo-access.v1.json +5 -0
- package/fixtures/knowledge-health/workspace/atelier.project.json +18 -0
- package/fixtures/knowledge-health/workspace/knowledge-plan.json +74 -0
- package/fixtures/knowledge-health/workspace/records/checklist.md +18 -0
- package/fixtures/knowledge-health/workspace/records/pilot.md +16 -0
- package/fixtures/knowledge-health/workspace/repo-access.v1.json +9 -0
- package/fixtures/personal-workspace/overlay.json +24 -0
- package/fixtures/templates/local-library.v1.json +76 -0
- package/fixtures/templates/upgrade-contracts/adoption-policy.v2/invalid.json +16 -0
- package/fixtures/templates/upgrade-contracts/adoption-policy.v2/valid.json +13 -0
- package/fixtures/templates/upgrade-contracts/migration.v3/invalid.json +24 -0
- package/fixtures/templates/upgrade-contracts/migration.v3/valid.json +21 -0
- package/fixtures/templates/upgrade-contracts/template-adoption.v1/invalid.json +60 -0
- package/fixtures/templates/upgrade-contracts/template-adoption.v1/valid.json +57 -0
- package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/invalid.json +85 -0
- package/fixtures/templates/upgrade-contracts/upgrade-plan.v3/valid.json +82 -0
- package/package.json +60 -5
- package/plugins/obsidian/main.js +57 -8
- package/plugins/obsidian/manifest.json +1 -1
- package/skills/claude/atelier-build-harness/SKILL.md +59 -0
- package/skills/claude/atelier-coordination/SKILL.md +32 -0
- package/skills/claude/atelier-discovery-harness/SKILL.md +48 -0
- package/skills/claude/atelier-guided-upgrade/SKILL.md +29 -0
- package/skills/claude/atelier-interaction/SKILL.md +34 -0
- package/skills/claude/atelier-knowledge-harness/SKILL.md +60 -0
- package/skills/claude/atelier-knowledge-setup/SKILL.md +72 -0
- package/skills/claude/atelier-practical-judgment/SKILL.md +64 -0
- package/skills/claude/atelier-research-harness/SKILL.md +43 -0
- package/skills/claude/atelier-skill-steward/SKILL.md +53 -0
- package/skills/claude/atelier-trackables/SKILL.md +40 -0
- package/skills/codex/atelier-build-harness/SKILL.md +59 -0
- package/skills/codex/atelier-coordination/SKILL.md +32 -0
- package/skills/codex/atelier-discovery-harness/SKILL.md +48 -0
- package/skills/codex/atelier-guided-upgrade/SKILL.md +29 -0
- package/skills/codex/atelier-interaction/SKILL.md +34 -0
- package/skills/codex/atelier-knowledge-harness/SKILL.md +60 -0
- package/skills/codex/atelier-knowledge-setup/SKILL.md +72 -0
- package/skills/codex/atelier-practical-judgment/SKILL.md +64 -0
- package/skills/codex/atelier-research-harness/SKILL.md +43 -0
- package/skills/codex/atelier-skill-steward/SKILL.md +53 -0
- package/skills/codex/atelier-trackables/SKILL.md +40 -0
- package/src/architecture/catalog.mjs +355 -0
- package/src/architecture/index.mjs +93 -0
- package/src/boundary/content-rules.mjs +536 -69
- package/src/boundary/delegation-command.mjs +158 -0
- package/src/boundary/delegation.mjs +396 -0
- package/src/boundary/policy.mjs +185 -64
- package/src/build/git.mjs +18 -0
- package/src/build/index.mjs +3 -0
- package/src/build/ledger.mjs +88 -0
- package/src/capabilities/adoption.mjs +381 -0
- package/src/capabilities/evidence.mjs +140 -0
- package/src/capabilities/files.mjs +124 -0
- package/src/capabilities/index.mjs +4 -0
- package/src/capabilities/instructions.mjs +250 -0
- package/src/capabilities/package.mjs +136 -0
- package/src/cli/command-failure.mjs +36 -0
- package/src/cli/execute-command.mjs +16 -2
- package/src/cli/run.mjs +66 -9
- package/src/coauthor/store.mjs +43 -2
- package/src/collaboration/proposals.mjs +189 -0
- package/src/commands/architecture.mjs +27 -0
- package/src/commands/boundary.mjs +3 -0
- package/src/commands/capability.mjs +73 -0
- package/src/commands/enroll.mjs +3 -0
- package/src/commands/harness.mjs +79 -0
- package/src/commands/ingest.mjs +39 -0
- package/src/commands/init.mjs +4 -1
- package/src/commands/inquiry.mjs +66 -0
- package/src/commands/knowledge-semantic.mjs +128 -0
- package/src/commands/knowledge.mjs +119 -0
- package/src/commands/learn.mjs +61 -0
- package/src/commands/obsidian.mjs +772 -65
- package/src/commands/practice.mjs +24 -0
- package/src/commands/setup.mjs +22 -2
- package/src/commands/trackable.mjs +19 -0
- package/src/contracts/corpus.mjs +30 -0
- package/src/coordination/index.mjs +110 -0
- package/src/evidence-navigation/contracts.mjs +60 -0
- package/src/evidence-navigation/evaluate.mjs +69 -0
- package/src/evidence-navigation/generation.mjs +22 -0
- package/src/evidence-navigation/index.mjs +2 -0
- package/src/evidence-navigation/local.mjs +167 -0
- package/src/evidence-navigation/schema.generated.mjs +604 -0
- package/src/evidence-navigation/types.mjs +12 -0
- package/src/export/atelier-export-contract.mjs +35 -8
- package/src/graph/enroll.mjs +248 -0
- package/src/graph/graph.mjs +30 -6
- package/src/graph/knowledge-graph.mjs +77 -9
- package/src/harnesses/contracts.mjs +41 -0
- package/src/harnesses/exchange.mjs +154 -0
- package/src/harnesses/feedback.mjs +16 -0
- package/src/harnesses/history.mjs +37 -0
- package/src/harnesses/index.mjs +4 -0
- package/src/harnesses/store.mjs +29 -0
- package/src/ingestion/contracts.mjs +41 -0
- package/src/ingestion/evaluation.mjs +119 -0
- package/src/ingestion/optional/composition/index.mjs +171 -0
- package/src/ingestion/optional/evaluation/index.mjs +219 -0
- package/src/ingestion/optional/graphify/composition-binding.mjs +60 -0
- package/src/ingestion/optional/graphify/composition_receiving.py +185 -0
- package/src/ingestion/optional/graphify/graphify_supplier.py +938 -0
- package/src/ingestion/optional/graphify/json_bridge.py +163 -0
- package/src/ingestion/optional/graphify/native-closure-pins.json +275 -0
- package/src/ingestion/optional/graphify/native-pins.json +306 -0
- package/src/ingestion/optional/graphify/query_receiving.py +209 -0
- package/src/ingestion/optional/index.mjs +9 -0
- package/src/ingestion/optional/jev/bridge.mjs +166 -0
- package/src/ingestion/optional/jev/composition-binding.mjs +116 -0
- package/src/ingestion/optional/jev/judgments.mjs +174 -0
- package/src/ingestion/optional/jev/native-translation.mjs +32 -0
- package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/__init__.py +7 -0
- package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/adapter.py +966 -0
- package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/artifacts.py +101 -0
- package/src/ingestion/optional/lightrag/atelier_lightrag_supplier/projection.py +146 -0
- package/src/ingestion/optional/lightrag/composition-binding.mjs +67 -0
- package/src/ingestion/optional/vanilla/composition-binding.mjs +102 -0
- package/src/ingestion/optional/vanilla/index.mjs +218 -0
- package/src/ingestion/optional/vanilla/native-normalization.mjs +187 -0
- package/src/ingestion/processors.mjs +218 -0
- package/src/ingestion/semantic.mjs +203 -0
- package/src/ingestion/store.mjs +372 -0
- package/src/inquiry/beliefs.mjs +32 -0
- package/src/inquiry/contracts.mjs +23 -0
- package/src/inquiry/index.mjs +5 -0
- package/src/inquiry/ledger.mjs +135 -0
- package/src/inquiry/lenses.mjs +15 -0
- package/src/inquiry/projection.mjs +77 -0
- package/src/inquiry/store.mjs +35 -0
- package/src/intake/read-scope.mjs +12 -0
- package/src/intake/store.mjs +69 -6
- package/src/interaction/index.mjs +91 -0
- package/src/judgment/index.mjs +82 -0
- package/src/judgment/practice-evaluation.mjs +70 -0
- package/src/judgment/practice.mjs +144 -0
- package/src/knowledge/context.mjs +217 -0
- package/src/knowledge/index.mjs +5 -0
- package/src/knowledge/ingestion.mjs +79 -0
- package/src/knowledge/intake.mjs +33 -0
- package/src/knowledge/ledger.mjs +110 -0
- package/src/knowledge/participatory/guidance.mjs +36 -0
- package/src/knowledge/participatory/guided-contribution.mjs +44 -0
- package/src/knowledge/participatory/index.mjs +2 -0
- package/src/knowledge/participatory/installed-workshop.mjs +108 -0
- package/src/knowledge/plan.mjs +67 -0
- package/src/knowledge/projection.mjs +43 -0
- package/src/knowledge/semantic-operation.mjs +567 -0
- package/src/knowledge/sessions.mjs +467 -0
- package/src/knowledge/workspace.mjs +295 -0
- package/src/knowledge-health/assessment.mjs +165 -0
- package/src/knowledge-health/capabilities.mjs +350 -0
- package/src/knowledge-health/context.mjs +62 -0
- package/src/knowledge-health/example.mjs +47 -0
- package/src/knowledge-health/index.mjs +10 -0
- package/src/knowledge-health/owner-join.mjs +88 -0
- package/src/knowledge-health/proof/common.mjs +24 -0
- package/src/knowledge-health/proof/installed-check.mjs +100 -0
- package/src/knowledge-health/proof/native-readback.mjs +37 -0
- package/src/knowledge-health/proof/rehearse.mjs +68 -0
- package/src/knowledge-health/proof/validate-participant.mjs +17 -0
- package/src/knowledge-health/proof/verify-native-capture.mjs +14 -0
- package/src/knowledge-health/proof/workshop-check.mjs +36 -0
- package/src/knowledge-health/rule-identity.mjs +49 -0
- package/src/knowledge-health/workshop-composition.mjs +19 -0
- package/src/knowledge-health/workshop-profile.mjs +176 -0
- package/src/knowledge-health/workshop.mjs +99 -0
- package/src/learning/adapters.mjs +68 -0
- package/src/learning/assistance.mjs +127 -0
- package/src/learning/contracts.mjs +65 -0
- package/src/learning/store.mjs +272 -0
- package/src/personal-workspace/index.mjs +391 -0
- package/src/personal-workspace/selection.mjs +401 -0
- package/src/project/config.mjs +8 -0
- package/src/project/durable-state.mjs +3 -1
- package/src/project/file-class.mjs +1 -1
- package/src/project/path-match.mjs +2 -1
- package/src/projection/obsidian/edits/apply.mjs +55 -16
- package/src/projection/obsidian/materialize/prepare-view.mjs +87 -5
- package/src/projection/obsidian/personal-workspace.mjs +519 -0
- package/src/projection/obsidian/proposals/adapter.mjs +79 -17
- package/src/projection/obsidian/proposals/observation.mjs +50 -4
- package/src/projection/obsidian/publication/publisher.mjs +214 -18
- package/src/projection/obsidian/publication/vault-list.mjs +4 -3
- package/src/projection/obsidian/recovery/index.mjs +4 -1
- package/src/projection/obsidian/recovery/store.mjs +160 -7
- package/src/projection/obsidian/selection-ui/contribution.mjs +6 -5
- package/src/projection/project.mjs +3 -2
- package/src/readiness/readiness.mjs +10 -3
- package/src/reflection/index.mjs +56 -0
- package/src/runtime/obsidian/app-production-seams.mjs +48 -16
- package/src/runtime/obsidian/app-registration.mjs +175 -28
- package/src/runtime/obsidian/app-restart.mjs +154 -0
- package/src/runtime/obsidian/engine.mjs +437 -56
- package/src/runtime/obsidian/extension-points.mjs +1 -1
- package/src/runtime/obsidian/index.mjs +10 -7
- package/src/runtime/obsidian/launch-plan.mjs +7 -4
- package/src/runtime/obsidian/lifecycle.mjs +108 -23
- package/src/runtime/obsidian/login-item.mjs +335 -0
- package/src/runtime/obsidian/machine-settings.mjs +119 -12
- package/src/runtime/obsidian/observation.mjs +36 -4
- package/src/runtime/obsidian/opening.mjs +173 -38
- package/src/runtime/obsidian/personal-selection.mjs +125 -0
- package/src/runtime/obsidian/pipeline.mjs +115 -6
- package/src/runtime/obsidian/plugin-channel.mjs +11 -3
- package/src/runtime/obsidian/plugin-choice.mjs +16 -4
- package/src/runtime/obsidian/plugin-drift.mjs +59 -11
- package/src/runtime/obsidian/plugin-presence.mjs +14 -1
- package/src/runtime/obsidian/private-lock.mjs +39 -4
- package/src/runtime/obsidian/process-identity.mjs +20 -10
- package/src/runtime/obsidian/project-views.mjs +282 -0
- package/src/runtime/obsidian/questions.mjs +48 -0
- package/src/runtime/obsidian/release-watch.mjs +56 -0
- package/src/runtime/obsidian/service-main.mjs +148 -19
- package/src/runtime/obsidian/service-manager-production.mjs +61 -0
- package/src/runtime/obsidian/service-managers.mjs +275 -0
- package/src/runtime/obsidian/service-record.mjs +87 -23
- package/src/runtime/obsidian/service.mjs +102 -9
- package/src/runtime/obsidian/startup-adapters.mjs +59 -21
- package/src/runtime/obsidian/unheld-evidence.mjs +84 -0
- package/src/runtime/obsidian/vault-location.mjs +300 -0
- package/src/runtime/obsidian/view-counts.mjs +34 -0
- package/src/runtime/obsidian/view-permission.mjs +334 -0
- package/src/server/local-sidecar.mjs +169 -2
- package/src/server/server.mjs +28 -2
- package/src/template-bindings/project.mjs +92 -0
- package/src/templates/profile.mjs +225 -0
- package/src/trackables/domain.mjs +175 -0
- package/src/trackables/store.mjs +114 -0
- package/src/ui/control-system.mjs +201 -0
- package/src/ui/html-primitives.mjs +3 -0
- package/src/ui/knowledge-page.mjs +1388 -0
- package/src/upgrade/closure-diagnostics.mjs +135 -0
- package/src/upgrade/closure.mjs +649 -0
- package/src/upgrade/explanation.mjs +1 -1
- package/src/upgrade/template-participant.mjs +171 -0
- package/src/upgrade/transaction.mjs +72 -25
- package/src/upgrade/upgrade.mjs +20 -7
- package/templates/external-project-workspace/pack-lifecycle.json +7 -1
- package/templates/knowledge-workspace/.gitattributes +2 -0
- package/templates/knowledge-workspace/AGENTS.md +27 -0
- package/templates/knowledge-workspace/README.md +44 -0
- package/templates/knowledge-workspace/atelier.project.json +22 -0
- package/templates/knowledge-workspace/gitignore +6 -0
- package/templates/knowledge-workspace/knowledge-plan.json +111 -0
- package/templates/knowledge-workspace/knowledge-plan.schema.json +281 -0
- package/templates/knowledge-workspace/records/forecast.md +22 -0
- package/templates/knowledge-workspace/records/inspection.md +25 -0
- package/templates/knowledge-workspace/records/telescope.md +24 -0
- package/templates/knowledge-workspace/repo-access.v1.json +9 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto'
|
|
2
|
+
import { performance } from 'node:perf_hooks'
|
|
3
|
+
|
|
4
|
+
// Private Q02 execution/assessment sidecar. Existing intake and knowledge owners
|
|
5
|
+
// retain all authoritative records; this module grants no execution permission.
|
|
6
|
+
export const PRESENCE_PROFILES = Object.freeze(['vanilla', 'graphify', 'lightrag', 'jev',
|
|
7
|
+
'graphify+lightrag', 'graphify+jev', 'lightrag+jev', 'graphify+lightrag+jev'])
|
|
8
|
+
const digest = value => createHash('sha256').update(JSON.stringify(value)).digest('hex')
|
|
9
|
+
const phases = new Set(['cold', 'incremental', 'warm', 'recovery'])
|
|
10
|
+
const terminalStates = new Set(['completed', 'failed', 'unavailable', 'unsupported', 'not-run', 'uncertain'])
|
|
11
|
+
const numberOrNull = value => value === null || Number.isFinite(value) && value >= 0
|
|
12
|
+
const requiredPins = ['installedCandidate', 'corpusDigest', 'targetsDigest', 'routeDigest', 'questionOrderDigest']
|
|
13
|
+
|
|
14
|
+
export function validateExecutionPlan(plan) {
|
|
15
|
+
if (!plan || requiredPins.some(key => typeof plan[key] !== 'string' || !plan[key]) ||
|
|
16
|
+
!Array.isArray(plan.tasks) || !plan.tasks.length) throw new TypeError('Pinned installed target, frozen inputs and explicit task cohort required')
|
|
17
|
+
const ids = new Set()
|
|
18
|
+
for (const task of plan.tasks) {
|
|
19
|
+
if (!task?.id || ids.has(task.id) || !PRESENCE_PROFILES.includes(task.profile) ||
|
|
20
|
+
!phases.has(task.phase) || !task.routeId || !Number.isSafeInteger(task.repetition) || task.repetition < 1 ||
|
|
21
|
+
!task.questionId || !task.cacheState) throw new TypeError('Unique tasks require profile, phase, route, repetition, question and cache state')
|
|
22
|
+
ids.add(task.id)
|
|
23
|
+
}
|
|
24
|
+
return Object.freeze(structuredClone(plan))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Host returns all attempted components, including failures and fallback. Unknown
|
|
28
|
+
// or omitted required charges remain unknown rather than becoming free work.
|
|
29
|
+
export function accountComponents(components) {
|
|
30
|
+
if (!Array.isArray(components)) throw new TypeError('Explicit accounting components required')
|
|
31
|
+
const currencies = new Set(), ids = new Set()
|
|
32
|
+
let knownSubtotal = 0, unknown = false
|
|
33
|
+
for (const item of components) {
|
|
34
|
+
if (!item?.id || ids.has(item.id) || !item.kind || !numberOrNull(item.cost) ||
|
|
35
|
+
!numberOrNull(item.elapsedMs) || typeof item.complete !== 'boolean') throw new TypeError('Unique valid attempted cost components required')
|
|
36
|
+
ids.add(item.id)
|
|
37
|
+
if (item.currency !== null && !/^[A-Z]{3}$/.test(item.currency ?? '')) throw new TypeError('Explicit currency or null required')
|
|
38
|
+
if (item.cost === null || !item.complete) unknown = true
|
|
39
|
+
else knownSubtotal += item.cost
|
|
40
|
+
if (item.cost !== null && item.cost !== 0 && item.currency === null) unknown = true
|
|
41
|
+
if (item.currency !== null) currencies.add(item.currency)
|
|
42
|
+
}
|
|
43
|
+
if (!components.length || currencies.size > 1) unknown = true
|
|
44
|
+
return { totalCost: unknown ? null : knownSubtotal, knownSubtotal,
|
|
45
|
+
currency: currencies.size === 1 ? [...currencies][0] : null,
|
|
46
|
+
complete: !unknown, attemptedComponents: components.length,
|
|
47
|
+
incompleteComponents: components.filter(x => x.cost === null || !x.complete).map(x => x.id),
|
|
48
|
+
unknownOrMixedCurrency: currencies.size > 1 || components.some(x => x.cost !== null && x.cost !== 0 && x.currency === null) }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Separate existing assessor receipts are verified by a trusted receiving host.
|
|
52
|
+
// Producer-supplied assessment fields never enter the useful-answer numerator.
|
|
53
|
+
export function assessmentBinding(record) {
|
|
54
|
+
return { taskId: record.taskId, planDigest: record.planDigest, questionId: record.questionId,
|
|
55
|
+
routeId: record.routeId, resultDigest: record.resultDigest }
|
|
56
|
+
}
|
|
57
|
+
function assessmentReceived(record, receipt, verifyAssessment) {
|
|
58
|
+
if (record.outcome !== 'completed' || typeof verifyAssessment !== 'function' || !receipt) return false
|
|
59
|
+
const binding = assessmentBinding(record)
|
|
60
|
+
if (Object.values(binding).some(x => typeof x !== 'string' || !x) ||
|
|
61
|
+
!receipt.receiptRef || !receipt.assessorRef || !receipt.rubricRef || receipt.bindingDigest !== digest(binding)) return false
|
|
62
|
+
try {
|
|
63
|
+
const verified = verifyAssessment(structuredClone(receipt), structuredClone(binding))
|
|
64
|
+
if (typeof verified?.then === 'function') { Promise.resolve(verified).catch(() => {}); return false }
|
|
65
|
+
return verified?.verified === true && verified?.current === true && !!verified.ownerRef &&
|
|
66
|
+
verified.receiptRef === receipt.receiptRef && verified.bindingDigest === receipt.bindingDigest &&
|
|
67
|
+
receipt.usefulAccepted === true && receipt.supportAccepted === true
|
|
68
|
+
} catch { return false }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function summarizeCohort({ assignedTaskIds, records, sharedComponents = [], assessmentReceipts = [], verifyAssessment }) {
|
|
72
|
+
if (!Array.isArray(assignedTaskIds) || !assignedTaskIds.length || new Set(assignedTaskIds).size !== assignedTaskIds.length ||
|
|
73
|
+
!Array.isArray(records) || !Array.isArray(assessmentReceipts)) throw new TypeError('Complete assigned denominator required')
|
|
74
|
+
const assigned = new Set(assignedTaskIds), observed = new Set(), assessmentTasks = new Set()
|
|
75
|
+
for (const record of records) {
|
|
76
|
+
if (!assigned.has(record.taskId) || observed.has(record.taskId) || !terminalStates.has(record.outcome)) throw new TypeError('Records must uniquely match the assigned cohort')
|
|
77
|
+
observed.add(record.taskId)
|
|
78
|
+
}
|
|
79
|
+
for (const receipt of assessmentReceipts) {
|
|
80
|
+
if (!assigned.has(receipt?.taskId) || assessmentTasks.has(receipt.taskId)) throw new TypeError('Separate assessor receipts must uniquely match assigned tasks')
|
|
81
|
+
assessmentTasks.add(receipt.taskId)
|
|
82
|
+
}
|
|
83
|
+
const useful = records.filter(record => assessmentReceived(record, assessmentReceipts.find(x => x.taskId === record.taskId), verifyAssessment))
|
|
84
|
+
const costs = [...sharedComponents, ...records.flatMap(x => x.components ?? [])]
|
|
85
|
+
let accounting
|
|
86
|
+
try { accounting = accountComponents(costs) }
|
|
87
|
+
catch (error) {
|
|
88
|
+
// Retain malformed/colliding accounting for reconciliation without losing
|
|
89
|
+
// already executed tasks or treating unverified charges as free work.
|
|
90
|
+
accounting = { totalCost: null, knownSubtotal: null, currency: null, complete: false,
|
|
91
|
+
attemptedComponents: costs.length, accountingIssue: error.message, retainedComponents: costs }
|
|
92
|
+
}
|
|
93
|
+
const missing = assignedTaskIds.filter(id => !observed.has(id))
|
|
94
|
+
const complete = !missing.length && records.every(x => Array.isArray(x.components) && x.components.length)
|
|
95
|
+
const totalCost = complete ? accounting.totalCost : null
|
|
96
|
+
return { assigned: assigned.size, observed: observed.size, missing,
|
|
97
|
+
usefulAccepted: useful.length, usefulAcceptedFraction: useful.length / assigned.size,
|
|
98
|
+
failedOrUnavailable: assigned.size - useful.length, accounting: { ...accounting, complete: complete && accounting.complete, totalCost },
|
|
99
|
+
costPerUsefulAcceptedAnswer: totalCost === null || !useful.length ? null : totalCost / useful.length,
|
|
100
|
+
elapsedObservations: records.map(x => ({ taskId: x.taskId, outcome: x.outcome, elapsedMs: x.elapsedMs ?? null })),
|
|
101
|
+
semanticQualityQualified: false, humanAuthorityVerified: false }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function amortizedCosts({ ingestionComponents, queryComponents, queryCounts = [1, 10, 100] }) {
|
|
105
|
+
const initial = accountComponents(ingestionComponents), query = accountComponents(queryComponents)
|
|
106
|
+
return queryCounts.map(count => {
|
|
107
|
+
if (!Number.isSafeInteger(count) || count < 1) throw new TypeError('Positive predeclared query counts required')
|
|
108
|
+
const compatible = initial.currency === query.currency || initial.totalCost === 0 || query.totalCost === 0
|
|
109
|
+
return { queryCount: count, totalCost: initial.totalCost === null || query.totalCost === null || !compatible ? null : initial.totalCost + count * query.totalCost,
|
|
110
|
+
costPerQuery: initial.totalCost === null || query.totalCost === null || !compatible ? null : initial.totalCost / count + query.totalCost,
|
|
111
|
+
assumedWorkload: true, observedDemand: false }
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Admission, native effects, resource bounds and cleanup belong to injected
|
|
117
|
+
* existing host owners. The host enforces per-call provider/CPU/deadline limits.
|
|
118
|
+
* No automatic retry/fallback, provider construction or rubric loading occurs.
|
|
119
|
+
*/
|
|
120
|
+
export function createQualificationExecutor({ admit, openTrial, executeTask, closeTrial, appendSidecar,
|
|
121
|
+
receiveAssessment, verifyAssessment,
|
|
122
|
+
monotonic = () => performance.now(), now = () => new Date().toISOString() }) {
|
|
123
|
+
for (const fn of [admit, openTrial, executeTask, closeTrial, appendSidecar]) if (typeof fn !== 'function') throw new TypeError('Actual admission, execution, sidecar and cleanup owners required')
|
|
124
|
+
if ((receiveAssessment !== undefined || verifyAssessment !== undefined) &&
|
|
125
|
+
(typeof receiveAssessment !== 'function' || typeof verifyAssessment !== 'function')) throw new TypeError('Separate assessment receiving and receipt verification owners required together')
|
|
126
|
+
return Object.freeze({ async run(planInput, { signal } = {}) {
|
|
127
|
+
const plan = validateExecutionPlan(planInput), planDigest = digest(plan)
|
|
128
|
+
const admission = await admit({ plan: structuredClone(plan), planDigest, signal })
|
|
129
|
+
if (admission?.planDigest !== planDigest || admission?.executionAllowed !== true ||
|
|
130
|
+
!admission?.ownerRef || !admission?.limitsRef) throw new Error('Existing owner refused or did not bind actual execution admission')
|
|
131
|
+
const records = [], trials = new Map(), sharedComponents = [], terminalCleanup = [], assessmentReceipts = [], componentIds = new Set(), sidecarFailures = []
|
|
132
|
+
const retainComponents = components => {
|
|
133
|
+
accountComponents(components)
|
|
134
|
+
if (components.some(x => componentIds.has(x.id))) throw new Error('Duplicate attempted accounting component across the cohort')
|
|
135
|
+
for (const x of components) componentIds.add(x.id)
|
|
136
|
+
}
|
|
137
|
+
const unknownAttempt = (task, stage, attemptedResult, error) => {
|
|
138
|
+
let id = `${task.id}/${stage}/unreported-attempt`
|
|
139
|
+
while (componentIds.has(id)) id += '/unreported'
|
|
140
|
+
componentIds.add(id)
|
|
141
|
+
return { outcome: 'uncertain', effectStage: stage, attemptedResult,
|
|
142
|
+
reconciliationReason: error?.message ?? 'actual result unreceived',
|
|
143
|
+
components: [{ id, kind: 'unreported-native-attempt', cost: null, currency: null, elapsedMs: null, complete: false }] }
|
|
144
|
+
}
|
|
145
|
+
const save = async (task, result, started, startedAt) => {
|
|
146
|
+
const record = { outcome: result.outcome, components: result.components, effectStage: result.effectStage,
|
|
147
|
+
reconciliationReason: result.reconciliationReason, executionResult: result, resultDigest: null,
|
|
148
|
+
taskId: task.id, profile: task.profile, phase: task.phase, routeId: task.routeId, repetition: task.repetition,
|
|
149
|
+
questionId: task.questionId, cacheState: task.cacheState, planDigest, startedAt, endedAt: now(), elapsedMs: Math.max(0, monotonic() - started),
|
|
150
|
+
qualification: 'unscored-execution-sidecar', admissionOwnerRef: admission.ownerRef }
|
|
151
|
+
// Retain execution before invoking a separate assessor or sidecar sink.
|
|
152
|
+
records.push(record)
|
|
153
|
+
record.executionResult = structuredClone(result)
|
|
154
|
+
record.resultDigest = digest(record.executionResult)
|
|
155
|
+
if (record.outcome === 'completed' && receiveAssessment) {
|
|
156
|
+
try {
|
|
157
|
+
const receipt = await receiveAssessment({ binding: assessmentBinding(record), result: structuredClone(result), plan: structuredClone(plan), signal })
|
|
158
|
+
if (receipt) {
|
|
159
|
+
record.assessmentReceiving = structuredClone(receipt)
|
|
160
|
+
if (receipt.taskId === task.id && receipt.bindingDigest === digest(assessmentBinding(record)) &&
|
|
161
|
+
receipt.receiptRef && receipt.assessorRef && receipt.rubricRef) assessmentReceipts.push(structuredClone(receipt))
|
|
162
|
+
}
|
|
163
|
+
} catch (error) { record.assessmentReceivingError = error.message }
|
|
164
|
+
}
|
|
165
|
+
await appendSidecar(structuredClone(record))
|
|
166
|
+
}
|
|
167
|
+
let failure
|
|
168
|
+
try {
|
|
169
|
+
for (const task of plan.tasks) {
|
|
170
|
+
if (signal?.aborted) break
|
|
171
|
+
const trialKey = `${task.profile}/${task.routeId}/${task.phase}/${task.repetition}`
|
|
172
|
+
if (!trials.has(trialKey)) {
|
|
173
|
+
const started = monotonic(), startedAt = now(), entry = { handle: null, task: structuredClone(task) }
|
|
174
|
+
trials.set(trialKey, entry)
|
|
175
|
+
let opened
|
|
176
|
+
try {
|
|
177
|
+
opened = await openTrial({ task: structuredClone(task), trialKey, planDigest, admission, signal })
|
|
178
|
+
if (opened?.handle) entry.handle = opened.handle
|
|
179
|
+
if (!entry.handle || !Array.isArray(opened.components) || !opened.components.length) throw new Error('Trial owner must return an actual handle and explicit shared accounting')
|
|
180
|
+
retainComponents(opened.components)
|
|
181
|
+
sharedComponents.push(...opened.components)
|
|
182
|
+
} catch (error) {
|
|
183
|
+
await save(task, unknownAttempt(task, 'trial-open', opened ?? error.attemptedResult, error), started, startedAt)
|
|
184
|
+
break
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const started = monotonic(), startedAt = now()
|
|
188
|
+
let result
|
|
189
|
+
try {
|
|
190
|
+
result = await executeTask({ task: structuredClone(task), trial: trials.get(trialKey).handle, planDigest, admission, signal })
|
|
191
|
+
if (!terminalStates.has(result?.outcome) || !Array.isArray(result.components) || !result.components.length) throw new Error('Incomplete host task receipt')
|
|
192
|
+
retainComponents(result.components)
|
|
193
|
+
} catch (error) {
|
|
194
|
+
result = unknownAttempt(task, 'task-execution', result ?? error.attemptedResult, error)
|
|
195
|
+
}
|
|
196
|
+
await save(task, result, started, startedAt)
|
|
197
|
+
if (result.outcome === 'uncertain') break
|
|
198
|
+
}
|
|
199
|
+
} catch (error) { failure = error }
|
|
200
|
+
finally {
|
|
201
|
+
for (const [trialKey, entry] of [...trials].reverse()) {
|
|
202
|
+
let cleanup
|
|
203
|
+
try { cleanup = await closeTrial({ trial: entry.handle, task: entry.task, trialKey, planDigest, admission }) }
|
|
204
|
+
catch (error) { cleanup = { verified: false, outcome: 'cleanup-uncertain', reason: error.message } }
|
|
205
|
+
terminalCleanup.push({ trialKey, ...cleanup })
|
|
206
|
+
}
|
|
207
|
+
try { await appendSidecar({ kind: 'trial-cleanup', planDigest, terminalCleanup, qualification: 'host-reported-not-independently-verified' }) }
|
|
208
|
+
catch (error) { sidecarFailures.push({ stage: 'trial-cleanup', error }); failure ??= error }
|
|
209
|
+
}
|
|
210
|
+
if (failure) {
|
|
211
|
+
// Original sidecar/cleanup failure retains all executed output and custody.
|
|
212
|
+
Object.assign(failure, { records, sharedComponents, assessmentReceipts, terminalCleanup, sidecarFailures, planDigest, retryAuthorized: false })
|
|
213
|
+
throw failure
|
|
214
|
+
}
|
|
215
|
+
return { planDigest, records, sharedComponents, assessmentReceipts, terminalCleanup,
|
|
216
|
+
cohort: summarizeCohort({ assignedTaskIds: plan.tasks.map(x => x.id), records, sharedComponents, assessmentReceipts, verifyAssessment }),
|
|
217
|
+
cleanupVerified: terminalCleanup.every(x => x.verified === true), nativeQualification: false, benefitQualified: false }
|
|
218
|
+
} })
|
|
219
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Private existing-host dispatch receiving; no SDK, process or receipt owner.
|
|
2
|
+
* The dispatcher owns a single selected query, canonical evidence receiving and
|
|
3
|
+
* independently verified host step receipt receiving, including no-hit output.
|
|
4
|
+
*/
|
|
5
|
+
export class GraphifyCompositionBindingError extends Error {
|
|
6
|
+
constructor(message, received, cause) {
|
|
7
|
+
super(message, { cause })
|
|
8
|
+
this.name = 'GraphifyCompositionBindingError'
|
|
9
|
+
// Native failures and rejected bridges retain actual outputs/costs. A failed
|
|
10
|
+
// snapshot keeps the original producer object explicitly in error custody.
|
|
11
|
+
try { this.supplierResult = structuredClone(received); this.snapshotState = 'received' }
|
|
12
|
+
catch (snapshotError) { this.supplierResult = received; this.snapshotState = 'failed'; this.snapshotError = snapshotError }
|
|
13
|
+
this.retryAuthorized = false
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const same = (left, right) => JSON.stringify(left) === JSON.stringify(right)
|
|
18
|
+
const object = value => value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
19
|
+
const artifact = value => object(value) && Object.keys(value).sort().join(',') === 'bytes,path,sha256' &&
|
|
20
|
+
typeof value.path === 'string' && value.path.length > 0 && /^[a-f0-9]{64}$/.test(value.sha256) && Number.isSafeInteger(value.bytes) && value.bytes >= 0
|
|
21
|
+
const sources = value => object(value) && Object.entries(value).every(([id, source]) => id.length > 0 && object(source) &&
|
|
22
|
+
source.sourceId === id && typeof source.path === 'string' && source.path.length > 0 && /^[a-f0-9]{64}$/.test(source.sourceDigest))
|
|
23
|
+
export function createGraphifyCompositionBinding({ dispatch }) {
|
|
24
|
+
if (typeof dispatch !== 'function') throw new TypeError('Existing host Graphify dispatch required')
|
|
25
|
+
const retrieve = async payload => {
|
|
26
|
+
let received
|
|
27
|
+
try { received = await dispatch({ operation: 'retrieve', payload }) }
|
|
28
|
+
catch (cause) { throw new GraphifyCompositionBindingError('Selected Graphify host dispatch failed; reconcile original custody', cause?.supplierResult ?? cause?.receipt ?? null, cause) }
|
|
29
|
+
const envelope = received?.envelope
|
|
30
|
+
const binding = received?.hostVerificationOriginal?.binding
|
|
31
|
+
if (received?.operation !== 'receive-composition' || received.outcome !== 'composition-envelope-received' ||
|
|
32
|
+
!envelope || envelope.provider !== 'graphify' || envelope.nativeOperation !== 'query' ||
|
|
33
|
+
typeof envelope.generation !== 'string' || !envelope.generation || envelope.generation !== received.generationId || !envelope.receiptRef || !envelope.bridgeReceipt ||
|
|
34
|
+
envelope.receiptAssurance !== 'explicit-verified-existing-host-bridge' ||
|
|
35
|
+
!Array.isArray(envelope.hits) || !Array.isArray(envelope.unresolved) ||
|
|
36
|
+
!artifact(envelope.artifactRef) || !artifact(received.compositionArtifact) ||
|
|
37
|
+
!artifact(envelope.supplierQueryReceipt) || !artifact(received.supplierQueryReceipt) ||
|
|
38
|
+
!artifact(envelope.supplierReceivingReceipt) || !artifact(received.supplierReceivingReceipt) ||
|
|
39
|
+
!sources(envelope.sourceBindings) || !sources(binding?.sourceBindings) ||
|
|
40
|
+
!artifact(binding?.queryArtifact) || !artifact(binding?.queryReceiptArtifact) || !artifact(binding?.receivingArtifact) ||
|
|
41
|
+
!same(envelope.supplierQueryReceipt, received.supplierQueryReceipt) ||
|
|
42
|
+
!same(envelope.supplierReceivingReceipt, received.supplierReceivingReceipt) ||
|
|
43
|
+
!same(envelope.receiptRef, received.receiptBridgeOriginal?.receiptRef) ||
|
|
44
|
+
!same(envelope.bridgeReceipt, received.receiptBridgeOriginal?.bridgeReceipt) ||
|
|
45
|
+
received.hostVerificationOriginal?.verified !== true || received.hostVerificationOriginal?.current !== true ||
|
|
46
|
+
binding?.provider !== 'graphify' || binding.generation !== envelope.generation ||
|
|
47
|
+
!same(binding.sourceBindings, envelope.sourceBindings) || !same(binding.queryArtifact, envelope.artifactRef) ||
|
|
48
|
+
!same(binding.queryReceiptArtifact, envelope.supplierQueryReceipt) || !same(binding.receivingArtifact, envelope.supplierReceivingReceipt) ||
|
|
49
|
+
!same(binding.receiptRef, envelope.receiptRef) || !same(binding.bridgeReceipt, envelope.bridgeReceipt) ||
|
|
50
|
+
!Object.hasOwn(binding, 'bridgeUsage') || !Object.hasOwn(received.receiptBridgeOriginal ?? {}, 'usage') ||
|
|
51
|
+
!object(envelope.usage?.bridge) || !Object.hasOwn(envelope.usage.bridge, 'usage') ||
|
|
52
|
+
!same(binding.bridgeUsage, received.receiptBridgeOriginal.usage) || !same(binding.bridgeUsage, envelope.usage.bridge.usage)) {
|
|
53
|
+
throw new GraphifyCompositionBindingError('Original Graphify receiving and actual verified host receipt bridge required', received)
|
|
54
|
+
}
|
|
55
|
+
return structuredClone(envelope)
|
|
56
|
+
}
|
|
57
|
+
return Object.freeze({ bindings: Object.freeze({ retrieve }), operationRoles: Object.freeze({ retrieve: 'retrieve' }),
|
|
58
|
+
hostRequired: Object.freeze(['single-selected-query', 'existing-canonical-evidence-hydration',
|
|
59
|
+
'independent-current-quote-eligibility', 'actual-verified-existing-host-step-receipt']) })
|
|
60
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"""Private existing-host step receipt receiving. No native dispatch or canonical.
|
|
2
|
+
|
|
3
|
+
Evidence eligibility and a selected operation's actual host receipt are separate.
|
|
4
|
+
The trusted host owns both callbacks; caller JSON cannot supply their authority.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
import copy
|
|
8
|
+
import fcntl
|
|
9
|
+
import hashlib
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import stat
|
|
13
|
+
import uuid
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from graphify_supplier import SupplierError, digest, json_safe, require
|
|
16
|
+
from query_receiving import _reference
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _read_artifact(supplier, directory, artifact):
|
|
20
|
+
require(isinstance(artifact, dict) and set(artifact) == {"path", "sha256", "bytes"},
|
|
21
|
+
"COMPOSITION_ARTIFACT", "Original artifact descriptor required")
|
|
22
|
+
path = Path(artifact["path"])
|
|
23
|
+
require(path.parent == directory and not directory.is_symlink()
|
|
24
|
+
and directory.parent == supplier.artifacts and not supplier.artifacts.is_symlink()
|
|
25
|
+
and path.is_file() and not path.is_symlink(), "COMPOSITION_ARTIFACT", "Original owned artifact required")
|
|
26
|
+
# Original op-directory files only; no symlink traversal at any open step.
|
|
27
|
+
root_fd = os.open(supplier.artifacts, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
|
|
28
|
+
directory_fd, file_fd = None, None
|
|
29
|
+
try:
|
|
30
|
+
directory_fd = os.open(directory.name, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=root_fd)
|
|
31
|
+
file_fd = os.open(path.name, os.O_RDONLY | os.O_NOFOLLOW, dir_fd=directory_fd)
|
|
32
|
+
before = os.fstat(file_fd)
|
|
33
|
+
require(stat.S_ISREG(before.st_mode), "COMPOSITION_ARTIFACT", "Regular original artifact required")
|
|
34
|
+
with os.fdopen(file_fd, "rb", closefd=False) as stream:
|
|
35
|
+
raw = stream.read()
|
|
36
|
+
after = os.fstat(file_fd)
|
|
37
|
+
require((before.st_dev, before.st_ino, before.st_size, before.st_mtime_ns, before.st_ctime_ns)
|
|
38
|
+
== (after.st_dev, after.st_ino, after.st_size, after.st_mtime_ns, after.st_ctime_ns),
|
|
39
|
+
"ARTIFACT_DRIFT", "Original artifact changed during readback")
|
|
40
|
+
finally:
|
|
41
|
+
if file_fd is not None: os.close(file_fd)
|
|
42
|
+
if directory_fd is not None: os.close(directory_fd)
|
|
43
|
+
os.close(root_fd)
|
|
44
|
+
require(len(raw) == artifact["bytes"] and hashlib.sha256(raw).hexdigest() == artifact["sha256"],
|
|
45
|
+
"ARTIFACT_DRIFT", "Original artifact differs from retained receiving")
|
|
46
|
+
return json.loads(raw)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def receive_composition(supplier, received_query, *, receipt_bridge, verify_receipt_bridge):
|
|
50
|
+
"""Receive exact retained query output through actual existing host receipts.
|
|
51
|
+
|
|
52
|
+
Returns an explicit unreceived result with original output/unknown costs on a
|
|
53
|
+
host callback or late freshness failure. It never substitutes a supplier hash
|
|
54
|
+
for a receipt owner. The JS binding retains that result on its error cause.
|
|
55
|
+
"""
|
|
56
|
+
require(callable(receipt_bridge) and callable(verify_receipt_bridge), "COMPOSITION_OWNER",
|
|
57
|
+
"Actual host receipt bridge and independent verifier required")
|
|
58
|
+
require(supplier.lock.acquire(blocking=False), "WRITER_BUSY", "A supplier operation owns receiving")
|
|
59
|
+
lease, details, directory = None, None, None
|
|
60
|
+
try:
|
|
61
|
+
lease = (supplier.artifacts / ".writer.lock").open("a+b")
|
|
62
|
+
try:
|
|
63
|
+
fcntl.flock(lease, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
|
64
|
+
except BlockingIOError as exc:
|
|
65
|
+
raise SupplierError("WRITER_BUSY", "Another process owns this supplier destination") from exc
|
|
66
|
+
received = json_safe(copy.deepcopy(received_query))
|
|
67
|
+
require(isinstance(received, dict) and isinstance(received.get("receivingArtifact"), dict),
|
|
68
|
+
"COMPOSITION_RECEIVING", "Exact retained query receiving required")
|
|
69
|
+
directory = Path(received["receivingArtifact"]["path"]).parent
|
|
70
|
+
original = _read_artifact(supplier, directory, received["receivingArtifact"])
|
|
71
|
+
require(original.get("envelope") == {k: v for k, v in received.items() if k != "receivingArtifact"},
|
|
72
|
+
"COMPOSITION_RECEIVING", "Original receiving envelope readback must agree")
|
|
73
|
+
operation_id = original["queryOperationId"]
|
|
74
|
+
query = supplier.read_capture(operation_id)["receipt"]
|
|
75
|
+
context = original["queryBinding"]
|
|
76
|
+
require(directory == supplier.artifacts / operation_id and query["operation"] == "query"
|
|
77
|
+
and query["status"] == "complete" and received["provider"] == "graphify"
|
|
78
|
+
and received["generation"] == context["generation"] == query["graphGeneration"]
|
|
79
|
+
and context["sourceBindings"] == query["sourceBindings"]
|
|
80
|
+
and received["artifactRef"] == context["queryArtifact"]
|
|
81
|
+
and isinstance(received["hits"], list) and isinstance(received["unresolved"], list),
|
|
82
|
+
"COMPOSITION_RECEIVING", "Original successful query/source/generation required")
|
|
83
|
+
native = _read_artifact(supplier, directory, context["queryArtifact"])
|
|
84
|
+
original_query_receipt = _read_artifact(supplier, directory, context["queryReceiptArtifact"])
|
|
85
|
+
require(query == original_query_receipt and received["usage"] == query.get("usage"),
|
|
86
|
+
"COMPOSITION_RECEIVING", "Original query receipt and usage must agree")
|
|
87
|
+
payload = {**copy.deepcopy(received), "nativeOperation": "query", "nativeResult": native,
|
|
88
|
+
"sourceBindings": copy.deepcopy(context["sourceBindings"]),
|
|
89
|
+
"supplierQueryReceipt": copy.deepcopy(context["queryReceiptArtifact"]),
|
|
90
|
+
"supplierReceivingReceipt": copy.deepcopy(received["receivingArtifact"]),
|
|
91
|
+
"evidenceReceiptRef": copy.deepcopy(received["receiptRef"]), "receiptRef": None,
|
|
92
|
+
"queryUsage": copy.deepcopy(query.get("usage")),
|
|
93
|
+
"usage": {"query": {"receiptArtifact": copy.deepcopy(context["queryReceiptArtifact"]),
|
|
94
|
+
"usage": copy.deepcopy(query.get("usage")), "assurance": query.get("usageAssurance")},
|
|
95
|
+
"receiving": {"artifact": copy.deepcopy(received["receivingArtifact"]), "usage": None},
|
|
96
|
+
"bridge": {"usage": None}},
|
|
97
|
+
"semanticAcceptance": "existing-owner-only", "canonicalMutation": False}
|
|
98
|
+
details = {"operation": "receive-composition", "queryOperationId": operation_id,
|
|
99
|
+
"generationId": context["generation"], "outcome": "composition-envelope-unreceived",
|
|
100
|
+
"originalQueryEnvelope": copy.deepcopy(received), "envelope": payload,
|
|
101
|
+
"supplierQueryReceipt": copy.deepcopy(context["queryReceiptArtifact"]),
|
|
102
|
+
"supplierReceivingReceipt": copy.deepcopy(received["receivingArtifact"]),
|
|
103
|
+
"receiptBridgeOriginal": None, "hostVerificationOriginal": None,
|
|
104
|
+
"authority": "none", "canonicalMutation": False}
|
|
105
|
+
for name in ("historyDigest", "activationRef"):
|
|
106
|
+
if name in context: payload[name] = copy.deepcopy(context[name])
|
|
107
|
+
try:
|
|
108
|
+
supplier._fresh(context["generation"], "graph")
|
|
109
|
+
bridged = json_safe(receipt_bridge(copy.deepcopy(payload), copy.deepcopy(query), copy.deepcopy(original)))
|
|
110
|
+
details["receiptBridgeOriginal"] = copy.deepcopy(bridged)
|
|
111
|
+
require(isinstance(bridged, dict) and _reference(bridged.get("receiptRef"))
|
|
112
|
+
and _reference(bridged.get("bridgeReceipt")) and "usage" in bridged,
|
|
113
|
+
"COMPOSITION_RECEIPT", "Original actual host step/bridge receipts and known or unknown usage required")
|
|
114
|
+
# This local exact-value guard is not owner authentication. It refuses
|
|
115
|
+
# listed paths and bare/sha256:-prefixed lower-case content hashes;
|
|
116
|
+
# other aliases/case/format variants remain the actual verifier's job.
|
|
117
|
+
identifiers = {digest(query), digest(original), digest(native), digest(payload)}
|
|
118
|
+
artifacts = query["artifacts"] + [context["queryReceiptArtifact"], received["receivingArtifact"]]
|
|
119
|
+
for artifact in artifacts:
|
|
120
|
+
identifiers.update((artifact["path"], artifact["sha256"], "sha256:" + artifact["sha256"]))
|
|
121
|
+
for name in ("receiptRef", "bridgeReceipt"):
|
|
122
|
+
reference = bridged[name]
|
|
123
|
+
require(reference["id"] not in identifiers and reference["id"].removeprefix("sha256:") not in identifiers
|
|
124
|
+
and reference["digest"] not in identifiers
|
|
125
|
+
and reference["digest"].removeprefix("sha256:") not in identifiers,
|
|
126
|
+
"COMPOSITION_RECEIPT", "Supplier artifact digests cannot become existing host receipts")
|
|
127
|
+
binding = {"provider": "graphify", "generation": context["generation"],
|
|
128
|
+
"sourceBindings": copy.deepcopy(context["sourceBindings"]),
|
|
129
|
+
"queryArtifact": copy.deepcopy(context["queryArtifact"]),
|
|
130
|
+
"queryReceiptArtifact": copy.deepcopy(context["queryReceiptArtifact"]),
|
|
131
|
+
"receivingArtifact": copy.deepcopy(received["receivingArtifact"]),
|
|
132
|
+
"envelopeDigest": digest(payload), "receiptRef": copy.deepcopy(bridged["receiptRef"]),
|
|
133
|
+
"bridgeReceipt": copy.deepcopy(bridged["bridgeReceipt"]), "bridgeUsage": copy.deepcopy(bridged["usage"])}
|
|
134
|
+
for name in ("historyDigest", "activationRef"):
|
|
135
|
+
if name in context: binding[name] = copy.deepcopy(context[name])
|
|
136
|
+
verdict = json_safe(verify_receipt_bridge(copy.deepcopy(binding), copy.deepcopy(payload), copy.deepcopy(bridged)))
|
|
137
|
+
details["hostVerificationOriginal"] = copy.deepcopy(verdict)
|
|
138
|
+
require(isinstance(verdict, dict) and verdict.get("binding") == binding
|
|
139
|
+
and verdict.get("verified") is True and verdict.get("current") is True,
|
|
140
|
+
"COMPOSITION_BRIDGE_UNVERIFIED", "Independent existing host must bind exact original query/receiving/source/generation/envelope/receipts")
|
|
141
|
+
supplier._fresh(context["generation"], "graph")
|
|
142
|
+
require(supplier.read_capture(operation_id)["receipt"] == query
|
|
143
|
+
and _read_artifact(supplier, directory, received["receivingArtifact"]) == original
|
|
144
|
+
and _read_artifact(supplier, directory, context["queryReceiptArtifact"]) == query,
|
|
145
|
+
"ARTIFACT_DRIFT", "Original query or receiving changed during host receipt receiving")
|
|
146
|
+
payload.update(receiptRef=copy.deepcopy(bridged["receiptRef"]), bridgeReceipt=copy.deepcopy(bridged["bridgeReceipt"]),
|
|
147
|
+
receiptAssurance="explicit-verified-existing-host-bridge")
|
|
148
|
+
payload["usage"]["bridge"] = {"receiptRef": copy.deepcopy(bridged["bridgeReceipt"]), "usage": copy.deepcopy(bridged["usage"])}
|
|
149
|
+
details["outcome"] = "composition-envelope-received"
|
|
150
|
+
except BaseException as exc:
|
|
151
|
+
details["error"] = {"type": type(exc).__name__, "code": getattr(exc, "code", "COMPOSITION_HOST_FAILURE")}
|
|
152
|
+
# Original potentially stale hits remain diagnostic under the original
|
|
153
|
+
# envelope. Refused bridging cannot provide any composition hit.
|
|
154
|
+
payload["hits"] = []
|
|
155
|
+
payload["receiptRef"] = None
|
|
156
|
+
payload["unresolved"].append({"reason": details["error"]["code"], "type": type(exc).__name__})
|
|
157
|
+
if isinstance(details["receiptBridgeOriginal"], dict):
|
|
158
|
+
payload["usage"]["bridge"] = {"receiptRef": copy.deepcopy(details["receiptBridgeOriginal"].get("bridgeReceipt")),
|
|
159
|
+
"usage": copy.deepcopy(details["receiptBridgeOriginal"].get("usage"))}
|
|
160
|
+
if not isinstance(exc, Exception):
|
|
161
|
+
# Control signals remain control signals; preserve originals and
|
|
162
|
+
# costs, capture cancellation if possible, then let finally clean
|
|
163
|
+
# both leases before the same exception reaches the host.
|
|
164
|
+
details["controlSignal"] = {"type": type(exc).__name__, "propagated": True}
|
|
165
|
+
try:
|
|
166
|
+
details["compositionArtifact"] = supplier._write(directory, f"composition-{uuid.uuid4().hex}.json", details)
|
|
167
|
+
except BaseException as capture_error:
|
|
168
|
+
details["captureError"] = {"type": type(capture_error).__name__, "code": getattr(capture_error, "code", "CAPTURE_FAILURE")}
|
|
169
|
+
exc.receipt = copy.deepcopy(details)
|
|
170
|
+
raise
|
|
171
|
+
capture = supplier._write(directory, f"composition-{uuid.uuid4().hex}.json", details)
|
|
172
|
+
return {**details, "compositionArtifact": capture}
|
|
173
|
+
except Exception as exc:
|
|
174
|
+
if isinstance(exc, SupplierError):
|
|
175
|
+
exc.receipt = copy.deepcopy(details) if details else copy.deepcopy(received_query)
|
|
176
|
+
raise
|
|
177
|
+
raise SupplierError("COMPOSITION_RECEIVING_FAILURE", "Host receiving failed; original custody retained", copy.deepcopy(details)) from exc
|
|
178
|
+
except BaseException as exc:
|
|
179
|
+
if not hasattr(exc, "receipt"):
|
|
180
|
+
exc.receipt = copy.deepcopy(details) if details else copy.deepcopy(received_query)
|
|
181
|
+
raise
|
|
182
|
+
finally:
|
|
183
|
+
if lease:
|
|
184
|
+
lease.close()
|
|
185
|
+
supplier.lock.release()
|