@openplanr/protocol 0.2.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/LICENSE +21 -0
- package/README.md +82 -0
- package/lib/dashboard/closed-json-contract.mjs +141 -0
- package/lib/dashboard/generated/operate-experience-surface-schema-data.mjs +67 -0
- package/lib/dashboard/generated/operate-review-schema-data.mjs +35 -0
- package/lib/dashboard/generated/operate-schema-token-codec.mjs +127 -0
- package/lib/dashboard/operate-experience-audit-display-contract.d.mts +196 -0
- package/lib/dashboard/operate-experience-audit-display-contract.mjs +700 -0
- package/lib/dashboard/operate-experience-display-contract.d.mts +572 -0
- package/lib/dashboard/operate-experience-display-contract.mjs +1007 -0
- package/lib/dashboard/operate-experience-surface-contract.d.mts +157 -0
- package/lib/dashboard/operate-experience-surface-contract.mjs +91 -0
- package/lib/dashboard/operate-review-contract.d.mts +34 -0
- package/lib/dashboard/operate-review-contract.mjs +175 -0
- package/lib/dashboard/operate-review-display-workspace-contract.d.mts +54 -0
- package/lib/dashboard/operate-review-display-workspace-contract.mjs +258 -0
- package/lib/dashboard/operate-review-payload-safety.d.mts +7 -0
- package/lib/dashboard/operate-review-payload-safety.mjs +42 -0
- package/lib/dashboard/operate-review-workspace-projection-v2.d.mts +218 -0
- package/lib/protocol/index.d.ts +2638 -0
- package/package.json +115 -0
- package/registries/commands.json +1952 -0
- package/registries/diagram-grammars.json +2407 -0
- package/registries/diagram-semantic-patterns.json +111 -0
- package/registries/output-paths.json +40 -0
- package/registries/outputs.json +864 -0
- package/registries/roles.json +661 -0
- package/registries/rules.json +261 -0
- package/registries/skill-host-profiles.json +247 -0
- package/registries/skill-modules.json +1112 -0
- package/registries/skill-routing.json +389 -0
- package/registries/skills.json +1545 -0
- package/registries/task-kinds.json +220 -0
- package/registry/adapters.json +110 -0
- package/registry/artifact-theme.json +60 -0
- package/registry/evaluation-graders.json +303 -0
- package/registry/evaluation-host-profiles.json +131 -0
- package/registry/frozen-commands.json +15 -0
- package/registry/landing-operations.json +20 -0
- package/registry/landing-workflows.json +70 -0
- package/registry/live-evidence-providers.json +1 -0
- package/registry/operate-v2-contracts.json +5965 -0
- package/registry/professional-skills.json +115 -0
- package/registry/roles.json +14 -0
- package/registry/ship-review-specialists.json +42 -0
- package/schemas/v1.0.0/design-approved.schema.json +35 -0
- package/schemas/v1.0.0/design-feedback.schema.json +169 -0
- package/schemas/v1.0.0/design-manifest.schema.json +90 -0
- package/schemas/v1.0.0/design-session.schema.json +73 -0
- package/schemas/v1.0.0/graph.schema.json +100 -0
- package/schemas/v1.0.0/pipeline-shipped.schema.json +154 -0
- package/schemas/v1.0.0/run-manifest.schema.json +81 -0
- package/schemas/v1.0.0/spec.schema.json +120 -0
- package/schemas/v1.0.0/stack.schema.json +184 -0
- package/schemas/v1.0.0/story.schema.json +95 -0
- package/schemas/v1.0.0/task.schema.json +171 -0
- package/schemas/v1.0.0/taste-profile.schema.json +96 -0
- package/schemas/v1.1.0/adapter-registry.schema.json +72 -0
- package/schemas/v1.1.0/artifact-envelope.schema.json +142 -0
- package/schemas/v1.1.0/artifact-paste.schema.json +49 -0
- package/schemas/v1.1.0/artifact-review.schema.json +97 -0
- package/schemas/v1.1.0/artifact-room-descriptor.schema.json +39 -0
- package/schemas/v1.1.0/artifact-room-event.schema.json +184 -0
- package/schemas/v1.1.0/artifact-room-signed-event.schema.json +58 -0
- package/schemas/v1.1.0/artifact-theme.schema.json +139 -0
- package/schemas/v1.1.0/browser-qa-gate.schema.json +21 -0
- package/schemas/v1.1.0/browser-qa-result.schema.json +24 -0
- package/schemas/v1.1.0/browser-qa-session.schema.json +12 -0
- package/schemas/v1.1.0/ecosystem-manifest.schema.json +46 -0
- package/schemas/v1.1.0/investigation-diagnosis.schema.json +12 -0
- package/schemas/v1.1.0/investigation-event.schema.json +15 -0
- package/schemas/v1.1.0/investigation-experiment.schema.json +17 -0
- package/schemas/v1.1.0/investigation-fix.schema.json +11 -0
- package/schemas/v1.1.0/investigation-hypothesis.schema.json +6 -0
- package/schemas/v1.1.0/investigation-observation.schema.json +10 -0
- package/schemas/v1.1.0/investigation-receipt.schema.json +7 -0
- package/schemas/v1.1.0/investigation-record.schema.json +7 -0
- package/schemas/v1.1.0/investigation-request.schema.json +34 -0
- package/schemas/v1.1.0/planning-review-event.schema.json +64 -0
- package/schemas/v1.1.0/planning-review-receipt.schema.json +19 -0
- package/schemas/v1.1.0/planning-review-record.schema.json +176 -0
- package/schemas/v1.1.0/planning-review-state.schema.json +19 -0
- package/schemas/v1.1.0/professional-skills.schema.json +105 -0
- package/schemas/v1.1.0/professional-specification.schema.json +111 -0
- package/schemas/v1.1.0/provenance-event.schema.json +82 -0
- package/schemas/v1.1.0/role-registry.schema.json +28 -0
- package/schemas/v1.1.0/runtime-lock.schema.json +39 -0
- package/schemas/v1.1.0/ship-closure.schema.json +353 -0
- package/schemas/v1.1.0/ship-review-specialist-registry.schema.json +29 -0
- package/schemas/v1.1.0/ship-risk-classification.schema.json +48 -0
- package/schemas/v1.1.0/specialist-review-result.schema.json +19 -0
- package/schemas/v1.10.0/design-review-bundle.schema.json +584 -0
- package/schemas/v1.10.0/design-review-context.schema.json +191 -0
- package/schemas/v1.10.0/design-review-handoff.schema.json +407 -0
- package/schemas/v1.10.0/design-review-metadata-payload.schema.json +106 -0
- package/schemas/v1.11.0/design-review-metadata-payload.schema.json +107 -0
- package/schemas/v1.12.0/enterprise-access-context.schema.json +217 -0
- package/schemas/v1.12.0/enterprise-agent-handoff.schema.json +508 -0
- package/schemas/v1.12.0/enterprise-artifact-revision.schema.json +87 -0
- package/schemas/v1.12.0/enterprise-change-proposal.schema.json +359 -0
- package/schemas/v1.12.0/enterprise-evidence-reference.schema.json +147 -0
- package/schemas/v1.12.0/enterprise-review-thread.schema.json +278 -0
- package/schemas/v1.12.0/enterprise-sync-state.schema.json +169 -0
- package/schemas/v1.2.0/adapter-registry.schema.json +83 -0
- package/schemas/v1.2.0/dashboard-bootstrap.schema.json +219 -0
- package/schemas/v1.2.0/ecosystem-release-operation.schema.json +90 -0
- package/schemas/v1.2.0/ecosystem-saga.schema.json +54 -0
- package/schemas/v1.2.0/evidence-diagnostic.schema.json +77 -0
- package/schemas/v1.2.0/guided-answer-envelope.schema.json +73 -0
- package/schemas/v1.2.0/guided-confirmation.schema.json +128 -0
- package/schemas/v1.2.0/guided-question.schema.json +242 -0
- package/schemas/v1.2.0/guided-questionnaire.schema.json +278 -0
- package/schemas/v1.2.0/guided-session.schema.json +141 -0
- package/schemas/v1.2.0/landing-confirmation.schema.json +17 -0
- package/schemas/v1.2.0/landing-event.schema.json +12 -0
- package/schemas/v1.2.0/landing-operation-registry.schema.json +16 -0
- package/schemas/v1.2.0/landing-phase-receipt.schema.json +19 -0
- package/schemas/v1.2.0/landing-plan.schema.json +36 -0
- package/schemas/v1.2.0/landing-receipt.schema.json +12 -0
- package/schemas/v1.2.0/landing-workflow-catalog.schema.json +143 -0
- package/schemas/v1.2.0/operate-action-display-workspace.schema.json +119 -0
- package/schemas/v1.2.0/operate-cycle-display-workspace.schema.json +109 -0
- package/schemas/v1.2.0/operate-executive-board-display-surface.schema.json +72 -0
- package/schemas/v1.2.0/operate-experience-audit-display-surface.schema.json +328 -0
- package/schemas/v1.2.0/operate-experience-display-surface.schema.json +46 -0
- package/schemas/v1.2.0/operate-experience-surface.schema.json +590 -0
- package/schemas/v1.2.0/operate-recovery-display-surface.schema.json +85 -0
- package/schemas/v1.2.0/structured-action.schema.json +91 -0
- package/schemas/v1.3.0/adapter-registry.schema.json +84 -0
- package/schemas/v1.3.0/ecosystem-manifest.schema.json +120 -0
- package/schemas/v1.3.0/release-compatibility-claim.schema.json +46 -0
- package/schemas/v1.3.0/release-ledger-receipt.schema.json +45 -0
- package/schemas/v1.3.0/release-ledger.schema.json +60 -0
- package/schemas/v1.4.0/adapter-registry.schema.json +62 -0
- package/schemas/v1.4.0/evaluation-aggregate-report.schema.json +166 -0
- package/schemas/v1.4.0/evaluation-budget.schema.json +49 -0
- package/schemas/v1.4.0/evaluation-corpus.schema.json +93 -0
- package/schemas/v1.4.0/evaluation-fixture.schema.json +64 -0
- package/schemas/v1.4.0/evaluation-gate-policy.schema.json +33 -0
- package/schemas/v1.4.0/evaluation-grader-registration.schema.json +141 -0
- package/schemas/v1.4.0/evaluation-grader-registry.schema.json +20 -0
- package/schemas/v1.4.0/evaluation-host-profile-registry.schema.json +20 -0
- package/schemas/v1.4.0/evaluation-host-profile.schema.json +73 -0
- package/schemas/v1.4.0/evaluation-observation.schema.json +76 -0
- package/schemas/v1.4.0/evaluation-run-result.schema.json +84 -0
- package/schemas/v1.4.0/evaluation-scenario.schema.json +231 -0
- package/schemas/v1.4.0/evaluation-waiver.schema.json +65 -0
- package/schemas/v1.4.0/skill-certification-receipt.schema.json +103 -0
- package/schemas/v1.5.0/command-catalog.schema.json +296 -0
- package/schemas/v1.5.0/common.schema.json +261 -0
- package/schemas/v1.5.0/generated-asset-manifest.schema.json +313 -0
- package/schemas/v1.5.0/implementation-result.schema.json +152 -0
- package/schemas/v1.5.0/migration-preservation-manifest.schema.json +749 -0
- package/schemas/v1.5.0/output-catalog.schema.json +210 -0
- package/schemas/v1.5.0/output-path-catalog.schema.json +81 -0
- package/schemas/v1.5.0/role-registry.schema.json +261 -0
- package/schemas/v1.5.0/rule-catalog.schema.json +130 -0
- package/schemas/v1.5.0/skill-catalog.schema.json +303 -0
- package/schemas/v1.5.0/task-kind-registry.schema.json +167 -0
- package/schemas/v1.5.0/task-manifest.schema.json +373 -0
- package/schemas/v1.5.0/task-output-manifest.schema.json +462 -0
- package/schemas/v1.6.0/common.schema.json +462 -0
- package/schemas/v1.6.0/diagram-consumer-reference.schema.json +167 -0
- package/schemas/v1.6.0/diagram-document.schema.json +699 -0
- package/schemas/v1.6.0/diagram-fidelity-report.schema.json +137 -0
- package/schemas/v1.6.0/diagram-manifest.schema.json +162 -0
- package/schemas/v1.6.0/diagram-quality-report.schema.json +148 -0
- package/schemas/v1.6.0/diagram-review-binding.schema.json +132 -0
- package/schemas/v1.6.0/diagram-semantic-pattern-registry.schema.json +90 -0
- package/schemas/v1.6.0/diagram-type-registry.schema.json +373 -0
- package/schemas/v1.6.0/generated-asset-manifest.schema.json +103 -0
- package/schemas/v1.6.0/skill-catalog.schema.json +84 -0
- package/schemas/v1.6.0/skill-completion-receipt.schema.json +72 -0
- package/schemas/v1.6.0/skill-consent-record.schema.json +74 -0
- package/schemas/v1.6.0/skill-host-profile-registry.schema.json +526 -0
- package/schemas/v1.6.0/skill-learning-record.schema.json +116 -0
- package/schemas/v1.6.0/skill-module-registry.schema.json +108 -0
- package/schemas/v1.6.0/skill-routing-registry.schema.json +93 -0
- package/schemas/v1.6.0/skill-session.schema.json +73 -0
- package/schemas/v1.6.0/skill-source.schema.json +169 -0
- package/schemas/v1.7.0/common.schema.json +464 -0
- package/schemas/v1.7.0/generated-asset-manifest.schema.json +103 -0
- package/schemas/v1.7.0/planning-id-sequence.schema.json +50 -0
- package/schemas/v1.7.0/request-authority.schema.json +71 -0
- package/schemas/v1.7.0/skill-catalog.schema.json +84 -0
- package/schemas/v1.7.0/skill-completion-receipt.schema.json +72 -0
- package/schemas/v1.7.0/skill-consent-record.schema.json +74 -0
- package/schemas/v1.7.0/skill-host-profile-registry.schema.json +526 -0
- package/schemas/v1.7.0/skill-learning-record.schema.json +116 -0
- package/schemas/v1.7.0/skill-module-registry.schema.json +108 -0
- package/schemas/v1.7.0/skill-routing-registry.schema.json +93 -0
- package/schemas/v1.7.0/skill-session.schema.json +73 -0
- package/schemas/v1.7.0/skill-source.schema.json +169 -0
- package/schemas/v1.7.0/spec.schema.json +117 -0
- package/schemas/v1.7.0/story.schema.json +107 -0
- package/schemas/v1.7.0/task.schema.json +217 -0
- package/schemas/v1.8.0/common.schema.json +96 -0
- package/schemas/v1.8.0/skill-package.schema.json +63 -0
- package/schemas/v1.8.0/utility-command-catalog.schema.json +82 -0
- package/schemas/v1.9.0/design-document.schema.json +306 -0
- package/schemas/v1.9.0/design-review-bundle.schema.json +346 -0
- package/schemas/v1.9.0/design-review-workspace.schema.json +108 -0
- package/schemas/v1.9.0/design-workspace-create.schema.json +170 -0
- package/schemas/v1.9.0/design-workspace-event.schema.json +97 -0
- package/schemas/v1.9.0/design-workspace-revision.schema.json +56 -0
- package/schemas/v2.0.0/agent-runtime-manifest.schema.json +59 -0
- package/schemas/v2.0.0/business-operating-snapshot-projection.schema.json +14 -0
- package/schemas/v2.0.0/operate-allowed-action.schema.json +181 -0
- package/schemas/v2.0.0/operate-api-envelope.schema.json +225 -0
- package/schemas/v2.0.0/operate-capability-provider-registration.schema.json +30 -0
- package/schemas/v2.0.0/operate-domain-registration.schema.json +284 -0
- package/schemas/v2.0.0/operate-evidence-provider-registration.schema.json +55 -0
- package/schemas/v2.0.0/operate-evidence-resolver-registration.schema.json +46 -0
- package/schemas/v2.0.0/operate-executor-registration.schema.json +27 -0
- package/schemas/v2.0.0/operate-experience-live-patch.schema.json +47 -0
- package/schemas/v2.0.0/operate-experience-preview.schema.json +51 -0
- package/schemas/v2.0.0/operate-experience-view.schema.json +281 -0
- package/schemas/v2.0.0/operate-live-evidence-provider-registration.schema.json +48 -0
- package/schemas/v2.0.0/operate-live-evidence-provider-registry.schema.json +17 -0
- package/schemas/v2.0.0/operate-metric-provider-registration.schema.json +12 -0
- package/schemas/v2.0.0/operate-policy-provider-registration.schema.json +33 -0
- package/schemas/v2.0.0/operate-review-bound-submission.schema.json +29 -0
- package/schemas/v2.0.0/operate-review-display-workspace.schema.json +390 -0
- package/schemas/v2.0.0/operate-snapshot-provider-registration.schema.json +16 -0
- package/schemas/v2.0.0/operate-tool-call.schema.json +172 -0
- package/schemas/v2.0.0/operate-verification-provider-registration.schema.json +12 -0
- package/schemas/v2.0.0/operating-action-policy.schema.json +31 -0
- package/schemas/v2.0.0/operating-action-verification-plan.schema.json +13 -0
- package/schemas/v2.0.0/operating-action.schema.json +86 -0
- package/schemas/v2.0.0/operating-advisor-result.schema.json +394 -0
- package/schemas/v2.0.0/operating-approval-record.schema.json +23 -0
- package/schemas/v2.0.0/operating-approval-requirement.schema.json +31 -0
- package/schemas/v2.0.0/operating-artifact.schema.json +52 -0
- package/schemas/v2.0.0/operating-assignment.schema.json +437 -0
- package/schemas/v2.0.0/operating-assumption.schema.json +16 -0
- package/schemas/v2.0.0/operating-capability-availability.schema.json +15 -0
- package/schemas/v2.0.0/operating-capability-grant.schema.json +14 -0
- package/schemas/v2.0.0/operating-challenger-review.schema.json +204 -0
- package/schemas/v2.0.0/operating-checkpoint.schema.json +43 -0
- package/schemas/v2.0.0/operating-claim.schema.json +17 -0
- package/schemas/v2.0.0/operating-connector-checkpoint.schema.json +28 -0
- package/schemas/v2.0.0/operating-context-capture.schema.json +74 -0
- package/schemas/v2.0.0/operating-cycle-input-binding.schema.json +30 -0
- package/schemas/v2.0.0/operating-cycle.schema.json +42 -0
- package/schemas/v2.0.0/operating-decision-ledger.schema.json +237 -0
- package/schemas/v2.0.0/operating-decision.schema.json +137 -0
- package/schemas/v2.0.0/operating-delivery-evidence.schema.json +46 -0
- package/schemas/v2.0.0/operating-delivery-route.schema.json +43 -0
- package/schemas/v2.0.0/operating-delta.schema.json +13 -0
- package/schemas/v2.0.0/operating-domain-projection.schema.json +15 -0
- package/schemas/v2.0.0/operating-event-trigger.schema.json +11 -0
- package/schemas/v2.0.0/operating-event.schema.json +505 -0
- package/schemas/v2.0.0/operating-evidence-candidate.schema.json +88 -0
- package/schemas/v2.0.0/operating-evidence-edge.schema.json +39 -0
- package/schemas/v2.0.0/operating-evidence-graph.schema.json +25 -0
- package/schemas/v2.0.0/operating-evidence-observation.schema.json +48 -0
- package/schemas/v2.0.0/operating-evidence-ref.schema.json +51 -0
- package/schemas/v2.0.0/operating-evidence-resolution.schema.json +54 -0
- package/schemas/v2.0.0/operating-execution-result.schema.json +23 -0
- package/schemas/v2.0.0/operating-executive-board.schema.json +78 -0
- package/schemas/v2.0.0/operating-finding.schema.json +116 -0
- package/schemas/v2.0.0/operating-governed-operation.schema.json +54 -0
- package/schemas/v2.0.0/operating-intelligence-input-bundle.schema.json +128 -0
- package/schemas/v2.0.0/operating-intelligence-plan.schema.json +302 -0
- package/schemas/v2.0.0/operating-learning-receipt.schema.json +31 -0
- package/schemas/v2.0.0/operating-learning.schema.json +13 -0
- package/schemas/v2.0.0/operating-live-evidence-consent-record.schema.json +42 -0
- package/schemas/v2.0.0/operating-live-evidence-ingestion.schema.json +31 -0
- package/schemas/v2.0.0/operating-measurement-plan.schema.json +18 -0
- package/schemas/v2.0.0/operating-measurement-schedule-receipt.schema.json +7 -0
- package/schemas/v2.0.0/operating-measurement-schedule.schema.json +16 -0
- package/schemas/v2.0.0/operating-metric-observation.schema.json +15 -0
- package/schemas/v2.0.0/operating-metric.schema.json +18 -0
- package/schemas/v2.0.0/operating-model-state.schema.json +36 -0
- package/schemas/v2.0.0/operating-objective.schema.json +21 -0
- package/schemas/v2.0.0/operating-origin.schema.json +31 -0
- package/schemas/v2.0.0/operating-outcome-evaluation.schema.json +46 -0
- package/schemas/v2.0.0/operating-outcome.schema.json +13 -0
- package/schemas/v2.0.0/operating-planning-proposal.schema.json +45 -0
- package/schemas/v2.0.0/operating-policy-evaluation.schema.json +28 -0
- package/schemas/v2.0.0/operating-review-read.schema.json +217 -0
- package/schemas/v2.0.0/operating-review-receipt.schema.json +64 -0
- package/schemas/v2.0.0/operating-review.schema.json +47 -0
- package/schemas/v2.0.0/operating-risk.schema.json +96 -0
- package/schemas/v2.0.0/operating-rollback-plan.schema.json +10 -0
- package/schemas/v2.0.0/operating-rollback-result.schema.json +20 -0
- package/schemas/v2.0.0/operating-runtime-state.schema.json +289 -0
- package/schemas/v2.0.0/operating-scenario.schema.json +13 -0
- package/schemas/v2.0.0/operating-snapshot.schema.json +38 -0
- package/schemas/v2.0.0/operating-submission.schema.json +34 -0
- package/schemas/v2.0.0/operating-trace-matrix.schema.json +176 -0
- package/schemas/v2.0.0/operating-work-change-set.schema.json +89 -0
- package/schemas/v2.0.0/operating-work-ledger.schema.json +40 -0
- package/schemas/v2.0.0/software-operating-snapshot-projection.schema.json +14 -0
- package/src/browser-contracts.d.mts +5 -0
- package/src/browser-contracts.mjs +40 -0
- package/src/canonical-json.d.mts +5 -0
- package/src/canonical-json.mjs +142 -0
- package/src/compat/live-evidence-v2.mjs +1019 -0
- package/src/compat/operate-experience-live-patch.mjs +66 -0
- package/src/compat/operating-planning-contracts.mjs +114 -0
- package/src/contracts.d.mts +42 -0
- package/src/contracts.mjs +990 -0
- package/src/design-contracts.d.mts +62 -0
- package/src/design-contracts.mjs +186 -0
- package/src/design-publication-contracts.d.mts +4 -0
- package/src/design-publication-contracts.mjs +85 -0
- package/src/diagram-contracts.d.mts +19 -0
- package/src/diagram-contracts.mjs +28 -0
- package/src/enterprise-contracts.d.mts +107 -0
- package/src/enterprise-contracts.mjs +463 -0
- package/src/errors.d.mts +11 -0
- package/src/errors.mjs +109 -0
- package/src/generated/canonical-registries.mjs +5554 -0
- package/src/generated/contract-catalog-v2.mjs +7076 -0
- package/src/generated/diagram-registries.mjs +2529 -0
- package/src/index.d.mts +10 -0
- package/src/index.mjs +40 -0
- package/src/json-schema.d.mts +7 -0
- package/src/json-schema.mjs +283 -0
- package/src/planning-contracts.d.mts +10 -0
- package/src/planning-contracts.mjs +53 -0
- package/src/registries.d.mts +40 -0
- package/src/registries.mjs +261 -0
- package/src/review-experience-contracts.d.mts +11 -0
- package/src/review-experience-contracts.mjs +103 -0
- package/src/semver.d.mts +2 -0
- package/src/semver.mjs +7 -0
- package/src/skill-source-contracts.d.mts +25 -0
- package/src/skill-source-contracts.mjs +105 -0
- package/src/task-contracts.d.mts +7 -0
- package/src/task-contracts.mjs +130 -0
- package/src/workspace-contracts.d.mts +26 -0
- package/src/workspace-contracts.mjs +83 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { verifyDocumentDigest } from './canonical-json.mjs';
|
|
2
|
+
import { CANONICAL_REGISTRIES } from './generated/canonical-registries.mjs';
|
|
3
|
+
import { PROTOCOL_ERROR_CODES, ProtocolError } from './errors.mjs';
|
|
4
|
+
|
|
5
|
+
const fail = (code, message, details) => {
|
|
6
|
+
throw new ProtocolError(code, message, '', details);
|
|
7
|
+
};
|
|
8
|
+
const equal = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
9
|
+
|
|
10
|
+
function assertDocument(name, value, kind) {
|
|
11
|
+
if (!value || typeof value !== 'object' || Array.isArray(value) || value.kind !== kind
|
|
12
|
+
|| value.protocolVersion !== '1.5.0' || value.digestAlgorithm !== 'sha256'
|
|
13
|
+
|| value.canonicalization !== 'rfc8785' || !verifyDocumentDigest(value)) {
|
|
14
|
+
fail(PROTOCOL_ERROR_CODES.DOCUMENT_INVALID, `${name} is not a digest-bound Protocol 1.5 document.`, { name });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function assertSortedUnique(values, key, name) {
|
|
19
|
+
const keys = values.map((value) => value[key]);
|
|
20
|
+
if (new Set(keys).size !== keys.length) fail(PROTOCOL_ERROR_CODES.DUPLICATE_ID, `${name} contains duplicate ${key} values.`, { keys });
|
|
21
|
+
const sorted = [...keys].sort();
|
|
22
|
+
if (!equal(keys, sorted)) fail(PROTOCOL_ERROR_CODES.SORT_ORDER_INVALID, `${name} must be sorted by ${key}.`, { keys, sorted });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const EXPECTED_ROLES = Object.freeze({
|
|
26
|
+
'planr-backend': ['backend-agent', 'dev', 'conditional', 'implementation-high', 'implementation-result'],
|
|
27
|
+
'planr-database': ['db-agent', 'po-preflight', 'conditional', 'analysis-high', 'task-output-manifest'],
|
|
28
|
+
'planr-designer': ['designer-agent', 'po', 'conditional', 'analysis-high', 'designer-output'],
|
|
29
|
+
'planr-devops': ['devops-agent', 'post-build', 'conditional', 'analysis-high', 'task-output-manifest'],
|
|
30
|
+
'planr-documentation': ['doc-gen-agent', 'post-build', 'conditional', 'analysis-high', 'task-output-manifest'],
|
|
31
|
+
'planr-entity-scaffold': ['entity-scaffold-agent', 'po-preflight', 'manual', 'analysis-high', 'task-output-manifest'],
|
|
32
|
+
'planr-frontend': ['frontend-agent', 'dev', 'conditional', 'implementation-high', 'implementation-result'],
|
|
33
|
+
'planr-qa': ['qa-agent', 'qa', 'always', 'read-only-qa', 'task-output-manifest'],
|
|
34
|
+
'planr-specification': ['specification-agent', 'po', 'always', 'analysis-high', 'specification-output'],
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const EXPECTED_TASK_KINDS = Object.freeze({
|
|
38
|
+
backend: 'planr-backend', database: 'planr-database', devops: 'planr-devops', documentation: 'planr-documentation',
|
|
39
|
+
'entity-scaffold': 'planr-entity-scaffold', frontend: 'planr-frontend', qa: 'planr-qa',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const EXPECTED_SKILLS = Object.freeze([
|
|
43
|
+
'planr-artifact', 'planr-browser-qa', 'planr-ceo-review', 'planr-chair-review', 'planr-challenger-review', 'planr-cmo-review',
|
|
44
|
+
'planr-coo-review', 'planr-cpo-review', 'planr-cto-review', 'planr-dashboard', 'planr-design', 'planr-design-loop',
|
|
45
|
+
'planr-design-review', 'planr-diagram', 'planr-doctor', 'planr-investigate', 'planr-land', 'planr-operate', 'planr-plan',
|
|
46
|
+
'planr-plan-review', 'planr-release', 'planr-ship', 'planr-spec', 'planr-status', 'planr-sync',
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
export function validateCanonicalRegistries(registries = CANONICAL_REGISTRIES) {
|
|
50
|
+
const roles = registries['roles.json'];
|
|
51
|
+
const taskKinds = registries['task-kinds.json'];
|
|
52
|
+
const rules = registries['rules.json'];
|
|
53
|
+
const commands = registries['commands.json'];
|
|
54
|
+
const skills = registries['skills.json'];
|
|
55
|
+
const outputs = registries['outputs.json'];
|
|
56
|
+
const outputPaths = registries['output-paths.json'];
|
|
57
|
+
assertDocument('roles.json', roles, 'role-registry');
|
|
58
|
+
assertDocument('task-kinds.json', taskKinds, 'task-kind-registry');
|
|
59
|
+
assertDocument('rules.json', rules, 'rule-catalog');
|
|
60
|
+
assertDocument('commands.json', commands, 'command-catalog');
|
|
61
|
+
assertDocument('skills.json', skills, 'skill-catalog');
|
|
62
|
+
assertDocument('outputs.json', outputs, 'output-catalog');
|
|
63
|
+
assertDocument('output-paths.json', outputPaths, 'output-path-catalog');
|
|
64
|
+
|
|
65
|
+
if (roles.roles.length !== 9) fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Protocol 0.1 requires exactly nine canonical roles.');
|
|
66
|
+
assertSortedUnique(roles.roles, 'roleId', 'roles.json');
|
|
67
|
+
const aliases = new Set();
|
|
68
|
+
const canonicalRoleIds = new Set(roles.roles.map(({ roleId }) => roleId));
|
|
69
|
+
for (const role of roles.roles) {
|
|
70
|
+
if (role.legacyAliases.length !== 1 || aliases.has(role.legacyAliases[0].id) || canonicalRoleIds.has(role.legacyAliases[0].id)) {
|
|
71
|
+
fail(PROTOCOL_ERROR_CODES.DUPLICATE_ID, `Role alias collision for ${role.roleId}.`);
|
|
72
|
+
}
|
|
73
|
+
aliases.add(role.legacyAliases[0].id);
|
|
74
|
+
const expected = EXPECTED_ROLES[role.roleId];
|
|
75
|
+
if (!expected || !equal([
|
|
76
|
+
role.legacyAliases[0]?.id, role.phase, role.activation, role.capabilityTier, role.outputContracts[0]?.id,
|
|
77
|
+
], expected)) {
|
|
78
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, `Role compatibility mapping drifted for ${role.roleId}.`);
|
|
79
|
+
}
|
|
80
|
+
if (role.adapterMappings.length < 3 || role.qaCoverage.length < 1) {
|
|
81
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, `Role ${role.roleId} lacks adapter parity or QA coverage.`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const qa = roles.roles.find(({ roleId }) => roleId === 'planr-qa');
|
|
85
|
+
const database = roles.roles.find(({ roleId }) => roleId === 'planr-database');
|
|
86
|
+
const devops = roles.roles.find(({ roleId }) => roleId === 'planr-devops');
|
|
87
|
+
if (qa.writeBoundary.repositoryAccess !== 'read-only' || qa.writeBoundary.allowedOutputClasses.includes('C')) {
|
|
88
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'QA must remain read-only.');
|
|
89
|
+
}
|
|
90
|
+
if (database.writeBoundary.externalDataAccess !== 'read-only' || !database.writeBoundary.forbiddenEffects.includes('database-mutation')) {
|
|
91
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Database inspection must remain externally read-only.');
|
|
92
|
+
}
|
|
93
|
+
if (!devops.writeBoundary.forbiddenEffects.includes('deploy')) {
|
|
94
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'DevOps configuration authority must forbid deploy.');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (taskKinds.roleRegistryDigest !== roles.documentDigest || taskKinds.bindings.length !== 7) {
|
|
98
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, 'Task-kind registry is not bound to the exact role registry.');
|
|
99
|
+
}
|
|
100
|
+
assertSortedUnique(taskKinds.bindings, 'taskKind', 'task-kinds.json bindings');
|
|
101
|
+
for (const binding of taskKinds.bindings) {
|
|
102
|
+
if (EXPECTED_TASK_KINDS[binding.taskKind] !== binding.roleId || !canonicalRoleIds.has(binding.roleId)) {
|
|
103
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Task kind ${binding.taskKind} has a mismatched role binding.`);
|
|
104
|
+
}
|
|
105
|
+
const expectedOutput = ['backend', 'frontend'].includes(binding.taskKind)
|
|
106
|
+
? 'implementation-result'
|
|
107
|
+
: 'task-output-manifest';
|
|
108
|
+
if (!equal(binding.outputContracts, [{ id: expectedOutput, version: '1.0.0' }])) {
|
|
109
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Task kind ${binding.taskKind} has a mismatched output contract.`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (!equal(taskKinds.legacyMappings.map(({ legacyType, legacyAgent, taskKind, precedence }) => [legacyType, legacyAgent, taskKind, precedence]), [
|
|
113
|
+
['UI', 'frontend-agent', 'frontend', 1], ['Tech', 'db-agent', 'database', 2],
|
|
114
|
+
['Tech', 'backend-agent', 'backend', 3], ['Tech', null, 'backend', 4],
|
|
115
|
+
])) fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Legacy UI/Tech routing precedence drifted.');
|
|
116
|
+
|
|
117
|
+
assertSortedUnique(rules.rules, 'ruleId', 'rules.json');
|
|
118
|
+
if (!equal(rules.rules.map(({ ruleId }) => ruleId), ['R1', 'R10', 'R2', 'R3', 'R4', 'R5', 'R6', 'R7', 'R8', 'R9'].sort())) {
|
|
119
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Rule catalog must contain exact R1-R10.');
|
|
120
|
+
}
|
|
121
|
+
if (rules.rules.some((rule) => !rule.enforcementPoints.length || !rule.testRefs.length || !rule.citedBy.length)) {
|
|
122
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Every rule requires enforcement, tests, and citations.');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const inventory = commands.inventory;
|
|
126
|
+
if (inventory.rootCommandModules !== 39 || inventory.rootCommandSlugs.length !== 39
|
|
127
|
+
|| inventory.pipelineMachineLeaves !== 31 || inventory.pipelineMachineGrammar.length !== 31
|
|
128
|
+
|| inventory.frozenClaudeDocuments !== 8 || inventory.frozenClaudeSlugs.length !== 8) {
|
|
129
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Command inventory floors drifted.');
|
|
130
|
+
}
|
|
131
|
+
assertSortedUnique(commands.commands, 'commandId', 'commands.json');
|
|
132
|
+
const grammar = commands.commands.map(({ argv }) => JSON.stringify(argv));
|
|
133
|
+
if (new Set(grammar).size !== grammar.length) fail(PROTOCOL_ERROR_CODES.DUPLICATE_ID, 'Command grammar contains duplicate argv entries.');
|
|
134
|
+
if (commands.commands.some(({ argv }) => argv[0] === 'pipeline' && argv[1] === 'operate')) {
|
|
135
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Retired pipeline Operate grammar became callable.');
|
|
136
|
+
}
|
|
137
|
+
if (!commands.commands.some(({ argv, lifecycle }) => argv[0] === 'operate' && lifecycle === 'active')
|
|
138
|
+
|| !commands.negativeContracts.some(({ forbiddenArgvPrefix }) => equal(forbiddenArgvPrefix, ['pipeline', 'operate']))) {
|
|
139
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Operate facade/retirement negative contract drifted.');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
assertSortedUnique(skills.skills, 'skillId', 'skills.json');
|
|
143
|
+
const skillIds = skills.skills.map(({ skillId }) => skillId);
|
|
144
|
+
if (!equal(skillIds, EXPECTED_SKILLS)) {
|
|
145
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Canonical skill membership differs from the active source registry.');
|
|
146
|
+
}
|
|
147
|
+
if (skillIds.some((id) => canonicalRoleIds.has(id)) || skills.skills.some((skill) => skill.hosts.length < 3 || !skill.certificationRefs.length)) {
|
|
148
|
+
fail(PROTOCOL_ERROR_CODES.DUPLICATE_ID, 'Skill/role IDs collide or a skill lacks host/certification parity.');
|
|
149
|
+
}
|
|
150
|
+
const ship = skills.skills.find(({ skillId }) => skillId === 'planr-ship');
|
|
151
|
+
if (!equal(ship?.contracts?.outputs, [{ id: 'implementation-result', version: '1.0.0' }])) {
|
|
152
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, 'Planr Ship must produce the canonical implementation result.');
|
|
153
|
+
}
|
|
154
|
+
const aliasIds = skills.compatibilityAliases.map(({ aliasId }) => aliasId).sort();
|
|
155
|
+
if (aliasIds.length !== 0) {
|
|
156
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Protocol 1.8 canonical skills must not expose compatibility aliases.');
|
|
157
|
+
}
|
|
158
|
+
for (const command of commands.commands.filter(({ surface }) => surface === 'frozen-host-alias')) {
|
|
159
|
+
if (!skillIds.includes(command.skillId)) fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Frozen command ${command.commandId} has no canonical skill.`);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
assertSortedUnique(outputs.outputs, 'outputId', 'outputs.json');
|
|
163
|
+
if (!['A', 'B', 'C', 'D'].every((outputClass) => outputs.outputs.some((output) => output.outputClass === outputClass))) {
|
|
164
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Output catalog must cover Classes A-D.');
|
|
165
|
+
}
|
|
166
|
+
if (outputs.outputs.some((output) => !output.generator || !output.validator || !output.compatibilityReaders.length || !output.testRefs.length)) {
|
|
167
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, 'Every output requires generator, validator, reader, and test custody.');
|
|
168
|
+
}
|
|
169
|
+
const modeAwarePlanningIds = ['gherkin-feature', 'professional-specification', 'task', 'user-story'];
|
|
170
|
+
assertSortedUnique(outputPaths.outputs, 'outputId', 'output-paths.json');
|
|
171
|
+
if (outputPaths.outputCatalogDigest !== outputs.documentDigest
|
|
172
|
+
|| !equal(outputPaths.outputs.map(({ outputId }) => outputId), modeAwarePlanningIds)) {
|
|
173
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, 'Project-mode paths must bind the exact output catalog and complete planning output set.');
|
|
174
|
+
}
|
|
175
|
+
for (const outputPath of outputPaths.outputs) {
|
|
176
|
+
const output = outputs.outputs.find(({ outputId }) => outputId === outputPath.outputId);
|
|
177
|
+
if (outputPath.pathTemplates.default !== output?.pathTemplate
|
|
178
|
+
|| !outputPath.pathTemplates['spec-driven']) {
|
|
179
|
+
fail(PROTOCOL_ERROR_CODES.REGISTRY_INVALID, `Output ${outputPath.outputId} has an invalid project-mode path contract.`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
validateCanonicalRegistries();
|
|
186
|
+
|
|
187
|
+
const roleIndex = new Map(CANONICAL_REGISTRIES['roles.json'].roles.map((role) => [role.roleId, role]));
|
|
188
|
+
const aliasIndex = new Map(CANONICAL_REGISTRIES['roles.json'].roles.flatMap((role) => role.legacyAliases.map(({ id }) => [id, role])));
|
|
189
|
+
const taskKindIndex = new Map(CANONICAL_REGISTRIES['task-kinds.json'].bindings.map((binding) => [binding.taskKind, binding]));
|
|
190
|
+
|
|
191
|
+
export { CANONICAL_REGISTRIES };
|
|
192
|
+
|
|
193
|
+
export function getCanonicalRegistry(name) {
|
|
194
|
+
const value = CANONICAL_REGISTRIES[name];
|
|
195
|
+
if (!value) fail(PROTOCOL_ERROR_CODES.ASSET_NOT_FOUND, `Unknown canonical registry: ${name}`);
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function getRole(roleId) {
|
|
200
|
+
const role = roleIndex.get(roleId);
|
|
201
|
+
if (!role) fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Unknown canonical role: ${roleId}`);
|
|
202
|
+
return role;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function resolveLegacyRoleAlias(alias) {
|
|
206
|
+
return aliasIndex.get(alias) ?? null;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function resolveTaskKind(taskKind) {
|
|
210
|
+
const binding = taskKindIndex.get(taskKind);
|
|
211
|
+
if (!binding) fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Unknown task kind: ${taskKind}`);
|
|
212
|
+
return binding;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Resolve one output definition from the canonical catalog or a compatible supplied catalog. */
|
|
216
|
+
export function getOutput(outputId, registries = CANONICAL_REGISTRIES) {
|
|
217
|
+
const output = registries['outputs.json']?.outputs?.find((candidate) => candidate.outputId === outputId);
|
|
218
|
+
if (!output) fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Unknown output: ${outputId}`);
|
|
219
|
+
return output;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Select the canonical template for one project mode while preserving legacy catalog fallback. */
|
|
223
|
+
export function getOutputPathTemplate(outputId, projectMode = 'default', registries = CANONICAL_REGISTRIES) {
|
|
224
|
+
if (projectMode !== 'default' && projectMode !== 'spec-driven') {
|
|
225
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Unknown project mode: ${projectMode}`);
|
|
226
|
+
}
|
|
227
|
+
const output = getOutput(outputId, registries);
|
|
228
|
+
const outputPath = registries['output-paths.json']?.outputs?.find((candidate) => candidate.outputId === outputId);
|
|
229
|
+
return outputPath?.pathTemplates?.[projectMode] ?? output.pathTemplate;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const PATH_TOKEN = /\{([A-Za-z][A-Za-z0-9]*)\}/gu;
|
|
233
|
+
const SAFE_RELATIVE_PATH = /^(?!\/)(?![A-Za-z]:)(?!.*\\)(?!.*(?:^|\/)\.{1,2}(?:\/|$))(?!.*\/\/).+$/u;
|
|
234
|
+
const MAX_RELATIVE_PATH_LENGTH = 1024;
|
|
235
|
+
|
|
236
|
+
/** Resolve one catalog path with explicit mode and named template arguments. */
|
|
237
|
+
export function resolveOutputPath(outputId, options = {}, registries = CANONICAL_REGISTRIES) {
|
|
238
|
+
const { projectMode = 'default', pathArguments = {} } = options;
|
|
239
|
+
const template = getOutputPathTemplate(outputId, projectMode, registries);
|
|
240
|
+
const missing = [...new Set([...template.matchAll(PATH_TOKEN)].map((match) => match[1]))]
|
|
241
|
+
.filter((name) => typeof pathArguments[name] !== 'string' || pathArguments[name].length === 0);
|
|
242
|
+
if (missing.length > 0) {
|
|
243
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Output ${outputId} path is missing arguments: ${missing.join(', ')}.`, { outputId, projectMode, missing });
|
|
244
|
+
}
|
|
245
|
+
const resolved = template.replace(PATH_TOKEN, (_token, name) => pathArguments[name]);
|
|
246
|
+
if (resolved.length > MAX_RELATIVE_PATH_LENGTH
|
|
247
|
+
|| !SAFE_RELATIVE_PATH.test(resolved)
|
|
248
|
+
|| /[\u0000\r\n]/u.test(resolved)) {
|
|
249
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Output ${outputId} resolved to an invalid relative path.`, { outputId, projectMode });
|
|
250
|
+
}
|
|
251
|
+
return resolved;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Route only explicit legacy fields; prose, filenames, hosts, and models are never evidence. */
|
|
255
|
+
export function routeLegacyTask({ legacyType, legacyAgent = null }) {
|
|
256
|
+
const mappings = CANONICAL_REGISTRIES['task-kinds.json'].legacyMappings;
|
|
257
|
+
const exact = mappings.find((mapping) => mapping.legacyType === legacyType && mapping.legacyAgent === legacyAgent);
|
|
258
|
+
if (exact) return resolveTaskKind(exact.taskKind);
|
|
259
|
+
if (legacyType === 'Tech' && legacyAgent === null) return resolveTaskKind('backend');
|
|
260
|
+
fail(PROTOCOL_ERROR_CODES.REFERENCE_INVALID, `Legacy routing requires an explicit reviewed mapping for ${legacyType}/${legacyAgent ?? '<none>'}.`);
|
|
261
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const DESIGN_REVIEW_CONTEXT_SCHEMA: Readonly<Record<string, unknown>>;
|
|
2
|
+
export declare const DESIGN_FINGERPRINT_SCHEMA: Readonly<Record<string, unknown>>;
|
|
3
|
+
export declare const DESIGN_REVIEW_BUNDLE_V11_SCHEMA: Readonly<Record<string, unknown>>;
|
|
4
|
+
export declare const DESIGN_HANDOFF_CONTENT_SCHEMA: Readonly<Record<string, unknown>>;
|
|
5
|
+
export declare const DESIGN_HANDOFF_SCHEMA: Readonly<Record<string, unknown>>;
|
|
6
|
+
export declare const DESIGN_REVIEW_METADATA_PAYLOAD_SCHEMA: Readonly<Record<string, unknown>>;
|
|
7
|
+
export declare const DESIGN_REVIEW_METADATA_PAYLOAD_V11_SCHEMA: Readonly<Record<string, unknown>>;
|
|
8
|
+
export declare const REVIEW_EXPERIENCE_SCHEMAS: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
|
|
9
|
+
export declare function assertReviewExperience<T>(value: T, contract: Readonly<Record<string, unknown>>): T;
|
|
10
|
+
export declare function assertDesignReviewBundle<T>(value: T): T;
|
|
11
|
+
export declare function assertDesignReviewMetadata<T>(value: T): T;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { validateJson } from './json-schema.mjs';
|
|
2
|
+
import { DESIGN_REVIEW_BUNDLE_SCHEMA } from './workspace-contracts.mjs';
|
|
3
|
+
import { canonicalizeJson, sha256Hex } from './canonical-json.mjs';
|
|
4
|
+
|
|
5
|
+
const text = { type: 'string', maxLength: 16384 };
|
|
6
|
+
const id = { type: 'string', minLength: 1, maxLength: 128 };
|
|
7
|
+
const digest = { type: 'string', pattern: '^[a-f0-9]{64}$' };
|
|
8
|
+
const texts = { type: 'array', maxItems: 256, items: text };
|
|
9
|
+
const closed = (properties, required = Object.keys(properties)) => ({ type: 'object', additionalProperties: false, properties, required });
|
|
10
|
+
const list = (items, maxItems = 256) => ({ type: 'array', maxItems, items });
|
|
11
|
+
const schema = (name, properties, required) => ({
|
|
12
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
13
|
+
$id: `https://openplanr.dev/schemas/v1.10.0/${name}.schema.json`,
|
|
14
|
+
'x-openplanr-contract': { id: name, version: '1.10.0' },
|
|
15
|
+
...closed(properties, required),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const DESIGN_REVIEW_CONTEXT_SCHEMA = schema('design-review-context', {
|
|
19
|
+
kind: { const: 'openplanr-design-review-context' }, schemaVersion: { const: '1.0.0' }, designId: id,
|
|
20
|
+
brief: closed({ purpose: text, requests: { ...texts, maxItems: 3 }, audience: text }, ['purpose', 'requests']),
|
|
21
|
+
revisionSummary: text,
|
|
22
|
+
implementation: closed({
|
|
23
|
+
tokens: list(closed({ name: id, value: text, description: text }, ['name', 'value']), 512),
|
|
24
|
+
components: list(closed({ id, name: text, screenIds: list(id), anchorIds: list(id), states: list(closed({ name: id, description: text })), notes: text, responsive: text, accessibility: text }, ['id', 'name'])),
|
|
25
|
+
responsive: texts, accessibility: texts,
|
|
26
|
+
}),
|
|
27
|
+
}, ['kind', 'schemaVersion', 'designId', 'brief', 'implementation']);
|
|
28
|
+
|
|
29
|
+
export const DESIGN_FINGERPRINT_SCHEMA = closed({ screenId: id, variantId: id, frameId: id, contentDigest: digest, guidanceDigest: digest });
|
|
30
|
+
export const DESIGN_REVIEW_BUNDLE_V11_SCHEMA = {
|
|
31
|
+
...structuredClone(DESIGN_REVIEW_BUNDLE_SCHEMA),
|
|
32
|
+
$id: 'https://openplanr.dev/schemas/v1.10.0/design-review-bundle.schema.json',
|
|
33
|
+
'x-openplanr-contract': { id: 'design-review-bundle', version: '1.10.0' },
|
|
34
|
+
};
|
|
35
|
+
Object.assign(DESIGN_REVIEW_BUNDLE_V11_SCHEMA.properties, {
|
|
36
|
+
schemaVersion: { const: '1.1.0' }, reviewContext: DESIGN_REVIEW_CONTEXT_SCHEMA,
|
|
37
|
+
contextDigest: digest, fingerprints: list(DESIGN_FINGERPRINT_SCHEMA),
|
|
38
|
+
});
|
|
39
|
+
DESIGN_REVIEW_BUNDLE_V11_SCHEMA.required.push('reviewContext', 'contextDigest', 'fingerprints');
|
|
40
|
+
|
|
41
|
+
const item = closed({ pinId: id, reviewId: id, screenId: id, revisionId: id, text, refinement: text, stale: { type: 'boolean' }, author: text, reviewOf: digest, source: text }, ['pinId', 'text']);
|
|
42
|
+
export const DESIGN_HANDOFF_CONTENT_SCHEMA = closed({ summary: text, agreedChanges: list(item, 10000), openQuestions: list(item, 10000), deferred: list(item, 10000), rejected: list(item, 10000) });
|
|
43
|
+
export const DESIGN_HANDOFF_SCHEMA = schema('design-review-handoff', {
|
|
44
|
+
kind: { const: 'openplanr-design-review-handoff' }, schemaVersion: { const: '1.0.0' },
|
|
45
|
+
title: text, version: { type: 'integer', minimum: 1 }, status: { enum: ['draft', 'approved'] },
|
|
46
|
+
basis: closed({ designId: id, sourceRevision: digest, contextDigest: digest, reviewOf: digest, selectedVariant: id, feedbackDigest: digest, verificationDigest: digest, feedbackWatermark: { type: 'integer', minimum: 0 } }),
|
|
47
|
+
content: DESIGN_HANDOFF_CONTENT_SCHEMA, contentHash: digest, markdown: { type: 'string', maxLength: 2097152 },
|
|
48
|
+
affectedScreens: list(id), verificationGaps: texts, reviewNotes: list(closed({reviewId:id,text}),10000),
|
|
49
|
+
approval: closed({ contentHash: digest, at: { type: 'string', format: 'date-time' } }),
|
|
50
|
+
}, ['kind', 'schemaVersion', 'title', 'version', 'status', 'basis', 'content', 'contentHash', 'markdown', 'affectedScreens', 'verificationGaps', 'reviewNotes']);
|
|
51
|
+
|
|
52
|
+
export const DESIGN_REVIEW_METADATA_PAYLOAD_SCHEMA = schema('design-review-metadata-payload', {
|
|
53
|
+
schemaVersion: { const: '1.0.0' }, kind: { enum: ['category', 'disposition'] }, author: { ...text, minLength: 1, maxLength: 160 },
|
|
54
|
+
reviewOf: digest, pinId: id, category: { enum: ['question', 'suggestion', 'blocker'] },
|
|
55
|
+
disposition: { enum: ['accepted', 'deferred', 'rejected'] }, reason: text,
|
|
56
|
+
updatedAt: { type: 'string', format: 'date-time' },
|
|
57
|
+
}, ['schemaVersion', 'kind', 'author', 'reviewOf', 'pinId', 'updatedAt']);
|
|
58
|
+
DESIGN_REVIEW_METADATA_PAYLOAD_SCHEMA.allOf = [
|
|
59
|
+
{ if: { properties: { kind: { const: 'category' } } }, then: { required: ['category'], not: { required: ['disposition'] } } },
|
|
60
|
+
{ if: { properties: { kind: { const: 'disposition' } } }, then: { required: ['disposition', 'reason'], not: { required: ['category'] } } },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
// A request to change the product is distinct from a suggestion or a blocker.
|
|
64
|
+
// Keep the closed 1.0.0 payload intact for existing signed review history.
|
|
65
|
+
export const DESIGN_REVIEW_METADATA_PAYLOAD_V11_SCHEMA = {
|
|
66
|
+
...structuredClone(DESIGN_REVIEW_METADATA_PAYLOAD_SCHEMA),
|
|
67
|
+
$id: 'https://openplanr.dev/schemas/v1.11.0/design-review-metadata-payload.schema.json',
|
|
68
|
+
'x-openplanr-contract': { id: 'design-review-metadata-payload', version: '1.11.0' },
|
|
69
|
+
};
|
|
70
|
+
Object.assign(DESIGN_REVIEW_METADATA_PAYLOAD_V11_SCHEMA.properties, {
|
|
71
|
+
schemaVersion: { const: '1.1.0' },
|
|
72
|
+
category: { enum: ['question', 'suggestion', 'change-request', 'blocker'] },
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
export function assertReviewExperience(value, contract) {
|
|
76
|
+
const errors = validateJson(value, contract);
|
|
77
|
+
if (errors.length) throw new TypeError(`Invalid ${contract['x-openplanr-contract']?.id ?? 'review data'}: ${errors.slice(0, 4).map(item => `${item.path} ${item.detail}`).join('; ')}`);
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
export function assertDesignReviewMetadata(value) {
|
|
81
|
+
return assertReviewExperience(value, value?.schemaVersion === '1.1.0' ? DESIGN_REVIEW_METADATA_PAYLOAD_V11_SCHEMA : DESIGN_REVIEW_METADATA_PAYLOAD_SCHEMA);
|
|
82
|
+
}
|
|
83
|
+
export function assertDesignReviewBundle(value) {
|
|
84
|
+
assertReviewExperience(value, value?.schemaVersion === '1.1.0' ? DESIGN_REVIEW_BUNDLE_V11_SCHEMA : DESIGN_REVIEW_BUNDLE_SCHEMA);
|
|
85
|
+
if (value.schemaVersion === '1.1.0') {
|
|
86
|
+
if (value.reviewContext.designId !== value.design.id || value.contextDigest !== sha256Hex(canonicalizeJson(value.reviewContext))) throw new TypeError('Review context identity or digest does not match its published design.');
|
|
87
|
+
const entries = new Set(value.entries.map(entry => `${entry.screenId}:${entry.variantId}:${entry.frameId}`));
|
|
88
|
+
const seen = new Set();
|
|
89
|
+
for (const item of value.fingerprints) {
|
|
90
|
+
const key = `${item.screenId}:${item.variantId}:${item.frameId}`;
|
|
91
|
+
if (!entries.has(key) || seen.has(key)) throw new TypeError('Review fingerprints must identify distinct published artboards.');
|
|
92
|
+
seen.add(key);
|
|
93
|
+
}
|
|
94
|
+
if (seen.size && seen.size !== entries.size) throw new TypeError('Review fingerprints must cover every published artboard.');
|
|
95
|
+
}
|
|
96
|
+
return value;
|
|
97
|
+
}
|
|
98
|
+
export const REVIEW_EXPERIENCE_SCHEMAS = Object.freeze({
|
|
99
|
+
'design-review-context': DESIGN_REVIEW_CONTEXT_SCHEMA,
|
|
100
|
+
'design-review-bundle': DESIGN_REVIEW_BUNDLE_V11_SCHEMA,
|
|
101
|
+
'design-review-handoff': DESIGN_HANDOFF_SCHEMA,
|
|
102
|
+
'design-review-metadata-payload': DESIGN_REVIEW_METADATA_PAYLOAD_SCHEMA,
|
|
103
|
+
});
|
package/src/semver.d.mts
ADDED
package/src/semver.mjs
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Canonical SemVer 2.0.0 grammar (semver.org BNF). One source of truth so the
|
|
2
|
+
// skill-source JSON Schema and the compiler graph share a single definition of
|
|
3
|
+
// "exact version" and can never drift. Rejects empty dot-separated identifiers,
|
|
4
|
+
// leading-zero numeric identifiers, and empty prerelease/build segments.
|
|
5
|
+
export const SEMVER_PATTERN = '^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-((?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(?:\\.(?:0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\\+([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?$';
|
|
6
|
+
|
|
7
|
+
export const SEMVER_REGEX = new RegExp(SEMVER_PATTERN, 'u');
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const SKILL_SOURCE_V16_CONTRACT_FILES: Readonly<Record<string, string>>;
|
|
2
|
+
export declare const DIAGRAM_V16_CONTRACT_FILES: Readonly<Record<string, string>>;
|
|
3
|
+
export declare const PROTOCOL_V16_CONTRACT_FILES: Readonly<Record<string, string>>;
|
|
4
|
+
export declare const SKILL_SOURCE_V17_CONTRACT_FILES: Readonly<Record<string, string>>;
|
|
5
|
+
export declare const PLANNING_V17_CONTRACT_FILES: Readonly<Record<string, string>>;
|
|
6
|
+
export declare const PROTOCOL_V17_CONTRACT_FILES: Readonly<Record<string, string>>;
|
|
7
|
+
export declare const SKILL_PACKAGE_V18_CONTRACT_FILES: Readonly<Record<string, string>>;
|
|
8
|
+
export declare const PROTOCOL_V18_CONTRACT_FILES: Readonly<Record<string, string>>;
|
|
9
|
+
export declare const SKILL_SOURCE_V16_REGISTRIES: Readonly<Record<string, Readonly<{
|
|
10
|
+
kind: string;
|
|
11
|
+
protocolVersion: '1.6.0';
|
|
12
|
+
}>>>;
|
|
13
|
+
export declare const DIAGRAM_V16_REGISTRIES: Readonly<Record<string, Readonly<{
|
|
14
|
+
kind: string;
|
|
15
|
+
protocolVersion: '1.6.0';
|
|
16
|
+
}>>>;
|
|
17
|
+
export declare const PROTOCOL_V16_REGISTRIES: Readonly<Record<string, Readonly<{
|
|
18
|
+
kind: string;
|
|
19
|
+
protocolVersion: '1.6.0';
|
|
20
|
+
}>>>;
|
|
21
|
+
export declare const SKILL_SOURCE_V17_REGISTRIES: Readonly<Record<string, Readonly<{
|
|
22
|
+
kind: string;
|
|
23
|
+
protocolVersion: '1.7.0';
|
|
24
|
+
}>>>;
|
|
25
|
+
export declare const PROTOCOL_V17_REGISTRIES: typeof SKILL_SOURCE_V17_REGISTRIES;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Protocol 1.6 grows by additive contract families. Keep each family explicit,
|
|
2
|
+
// then expose one aggregate map to schema resolvers and browser consumers.
|
|
3
|
+
export const SKILL_SOURCE_V16_CONTRACT_FILES = Object.freeze({
|
|
4
|
+
'generated-asset-manifest': 'generated-asset-manifest.schema.json',
|
|
5
|
+
'skill-catalog': 'skill-catalog.schema.json',
|
|
6
|
+
'skill-completion-receipt': 'skill-completion-receipt.schema.json',
|
|
7
|
+
'skill-consent-record': 'skill-consent-record.schema.json',
|
|
8
|
+
'skill-host-profile-registry': 'skill-host-profile-registry.schema.json',
|
|
9
|
+
'skill-learning-record': 'skill-learning-record.schema.json',
|
|
10
|
+
'skill-module-registry': 'skill-module-registry.schema.json',
|
|
11
|
+
'skill-routing-registry': 'skill-routing-registry.schema.json',
|
|
12
|
+
'skill-session': 'skill-session.schema.json',
|
|
13
|
+
'skill-source': 'skill-source.schema.json',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const DIAGRAM_V16_CONTRACT_FILES = Object.freeze({
|
|
17
|
+
'diagram-consumer-reference': 'diagram-consumer-reference.schema.json',
|
|
18
|
+
'diagram-document': 'diagram-document.schema.json',
|
|
19
|
+
'diagram-fidelity-report': 'diagram-fidelity-report.schema.json',
|
|
20
|
+
'diagram-manifest': 'diagram-manifest.schema.json',
|
|
21
|
+
'diagram-quality-report': 'diagram-quality-report.schema.json',
|
|
22
|
+
'diagram-review-binding': 'diagram-review-binding.schema.json',
|
|
23
|
+
'diagram-semantic-pattern-registry': 'diagram-semantic-pattern-registry.schema.json',
|
|
24
|
+
'diagram-type-registry': 'diagram-type-registry.schema.json',
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export const PROTOCOL_V16_CONTRACT_FILES = Object.freeze({
|
|
28
|
+
...SKILL_SOURCE_V16_CONTRACT_FILES,
|
|
29
|
+
...DIAGRAM_V16_CONTRACT_FILES,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const SKILL_SOURCE_V17_CONTRACT_FILES = SKILL_SOURCE_V16_CONTRACT_FILES;
|
|
33
|
+
|
|
34
|
+
export const PLANNING_V17_CONTRACT_FILES = Object.freeze({
|
|
35
|
+
'planning-id-sequence': 'planning-id-sequence.schema.json',
|
|
36
|
+
'request-authority': 'request-authority.schema.json',
|
|
37
|
+
spec: 'spec.schema.json',
|
|
38
|
+
story: 'story.schema.json',
|
|
39
|
+
task: 'task.schema.json',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export const PROTOCOL_V17_CONTRACT_FILES = Object.freeze({
|
|
43
|
+
...SKILL_SOURCE_V17_CONTRACT_FILES,
|
|
44
|
+
...PLANNING_V17_CONTRACT_FILES,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export const SKILL_PACKAGE_V18_CONTRACT_FILES = Object.freeze({
|
|
48
|
+
'skill-package': 'skill-package.schema.json',
|
|
49
|
+
'utility-command-catalog': 'utility-command-catalog.schema.json',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export const PROTOCOL_V18_CONTRACT_FILES = SKILL_PACKAGE_V18_CONTRACT_FILES;
|
|
53
|
+
|
|
54
|
+
// Canonical classification for the additive registries stored in the shared
|
|
55
|
+
// registries/ directory. Projection, preservation, and ecosystem generators
|
|
56
|
+
// derive version custody from this descriptor instead of owning filename lists.
|
|
57
|
+
export const SKILL_SOURCE_V16_REGISTRIES = Object.freeze({
|
|
58
|
+
'skill-host-profiles.json': Object.freeze({
|
|
59
|
+
kind: 'skill-host-profile-registry',
|
|
60
|
+
protocolVersion: '1.6.0',
|
|
61
|
+
schemaVersion: '1.1.0',
|
|
62
|
+
documentVersion: '1.1.0',
|
|
63
|
+
}),
|
|
64
|
+
'skill-modules.json': Object.freeze({
|
|
65
|
+
kind: 'skill-module-registry',
|
|
66
|
+
protocolVersion: '1.6.0',
|
|
67
|
+
schemaVersion: '1.0.0',
|
|
68
|
+
documentVersion: '1.0.0',
|
|
69
|
+
}),
|
|
70
|
+
'skill-routing.json': Object.freeze({
|
|
71
|
+
kind: 'skill-routing-registry',
|
|
72
|
+
protocolVersion: '1.6.0',
|
|
73
|
+
schemaVersion: '1.0.0',
|
|
74
|
+
documentVersion: '1.0.0',
|
|
75
|
+
}),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
export const DIAGRAM_V16_REGISTRIES = Object.freeze({
|
|
79
|
+
'diagram-grammars.json': Object.freeze({
|
|
80
|
+
kind: 'diagram-type-registry',
|
|
81
|
+
protocolVersion: '1.6.0',
|
|
82
|
+
schemaVersion: '1.0.0',
|
|
83
|
+
documentVersion: '1.0.0',
|
|
84
|
+
}),
|
|
85
|
+
'diagram-semantic-patterns.json': Object.freeze({
|
|
86
|
+
kind: 'diagram-semantic-pattern-registry',
|
|
87
|
+
protocolVersion: '1.6.0',
|
|
88
|
+
schemaVersion: '1.0.0',
|
|
89
|
+
documentVersion: '1.0.0',
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
export const PROTOCOL_V16_REGISTRIES = Object.freeze({
|
|
94
|
+
...SKILL_SOURCE_V16_REGISTRIES,
|
|
95
|
+
...DIAGRAM_V16_REGISTRIES,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
export const SKILL_SOURCE_V17_REGISTRIES = Object.freeze(Object.fromEntries(
|
|
99
|
+
Object.entries(SKILL_SOURCE_V16_REGISTRIES).map(([file, descriptor]) => [file, Object.freeze({
|
|
100
|
+
...descriptor,
|
|
101
|
+
protocolVersion: '1.7.0',
|
|
102
|
+
})]),
|
|
103
|
+
));
|
|
104
|
+
|
|
105
|
+
export const PROTOCOL_V17_REGISTRIES = SKILL_SOURCE_V17_REGISTRIES;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ProtocolSemanticDiagnostic { code: string; path: string; message: string }
|
|
2
|
+
export declare function validateTaskManifestSemantics(value: unknown, options?: object): ProtocolSemanticDiagnostic[];
|
|
3
|
+
export declare function assertTaskManifestSemantics<T>(value: T, options?: object): T;
|
|
4
|
+
export declare function validateTaskGraph(values: unknown[]): ProtocolSemanticDiagnostic[];
|
|
5
|
+
export declare function countR2Tasks(values: unknown[]): number;
|
|
6
|
+
export declare function validateTaskOutputSemantics(value: unknown, options?: { taskManifest?: any }): ProtocolSemanticDiagnostic[];
|
|
7
|
+
export declare function assertTaskOutputSemantics<T>(value: T, options?: { taskManifest?: any }): T;
|