mirai-graph 1.3.0 → 2.1.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/cli.js +6 -0
- package/index.js +1 -0
- package/package.json +9 -121
- package/.github/workflows/ci.yml +0 -48
- package/.github/workflows/mirai-graph-validate.yml +0 -30
- package/CHANGELOG.md +0 -702
- package/CITATION.cff +0 -21
- package/LICENSE +0 -21
- package/LICENSE-DOCS +0 -26
- package/README.md +0 -351
- package/ROADMAP.md +0 -241
- package/benchmarks/protocols/measure-convert-optimize.md +0 -131
- package/benchmarks/synthetic-context-reduction-v0/README.md +0 -70
- package/benchmarks/synthetic-context-reduction-v0/RESULT.md +0 -52
- package/benchmarks/synthetic-context-reduction-v0/expected/context-pack-compact.md +0 -31
- package/benchmarks/synthetic-context-reduction-v0/gates/results.json +0 -12
- package/benchmarks/synthetic-context-reduction-v0/graph/objects.json +0 -114
- package/benchmarks/synthetic-context-reduction-v0/graph/relations.json +0 -74
- package/benchmarks/synthetic-context-reduction-v0/graph.json +0 -37
- package/benchmarks/synthetic-context-reduction-v0/metrics/example-metrics.json +0 -22
- package/benchmarks/synthetic-context-reduction-v0/results/baseline-comparison-result.json +0 -42
- package/benchmarks/synthetic-context-reduction-v0/results/context-pack.json +0 -181
- package/benchmarks/synthetic-context-reduction-v0/results/context-reduction-result.json +0 -8
- package/benchmarks/synthetic-context-reduction-v0/results/profile-conformance-result.json +0 -28
- package/benchmarks/synthetic-context-reduction-v0/results/readiness-score.json +0 -24
- package/benchmarks/synthetic-context-reduction-v0/reviews/semantic-completeness-review.json +0 -78
- package/benchmarks/synthetic-context-reduction-v0/scripts/calculate-context-reduction.js +0 -42
- package/benchmarks/synthetic-context-reduction-v0/source-corpus/audit-events.md +0 -8
- package/benchmarks/synthetic-context-reduction-v0/source-corpus/content-workflow.md +0 -8
- package/benchmarks/synthetic-context-reduction-v0/source-corpus/identity-access.md +0 -8
- package/benchmarks/synthetic-context-reduction-v0/source-corpus/notification-delivery.md +0 -8
- package/benchmarks/synthetic-context-reduction-v0/tasks/tasks.json +0 -31
- package/docs/README.md +0 -130
- package/docs/adoption/adopter-kit.md +0 -187
- package/docs/adoption/ai-employee-graph.md +0 -151
- package/docs/adoption/character-layer.md +0 -196
- package/docs/adoption/choose-profile.md +0 -106
- package/docs/adoption/cli.md +0 -134
- package/docs/adoption/connect-project-15-minutes.md +0 -122
- package/docs/adoption/developer-integration-guide.md +0 -122
- package/docs/adoption/end-to-end-control-loop.md +0 -168
- package/docs/adoption/for-developers.md +0 -210
- package/docs/adoption/getting-started.md +0 -192
- package/docs/adoption/mirai-graph-transition.md +0 -67
- package/docs/adoption/profile-conformance-fixtures.md +0 -112
- package/docs/adoption/seed-to-validated-package.md +0 -121
- package/docs/concept.md +0 -109
- package/docs/repository-purpose.md +0 -422
- package/docs/research/ai-work-field-instrumentation-bridge.md +0 -126
- package/docs/research/baseline-comparison-protocol.md +0 -79
- package/docs/research/evidence-package-v0.1.md +0 -99
- package/docs/research/evidence-package-v0.2.md +0 -150
- package/docs/research/evidence-package-v0.3.md +0 -256
- package/docs/research/independent-implementation-pilot-plan.md +0 -74
- package/docs/research/limitations-and-threats.md +0 -40
- package/docs/research/practice-science-program.md +0 -232
- package/docs/research/scientific-evidence-package.md +0 -188
- package/docs/research/semantic-completeness-review-protocol.md +0 -70
- package/docs/terminology.md +0 -119
- package/docs/transfer/ai-employee-profile-proposal.md +0 -119
- package/docs/transfer/federation-routing-control-loop-2026-05-31.md +0 -28
- package/docs/transfer/graph-capability-map-2026-05-29.md +0 -126
- package/docs/transfer/graph-skill-to-mirai-graph.md +0 -128
- package/docs/transfer/project-management-standard-harvest-2026-06-02.md +0 -322
- package/docs/transfer/skill-graph-standard-harvest-2026-05-31.md +0 -113
- package/docs/transfer/standard-gap-report-2026-05-28.md +0 -208
- package/examples/ai-employee-minimal/README.md +0 -53
- package/examples/ai-employee-minimal/gates/results.json +0 -35
- package/examples/ai-employee-minimal/graph/objects.json +0 -187
- package/examples/ai-employee-minimal/graph/relations.json +0 -167
- package/examples/ai-employee-minimal/graph.json +0 -37
- package/examples/ai-employee-minimal/results/profile-conformance-result.json +0 -28
- package/examples/character-layer-integration-minimal/README.md +0 -25
- package/examples/character-layer-integration-minimal/results/character-layer-integration.json +0 -53
- package/examples/character-layer-minimal/README.md +0 -29
- package/examples/character-layer-minimal/gates/results.json +0 -57
- package/examples/character-layer-minimal/graph/objects.json +0 -165
- package/examples/character-layer-minimal/graph/relations.json +0 -178
- package/examples/character-layer-minimal/graph.json +0 -37
- package/examples/character-layer-readiness-1-0/README.md +0 -27
- package/examples/character-layer-readiness-1-0/results/character-layer-readiness.json +0 -90
- package/examples/dynamic-episode-minimal/README.md +0 -34
- package/examples/dynamic-episode-minimal/gates/results.json +0 -12
- package/examples/dynamic-episode-minimal/graph/objects.json +0 -92
- package/examples/dynamic-episode-minimal/graph/relations.json +0 -29
- package/examples/dynamic-episode-minimal/graph.json +0 -47
- package/examples/dynamic-episode-minimal/invalid-canonical-write-allowed.json +0 -40
- package/examples/dynamic-episode-minimal/invalid-evidence-as-authorization.json +0 -46
- package/examples/dynamic-episode-minimal/invalid-missing-event.json +0 -35
- package/examples/dynamic-episode-minimal/invalid-missing-selected-path.json +0 -40
- package/examples/dynamic-episode-minimal/invalid-unclassified-finding.json +0 -50
- package/examples/dynamic-episode-minimal/results/dynamic-episode-trace.json +0 -149
- package/examples/federation-routing-smoke/README.md +0 -19
- package/examples/federation-routing-smoke/federation-health-dashboard.json +0 -42
- package/examples/federation-routing-smoke/route-explanation.json +0 -32
- package/examples/federation-routing-smoke/route-regression-result.json +0 -35
- package/examples/federation-routing-smoke/routes/production-deploy-execution-evidence.json +0 -17
- package/examples/federation-routing-smoke/routes/production-deploy-route-result.json +0 -12
- package/examples/federation-routing-smoke/routes/production-deploy-runtime-preflight.json +0 -8
- package/examples/federation-routing-smoke/routes/production-deploy-stderr.txt +0 -1
- package/examples/federation-routing-smoke/routes/production-deploy-stdout.txt +0 -1
- package/examples/federation-routing-smoke/routes/search-page-execution-evidence.json +0 -17
- package/examples/federation-routing-smoke/routes/search-page-route-result.json +0 -12
- package/examples/federation-routing-smoke/routes/search-page-stderr.txt +0 -1
- package/examples/federation-routing-smoke/routes/search-page-stdout.txt +0 -1
- package/examples/federation-routing-smoke/routing-fixture-run.json +0 -66
- package/examples/federation-routing-smoke/routing-fixtures.json +0 -44
- package/examples/goal-vector-quality-control-minimal/README.md +0 -22
- package/examples/goal-vector-quality-control-minimal/gates/results.json +0 -22
- package/examples/goal-vector-quality-control-minimal/graph/objects.json +0 -56
- package/examples/goal-vector-quality-control-minimal/graph/relations.json +0 -29
- package/examples/goal-vector-quality-control-minimal/graph.json +0 -41
- package/examples/goal-vector-quality-control-minimal/invalid-complete-without-evidence.json +0 -77
- package/examples/goal-vector-quality-control-minimal/invalid-correction-without-route.json +0 -86
- package/examples/goal-vector-quality-control-minimal/invalid-missing-reverse-audit.json +0 -77
- package/examples/goal-vector-quality-control-minimal/invalid-missing-vector-link.json +0 -62
- package/examples/goal-vector-quality-control-minimal/invalid-tests-as-acceptance.json +0 -72
- package/examples/goal-vector-quality-control-minimal/results/goal-vector-quality-control.json +0 -130
- package/examples/graph-dna-alignment-minimal/README.md +0 -16
- package/examples/graph-dna-alignment-minimal/graph/objects.json +0 -38
- package/examples/graph-dna-alignment-minimal/graph/relations.json +0 -20
- package/examples/graph-dna-alignment-minimal/graph.json +0 -37
- package/examples/graph-dna-alignment-minimal/results/graph-dna-alignment.json +0 -32
- package/examples/graph-seed-minimal/README.md +0 -9
- package/examples/graph-seed-minimal/graph-embryo.json +0 -63
- package/examples/graph-seed-minimal/graph-seed.json +0 -60
- package/examples/implementation-control-cycles/README.md +0 -47
- package/examples/implementation-control-cycles/gates/results.json +0 -22
- package/examples/implementation-control-cycles/graph/objects.json +0 -119
- package/examples/implementation-control-cycles/graph/relations.json +0 -200
- package/examples/implementation-control-cycles/graph.json +0 -37
- package/examples/implementation-control-cycles/results/implementation-control-cycles.json +0 -456
- package/examples/implementation-control-minimal/README.md +0 -39
- package/examples/implementation-control-minimal/gates/results.json +0 -42
- package/examples/implementation-control-minimal/graph/objects.json +0 -128
- package/examples/implementation-control-minimal/graph/relations.json +0 -128
- package/examples/implementation-control-minimal/graph.json +0 -37
- package/examples/implementation-control-minimal/results/implementation-control-loop.json +0 -21
- package/examples/instrumentation-layer-minimal/README.md +0 -32
- package/examples/instrumentation-layer-minimal/gates/results.json +0 -11
- package/examples/instrumentation-layer-minimal/graph/objects.json +0 -74
- package/examples/instrumentation-layer-minimal/graph/relations.json +0 -56
- package/examples/instrumentation-layer-minimal/graph.json +0 -37
- package/examples/instrumentation-layer-minimal/invalid-cockpit-missing-gates.json +0 -40
- package/examples/instrumentation-layer-minimal/invalid-feedback-accepted-with-blocking.json +0 -38
- package/examples/instrumentation-layer-minimal/invalid-feedback-process-improvement-without-kaizen.json +0 -38
- package/examples/instrumentation-layer-minimal/invalid-traceability-missing-evidence.json +0 -43
- package/examples/instrumentation-layer-minimal/results/development-cockpit.json +0 -68
- package/examples/instrumentation-layer-minimal/results/feature-implementation-traceability.json +0 -56
- package/examples/instrumentation-layer-minimal/results/multi-source-quality-feedback.json +0 -72
- package/examples/invalid-character-layer-context-authorization/graph/objects.json +0 -22
- package/examples/invalid-character-layer-context-authorization/graph/relations.json +0 -1
- package/examples/invalid-character-layer-context-authorization/graph.json +0 -35
- package/examples/invalid-character-layer-correction-loop-no-review/graph/objects.json +0 -22
- package/examples/invalid-character-layer-correction-loop-no-review/graph/relations.json +0 -1
- package/examples/invalid-character-layer-correction-loop-no-review/graph.json +0 -35
- package/examples/invalid-character-layer-feedback-auto-update/graph/objects.json +0 -22
- package/examples/invalid-character-layer-feedback-auto-update/graph/relations.json +0 -1
- package/examples/invalid-character-layer-feedback-auto-update/graph.json +0 -35
- package/examples/invalid-character-layer-object-kind/graph/objects.json +0 -22
- package/examples/invalid-character-layer-object-kind/graph/relations.json +0 -1
- package/examples/invalid-character-layer-object-kind/graph.json +0 -35
- package/examples/invalid-character-layer-relation-direction/graph/objects.json +0 -33
- package/examples/invalid-character-layer-relation-direction/graph/relations.json +0 -13
- package/examples/invalid-character-layer-relation-direction/graph.json +0 -35
- package/examples/invalid-character-layer-relation-type/graph/objects.json +0 -33
- package/examples/invalid-character-layer-relation-type/graph/relations.json +0 -13
- package/examples/invalid-character-layer-relation-type/graph.json +0 -35
- package/examples/invalid-character-layer-role-permission/graph/objects.json +0 -22
- package/examples/invalid-character-layer-role-permission/graph/relations.json +0 -1
- package/examples/invalid-character-layer-role-permission/graph.json +0 -35
- package/examples/invalid-context-pack-missing-explanation/context-pack.json +0 -25
- package/examples/invalid-missing-relation-target/graph/objects.json +0 -11
- package/examples/invalid-missing-relation-target/graph/relations.json +0 -11
- package/examples/invalid-missing-relation-target/graph.json +0 -32
- package/examples/invalid-profile-object-kind/graph/objects.json +0 -20
- package/examples/invalid-profile-object-kind/graph/relations.json +0 -1
- package/examples/invalid-profile-object-kind/graph.json +0 -32
- package/examples/invalid-profile-relation-type/graph/objects.json +0 -29
- package/examples/invalid-profile-relation-type/graph/relations.json +0 -11
- package/examples/invalid-profile-relation-type/graph.json +0 -32
- package/examples/invalid-relation-id-mismatch/graph/objects.json +0 -29
- package/examples/invalid-relation-id-mismatch/graph/relations.json +0 -11
- package/examples/invalid-relation-id-mismatch/graph.json +0 -32
- package/examples/invalid-seed-unsafe-write/graph-seed.json +0 -27
- package/examples/invalid-societal-governance-auto-learning-update/graph/objects.json +0 -29
- package/examples/invalid-societal-governance-auto-learning-update/graph/relations.json +0 -11
- package/examples/invalid-societal-governance-auto-learning-update/graph.json +0 -35
- package/examples/invalid-societal-governance-avatar-no-consent/graph/objects.json +0 -29
- package/examples/invalid-societal-governance-avatar-no-consent/graph/relations.json +0 -11
- package/examples/invalid-societal-governance-avatar-no-consent/graph.json +0 -35
- package/examples/invalid-societal-governance-generated-context-authorization/graph/objects.json +0 -38
- package/examples/invalid-societal-governance-generated-context-authorization/graph/relations.json +0 -20
- package/examples/invalid-societal-governance-generated-context-authorization/graph.json +0 -35
- package/examples/invalid-societal-governance-missing-appeal-path/graph/objects.json +0 -29
- package/examples/invalid-societal-governance-missing-appeal-path/graph/relations.json +0 -11
- package/examples/invalid-societal-governance-missing-appeal-path/graph.json +0 -35
- package/examples/invalid-societal-governance-private-trace-exposed/graph/objects.json +0 -29
- package/examples/invalid-societal-governance-private-trace-exposed/graph/relations.json +0 -11
- package/examples/invalid-societal-governance-private-trace-exposed/graph.json +0 -35
- package/examples/invalid-societal-governance-rights-overridden/graph/objects.json +0 -29
- package/examples/invalid-societal-governance-rights-overridden/graph/relations.json +0 -11
- package/examples/invalid-societal-governance-rights-overridden/graph.json +0 -35
- package/examples/launch-record-minimal/README.md +0 -29
- package/examples/launch-record-minimal/gates/results.json +0 -12
- package/examples/launch-record-minimal/graph/objects.json +0 -47
- package/examples/launch-record-minimal/graph/relations.json +0 -38
- package/examples/launch-record-minimal/graph.json +0 -34
- package/examples/launch-record-minimal/results/launch-record.json +0 -51
- package/examples/managed-project-control-loop/README.md +0 -43
- package/examples/managed-project-control-loop/gates/results.json +0 -22
- package/examples/managed-project-control-loop/graph/objects.json +0 -119
- package/examples/managed-project-control-loop/graph/relations.json +0 -110
- package/examples/managed-project-control-loop/graph.json +0 -37
- package/examples/managed-project-control-loop/results/managed-loop-result.json +0 -21
- package/examples/minimal-graph/README.md +0 -15
- package/examples/minimal-graph/gates/results.json +0 -12
- package/examples/minimal-graph/graph/objects.json +0 -24
- package/examples/minimal-graph/graph/relations.json +0 -11
- package/examples/minimal-graph/graph.json +0 -37
- package/examples/minimal-graph/results/profile-conformance-result.json +0 -26
- package/examples/model-portability-minimal/README.md +0 -15
- package/examples/model-portability-minimal/results/model-portability-evidence.json +0 -55
- package/examples/organization-governance-minimal/README.md +0 -29
- package/examples/organization-governance-minimal/gates/results.json +0 -21
- package/examples/organization-governance-minimal/graph/objects.json +0 -147
- package/examples/organization-governance-minimal/graph/relations.json +0 -147
- package/examples/organization-governance-minimal/graph.json +0 -37
- package/examples/organization-governance-minimal/results/profile-conformance-result.json +0 -31
- package/examples/process-control-contract-minimal/README.md +0 -19
- package/examples/process-control-contract-minimal/graph/objects.json +0 -38
- package/examples/process-control-contract-minimal/graph/relations.json +0 -29
- package/examples/process-control-contract-minimal/graph.json +0 -34
- package/examples/process-control-contract-minimal/results/process-control-contract.json +0 -58
- package/examples/process-transition-minimal/README.md +0 -25
- package/examples/process-transition-minimal/invalid-missing-launch-record.json +0 -14
- package/examples/process-transition-minimal/invalid-ready-to-written.json +0 -14
- package/examples/process-transition-minimal/invalid-release-missing-evidence.json +0 -14
- package/examples/process-transition-minimal/invalid-sync-to-update.json +0 -14
- package/examples/process-transition-minimal/invalid-terminal-missing-kaizen.json +0 -14
- package/examples/process-transition-minimal/invalid-tests-to-approved.json +0 -14
- package/examples/process-transition-minimal/results/transition-explanation-invalid-ready-to-written.json +0 -35
- package/examples/process-transition-minimal/results/transition-explanation-valid.json +0 -34
- package/examples/process-transition-minimal/state-machine.json +0 -79
- package/examples/process-transition-minimal/transition-request-skip-kaizen.json +0 -14
- package/examples/process-transition-minimal/transition-request.json +0 -14
- package/examples/project-technology-context-traversal/README.md +0 -17
- package/examples/project-technology-context-traversal/graph/objects.json +0 -78
- package/examples/project-technology-context-traversal/graph/relations.json +0 -47
- package/examples/project-technology-context-traversal/graph.json +0 -30
- package/examples/project-technology-context-traversal/selection.example.json +0 -29
- package/examples/project-technology-context-traversal/sources/announcement.md +0 -3
- package/examples/project-technology-context-traversal/sources/release-guide.md +0 -3
- package/examples/project-technology-context-traversal/sources/release-smoke.md +0 -3
- package/examples/project-technology-context-traversal/sources/rollback-policy.md +0 -3
- package/examples/risk-and-coordination-minimal/README.md +0 -16
- package/examples/risk-and-coordination-minimal/graph/objects.json +0 -47
- package/examples/risk-and-coordination-minimal/graph/relations.json +0 -29
- package/examples/risk-and-coordination-minimal/graph.json +0 -37
- package/examples/risk-and-coordination-minimal/results/multi-agent-coordination.json +0 -25
- package/examples/risk-and-coordination-minimal/results/risk-control-matrix.json +0 -34
- package/examples/self-service-onboarding/bootstrap-proposal/bootstrap-proposal.json +0 -20
- package/examples/self-service-onboarding/existing-graph/README.md +0 -4
- package/examples/self-service-onboarding/existing-graph/gates/results.json +0 -11
- package/examples/self-service-onboarding/existing-graph/graph/objects.json +0 -11
- package/examples/self-service-onboarding/existing-graph/graph/relations.json +0 -1
- package/examples/self-service-onboarding/existing-graph/graph.json +0 -36
- package/examples/self-service-onboarding/no-graph/README.md +0 -6
- package/examples/self-service-onboarding/no-graph/package.json +0 -6
- package/examples/self-service-onboarding/no-graph/src/index.js +0 -3
- package/examples/self-service-onboarding/stale-graph/README.md +0 -4
- package/examples/self-service-onboarding/stale-graph/graph.json +0 -36
- package/examples/semantic-intent-resolution-minimal/README.md +0 -13
- package/examples/semantic-intent-resolution-minimal/invalid-low-confidence-executes.json +0 -26
- package/examples/semantic-intent-resolution-minimal/invalid-proposal-canonical-update.json +0 -27
- package/examples/semantic-intent-resolution-minimal/results/semantic-intent-resolution.json +0 -45
- package/examples/skill-runtime-minimal/README.md +0 -29
- package/examples/skill-runtime-minimal/gates/results.json +0 -35
- package/examples/skill-runtime-minimal/graph/objects.json +0 -209
- package/examples/skill-runtime-minimal/graph/relations.json +0 -178
- package/examples/skill-runtime-minimal/graph.json +0 -37
- package/examples/skill-runtime-minimal/results/profile-conformance-result.json +0 -27
- package/examples/societal-governance-minimal/README.md +0 -37
- package/examples/societal-governance-minimal/graph/objects.json +0 -218
- package/examples/societal-governance-minimal/graph/relations.json +0 -209
- package/examples/societal-governance-minimal/graph.json +0 -37
- package/examples/source-boundary-minimal/README.md +0 -16
- package/examples/source-boundary-minimal/graph/objects.json +0 -38
- package/examples/source-boundary-minimal/graph/relations.json +0 -20
- package/examples/source-boundary-minimal/graph.json +0 -37
- package/examples/source-boundary-minimal/results/source-boundary-contract.json +0 -37
- package/examples/technology-quality-feedback-minimal/README.md +0 -33
- package/examples/technology-quality-feedback-minimal/graph/objects.json +0 -56
- package/examples/technology-quality-feedback-minimal/graph/relations.json +0 -47
- package/examples/technology-quality-feedback-minimal/graph.json +0 -34
- package/examples/technology-quality-feedback-minimal/invalid-accepted-with-blocking.json +0 -33
- package/examples/technology-quality-feedback-minimal/invalid-evidence-as-authorization.json +0 -22
- package/examples/technology-quality-feedback-minimal/invalid-missing-required-step.json +0 -22
- package/examples/technology-quality-feedback-minimal/invalid-process-improvement-without-kaizen.json +0 -33
- package/examples/technology-quality-feedback-minimal/invalid-spec-gap-without-route.json +0 -33
- package/examples/technology-quality-feedback-minimal/invalid-unclassified-finding.json +0 -33
- package/examples/technology-quality-feedback-minimal/results/technology-quality-feedback.json +0 -80
- package/examples/work-recovery-minimal/README.md +0 -15
- package/examples/work-recovery-minimal/graph/objects.json +0 -47
- package/examples/work-recovery-minimal/graph/relations.json +0 -20
- package/examples/work-recovery-minimal/graph.json +0 -37
- package/examples/work-recovery-minimal/results/recovery-resume-record.json +0 -17
- package/examples/work-recovery-minimal/results/work-state-machine.json +0 -21
- package/packages/cli/adopter-workflow.js +0 -228
- package/packages/cli/context-pack.js +0 -269
- package/packages/cli/graph-manifest.js +0 -367
- package/packages/cli/instrumentation-report.js +0 -97
- package/packages/cli/migrate-graph-manifest.js +0 -33
- package/packages/cli/mirai-graph.js +0 -154
- package/packages/cli/mirai_graph.js +0 -3
- package/packages/cli/playground-demo.js +0 -114
- package/packages/cli/project-technology.js +0 -129
- package/packages/cli/readiness-score.js +0 -164
- package/packages/cli/release-state.js +0 -329
- package/packages/cli/seed-preview.js +0 -78
- package/packages/cli/self-service-onboarding.js +0 -386
- package/packages/cli/validate-adopter-workflow.js +0 -63
- package/packages/cli/validate-artifact-releases.js +0 -282
- package/packages/cli/validate-baseline-comparison.js +0 -105
- package/packages/cli/validate-context-traversal.js +0 -292
- package/packages/cli/validate-graph-manifest-migration.js +0 -64
- package/packages/cli/validate-mirai-graph.js +0 -3245
- package/packages/cli/validate-process-transition-report.js +0 -105
- package/packages/cli/validate-profile-results.js +0 -64
- package/packages/cli/validate-project-continuity.js +0 -173
- package/packages/cli/validate-project-technology.js +0 -296
- package/packages/cli/validate-release-state.js +0 -100
- package/packages/cli/validate-routing-control-examples.js +0 -79
- package/packages/cli/validate-self-service-onboarding.js +0 -159
- package/packages/project-technology/artifact-release.js +0 -738
- package/packages/project-technology/context-traversal.js +0 -684
- package/packages/project-technology/continuity.js +0 -414
- package/packages/project-technology/index.js +0 -835
- package/pilots/independent-implementation-001-conference-planning/README.md +0 -40
- package/pilots/independent-implementation-001-conference-planning/gates/results.json +0 -12
- package/pilots/independent-implementation-001-conference-planning/graph/objects.json +0 -74
- package/pilots/independent-implementation-001-conference-planning/graph/relations.json +0 -56
- package/pilots/independent-implementation-001-conference-planning/graph-seed.json +0 -65
- package/pilots/independent-implementation-001-conference-planning/graph.json +0 -37
- package/pilots/independent-implementation-001-conference-planning/reports/pilot-report.md +0 -120
- package/pilots/independent-implementation-001-conference-planning/results/context-pack.json +0 -35
- package/pilots/independent-implementation-001-conference-planning/results/graph-embryo.json +0 -81
- package/pilots/independent-implementation-001-conference-planning/results/package-validation.json +0 -7
- package/pilots/independent-implementation-001-conference-planning/results/profile-conformance-result.json +0 -28
- package/pilots/independent-implementation-001-conference-planning/results/readiness-score.json +0 -26
- package/pilots/independent-implementation-001-conference-planning/results/seed-validation.json +0 -7
- package/pilots/independent-implementation-002-software-specification/README.md +0 -40
- package/pilots/independent-implementation-002-software-specification/gates/results.json +0 -22
- package/pilots/independent-implementation-002-software-specification/graph/objects.json +0 -101
- package/pilots/independent-implementation-002-software-specification/graph/relations.json +0 -92
- package/pilots/independent-implementation-002-software-specification/graph-seed.json +0 -72
- package/pilots/independent-implementation-002-software-specification/graph.json +0 -37
- package/pilots/independent-implementation-002-software-specification/reports/pilot-report.md +0 -142
- package/pilots/independent-implementation-002-software-specification/results/context-pack.json +0 -184
- package/pilots/independent-implementation-002-software-specification/results/graph-embryo.json +0 -90
- package/pilots/independent-implementation-002-software-specification/results/package-validation.json +0 -7
- package/pilots/independent-implementation-002-software-specification/results/profile-conformance-result.json +0 -28
- package/pilots/independent-implementation-002-software-specification/results/readiness-score.json +0 -26
- package/pilots/independent-implementation-002-software-specification/results/seed-validation.json +0 -7
- package/pilots/independent-implementation-002-software-specification/reviews/semantic-completeness-review.json +0 -81
- package/pilots/independent-implementation-003-ai-employee-workflow/README.md +0 -42
- package/pilots/independent-implementation-003-ai-employee-workflow/gates/results.json +0 -30
- package/pilots/independent-implementation-003-ai-employee-workflow/graph/objects.json +0 -156
- package/pilots/independent-implementation-003-ai-employee-workflow/graph/relations.json +0 -147
- package/pilots/independent-implementation-003-ai-employee-workflow/graph-seed.json +0 -90
- package/pilots/independent-implementation-003-ai-employee-workflow/graph.json +0 -37
- package/pilots/independent-implementation-003-ai-employee-workflow/reports/pilot-report.md +0 -49
- package/pilots/independent-implementation-003-ai-employee-workflow/results/profile-conformance-result.json +0 -30
- package/pilots/independent-implementation-004-research-program/README.md +0 -41
- package/pilots/independent-implementation-004-research-program/gates/results.json +0 -21
- package/pilots/independent-implementation-004-research-program/graph/objects.json +0 -102
- package/pilots/independent-implementation-004-research-program/graph/relations.json +0 -84
- package/pilots/independent-implementation-004-research-program/graph-seed.json +0 -76
- package/pilots/independent-implementation-004-research-program/graph.json +0 -37
- package/pilots/independent-implementation-004-research-program/reports/pilot-report.md +0 -50
- package/pilots/independent-implementation-004-research-program/results/profile-conformance-result.json +0 -30
- package/pilots/independent-implementation-005-organization-governance/README.md +0 -42
- package/pilots/independent-implementation-005-organization-governance/gates/results.json +0 -20
- package/pilots/independent-implementation-005-organization-governance/graph/objects.json +0 -137
- package/pilots/independent-implementation-005-organization-governance/graph/relations.json +0 -110
- package/pilots/independent-implementation-005-organization-governance/graph-seed.json +0 -97
- package/pilots/independent-implementation-005-organization-governance/graph.json +0 -37
- package/pilots/independent-implementation-005-organization-governance/reports/pilot-report.md +0 -47
- package/pilots/independent-implementation-005-organization-governance/results/profile-conformance-result.json +0 -29
- package/playground/README.md +0 -78
- package/playground/demo-report.md +0 -84
- package/profiles/README.md +0 -28
- package/profiles/ai-employee/README.md +0 -132
- package/profiles/ai-employee/profile.json +0 -58
- package/profiles/character-layer/README.md +0 -143
- package/profiles/character-layer/profile.json +0 -46
- package/profiles/implementation-control/README.md +0 -174
- package/profiles/implementation-control/profile.json +0 -108
- package/profiles/organization-governance/README.md +0 -60
- package/profiles/organization-governance/profile.json +0 -56
- package/profiles/project-management/README.md +0 -119
- package/profiles/project-management/profile.json +0 -38
- package/profiles/skill-runtime/README.md +0 -99
- package/profiles/skill-runtime/profile.json +0 -58
- package/profiles/societal-governance/README.md +0 -129
- package/profiles/societal-governance/profile.json +0 -121
- package/profiles/software-specification/README.md +0 -142
- package/profiles/software-specification/profile.json +0 -31
- package/publications/README.md +0 -39
- package/publications/observable-self-correcting-ai-workflows/README.md +0 -105
- package/publications/preprint-note.md +0 -11
- package/publications/preprint-outline.md +0 -45
- package/publications/semantic-intent-goal-vector-control/README.md +0 -99
- package/releases/0.1.0-alpha.0.md +0 -45
- package/releases/0.1.0-alpha.1.md +0 -63
- package/releases/0.1.0-alpha.10.md +0 -93
- package/releases/0.1.0-alpha.11.md +0 -114
- package/releases/0.1.0-alpha.2.md +0 -37
- package/releases/0.1.0-alpha.3.md +0 -61
- package/releases/0.1.0-alpha.4.md +0 -53
- package/releases/0.1.0-alpha.5.md +0 -48
- package/releases/0.1.0-alpha.6.md +0 -96
- package/releases/0.1.0-alpha.7.md +0 -114
- package/releases/0.1.0-alpha.8.md +0 -92
- package/releases/0.1.0-alpha.9.md +0 -80
- package/releases/1.0.0-rc.1.md +0 -121
- package/releases/1.0.0-rc.10.md +0 -14
- package/releases/1.0.0-rc.11.md +0 -14
- package/releases/1.0.0-rc.2.md +0 -79
- package/releases/1.0.0-rc.3.md +0 -51
- package/releases/1.0.0-rc.4.md +0 -70
- package/releases/1.0.0-rc.5.md +0 -88
- package/releases/1.0.0-rc.6.md +0 -76
- package/releases/1.0.0-rc.8.md +0 -17
- package/releases/1.0.0-rc.9.md +0 -14
- package/releases/1.0.0.md +0 -23
- package/releases/1.1.0.md +0 -36
- package/releases/1.1.1.md +0 -25
- package/releases/1.2.0.md +0 -19
- package/releases/1.3.0.md +0 -16
- package/releases/README.md +0 -135
- package/releases/societal-governance-profile-proposal.md +0 -45
- package/schemas/baseline-comparison-result.schema.json +0 -87
- package/schemas/character-layer-integration.schema.json +0 -112
- package/schemas/character-layer-readiness.schema.json +0 -73
- package/schemas/context-pack.schema.json +0 -190
- package/schemas/context-traversal-receipt.schema.json +0 -64
- package/schemas/development-cockpit.schema.json +0 -74
- package/schemas/dynamic-episode-trace.schema.json +0 -153
- package/schemas/feature-implementation-traceability.schema.json +0 -80
- package/schemas/federation-health-dashboard.schema.json +0 -47
- package/schemas/gate-result.schema.json +0 -44
- package/schemas/goal-vector-quality-control.schema.json +0 -131
- package/schemas/graph-dna-alignment.schema.json +0 -49
- package/schemas/graph-embryo.schema.json +0 -51
- package/schemas/graph-lock.schema.json +0 -28
- package/schemas/graph-manifest.schema.json +0 -154
- package/schemas/graph-seed.schema.json +0 -137
- package/schemas/implementation-control-cycle.schema.json +0 -265
- package/schemas/implementation-control-loop.schema.json +0 -84
- package/schemas/launch-record.schema.json +0 -78
- package/schemas/model-portability-evidence.schema.json +0 -93
- package/schemas/multi-agent-coordination.schema.json +0 -35
- package/schemas/multi-source-quality-feedback.schema.json +0 -54
- package/schemas/object.schema.json +0 -49
- package/schemas/package-manifest.schema.json +0 -53
- package/schemas/process-control-contract.schema.json +0 -100
- package/schemas/process-transition-request.schema.json +0 -41
- package/schemas/profile.schema.json +0 -56
- package/schemas/project-technology-extension.schema.json +0 -15
- package/schemas/project-technology-target-export.schema.json +0 -35
- package/schemas/readiness-score.schema.json +0 -43
- package/schemas/recovery-resume-record.schema.json +0 -25
- package/schemas/relation.schema.json +0 -43
- package/schemas/risk-control-matrix.schema.json +0 -36
- package/schemas/route-explanation.schema.json +0 -51
- package/schemas/route-regression-result.schema.json +0 -33
- package/schemas/routing-fixture-run.schema.json +0 -45
- package/schemas/routing-fixtures.schema.json +0 -59
- package/schemas/semantic-intent-resolution.schema.json +0 -151
- package/schemas/source-boundary-contract.schema.json +0 -31
- package/schemas/technology-quality-feedback.schema.json +0 -116
- package/schemas/work-state-machine.schema.json +0 -34
- package/standard/action-runtime-boundary.md +0 -99
- package/standard/adoption-levels.md +0 -69
- package/standard/conformance-levels.md +0 -133
- package/standard/context-pack-generation.md +0 -184
- package/standard/development-cockpit.md +0 -67
- package/standard/dynamic-episode-layer.md +0 -113
- package/standard/dynamic-layer-code-generation.md +0 -87
- package/standard/episode-trace.md +0 -97
- package/standard/evidence-provenance.md +0 -128
- package/standard/feature-implementation-traceability.md +0 -68
- package/standard/federation-health.md +0 -42
- package/standard/feedback-learning-gate.md +0 -101
- package/standard/goal-vector-quality-control.md +0 -128
- package/standard/governance.md +0 -137
- package/standard/graph-as-ai-brain.md +0 -81
- package/standard/graph-dna-alignment.md +0 -50
- package/standard/graph-dna.md +0 -70
- package/standard/graph-embryo.md +0 -69
- package/standard/graph-seed.md +0 -122
- package/standard/hybrid-source-of-truth.md +0 -91
- package/standard/implementation-control-cycles.md +0 -194
- package/standard/implementation-control.md +0 -102
- package/standard/launch-record.md +0 -53
- package/standard/lifecycle-readiness.md +0 -159
- package/standard/multi-agent-coordination.md +0 -50
- package/standard/multi-source-quality-feedback.md +0 -71
- package/standard/object-model.md +0 -167
- package/standard/organization-governance.md +0 -83
- package/standard/process-control-contract.md +0 -53
- package/standard/profile-boundaries.md +0 -225
- package/standard/profiles.md +0 -253
- package/standard/project-technology.md +0 -186
- package/standard/projection-views.md +0 -69
- package/standard/recovery-resume.md +0 -49
- package/standard/relation-model.md +0 -149
- package/standard/risk-control-matrix.md +0 -53
- package/standard/route-explanation.md +0 -35
- package/standard/route-regression.md +0 -33
- package/standard/routing-fixtures.md +0 -54
- package/standard/runtime-enablement.md +0 -85
- package/standard/semantic-intent-resolution.md +0 -91
- package/standard/source-boundary-contract.md +0 -49
- package/standard/standard-v0.1.md +0 -132
- package/standard/technology-quality-feedback.md +0 -97
- package/standard/test-suite.md +0 -159
- package/standard/work-state-machine.md +0 -62
- package/templates/README.md +0 -77
- package/templates/ai-employee-starter/README.md +0 -9
- package/templates/ai-employee-starter/gates/results.json +0 -12
- package/templates/ai-employee-starter/graph/objects.json +0 -90
- package/templates/ai-employee-starter/graph/relations.json +0 -47
- package/templates/ai-employee-starter/graph.json +0 -37
- package/templates/character-layer-starter/README.md +0 -39
- package/templates/character-layer-starter/gates/results.json +0 -20
- package/templates/character-layer-starter/graph/objects.json +0 -308
- package/templates/character-layer-starter/graph/relations.json +0 -344
- package/templates/character-layer-starter/graph.json +0 -37
- package/templates/organization-governance-starter/README.md +0 -9
- package/templates/organization-governance-starter/gates/results.json +0 -12
- package/templates/organization-governance-starter/graph/objects.json +0 -112
- package/templates/organization-governance-starter/graph/relations.json +0 -65
- package/templates/organization-governance-starter/graph.json +0 -37
- package/templates/research-program-starter/README.md +0 -9
- package/templates/research-program-starter/gates/results.json +0 -12
- package/templates/research-program-starter/graph/objects.json +0 -79
- package/templates/research-program-starter/graph/relations.json +0 -47
- package/templates/research-program-starter/graph.json +0 -37
- package/templates/software-project-starter/README.md +0 -9
- package/templates/software-project-starter/gates/results.json +0 -12
- package/templates/software-project-starter/graph/objects.json +0 -79
- package/templates/software-project-starter/graph/relations.json +0 -47
- package/templates/software-project-starter/graph.json +0 -37
|
@@ -1,835 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const crypto = require("crypto");
|
|
4
|
-
const fs = require("fs");
|
|
5
|
-
const os = require("os");
|
|
6
|
-
const path = require("path");
|
|
7
|
-
const { spawnSync } = require("child_process");
|
|
8
|
-
const {
|
|
9
|
-
FORMAT,
|
|
10
|
-
SCHEMA_ID,
|
|
11
|
-
SCHEMA_VERSION,
|
|
12
|
-
jsonBytes,
|
|
13
|
-
readJson,
|
|
14
|
-
validateManifest,
|
|
15
|
-
} = require("../cli/graph-manifest");
|
|
16
|
-
const traversal = require("./context-traversal");
|
|
17
|
-
const continuity = require("./continuity");
|
|
18
|
-
const artifacts = require("./artifact-release");
|
|
19
|
-
|
|
20
|
-
const CONTRACT_VERSION = "1.0.0";
|
|
21
|
-
const EXTENSION_KEY = "mirai.project_technology";
|
|
22
|
-
const LEGACY_EXTENSION_KEY = "simai.project_technology";
|
|
23
|
-
const LOCAL_DIR = path.join(".mirai-graph", "project-technology");
|
|
24
|
-
const LEGACY_LOCAL_DIR = path.join(".simai", "project-technology");
|
|
25
|
-
const INVENTORY_FILE = "inventory.json";
|
|
26
|
-
const BINDING_FILE = "target-provider-binding.json";
|
|
27
|
-
const IMPORT_DIR = "provider-exports";
|
|
28
|
-
const EXPORT_FILE = path.join("graph", "generated", "project-technology", "target-provider-export.json");
|
|
29
|
-
const TARGET_DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
|
|
30
|
-
const REVISION_RE = /^[0-9a-f]{40}$/;
|
|
31
|
-
const REF_RE = /^[A-Za-z0-9][A-Za-z0-9._:/@?=+*-]{1,255}$/;
|
|
32
|
-
const ACCEPTED_LIFECYCLES = new Set(["accepted", "implemented", "validated", "operating", "evolving"]);
|
|
33
|
-
const ACTIONS = new Set(["create", "modify", "delete", "rename", "migrate", "test", "document"]);
|
|
34
|
-
const TARGET_EXPORT_KEYS = new Set([
|
|
35
|
-
"schema_version", "target_id", "semantic_digest", "provider_revision",
|
|
36
|
-
"decision_refs", "goal_binding", "requirement_bindings", "constraint_ids",
|
|
37
|
-
"non_goal_ids", "deferred_boundary_ids", "allowed_change_scope",
|
|
38
|
-
"architecture_contract", "execution_contract_digest",
|
|
39
|
-
]);
|
|
40
|
-
const SECRET_PARTS = [".env", "credential", "secret", "token", "password", "private-key", "id_rsa", ".pem", ".p12"];
|
|
41
|
-
const EXCLUDED_PARTS = new Set([".git", ".mirai-graph", ".simai", "node_modules", "vendor", "dist", "build", "coverage", "generated"]);
|
|
42
|
-
|
|
43
|
-
function sortValue(value) {
|
|
44
|
-
if (Array.isArray(value)) return value.map(sortValue);
|
|
45
|
-
if (!value || typeof value !== "object") return value;
|
|
46
|
-
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, sortValue(value[key])]));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function canonicalBytes(value) {
|
|
50
|
-
return `${JSON.stringify(sortValue(value), null, 2)}\n`;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function sha256(value, prefix = false) {
|
|
54
|
-
const digest = crypto.createHash("sha256").update(Buffer.isBuffer(value) ? value : Buffer.from(String(value))).digest("hex");
|
|
55
|
-
return prefix ? `sha256:${digest}` : digest;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function atomicWrite(filePath, content) {
|
|
59
|
-
const bytes = Buffer.isBuffer(content) ? content : Buffer.from(String(content));
|
|
60
|
-
if (fs.existsSync(filePath) && fs.readFileSync(filePath).equals(bytes)) return false;
|
|
61
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
62
|
-
const temp = path.join(path.dirname(filePath), `.${path.basename(filePath)}.${process.pid}.${crypto.randomBytes(4).toString("hex")}`);
|
|
63
|
-
fs.writeFileSync(temp, bytes);
|
|
64
|
-
fs.renameSync(temp, filePath);
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function result(operation, operationMode, status, extra = {}) {
|
|
69
|
-
return {
|
|
70
|
-
schema_version: "1.0.0",
|
|
71
|
-
operation_id: `mirai.project_technology.${operation}`,
|
|
72
|
-
operation_mode: operationMode,
|
|
73
|
-
status,
|
|
74
|
-
changed: false,
|
|
75
|
-
blockers: [],
|
|
76
|
-
warnings: [],
|
|
77
|
-
next_action: "none",
|
|
78
|
-
...extra,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function git(repo, ...args) {
|
|
83
|
-
const completed = spawnSync("git", args, {
|
|
84
|
-
cwd: repo,
|
|
85
|
-
encoding: "utf8",
|
|
86
|
-
maxBuffer: 64 * 1024 * 1024,
|
|
87
|
-
});
|
|
88
|
-
return completed.status === 0 ? completed.stdout.trim() : "";
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function normalizeRepo(repo) {
|
|
92
|
-
return path.resolve(repo || ".");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function runtimeRoot(repo, manifest = null, options = {}) {
|
|
96
|
-
return continuity.stateRoot(repo, manifest || readManifest(repo).manifest, options);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function legacyRuntimeState(repo) {
|
|
100
|
-
const root = path.join(repo, LOCAL_DIR);
|
|
101
|
-
return {
|
|
102
|
-
root,
|
|
103
|
-
present: fs.existsSync(root),
|
|
104
|
-
inventory: path.join(root, INVENTORY_FILE),
|
|
105
|
-
binding: path.join(root, BINDING_FILE),
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function migrateProjectLocalRuntime(repo, manifest, root) {
|
|
110
|
-
const legacy = legacyRuntimeState(repo);
|
|
111
|
-
if (!legacy.present) return { changed: false, blockers: [], migration_ref: null };
|
|
112
|
-
const blockers = [];
|
|
113
|
-
let changed = false;
|
|
114
|
-
if (fs.existsSync(legacy.binding)) {
|
|
115
|
-
const binding = readJson(legacy.binding);
|
|
116
|
-
const identity = bindingValues(binding); blockers.push(...identity.blockers);
|
|
117
|
-
const ref = String(binding.provider_export_ref || "");
|
|
118
|
-
const exportPath = ref && !path.isAbsolute(ref) ? path.resolve(repo, ref) : null;
|
|
119
|
-
const exported = exportPath ? readExport(exportPath) : { export: {}, blockers: ["legacy_provider_export_missing"] };
|
|
120
|
-
blockers.push(...exported.blockers);
|
|
121
|
-
for (const key of Object.keys(identity.values)) if (exported.export[key] !== identity.values[key]) blockers.push(`legacy_${key}_mismatch`);
|
|
122
|
-
if (!blockers.length) {
|
|
123
|
-
const exportBytes = canonicalBytes(exported.export);
|
|
124
|
-
const exportSha = sha256(exportBytes);
|
|
125
|
-
changed = atomicWrite(path.join(root, IMPORT_DIR, `${exportSha}.json`), exportBytes) || changed;
|
|
126
|
-
changed = atomicWrite(path.join(root, BINDING_FILE), canonicalBytes({
|
|
127
|
-
schema_version: "1.0.0", ...identity.values,
|
|
128
|
-
provider_export_ref: `host-local://${IMPORT_DIR}/${exportSha}.json`,
|
|
129
|
-
provider_export_sha256: exportSha,
|
|
130
|
-
})) || changed;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
if (blockers.length) return { changed: false, blockers: [...new Set(blockers)].sort(), migration_ref: null };
|
|
134
|
-
const receipt = {
|
|
135
|
-
schema_version: "1.0.0",
|
|
136
|
-
status: "migrated",
|
|
137
|
-
repository_id: manifest.id,
|
|
138
|
-
source: LOCAL_DIR,
|
|
139
|
-
source_preserved: true,
|
|
140
|
-
active_runtime: "host-local",
|
|
141
|
-
};
|
|
142
|
-
const receiptName = `project-local-runtime-${sha256(canonicalBytes(receipt)).slice(0, 16)}.json`;
|
|
143
|
-
changed = atomicWrite(path.join(root, "migrations", receiptName), canonicalBytes(receipt)) || changed;
|
|
144
|
-
return { changed, blockers: [], migration_ref: `host-local://migrations/${receiptName}` };
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function readManifest(repo) {
|
|
148
|
-
const manifestPath = path.join(repo, "graph.json");
|
|
149
|
-
if (!fs.existsSync(manifestPath)) return { manifest: null, blockers: ["graph_manifest_missing"] };
|
|
150
|
-
if (fs.lstatSync(manifestPath).isSymbolicLink()) return { manifest: null, blockers: ["graph_manifest_symlink_unsafe"] };
|
|
151
|
-
let manifest;
|
|
152
|
-
try { manifest = readJson(manifestPath); } catch (_) { return { manifest: null, blockers: ["graph_manifest_invalid"] }; }
|
|
153
|
-
const blockers = validateManifest(manifest, repo);
|
|
154
|
-
return { manifest, blockers };
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function extensionContract() {
|
|
158
|
-
return {
|
|
159
|
-
contract_version: CONTRACT_VERSION,
|
|
160
|
-
enabled: true,
|
|
161
|
-
context_policy: "task_scoped",
|
|
162
|
-
source_boundary: "hybrid_sot",
|
|
163
|
-
continuity_policy: "task_boundary",
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function extensionState(manifest) {
|
|
168
|
-
const extensions = manifest && manifest.extensions && typeof manifest.extensions === "object" ? manifest.extensions : {};
|
|
169
|
-
const current = extensions[EXTENSION_KEY];
|
|
170
|
-
const legacy = extensions[LEGACY_EXTENSION_KEY];
|
|
171
|
-
if (current && typeof current === "object") {
|
|
172
|
-
const blockers = [];
|
|
173
|
-
if (current.contract_version !== CONTRACT_VERSION) blockers.push("project_technology_contract_version_mismatch");
|
|
174
|
-
if (current.context_policy !== "task_scoped") blockers.push("project_technology_context_policy_mismatch");
|
|
175
|
-
if (current.source_boundary !== "hybrid_sot") blockers.push("project_technology_source_boundary_mismatch");
|
|
176
|
-
return { contract: current, legacy: false, blockers };
|
|
177
|
-
}
|
|
178
|
-
if (legacy && typeof legacy === "object") return { contract: legacy, legacy: true, blockers: ["project_technology_migration_required"] };
|
|
179
|
-
return { contract: null, legacy: false, blockers: ["project_technology_not_configured"] };
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function boundedRefs(value, field, blockers, options = {}) {
|
|
183
|
-
const required = options.required !== false;
|
|
184
|
-
if (!Array.isArray(value) || (required && value.length === 0)) {
|
|
185
|
-
blockers.push(`provider_contract_${field}_empty`);
|
|
186
|
-
return [];
|
|
187
|
-
}
|
|
188
|
-
const output = [];
|
|
189
|
-
for (const item of value) {
|
|
190
|
-
if (typeof item !== "string" || !REF_RE.test(item) || (!options.allowGlob && /[*]/.test(item))) {
|
|
191
|
-
blockers.push(`provider_contract_${field}_unsafe`);
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
output.push(item);
|
|
195
|
-
}
|
|
196
|
-
return [...new Set(output)].sort();
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function dependencyCycle(relations) {
|
|
200
|
-
const edges = new Map();
|
|
201
|
-
for (const relation of relations) {
|
|
202
|
-
const parts = relation.split("->");
|
|
203
|
-
if (parts.length !== 2 || !parts[0] || !parts[1]) return true;
|
|
204
|
-
if (!edges.has(parts[0])) edges.set(parts[0], new Set());
|
|
205
|
-
edges.get(parts[0]).add(parts[1]);
|
|
206
|
-
}
|
|
207
|
-
const visited = new Set();
|
|
208
|
-
const visiting = new Set();
|
|
209
|
-
function visit(node) {
|
|
210
|
-
if (visiting.has(node)) return true;
|
|
211
|
-
if (visited.has(node)) return false;
|
|
212
|
-
visiting.add(node);
|
|
213
|
-
for (const child of edges.get(node) || []) if (visit(child)) return true;
|
|
214
|
-
visiting.delete(node); visited.add(node); return false;
|
|
215
|
-
}
|
|
216
|
-
return [...edges.keys()].some(visit);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function boundedRelations(value, field, blockers) {
|
|
220
|
-
if (!Array.isArray(value)) {
|
|
221
|
-
blockers.push(`provider_contract_${field}_empty`);
|
|
222
|
-
return [];
|
|
223
|
-
}
|
|
224
|
-
const output = [];
|
|
225
|
-
for (const relation of value) {
|
|
226
|
-
if (typeof relation !== "string") { blockers.push(`provider_contract_${field}_unsafe`); continue; }
|
|
227
|
-
const parts = relation.split("->");
|
|
228
|
-
if (parts.length !== 2 || parts.some((part) => !REF_RE.test(part))) {
|
|
229
|
-
blockers.push(`provider_contract_${field}_unsafe`); continue;
|
|
230
|
-
}
|
|
231
|
-
output.push(`${parts[0]}->${parts[1]}`);
|
|
232
|
-
}
|
|
233
|
-
return [...new Set(output)].sort();
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function normalizeExecutionContract(value) {
|
|
237
|
-
const blockers = [];
|
|
238
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return { contract: {}, blockers: ["provider_execution_contract_missing"] };
|
|
239
|
-
const allowed = new Set(["decision_refs", "goal_binding", "requirement_bindings", "constraint_ids", "non_goal_ids", "deferred_boundary_ids", "allowed_change_scope", "architecture_contract"]);
|
|
240
|
-
if (Object.keys(value).some((key) => !allowed.has(key))) blockers.push("provider_execution_contract_not_bounded");
|
|
241
|
-
|
|
242
|
-
const decisionRefs = boundedRefs(value.decision_refs, "decision_refs", blockers);
|
|
243
|
-
const goal = value.goal_binding && typeof value.goal_binding === "object" && !Array.isArray(value.goal_binding) ? value.goal_binding : {};
|
|
244
|
-
if (Object.keys(goal).some((key) => !["goal_id", "done_when_ids"].includes(key))) blockers.push("provider_contract_goal_binding_not_bounded");
|
|
245
|
-
const goalId = String(goal.goal_id || "").trim();
|
|
246
|
-
if (!REF_RE.test(goalId)) blockers.push("provider_contract_goal_id_missing_or_unsafe");
|
|
247
|
-
const doneWhenIds = boundedRefs(goal.done_when_ids, "done_when_ids", blockers);
|
|
248
|
-
|
|
249
|
-
const requirementBindings = [];
|
|
250
|
-
if (!Array.isArray(value.requirement_bindings) || value.requirement_bindings.length === 0) blockers.push("provider_contract_requirement_bindings_empty");
|
|
251
|
-
else {
|
|
252
|
-
const seen = new Set();
|
|
253
|
-
for (const item of value.requirement_bindings) {
|
|
254
|
-
if (!item || typeof item !== "object" || Array.isArray(item) || Object.keys(item).some((key) => !["requirement_id", "acceptance_ids", "done_when_ids"].includes(key))) {
|
|
255
|
-
blockers.push("provider_contract_requirement_binding_invalid"); continue;
|
|
256
|
-
}
|
|
257
|
-
const requirementId = String(item.requirement_id || "").trim();
|
|
258
|
-
if (!REF_RE.test(requirementId) || seen.has(requirementId)) { blockers.push("provider_contract_requirement_id_missing_duplicate_or_unsafe"); continue; }
|
|
259
|
-
seen.add(requirementId);
|
|
260
|
-
const acceptanceIds = boundedRefs(item.acceptance_ids, "acceptance_ids", blockers);
|
|
261
|
-
const linkedDoneWhen = boundedRefs(item.done_when_ids, "requirement_done_when_ids", blockers);
|
|
262
|
-
if (linkedDoneWhen.some((id) => !doneWhenIds.includes(id))) blockers.push("provider_contract_requirement_done_when_outside_goal");
|
|
263
|
-
requirementBindings.push({ requirement_id: requirementId, acceptance_ids: acceptanceIds, done_when_ids: linkedDoneWhen });
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
requirementBindings.sort((a, b) => a.requirement_id.localeCompare(b.requirement_id));
|
|
267
|
-
|
|
268
|
-
const constraintIds = boundedRefs(value.constraint_ids, "constraint_ids", blockers);
|
|
269
|
-
const nonGoalIds = boundedRefs(value.non_goal_ids, "non_goal_ids", blockers);
|
|
270
|
-
const deferredIds = boundedRefs(value.deferred_boundary_ids, "deferred_boundary_ids", blockers);
|
|
271
|
-
const scopes = [];
|
|
272
|
-
if (!Array.isArray(value.allowed_change_scope) || value.allowed_change_scope.length === 0) blockers.push("provider_contract_allowed_change_scope_empty");
|
|
273
|
-
else for (const item of value.allowed_change_scope) {
|
|
274
|
-
if (!item || typeof item !== "object" || Array.isArray(item) || Object.keys(item).some((key) => !["repository_id", "owner_id", "package_id", "file_patterns", "actions"].includes(key))) {
|
|
275
|
-
blockers.push("provider_contract_allowed_change_scope_invalid"); continue;
|
|
276
|
-
}
|
|
277
|
-
const ids = Object.fromEntries(["repository_id", "owner_id", "package_id"].map((key) => [key, String(item[key] || "").trim()]));
|
|
278
|
-
if (Object.values(ids).some((id) => !REF_RE.test(id))) { blockers.push("provider_contract_scope_identity_missing_or_unsafe"); continue; }
|
|
279
|
-
const patterns = boundedRefs(item.file_patterns, "scope_file_patterns", blockers, { allowGlob: true });
|
|
280
|
-
if (patterns.some((entry) => path.isAbsolute(entry) || entry.split(/[\\/]+/).includes("..") || entry.split(/[\\/]+/)[0] === "source")) blockers.push("provider_contract_scope_file_pattern_unsafe");
|
|
281
|
-
const actions = boundedRefs(item.actions, "scope_actions", blockers);
|
|
282
|
-
if (actions.some((action) => !ACTIONS.has(action))) blockers.push("provider_contract_scope_action_unsupported");
|
|
283
|
-
scopes.push({ ...ids, file_patterns: patterns, actions });
|
|
284
|
-
}
|
|
285
|
-
scopes.sort((a, b) => canonicalBytes(a).localeCompare(canonicalBytes(b)));
|
|
286
|
-
|
|
287
|
-
const architecture = value.architecture_contract && typeof value.architecture_contract === "object" && !Array.isArray(value.architecture_contract) ? value.architecture_contract : {};
|
|
288
|
-
const architectureAllowed = new Set([
|
|
289
|
-
"contract_ref", "acceptance_ref", "architecture_owner_id", "lifecycle", "owner_ids", "component_ids",
|
|
290
|
-
"package_ids", "capability_ids", "ownership_boundaries", "required_relations",
|
|
291
|
-
"allowed_relations", "forbidden_relations", "required_dependencies", "forbidden_dependencies",
|
|
292
|
-
]);
|
|
293
|
-
if (Object.keys(architecture).some((key) => !architectureAllowed.has(key))) blockers.push("provider_architecture_contract_not_bounded");
|
|
294
|
-
const contractRef = String(architecture.contract_ref || "").trim();
|
|
295
|
-
const acceptanceRef = String(architecture.acceptance_ref || "").trim();
|
|
296
|
-
const architectureOwnerId = String(architecture.architecture_owner_id || "").trim();
|
|
297
|
-
const lifecycle = String(architecture.lifecycle || "").trim();
|
|
298
|
-
if (!REF_RE.test(contractRef)) blockers.push("provider_architecture_contract_ref_missing_or_unsafe");
|
|
299
|
-
if (!REF_RE.test(acceptanceRef)) blockers.push("provider_architecture_acceptance_ref_missing_or_unsafe");
|
|
300
|
-
if (!REF_RE.test(architectureOwnerId)) blockers.push("provider_architecture_owner_missing_or_unsafe");
|
|
301
|
-
if (!ACCEPTED_LIFECYCLES.has(lifecycle)) blockers.push("provider_architecture_not_accepted");
|
|
302
|
-
const ownerIds = boundedRefs(architecture.owner_ids, "architecture_owner_ids", blockers);
|
|
303
|
-
const componentIds = boundedRefs(architecture.component_ids, "architecture_component_ids", blockers);
|
|
304
|
-
const packageIds = boundedRefs(architecture.package_ids, "architecture_package_ids", blockers);
|
|
305
|
-
const capabilityIds = boundedRefs(architecture.capability_ids, "architecture_capability_ids", blockers);
|
|
306
|
-
const ownershipBoundaries = [];
|
|
307
|
-
if (!Array.isArray(architecture.ownership_boundaries) || architecture.ownership_boundaries.length === 0) blockers.push("provider_architecture_ownership_boundaries_empty");
|
|
308
|
-
else for (const boundary of architecture.ownership_boundaries) {
|
|
309
|
-
const keys = ["subject_ref", "data_owner", "access_owner", "lifecycle_owner", "interface_owner", "runtime_owner"];
|
|
310
|
-
if (!boundary || typeof boundary !== "object" || Array.isArray(boundary) || Object.keys(boundary).some((key) => !keys.includes(key))) {
|
|
311
|
-
blockers.push("provider_architecture_ownership_boundary_invalid"); continue;
|
|
312
|
-
}
|
|
313
|
-
const normalizedBoundary = Object.fromEntries(keys.map((key) => [key, String(boundary[key] || "").trim()]));
|
|
314
|
-
if (Object.values(normalizedBoundary).some((id) => !REF_RE.test(id))) {
|
|
315
|
-
blockers.push("provider_architecture_ownership_boundary_unsafe"); continue;
|
|
316
|
-
}
|
|
317
|
-
if (![...componentIds, ...packageIds, ...capabilityIds].includes(normalizedBoundary.subject_ref)) blockers.push("provider_architecture_ownership_subject_unknown");
|
|
318
|
-
if (["data_owner", "access_owner", "lifecycle_owner", "interface_owner", "runtime_owner"].some((key) => !ownerIds.includes(normalizedBoundary[key]))) blockers.push("provider_architecture_boundary_owner_unapproved");
|
|
319
|
-
ownershipBoundaries.push(normalizedBoundary);
|
|
320
|
-
}
|
|
321
|
-
ownershipBoundaries.sort((a, b) => canonicalBytes(a).localeCompare(canonicalBytes(b)));
|
|
322
|
-
const requiredRelations = boundedRelations(architecture.required_relations, "architecture_required_relations", blockers);
|
|
323
|
-
const allowedRelations = boundedRelations(architecture.allowed_relations, "architecture_allowed_relations", blockers);
|
|
324
|
-
const forbiddenRelations = boundedRelations(architecture.forbidden_relations, "architecture_forbidden_relations", blockers);
|
|
325
|
-
if (requiredRelations.some((item) => forbiddenRelations.includes(item))) blockers.push("provider_architecture_forbidden_relation");
|
|
326
|
-
const requiredDependencies = boundedRelations(architecture.required_dependencies, "required_dependencies", blockers);
|
|
327
|
-
const forbiddenDependencies = boundedRelations(architecture.forbidden_dependencies, "forbidden_dependencies", blockers);
|
|
328
|
-
if (requiredDependencies.some((item) => forbiddenDependencies.includes(item))) blockers.push("provider_architecture_forbidden_dependency");
|
|
329
|
-
if (dependencyCycle(requiredDependencies)) blockers.push("provider_architecture_dependency_cycle");
|
|
330
|
-
if (scopes.some((scope) => !ownerIds.includes(scope.owner_id))) blockers.push("provider_contract_scope_owner_unapproved");
|
|
331
|
-
if (scopes.some((scope) => !packageIds.includes(scope.package_id))) blockers.push("provider_contract_scope_package_unapproved");
|
|
332
|
-
|
|
333
|
-
const contract = {
|
|
334
|
-
decision_refs: decisionRefs,
|
|
335
|
-
goal_binding: { goal_id: goalId, done_when_ids: doneWhenIds },
|
|
336
|
-
requirement_bindings: requirementBindings,
|
|
337
|
-
constraint_ids: constraintIds,
|
|
338
|
-
non_goal_ids: nonGoalIds,
|
|
339
|
-
deferred_boundary_ids: deferredIds,
|
|
340
|
-
allowed_change_scope: scopes,
|
|
341
|
-
architecture_contract: {
|
|
342
|
-
contract_ref: contractRef,
|
|
343
|
-
acceptance_ref: acceptanceRef,
|
|
344
|
-
architecture_owner_id: architectureOwnerId,
|
|
345
|
-
lifecycle,
|
|
346
|
-
owner_ids: ownerIds,
|
|
347
|
-
component_ids: componentIds,
|
|
348
|
-
package_ids: packageIds,
|
|
349
|
-
capability_ids: capabilityIds,
|
|
350
|
-
ownership_boundaries: ownershipBoundaries,
|
|
351
|
-
required_relations: requiredRelations,
|
|
352
|
-
allowed_relations: allowedRelations,
|
|
353
|
-
forbidden_relations: forbiddenRelations,
|
|
354
|
-
required_dependencies: requiredDependencies,
|
|
355
|
-
forbidden_dependencies: forbiddenDependencies,
|
|
356
|
-
},
|
|
357
|
-
};
|
|
358
|
-
return { contract, blockers: [...new Set(blockers)].sort() };
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
function specObjectFiles(repo, manifest) {
|
|
362
|
-
const found = [];
|
|
363
|
-
const indexCandidates = [path.join(repo, "graph", "specs", "index.json")];
|
|
364
|
-
if (manifest && manifest.graph) for (const item of manifest.graph.objects || []) if (item.endsWith("index.json")) indexCandidates.push(path.join(repo, item));
|
|
365
|
-
for (const indexPath of [...new Set(indexCandidates)]) {
|
|
366
|
-
if (!fs.existsSync(indexPath)) continue;
|
|
367
|
-
if (fs.lstatSync(indexPath).isSymbolicLink()) continue;
|
|
368
|
-
try {
|
|
369
|
-
const index = readJson(indexPath);
|
|
370
|
-
for (const ref of [...(index.object_files || []), ...(index.objects || [])]) {
|
|
371
|
-
const absolute = path.isAbsolute(ref) ? ref : ref.startsWith("graph/specs/") ? path.join(repo, ref) : path.join(path.dirname(indexPath), ref);
|
|
372
|
-
if (fs.existsSync(absolute) && !fs.lstatSync(absolute).isSymbolicLink() && fs.statSync(absolute).isFile()) found.push(absolute);
|
|
373
|
-
}
|
|
374
|
-
} catch (_) { /* reported by caller if no usable objects */ }
|
|
375
|
-
}
|
|
376
|
-
if (found.length === 0) {
|
|
377
|
-
const objectsDir = path.join(repo, "graph", "specs", "objects");
|
|
378
|
-
if (fs.existsSync(objectsDir)) for (const name of fs.readdirSync(objectsDir).sort()) {
|
|
379
|
-
const candidate = path.join(objectsDir, name);
|
|
380
|
-
if (name.endsWith(".json") && !fs.lstatSync(candidate).isSymbolicLink()) found.push(candidate);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return [...new Set(found)];
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
function targetContract(repo, targetId, semanticDigest, manifest) {
|
|
387
|
-
const blockers = [];
|
|
388
|
-
const matches = [];
|
|
389
|
-
for (const file of specObjectFiles(repo, manifest)) {
|
|
390
|
-
try { const object = readJson(file); if (object.id === targetId) matches.push({ object, file }); } catch (_) { blockers.push("provider_target_object_invalid"); }
|
|
391
|
-
}
|
|
392
|
-
if (matches.length !== 1) return { contract: {}, blockers: [...blockers, "provider_target_object_count_invalid"] };
|
|
393
|
-
const target = matches[0].object;
|
|
394
|
-
const relative = path.relative(repo, matches[0].file).split(path.sep).join("/");
|
|
395
|
-
if (!trackedFiles(repo).includes(relative)) blockers.push("provider_target_object_not_revision_bound");
|
|
396
|
-
const clean = spawnSync("git", ["diff", "--quiet", "HEAD", "--", relative], { cwd: repo });
|
|
397
|
-
if (clean.status !== 0) blockers.push("provider_target_object_not_revision_bound");
|
|
398
|
-
if (!["system", "contract"].includes(target.tz_role)) blockers.push("provider_target_role_not_canonical");
|
|
399
|
-
if (!ACCEPTED_LIFECYCLES.has(target.lifecycle)) blockers.push("provider_target_not_accepted");
|
|
400
|
-
if (String(target.semantic_digest || "").toLowerCase() !== semanticDigest) blockers.push("provider_target_semantic_digest_mismatch");
|
|
401
|
-
const normalized = normalizeExecutionContract(target.provider_execution_contract);
|
|
402
|
-
return { contract: normalized.contract, blockers: [...new Set([...blockers, ...normalized.blockers])].sort() };
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
function bindingValues(options) {
|
|
406
|
-
const values = {
|
|
407
|
-
target_id: String(options.target_id || options.targetId || "").trim(),
|
|
408
|
-
semantic_digest: String(options.semantic_digest || options.semanticDigest || "").trim().toLowerCase(),
|
|
409
|
-
provider_revision: String(options.provider_revision || options.providerRevision || "").trim().toLowerCase(),
|
|
410
|
-
};
|
|
411
|
-
const blockers = [];
|
|
412
|
-
if (!REF_RE.test(values.target_id)) blockers.push("target_id_invalid");
|
|
413
|
-
if (!TARGET_DIGEST_RE.test(values.semantic_digest)) blockers.push("semantic_digest_invalid");
|
|
414
|
-
if (!REVISION_RE.test(values.provider_revision)) blockers.push("provider_revision_invalid");
|
|
415
|
-
return { values, blockers };
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
function readExport(filePath) {
|
|
419
|
-
const blockers = [];
|
|
420
|
-
if (!filePath || !fs.existsSync(filePath) || fs.lstatSync(filePath).isSymbolicLink()) return { export: {}, blockers: ["provider_export_missing_or_unsafe"] };
|
|
421
|
-
const bytes = fs.readFileSync(filePath);
|
|
422
|
-
if (bytes.length > 64 * 1024) return { export: {}, blockers: ["provider_export_too_large"] };
|
|
423
|
-
let payload;
|
|
424
|
-
try { payload = JSON.parse(bytes.toString("utf8").replace(/^\uFEFF/, "")); } catch (_) { return { export: {}, blockers: ["provider_export_invalid"] }; }
|
|
425
|
-
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return { export: {}, blockers: ["provider_export_invalid"] };
|
|
426
|
-
if (Object.keys(payload).some((key) => !TARGET_EXPORT_KEYS.has(key))) blockers.push("provider_export_not_bounded");
|
|
427
|
-
const identity = bindingValues(payload); blockers.push(...identity.blockers);
|
|
428
|
-
const executionFields = [
|
|
429
|
-
"decision_refs", "goal_binding", "requirement_bindings", "constraint_ids",
|
|
430
|
-
"non_goal_ids", "deferred_boundary_ids", "allowed_change_scope", "architecture_contract",
|
|
431
|
-
];
|
|
432
|
-
const normalized = normalizeExecutionContract(Object.fromEntries(executionFields.map((key) => [key, payload[key]])));
|
|
433
|
-
blockers.push(...normalized.blockers);
|
|
434
|
-
const digest = sha256(canonicalBytes(normalized.contract));
|
|
435
|
-
if (!payload.execution_contract_digest) blockers.push("provider_execution_contract_digest_missing");
|
|
436
|
-
else if (payload.execution_contract_digest !== digest) blockers.push("provider_execution_contract_digest_mismatch");
|
|
437
|
-
return { export: { schema_version: "1.0.0", ...identity.values, ...normalized.contract, execution_contract_digest: digest }, blockers: [...new Set(blockers)].sort(), raw_sha256: sha256(bytes) };
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
function trackedFiles(repo) {
|
|
441
|
-
const tracked = git(repo, "ls-files", "-z");
|
|
442
|
-
return tracked ? tracked.split("\0").filter(Boolean) : [];
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
function safeTrackedFile(relative) {
|
|
446
|
-
const lowered = relative.toLowerCase();
|
|
447
|
-
const parts = relative.split(/[\\/]+/);
|
|
448
|
-
if (parts.some((part) => EXCLUDED_PARTS.has(part))) return false;
|
|
449
|
-
if (parts[0] === "source" && parts[1] === "private") return false;
|
|
450
|
-
return !SECRET_PARTS.some((part) => lowered.includes(part));
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function inventory(repo) {
|
|
454
|
-
const entries = [];
|
|
455
|
-
for (const relative of trackedFiles(repo).filter(safeTrackedFile).sort()) {
|
|
456
|
-
const absolute = path.join(repo, relative);
|
|
457
|
-
if (!fs.existsSync(absolute) || fs.lstatSync(absolute).isSymbolicLink() || !fs.statSync(absolute).isFile()) continue;
|
|
458
|
-
const bytes = fs.readFileSync(absolute);
|
|
459
|
-
entries.push({ path: relative.split(path.sep).join("/"), bytes: bytes.length, sha256: sha256(bytes) });
|
|
460
|
-
}
|
|
461
|
-
const payload = {
|
|
462
|
-
schema_version: "1.0.0",
|
|
463
|
-
repository_id: readManifest(repo).manifest?.id || path.basename(repo),
|
|
464
|
-
revision: git(repo, "rev-parse", "HEAD") || null,
|
|
465
|
-
files: entries,
|
|
466
|
-
};
|
|
467
|
-
payload.inventory_digest = sha256(canonicalBytes(payload), true);
|
|
468
|
-
return payload;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
function context(repoArg, options = {}) {
|
|
472
|
-
if (options.phase === "expand") return traversal.expandContext(repoArg, options.traversalReceipt, options.selectedIds, options);
|
|
473
|
-
if (options.phase === "compile") return traversal.compileContext(repoArg, options.traversalReceipt, options.selection, options);
|
|
474
|
-
if (options.phase === "verify") return traversal.verifyContext(repoArg, options.contextPack, options.usageEvidence, options);
|
|
475
|
-
if (options.phase === "discover") return traversal.discoverContext(repoArg, options.task, options);
|
|
476
|
-
const discovered = traversal.discoverContext(repoArg, options.task, options);
|
|
477
|
-
const nodes = new Map((discovered.traversal_receipt?.nodes || []).map((node) => [node.id, node]));
|
|
478
|
-
return {
|
|
479
|
-
...discovered,
|
|
480
|
-
operation_id: "mirai.project_technology.context",
|
|
481
|
-
task: discovered.traversal_receipt?.task?.text || "",
|
|
482
|
-
included_objects: (discovered.traversal_receipt?.candidates || []).map((candidate) => ({
|
|
483
|
-
object_id: candidate.id,
|
|
484
|
-
score: candidate.score,
|
|
485
|
-
title: nodes.get(candidate.id)?.title || null,
|
|
486
|
-
summary: nodes.get(candidate.id)?.summary || null,
|
|
487
|
-
source_refs: (nodes.get(candidate.id)?.source_refs || []).map((source) => source.ref),
|
|
488
|
-
})),
|
|
489
|
-
runtime_contract: { graph_first_scope: "routing/capability/policy orientation", raw_source_authoritative: true, canonical_write_allowed: false },
|
|
490
|
-
continuity: continuity.status(normalizeRepo(repoArg), readManifest(normalizeRepo(repoArg)).manifest, options),
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
function targetBindingStatus(repo, options = {}) {
|
|
495
|
-
const manifest = readManifest(repo).manifest;
|
|
496
|
-
const root = runtimeRoot(repo, manifest, options);
|
|
497
|
-
const bindingPath = path.join(root, BINDING_FILE);
|
|
498
|
-
if (!fs.existsSync(bindingPath)) return { status: "not_configured", enabled: false, blockers: [], next_action: "connect an exact target provider binding" };
|
|
499
|
-
let binding;
|
|
500
|
-
try { binding = readJson(bindingPath); } catch (_) { return { status: "blocked", enabled: true, blockers: ["target_binding_invalid"] }; }
|
|
501
|
-
const identity = bindingValues(binding);
|
|
502
|
-
const exportRef = String(binding.provider_export_ref || "");
|
|
503
|
-
const hostPrefix = "host-local://";
|
|
504
|
-
const exportPath = exportRef.startsWith(hostPrefix) ? path.join(root, exportRef.slice(hostPrefix.length)) : null;
|
|
505
|
-
const blockers = [...identity.blockers];
|
|
506
|
-
if (!exportPath || !exportPath.startsWith(`${root}${path.sep}`)) blockers.push("provider_export_outside_host_state");
|
|
507
|
-
const exported = exportPath ? readExport(exportPath) : { export: {}, blockers: ["provider_export_missing"] };
|
|
508
|
-
blockers.push(...exported.blockers);
|
|
509
|
-
for (const key of Object.keys(identity.values)) if (exported.export[key] !== identity.values[key]) blockers.push(`${key}_mismatch`);
|
|
510
|
-
if (!binding.provider_export_sha256 || binding.provider_export_sha256 !== exported.raw_sha256) blockers.push("provider_export_digest_mismatch");
|
|
511
|
-
const repositoryId = readManifest(repo).manifest?.id || path.basename(repo);
|
|
512
|
-
if (Array.isArray(exported.export.allowed_change_scope) && !exported.export.allowed_change_scope.some((scope) => scope.repository_id === repositoryId)) {
|
|
513
|
-
blockers.push("provider_contract_repository_scope_unapproved");
|
|
514
|
-
}
|
|
515
|
-
return {
|
|
516
|
-
status: blockers.length ? "blocked" : "ready",
|
|
517
|
-
enabled: true,
|
|
518
|
-
...identity.values,
|
|
519
|
-
provider_export_ref: exportRef || null,
|
|
520
|
-
provider_export_sha256: binding.provider_export_sha256 || null,
|
|
521
|
-
execution_contract: Object.fromEntries(["decision_refs", "goal_binding", "requirement_bindings", "constraint_ids", "non_goal_ids", "deferred_boundary_ids", "allowed_change_scope", "architecture_contract"].map((key) => [key, exported.export[key]])),
|
|
522
|
-
execution_contract_digest: exported.export.execution_contract_digest || null,
|
|
523
|
-
blockers: [...new Set(blockers)].sort(),
|
|
524
|
-
next_action: blockers.length ? "refresh or repair the exact provider binding" : "none",
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
function status(repoArg, options = {}) {
|
|
529
|
-
const repo = normalizeRepo(repoArg);
|
|
530
|
-
const manifestState = readManifest(repo);
|
|
531
|
-
const ext = extensionState(manifestState.manifest);
|
|
532
|
-
let stored = null;
|
|
533
|
-
const root = runtimeRoot(repo, manifestState.manifest, options);
|
|
534
|
-
try { if (fs.existsSync(path.join(root, INVENTORY_FILE))) stored = readJson(path.join(root, INVENTORY_FILE)); } catch (_) { /* stale */ }
|
|
535
|
-
const current = inventory(repo);
|
|
536
|
-
const freshness = stored && stored.inventory_digest === current.inventory_digest ? "current" : stored ? "stale" : "missing";
|
|
537
|
-
const blockers = [...manifestState.blockers, ...ext.blockers];
|
|
538
|
-
if (!stored && legacyRuntimeState(repo).present) blockers.push("project_technology_host_state_migration_required");
|
|
539
|
-
if (ext.contract && ext.contract.enabled === false) blockers.push("project_technology_disabled");
|
|
540
|
-
if (freshness !== "current") blockers.push(`project_technology_inventory_${freshness}`);
|
|
541
|
-
const binding = targetBindingStatus(repo, options);
|
|
542
|
-
if (binding.status === "blocked") blockers.push(...binding.blockers);
|
|
543
|
-
return result("status", "read_only", blockers.length ? "blocked" : "success", {
|
|
544
|
-
repository_id: manifestState.manifest?.id || path.basename(repo),
|
|
545
|
-
enabled: Boolean(ext.contract && ext.contract.enabled && !ext.legacy),
|
|
546
|
-
manifest_status: manifestState.blockers.length ? "blocked" : "current",
|
|
547
|
-
technology_freshness: freshness,
|
|
548
|
-
technology_digest: current.inventory_digest,
|
|
549
|
-
target_binding: binding,
|
|
550
|
-
continuity: continuity.status(repo, manifestState.manifest, {}),
|
|
551
|
-
blockers: [...new Set(blockers)].sort(),
|
|
552
|
-
next_action: ext.legacy ? "run enable --apply to migrate the legacy contract" : blockers.length ? "run plan, then the required transactional operation" : "none",
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
function explain(repoArg) {
|
|
557
|
-
return result("explain", "read_only", "success", {
|
|
558
|
-
repository_id: readManifest(normalizeRepo(repoArg)).manifest?.id || path.basename(normalizeRepo(repoArg)),
|
|
559
|
-
explanation: "Project Technology uses one Mirai Graph manifest to build bounded task context, bind accepted targets and verify repository technology without replacing raw owner sources.",
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
function plan(repoArg) {
|
|
564
|
-
const state = status(repoArg);
|
|
565
|
-
return result("plan", "read_only", "success", {
|
|
566
|
-
current_status: state.status,
|
|
567
|
-
planned_changes: ["validate_graph_manifest", "migrate_legacy_extension_if_present", "migrate_project_local_runtime_to_host_state", "enable_public_contract", "build_safe_inventory", "verify_target_binding"],
|
|
568
|
-
blockers: state.blockers.filter((item) => !["project_technology_not_configured", "project_technology_migration_required", "project_technology_inventory_missing", "project_technology_inventory_stale"].includes(item)),
|
|
569
|
-
next_action: "rerun the selected operation with --apply",
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
function preview(operation, repoArg, options = {}) {
|
|
574
|
-
const state = status(repoArg, options);
|
|
575
|
-
return result(operation, "preview", "preview", { apply_required: true, current_status: state.status, blockers: state.blockers.filter((item) => item.startsWith("graph_manifest_")), next_action: `${operation} --apply` });
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
function enable(repoArg, options = {}) {
|
|
579
|
-
const repo = normalizeRepo(repoArg);
|
|
580
|
-
const manifestState = readManifest(repo);
|
|
581
|
-
if (!manifestState.manifest || manifestState.blockers.length) return result("enable", "transactional", "fail", { blockers: manifestState.blockers, next_action: "repair graph.json" });
|
|
582
|
-
const manifest = structuredClone(manifestState.manifest);
|
|
583
|
-
const extensions = { ...(manifest.extensions || {}) };
|
|
584
|
-
const legacy = extensions[LEGACY_EXTENSION_KEY];
|
|
585
|
-
delete extensions[LEGACY_EXTENSION_KEY];
|
|
586
|
-
extensions[EXTENSION_KEY] = extensionContract();
|
|
587
|
-
manifest.extensions = extensions;
|
|
588
|
-
const root = runtimeRoot(repo, manifest, options);
|
|
589
|
-
const runtimeMigration = migrateProjectLocalRuntime(repo, manifest, root);
|
|
590
|
-
if (runtimeMigration.blockers.length) return result("enable", "transactional", "fail", {
|
|
591
|
-
blockers: runtimeMigration.blockers,
|
|
592
|
-
next_action: "repair the project-local runtime before host-state migration",
|
|
593
|
-
});
|
|
594
|
-
const migrationRoot = path.join(root, "migrations", sha256(canonicalBytes({ legacy: legacy || null, head: git(repo, "rev-parse", "HEAD") })).slice(0, 16));
|
|
595
|
-
fs.mkdirSync(migrationRoot, { recursive: true });
|
|
596
|
-
atomicWrite(path.join(migrationRoot, "graph.json.before"), fs.readFileSync(path.join(repo, "graph.json")));
|
|
597
|
-
if (legacy) atomicWrite(path.join(migrationRoot, "legacy-extension.json"), canonicalBytes(legacy));
|
|
598
|
-
const legacyLocal = path.join(repo, LEGACY_LOCAL_DIR);
|
|
599
|
-
if (fs.existsSync(legacyLocal)) atomicWrite(path.join(migrationRoot, "legacy-local-state.json"), canonicalBytes({ status: "preserved_for_rollback", path: LEGACY_LOCAL_DIR }));
|
|
600
|
-
const manifestChanged = atomicWrite(path.join(repo, "graph.json"), canonicalBytes(manifest));
|
|
601
|
-
const inv = inventory(repo);
|
|
602
|
-
const inventoryChanged = atomicWrite(path.join(root, INVENTORY_FILE), canonicalBytes(inv));
|
|
603
|
-
const verified = readManifest(repo);
|
|
604
|
-
if (verified.blockers.length || extensionState(verified.manifest).blockers.length) {
|
|
605
|
-
fs.copyFileSync(path.join(migrationRoot, "graph.json.before"), path.join(repo, "graph.json"));
|
|
606
|
-
return result("enable", "transactional", "fail", { blockers: ["project_technology_enable_rolled_back", ...verified.blockers], next_action: "inspect the rollback receipt" });
|
|
607
|
-
}
|
|
608
|
-
return result("enable", "transactional", "success", {
|
|
609
|
-
changed: manifestChanged || inventoryChanged || runtimeMigration.changed,
|
|
610
|
-
migration_ref: runtimeMigration.migration_ref || `host-local://migrations/${path.basename(migrationRoot)}`,
|
|
611
|
-
technology_digest: inv.inventory_digest,
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
function sync(repoArg, options = {}) {
|
|
616
|
-
const repo = normalizeRepo(repoArg);
|
|
617
|
-
const manifestState = readManifest(repo);
|
|
618
|
-
const ext = extensionState(manifestState.manifest);
|
|
619
|
-
const blockers = [...manifestState.blockers, ...ext.blockers];
|
|
620
|
-
const hostRoot = runtimeRoot(repo, manifestState.manifest, options);
|
|
621
|
-
if (legacyRuntimeState(repo).present && !fs.existsSync(path.join(hostRoot, INVENTORY_FILE))) blockers.push("project_technology_host_state_migration_required");
|
|
622
|
-
if (!ext.contract || ext.legacy || ext.contract.enabled !== true) blockers.push("project_technology_not_enabled");
|
|
623
|
-
if (blockers.length) return result("sync", "transactional", "fail", { blockers: [...new Set(blockers)].sort(), next_action: "enable or repair Project Technology" });
|
|
624
|
-
let continuityResult = null;
|
|
625
|
-
if (options.boundary) {
|
|
626
|
-
continuityResult = continuity.sync(repo, manifestState.manifest, options.boundary, options.continuityEvidence, options);
|
|
627
|
-
if (continuityResult.status !== "success") return result("sync", "transactional", continuityResult.status, {
|
|
628
|
-
blockers: continuityResult.blockers,
|
|
629
|
-
continuity: continuityResult.continuity || null,
|
|
630
|
-
next_action: "repair the continuity evidence or reconcile the graph state",
|
|
631
|
-
});
|
|
632
|
-
if (options.boundary === "task_start") return result("sync", "read_only", "success", {
|
|
633
|
-
changed: false,
|
|
634
|
-
technology_digest: inventory(repo).inventory_digest,
|
|
635
|
-
target_binding: targetBindingStatus(repo, options),
|
|
636
|
-
continuity: continuityResult.continuity,
|
|
637
|
-
});
|
|
638
|
-
}
|
|
639
|
-
const inv = inventory(repo);
|
|
640
|
-
const currentManifest = readManifest(repo).manifest;
|
|
641
|
-
const changed = atomicWrite(path.join(runtimeRoot(repo, currentManifest || manifestState.manifest, options), INVENTORY_FILE), canonicalBytes(inv));
|
|
642
|
-
return result("sync", "transactional", "success", {
|
|
643
|
-
changed: changed || Boolean(continuityResult?.changed),
|
|
644
|
-
technology_digest: inv.inventory_digest,
|
|
645
|
-
target_binding: targetBindingStatus(repo, options),
|
|
646
|
-
continuity: continuityResult?.continuity || continuity.status(repo, currentManifest, options),
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
function provide(repoArg, options = {}) {
|
|
651
|
-
const repo = normalizeRepo(repoArg);
|
|
652
|
-
const identity = bindingValues(options);
|
|
653
|
-
const manifestState = readManifest(repo);
|
|
654
|
-
const ext = extensionState(manifestState.manifest);
|
|
655
|
-
const blockers = [...identity.blockers, ...manifestState.blockers, ...ext.blockers];
|
|
656
|
-
if (!ext.contract || ext.legacy || ext.contract.enabled !== true) blockers.push("project_technology_not_enabled");
|
|
657
|
-
const head = git(repo, "rev-parse", "HEAD").toLowerCase();
|
|
658
|
-
if (head !== identity.values.provider_revision) blockers.push("provider_revision_does_not_match_head");
|
|
659
|
-
const target = targetContract(repo, identity.values.target_id, identity.values.semantic_digest, manifestState.manifest);
|
|
660
|
-
blockers.push(...target.blockers);
|
|
661
|
-
if (blockers.length) return result("provide", "transactional", "fail", { blockers: [...new Set(blockers)].sort(), next_action: "repair the accepted target contract" });
|
|
662
|
-
const executionContractDigest = sha256(canonicalBytes(target.contract));
|
|
663
|
-
const payload = { schema_version: "1.0.0", ...identity.values, ...target.contract, execution_contract_digest: executionContractDigest };
|
|
664
|
-
const changed = atomicWrite(path.join(repo, EXPORT_FILE), canonicalBytes(payload));
|
|
665
|
-
return result("provide", "transactional", "success", { changed, export_ref: EXPORT_FILE, target_binding: payload });
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
function providerRootFor(exportPath) {
|
|
669
|
-
const completed = spawnSync("git", ["-C", path.dirname(exportPath), "rev-parse", "--show-toplevel"], { encoding: "utf8" });
|
|
670
|
-
return completed.status === 0 ? completed.stdout.trim() : null;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
function connect(repoArg, options = {}) {
|
|
674
|
-
const repo = normalizeRepo(repoArg);
|
|
675
|
-
const source = path.resolve(String(options.source || ""));
|
|
676
|
-
const identity = bindingValues(options);
|
|
677
|
-
const read = readExport(source);
|
|
678
|
-
const manifestState = readManifest(repo);
|
|
679
|
-
const ext = extensionState(manifestState.manifest);
|
|
680
|
-
const blockers = [...identity.blockers, ...read.blockers, ...manifestState.blockers, ...ext.blockers];
|
|
681
|
-
if (!ext.contract || ext.legacy || ext.contract.enabled !== true) blockers.push("project_technology_not_enabled");
|
|
682
|
-
for (const key of Object.keys(identity.values)) if (read.export[key] !== identity.values[key]) blockers.push(`${key}_mismatch`);
|
|
683
|
-
const providerRoot = providerRootFor(source);
|
|
684
|
-
if (!providerRoot) blockers.push("provider_revision_order_unverifiable");
|
|
685
|
-
else if (git(providerRoot, "rev-parse", "HEAD").toLowerCase() !== identity.values.provider_revision) blockers.push("provider_revision_does_not_match_head");
|
|
686
|
-
const root = runtimeRoot(repo, manifestState.manifest, options);
|
|
687
|
-
const currentPath = path.join(root, BINDING_FILE);
|
|
688
|
-
let current = null;
|
|
689
|
-
try { if (fs.existsSync(currentPath)) current = readJson(currentPath); } catch (_) { blockers.push("current_target_binding_invalid"); }
|
|
690
|
-
if (current) {
|
|
691
|
-
if (!options.refreshBinding) {
|
|
692
|
-
const same = Object.keys(identity.values).every((key) => current[key] === identity.values[key]);
|
|
693
|
-
if (!same) blockers.push("target_provider_conflict", "target_provider_refresh_required");
|
|
694
|
-
else {
|
|
695
|
-
const currentState = targetBindingStatus(repo, options);
|
|
696
|
-
if (currentState.status !== "ready") blockers.push(...currentState.blockers);
|
|
697
|
-
if (currentState.execution_contract_digest !== read.export.execution_contract_digest) blockers.push("target_provider_conflict", "provider_execution_contract_mismatch");
|
|
698
|
-
}
|
|
699
|
-
} else {
|
|
700
|
-
if (current.target_id !== identity.values.target_id) blockers.push("target_provider_target_mismatch");
|
|
701
|
-
if (current.semantic_digest !== identity.values.semantic_digest) blockers.push("target_provider_semantic_mismatch");
|
|
702
|
-
const currentState = targetBindingStatus(repo, options);
|
|
703
|
-
if (currentState.status !== "ready") blockers.push(...currentState.blockers);
|
|
704
|
-
if (currentState.execution_contract_digest !== read.export.execution_contract_digest) blockers.push("provider_execution_contract_refresh_mismatch");
|
|
705
|
-
if (!providerRoot) blockers.push("provider_revision_order_unverifiable");
|
|
706
|
-
else {
|
|
707
|
-
if (current.provider_revision !== identity.values.provider_revision) {
|
|
708
|
-
const ancestry = spawnSync("git", ["-C", providerRoot, "merge-base", "--is-ancestor", current.provider_revision, identity.values.provider_revision]);
|
|
709
|
-
if (ancestry.status !== 0) blockers.push("provider_revision_not_forward");
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
} else if (options.refreshBinding) blockers.push("target_provider_binding_missing_for_refresh");
|
|
714
|
-
if (blockers.length) return result("connect", "transactional", "fail", { blockers: [...new Set(blockers)].sort(), next_action: "repair the provider export or request an explicit accepted target change" });
|
|
715
|
-
const exportBytes = canonicalBytes(read.export);
|
|
716
|
-
const exportSha = sha256(exportBytes);
|
|
717
|
-
const imported = path.join(root, IMPORT_DIR, `${exportSha}.json`);
|
|
718
|
-
const binding = { schema_version: "1.0.0", ...identity.values, provider_export_ref: `host-local://${IMPORT_DIR}/${exportSha}.json`, provider_export_sha256: exportSha };
|
|
719
|
-
const transaction = fs.mkdtempSync(path.join(os.tmpdir(), "mirai-project-technology-"));
|
|
720
|
-
const bindingBefore = fs.existsSync(currentPath) ? fs.readFileSync(currentPath) : null;
|
|
721
|
-
const importBefore = fs.existsSync(imported) ? fs.readFileSync(imported) : null;
|
|
722
|
-
try {
|
|
723
|
-
const exportChanged = atomicWrite(imported, exportBytes);
|
|
724
|
-
const bindingChanged = atomicWrite(currentPath, canonicalBytes(binding));
|
|
725
|
-
fs.rmSync(transaction, { recursive: true, force: true });
|
|
726
|
-
return result("connect", "transactional", "success", { changed: exportChanged || bindingChanged, refresh_binding: Boolean(options.refreshBinding), target_binding: targetBindingStatus(repo, options) });
|
|
727
|
-
} catch (_) {
|
|
728
|
-
if (bindingBefore) atomicWrite(currentPath, bindingBefore); else if (fs.existsSync(currentPath)) fs.unlinkSync(currentPath);
|
|
729
|
-
if (importBefore) atomicWrite(imported, importBefore); else if (fs.existsSync(imported)) fs.unlinkSync(imported);
|
|
730
|
-
fs.rmSync(transaction, { recursive: true, force: true });
|
|
731
|
-
return result("connect", "transactional", "fail", { blockers: ["target_provider_transaction_failed", "target_provider_rollback_applied"], next_action: "inspect filesystem permissions and retry" });
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
|
|
735
|
-
function disconnect(repoArg, options = {}) {
|
|
736
|
-
const repo = normalizeRepo(repoArg);
|
|
737
|
-
const root = runtimeRoot(repo, readManifest(repo).manifest, options);
|
|
738
|
-
const bindingPath = path.join(root, BINDING_FILE);
|
|
739
|
-
if (!fs.existsSync(bindingPath)) return result("disconnect", "transactional", "success");
|
|
740
|
-
const backup = path.join(root, "rollback", `binding-${sha256(fs.readFileSync(bindingPath)).slice(0, 16)}.json`);
|
|
741
|
-
atomicWrite(backup, fs.readFileSync(bindingPath));
|
|
742
|
-
fs.unlinkSync(bindingPath);
|
|
743
|
-
return result("disconnect", "transactional", "success", { changed: true, rollback_ref: `host-local://rollback/${path.basename(backup)}` });
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
function disable(repoArg) {
|
|
747
|
-
const repo = normalizeRepo(repoArg);
|
|
748
|
-
const manifestState = readManifest(repo);
|
|
749
|
-
if (!manifestState.manifest || manifestState.blockers.length) return result("disable", "transactional", "fail", { blockers: manifestState.blockers });
|
|
750
|
-
const manifest = structuredClone(manifestState.manifest);
|
|
751
|
-
const current = extensionState(manifest);
|
|
752
|
-
if (!current.contract || current.legacy) return result("disable", "transactional", "fail", { blockers: current.blockers });
|
|
753
|
-
manifest.extensions[EXTENSION_KEY] = { ...current.contract, enabled: false };
|
|
754
|
-
const changed = atomicWrite(path.join(repo, "graph.json"), canonicalBytes(manifest));
|
|
755
|
-
return result("disable", "transactional", "success", { changed });
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
function repair(repoArg, options = {}) {
|
|
759
|
-
const repo = normalizeRepo(repoArg);
|
|
760
|
-
const manifestState = readManifest(repo);
|
|
761
|
-
if (!manifestState.manifest || manifestState.blockers.length) return result("repair", "transactional", "fail", { blockers: manifestState.blockers, next_action: "repair graph.json before Project Technology" });
|
|
762
|
-
const ext = extensionState(manifestState.manifest);
|
|
763
|
-
if (!ext.contract || ext.legacy) return enable(repo, options);
|
|
764
|
-
if (ext.blockers.length) return enable(repo, options);
|
|
765
|
-
const root = runtimeRoot(repo, manifestState.manifest, options);
|
|
766
|
-
if (legacyRuntimeState(repo).present && !fs.existsSync(path.join(root, INVENTORY_FILE))) return enable(repo, options);
|
|
767
|
-
return sync(repo, options);
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
function verify(repoArg, options = {}) {
|
|
771
|
-
const state = status(repoArg, options);
|
|
772
|
-
const blockers = [...state.blockers];
|
|
773
|
-
const repo = normalizeRepo(repoArg);
|
|
774
|
-
const manifest = readManifest(repo).manifest;
|
|
775
|
-
const continuityResult = continuity.verify(repo, manifest, options);
|
|
776
|
-
if (continuity.continuityPolicy(manifest) === "task_boundary" || options.receiptDigest || options.significantWork) blockers.push(...continuityResult.blockers);
|
|
777
|
-
if (options.significantWork && state.target_binding.status !== "ready") blockers.push("accepted_target_binding_required_for_significant_work");
|
|
778
|
-
return result("verify", "read_only", blockers.length ? "blocked" : "success", {
|
|
779
|
-
repository_id: state.repository_id,
|
|
780
|
-
enabled: state.enabled,
|
|
781
|
-
manifest_status: state.manifest_status,
|
|
782
|
-
technology_freshness: state.technology_freshness,
|
|
783
|
-
technology_digest: state.technology_digest,
|
|
784
|
-
target_binding: state.target_binding,
|
|
785
|
-
continuity: continuityResult.continuity,
|
|
786
|
-
blockers: [...new Set(blockers)].sort(),
|
|
787
|
-
next_action: blockers.length ? "repair the listed Project Technology blockers" : "none",
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
function execute(operation, repoArg, options = {}) {
|
|
792
|
-
if (operation === "artifact") return artifacts.executeArtifact(repoArg, options);
|
|
793
|
-
const readOnly = { explain, status, plan, verify, context };
|
|
794
|
-
if (readOnly[operation]) return readOnly[operation](repoArg, options);
|
|
795
|
-
const transactional = { enable, sync, connect, disconnect, provide, disable, repair };
|
|
796
|
-
if (!transactional[operation]) return result(operation, "read_only", "fail", { blockers: ["unsupported_project_technology_operation"] });
|
|
797
|
-
if (!options.apply) return preview(operation, repoArg, options);
|
|
798
|
-
return transactional[operation](repoArg, options);
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
module.exports = {
|
|
802
|
-
CONTRACT_VERSION,
|
|
803
|
-
EXTENSION_KEY,
|
|
804
|
-
LOCAL_DIR,
|
|
805
|
-
bindingValues,
|
|
806
|
-
canonicalBytes,
|
|
807
|
-
compareArtifactReleases: artifacts.compareArtifactReleases,
|
|
808
|
-
connect,
|
|
809
|
-
compileContext: traversal.compileContext,
|
|
810
|
-
context,
|
|
811
|
-
createArtifactRelease: artifacts.createArtifactRelease,
|
|
812
|
-
discoverContext: traversal.discoverContext,
|
|
813
|
-
disable,
|
|
814
|
-
disconnect,
|
|
815
|
-
enable,
|
|
816
|
-
execute,
|
|
817
|
-
expandContext: traversal.expandContext,
|
|
818
|
-
explain,
|
|
819
|
-
extensionContract,
|
|
820
|
-
inventory,
|
|
821
|
-
inspectArtifactBundle: artifacts.inspectArtifactBundle,
|
|
822
|
-
normalizeExecutionContract,
|
|
823
|
-
continuity,
|
|
824
|
-
plan,
|
|
825
|
-
provide,
|
|
826
|
-
readExport,
|
|
827
|
-
repair,
|
|
828
|
-
sha256,
|
|
829
|
-
status,
|
|
830
|
-
sync,
|
|
831
|
-
targetBindingStatus,
|
|
832
|
-
verify,
|
|
833
|
-
verifyArtifactRelease: artifacts.verifyArtifactRelease,
|
|
834
|
-
verifyContext: traversal.verifyContext,
|
|
835
|
-
};
|