project-tiny-context-harness 0.8.17 → 0.11.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/README.md +93 -30
- package/assets/README.md +158 -44
- package/assets/README.zh-CN.md +88 -29
- package/assets/agents/AGENTS_CORE.md +2 -2
- package/assets/context_templates/context.toml +6 -1
- package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_helpers.cs +301 -0
- package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_run.cs +197 -0
- package/assets/runtime/windows-job-supervisor/formal_process_supervisor_native_types.cs +215 -0
- package/assets/runtime/windows-job-supervisor/windows_job_process_supervisor.ps1 +117 -0
- package/assets/skills/design-resource-authoring/SKILL.md +6 -3
- package/assets/skills/design-resource-authoring/references/authority-delta-assessment.md +52 -0
- package/assets/skills/design-resource-authoring/references/downstream-handoff.md +5 -1
- package/assets/skills/design-system-authoring/SKILL.md +23 -17
- package/assets/skills/design-system-authoring/references/authority-adoption.md +19 -9
- package/assets/skills/design-system-authoring/references/open-design-design-system-provider.md +4 -0
- package/assets/skills/long-task-workflow/SKILL.md +6 -6
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +10 -4
- package/assets/skills/long-task-workflow/references/contract-authoring.md +5 -5
- package/assets/skills/long-task-workflow/references/evidence-design.md +14 -3
- package/assets/skills/long-task-workflow/references/source-authoring.md +11 -8
- package/assets/tools/context_rules.json +53 -0
- package/assets/tools/validate_context.py +302 -77
- package/dist/cli.js +2 -1
- package/dist/commands/context-create.d.ts +1 -0
- package/dist/commands/context-create.js +90 -0
- package/dist/commands/context-inspect.d.ts +1 -0
- package/dist/commands/context-inspect.js +98 -0
- package/dist/commands/context-move.d.ts +1 -0
- package/dist/commands/context-move.js +78 -0
- package/dist/commands/context-register.d.ts +1 -0
- package/dist/commands/context-register.js +110 -0
- package/dist/commands/context-transaction.d.ts +1 -0
- package/dist/commands/context-transaction.js +84 -0
- package/dist/commands/context.d.ts +1 -0
- package/dist/commands/context.js +36 -0
- package/dist/commands/design-authority-delta.d.ts +1 -0
- package/dist/commands/design-authority-delta.js +53 -0
- package/dist/commands/design-authority.d.ts +1 -0
- package/dist/commands/design-authority.js +104 -0
- package/dist/commands/design-resource.js +8 -1
- package/dist/commands/doctor.d.ts +1 -1
- package/dist/commands/doctor.js +61 -3
- package/dist/commands/index.js +19 -2
- package/dist/commands/long-task-authoring.js +20 -2
- package/dist/commands/long-task-workdir.d.ts +2 -0
- package/dist/commands/long-task-workdir.js +23 -0
- package/dist/commands/long-task.js +75 -6
- package/dist/commands/route.d.ts +15 -0
- package/dist/commands/route.js +142 -0
- package/dist/index.d.ts +3 -13
- package/dist/index.js +3 -12
- package/dist/lib/cli-exit.d.ts +14 -0
- package/dist/lib/cli-exit.js +19 -0
- package/dist/lib/context-catalog/catalog-default-footprint.d.ts +3 -0
- package/dist/lib/context-catalog/catalog-default-footprint.js +53 -0
- package/dist/lib/context-catalog/catalog-diagnostics.d.ts +9 -0
- package/dist/lib/context-catalog/catalog-diagnostics.js +34 -0
- package/dist/lib/context-catalog/catalog-discovery.d.ts +7 -0
- package/dist/lib/context-catalog/catalog-discovery.js +81 -0
- package/dist/lib/context-catalog/catalog-load.d.ts +8 -0
- package/dist/lib/context-catalog/catalog-load.js +187 -0
- package/dist/lib/context-catalog/catalog-path-validation.d.ts +7 -0
- package/dist/lib/context-catalog/catalog-path-validation.js +62 -0
- package/dist/lib/context-catalog/catalog-paths.d.ts +11 -0
- package/dist/lib/context-catalog/catalog-paths.js +41 -0
- package/dist/lib/context-catalog/catalog-portable-contract.d.ts +15 -0
- package/dist/lib/context-catalog/catalog-portable-contract.js +68 -0
- package/dist/lib/context-catalog/catalog-staged-path-safety.d.ts +1 -0
- package/dist/lib/context-catalog/catalog-staged-path-safety.js +36 -0
- package/dist/lib/context-catalog/catalog-types.d.ts +40 -0
- package/dist/lib/context-catalog/catalog-types.js +1 -0
- package/dist/lib/context-catalog/catalog-validation.d.ts +9 -0
- package/dist/lib/context-catalog/catalog-validation.js +148 -0
- package/dist/lib/context-create/context-create-path.d.ts +2 -0
- package/dist/lib/context-create/context-create-path.js +30 -0
- package/dist/lib/context-create/context-create-template.d.ts +2 -0
- package/dist/lib/context-create/context-create-template.js +95 -0
- package/dist/lib/context-create/context-create-types.d.ts +28 -0
- package/dist/lib/context-create/context-create-types.js +1 -0
- package/dist/lib/context-create/context-create-write.d.ts +1 -0
- package/dist/lib/context-create/context-create-write.js +85 -0
- package/dist/lib/context-create/context-create.d.ts +2 -0
- package/dist/lib/context-create/context-create.js +84 -0
- package/dist/lib/context-default-footprint.d.ts +2 -3
- package/dist/lib/context-default-footprint.js +49 -57
- package/dist/lib/context-doctor/context-doctor-types.d.ts +16 -0
- package/dist/lib/context-doctor/context-doctor-types.js +15 -0
- package/dist/lib/context-doctor/context-doctor.d.ts +2 -0
- package/dist/lib/context-doctor/context-doctor.js +130 -0
- package/dist/lib/context-graph-snapshot.d.ts +5 -0
- package/dist/lib/context-graph-snapshot.js +46 -25
- package/dist/lib/context-inspect/context-inspect-projection.d.ts +9 -0
- package/dist/lib/context-inspect/context-inspect-projection.js +49 -0
- package/dist/lib/context-inspect/context-inspect-render.d.ts +2 -0
- package/dist/lib/context-inspect/context-inspect-render.js +29 -0
- package/dist/lib/context-inspect/context-inspect-types.d.ts +43 -0
- package/dist/lib/context-inspect/context-inspect-types.js +1 -0
- package/dist/lib/context-inspect/context-inspect.d.ts +2 -0
- package/dist/lib/context-inspect/context-inspect.js +104 -0
- package/dist/lib/context-manifest-schema.d.ts +1 -1
- package/dist/lib/context-manifest-schema.js +4 -20
- package/dist/lib/context-markdown/context-markdown-analysis.d.ts +15 -0
- package/dist/lib/context-markdown/context-markdown-analysis.js +245 -0
- package/dist/lib/context-markdown/context-markdown-extract.d.ts +7 -0
- package/dist/lib/context-markdown/context-markdown-extract.js +114 -0
- package/dist/lib/context-markdown/context-markdown-types.d.ts +57 -0
- package/dist/lib/context-markdown/context-markdown-types.js +1 -0
- package/dist/lib/context-move/context-move-input.d.ts +8 -0
- package/dist/lib/context-move/context-move-input.js +17 -0
- package/dist/lib/context-move/context-move-literal-scan.d.ts +20 -0
- package/dist/lib/context-move/context-move-literal-scan.js +213 -0
- package/dist/lib/context-move/context-move-live-validation.d.ts +3 -0
- package/dist/lib/context-move/context-move-live-validation.js +56 -0
- package/dist/lib/context-move/context-move-markdown-plan.d.ts +22 -0
- package/dist/lib/context-move/context-move-markdown-plan.js +39 -0
- package/dist/lib/context-move/context-move-projection.d.ts +3 -0
- package/dist/lib/context-move/context-move-projection.js +11 -0
- package/dist/lib/context-move/context-move-reference-validation.d.ts +11 -0
- package/dist/lib/context-move/context-move-reference-validation.js +64 -0
- package/dist/lib/context-move/context-move-render.d.ts +2 -0
- package/dist/lib/context-move/context-move-render.js +24 -0
- package/dist/lib/context-move/context-move-support.d.ts +10 -0
- package/dist/lib/context-move/context-move-support.js +88 -0
- package/dist/lib/context-move/context-move-transaction-plan.d.ts +24 -0
- package/dist/lib/context-move/context-move-transaction-plan.js +108 -0
- package/dist/lib/context-move/context-move-types.d.ts +74 -0
- package/dist/lib/context-move/context-move-types.js +1 -0
- package/dist/lib/context-move/context-move.d.ts +8 -0
- package/dist/lib/context-move/context-move.js +180 -0
- package/dist/lib/context-mutation/manifest-lossless-patch.d.ts +28 -0
- package/dist/lib/context-mutation/manifest-lossless-patch.js +208 -0
- package/dist/lib/context-mutation/markdown-link-patch.d.ts +34 -0
- package/dist/lib/context-mutation/markdown-link-patch.js +143 -0
- package/dist/lib/context-mutation/markdown-link-spans.d.ts +10 -0
- package/dist/lib/context-mutation/markdown-link-spans.js +179 -0
- package/dist/lib/context-mutation/mutation-cas.d.ts +13 -0
- package/dist/lib/context-mutation/mutation-cas.js +365 -0
- package/dist/lib/context-mutation/mutation-command-support.d.ts +12 -0
- package/dist/lib/context-mutation/mutation-command-support.js +57 -0
- package/dist/lib/context-mutation/mutation-commit.d.ts +12 -0
- package/dist/lib/context-mutation/mutation-commit.js +89 -0
- package/dist/lib/context-mutation/mutation-directories.d.ts +5 -0
- package/dist/lib/context-mutation/mutation-directories.js +56 -0
- package/dist/lib/context-mutation/mutation-file-state.d.ts +14 -0
- package/dist/lib/context-mutation/mutation-file-state.js +137 -0
- package/dist/lib/context-mutation/mutation-journal-file-validation.d.ts +1 -0
- package/dist/lib/context-mutation/mutation-journal-file-validation.js +106 -0
- package/dist/lib/context-mutation/mutation-journal-io.d.ts +5 -0
- package/dist/lib/context-mutation/mutation-journal-io.js +55 -0
- package/dist/lib/context-mutation/mutation-journal-storage.d.ts +18 -0
- package/dist/lib/context-mutation/mutation-journal-storage.js +283 -0
- package/dist/lib/context-mutation/mutation-journal-validation-support.d.ts +16 -0
- package/dist/lib/context-mutation/mutation-journal-validation-support.js +140 -0
- package/dist/lib/context-mutation/mutation-journal-validation.d.ts +3 -0
- package/dist/lib/context-mutation/mutation-journal-validation.js +177 -0
- package/dist/lib/context-mutation/mutation-journal.d.ts +8 -0
- package/dist/lib/context-mutation/mutation-journal.js +111 -0
- package/dist/lib/context-mutation/mutation-live-validation.d.ts +3 -0
- package/dist/lib/context-mutation/mutation-live-validation.js +51 -0
- package/dist/lib/context-mutation/mutation-long-task-guard.d.ts +6 -0
- package/dist/lib/context-mutation/mutation-long-task-guard.js +57 -0
- package/dist/lib/context-mutation/mutation-recovery.d.ts +4 -0
- package/dist/lib/context-mutation/mutation-recovery.js +189 -0
- package/dist/lib/context-mutation/mutation-staged-fs.d.ts +5 -0
- package/dist/lib/context-mutation/mutation-staged-fs.js +56 -0
- package/dist/lib/context-mutation/mutation-types.d.ts +103 -0
- package/dist/lib/context-mutation/mutation-types.js +1 -0
- package/dist/lib/context-register/context-register-input.d.ts +11 -0
- package/dist/lib/context-register/context-register-input.js +43 -0
- package/dist/lib/context-register/context-register-render.d.ts +2 -0
- package/dist/lib/context-register/context-register-render.js +21 -0
- package/dist/lib/context-register/context-register-support.d.ts +6 -0
- package/dist/lib/context-register/context-register-support.js +46 -0
- package/dist/lib/context-register/context-register-types.d.ts +46 -0
- package/dist/lib/context-register/context-register-types.js +1 -0
- package/dist/lib/context-register/context-register.d.ts +8 -0
- package/dist/lib/context-register/context-register.js +155 -0
- package/dist/lib/context-router/context-route-budget.d.ts +15 -0
- package/dist/lib/context-router/context-route-budget.js +14 -0
- package/dist/lib/context-router/context-route-candidates.d.ts +15 -0
- package/dist/lib/context-router/context-route-candidates.js +112 -0
- package/dist/lib/context-router/context-route-order.d.ts +6 -0
- package/dist/lib/context-router/context-route-order.js +53 -0
- package/dist/lib/context-router/context-route-paths.d.ts +16 -0
- package/dist/lib/context-router/context-route-paths.js +109 -0
- package/dist/lib/context-router/context-route-render.d.ts +2 -0
- package/dist/lib/context-router/context-route-render.js +32 -0
- package/dist/lib/context-router/context-route-scan.d.ts +18 -0
- package/dist/lib/context-router/context-route-scan.js +156 -0
- package/dist/lib/context-router/context-route-selection.d.ts +16 -0
- package/dist/lib/context-router/context-route-selection.js +72 -0
- package/dist/lib/context-router/context-route-terms.d.ts +13 -0
- package/dist/lib/context-router/context-route-terms.js +202 -0
- package/dist/lib/context-router/context-route-types.d.ts +101 -0
- package/dist/lib/context-router/context-route-types.js +1 -0
- package/dist/lib/context-router/context-route.d.ts +2 -0
- package/dist/lib/context-router/context-route.js +127 -0
- package/dist/lib/context-units-migration.d.ts +13 -0
- package/dist/lib/context-units-migration.js +217 -0
- package/dist/lib/design-authority-binding.d.ts +7 -0
- package/dist/lib/design-authority-binding.js +96 -0
- package/dist/lib/design-authority-closure.d.ts +3 -0
- package/dist/lib/design-authority-closure.js +201 -0
- package/dist/lib/design-authority-delta-codec-primitives.d.ts +10 -0
- package/dist/lib/design-authority-delta-codec-primitives.js +58 -0
- package/dist/lib/design-authority-delta-codec.d.ts +2 -0
- package/dist/lib/design-authority-delta-codec.js +193 -0
- package/dist/lib/design-authority-delta-types.d.ts +65 -0
- package/dist/lib/design-authority-delta-types.js +6 -0
- package/dist/lib/design-authority-delta-validation.d.ts +2 -0
- package/dist/lib/design-authority-delta-validation.js +16 -0
- package/dist/lib/design-authority-digest.d.ts +8 -0
- package/dist/lib/design-authority-digest.js +36 -0
- package/dist/lib/design-authority-files.d.ts +9 -0
- package/dist/lib/design-authority-files.js +62 -0
- package/dist/lib/design-authority-format.d.ts +2 -0
- package/dist/lib/design-authority-format.js +93 -0
- package/dist/lib/design-authority-links.d.ts +10 -0
- package/dist/lib/design-authority-links.js +137 -0
- package/dist/lib/design-authority-manifest.d.ts +4 -0
- package/dist/lib/design-authority-manifest.js +144 -0
- package/dist/lib/design-authority-tokens.d.ts +9 -0
- package/dist/lib/design-authority-tokens.js +45 -0
- package/dist/lib/design-authority-types.d.ts +80 -0
- package/dist/lib/design-authority-types.js +23 -0
- package/dist/lib/design-md-tool-adapter.d.ts +9 -0
- package/dist/lib/design-md-tool-adapter.js +152 -0
- package/dist/lib/design-md-tool-normalization.d.ts +7 -0
- package/dist/lib/design-md-tool-normalization.js +78 -0
- package/dist/lib/design-md-tool-types.d.ts +99 -0
- package/dist/lib/design-md-tool-types.js +8 -0
- package/dist/lib/design-resource-handoff-input-types.d.ts +1 -1
- package/dist/lib/design-resource-handoff-manifest-projection.js +3 -0
- package/dist/lib/design-resource-handoff-shape.js +14 -2
- package/dist/lib/design-resource-handoff-types.d.ts +3 -0
- package/dist/lib/design-resource-handoff-validation.js +16 -4
- package/dist/lib/design-resource-implementation-feasibility-validation-support.js +1 -1
- package/dist/lib/design-resource-recovery-current.js +22 -0
- package/dist/lib/design-resource-recovery-shape.js +64 -7
- package/dist/lib/design-resource-recovery-types.d.ts +4 -1
- package/dist/lib/design-resource-symbolic-fact-shape.js +7 -1
- package/dist/lib/design-resource-symbolic-fact-types.d.ts +3 -0
- package/dist/lib/design-resource-symbolic-fact-validation.js +15 -3
- package/dist/lib/doctor.d.ts +2 -1
- package/dist/lib/doctor.js +29 -1
- package/dist/lib/fs.js +1 -1
- package/dist/lib/long-task-acceptance-reachability-claims.d.ts +2 -0
- package/dist/lib/long-task-acceptance-reachability-claims.js +279 -0
- package/dist/lib/long-task-acceptance-reachability-design.d.ts +2 -0
- package/dist/lib/long-task-acceptance-reachability-design.js +96 -0
- package/dist/lib/long-task-acceptance-reachability-external.d.ts +9 -0
- package/dist/lib/long-task-acceptance-reachability-external.js +123 -0
- package/dist/lib/long-task-acceptance-reachability-helpers.d.ts +64 -0
- package/dist/lib/long-task-acceptance-reachability-helpers.js +473 -0
- package/dist/lib/long-task-acceptance-reachability-semantic.d.ts +2 -0
- package/dist/lib/long-task-acceptance-reachability-semantic.js +122 -0
- package/dist/lib/long-task-acceptance-reachability-types.d.ts +91 -0
- package/dist/lib/long-task-acceptance-reachability-types.js +1 -0
- package/dist/lib/long-task-acceptance-reachability.d.ts +4 -0
- package/dist/lib/long-task-acceptance-reachability.js +115 -0
- package/dist/lib/long-task-activation-validation.d.ts +6 -0
- package/dist/lib/long-task-activation-validation.js +72 -69
- package/dist/lib/long-task-active-authority-lock-context.d.ts +4 -0
- package/dist/lib/long-task-active-authority-lock-context.js +29 -0
- package/dist/lib/long-task-applicability-identity.d.ts +25 -0
- package/dist/lib/long-task-applicability-identity.js +60 -0
- package/dist/lib/long-task-authoring-preflight-diagnostics.js +8 -0
- package/dist/lib/long-task-authoring-preflight-types.d.ts +2 -0
- package/dist/lib/long-task-authoring-preflight-types.js +9 -0
- package/dist/lib/long-task-authoring-preflight.js +18 -2
- package/dist/lib/long-task-authority-material-diff.js +4 -0
- package/dist/lib/long-task-authority-materials.js +19 -0
- package/dist/lib/long-task-authority-policy.d.ts +3 -0
- package/dist/lib/long-task-authority-policy.js +3 -0
- package/dist/lib/long-task-authority-revision-details.js +2 -1
- package/dist/lib/long-task-authority-types.d.ts +2 -0
- package/dist/lib/long-task-authority.js +2 -0
- package/dist/lib/long-task-check-shape.js +6 -1
- package/dist/lib/long-task-claim-definitions.js +1 -3
- package/dist/lib/long-task-claim-semantic-proof-floor.d.ts +3 -0
- package/dist/lib/long-task-claim-semantic-proof-floor.js +78 -0
- package/dist/lib/long-task-claims.d.ts +0 -18
- package/dist/lib/long-task-claims.js +15 -14
- package/dist/lib/long-task-command-process.js +3 -0
- package/dist/lib/long-task-compact-authoring.js +3 -0
- package/dist/lib/long-task-compact-projections.js +10 -0
- package/dist/lib/long-task-complete-delivery-evidence-types.d.ts +38 -0
- package/dist/lib/long-task-complete-delivery-evidence-types.js +1 -0
- package/dist/lib/long-task-completion-types.d.ts +109 -0
- package/dist/lib/long-task-completion-types.js +1 -0
- package/dist/lib/long-task-conformance-policy.d.ts +2 -1
- package/dist/lib/long-task-conformance-policy.js +11 -4
- package/dist/lib/long-task-context-authority-topology.js +6 -4
- package/dist/lib/long-task-contract-types.d.ts +52 -1
- package/dist/lib/long-task-counterfactual-sandbox.d.ts +7 -1
- package/dist/lib/long-task-counterfactual-sandbox.js +86 -6
- package/dist/lib/long-task-delivery-compiler-preflight.d.ts +24 -0
- package/dist/lib/long-task-delivery-compiler-preflight.js +32 -0
- package/dist/lib/long-task-delivery-compiler.d.ts +1 -0
- package/dist/lib/long-task-delivery-compiler.js +59 -44
- package/dist/lib/long-task-delivery-parser.d.ts +3 -0
- package/dist/lib/long-task-delivery-parser.js +26 -8
- package/dist/lib/long-task-delivery-types.d.ts +2 -0
- package/dist/lib/long-task-delivery-types.js +2 -0
- package/dist/lib/long-task-delivery-validation.d.ts +6 -1
- package/dist/lib/long-task-delivery-validation.js +19 -4
- package/dist/lib/long-task-design-feasibility-binding.d.ts +1 -0
- package/dist/lib/long-task-design-feasibility-binding.js +3 -3
- package/dist/lib/long-task-design-feasibility-source-closure.js +11 -2
- package/dist/lib/long-task-design-obligation.d.ts +50 -0
- package/dist/lib/long-task-design-obligation.js +99 -0
- package/dist/lib/long-task-design-resource-handoff.d.ts +3 -1
- package/dist/lib/long-task-design-resource-handoff.js +36 -12
- package/dist/lib/long-task-design-resource-method-binding.js +12 -0
- package/dist/lib/long-task-effective-external-takeover.d.ts +15 -0
- package/dist/lib/long-task-effective-external-takeover.js +109 -0
- package/dist/lib/long-task-effective-external-ui-takeover.d.ts +5 -0
- package/dist/lib/long-task-effective-external-ui-takeover.js +117 -0
- package/dist/lib/long-task-evidence-capability-codec.js +91 -0
- package/dist/lib/long-task-evidence-capability-runtime.js +62 -14
- package/dist/lib/long-task-evidence-capability-types.d.ts +3 -2
- package/dist/lib/long-task-evidence-v2.d.ts +6 -1
- package/dist/lib/long-task-evidence-v2.js +253 -170
- package/dist/lib/long-task-execution-observation.d.ts +7 -0
- package/dist/lib/long-task-execution-observation.js +21 -4
- package/dist/lib/long-task-expected-authority.d.ts +4 -0
- package/dist/lib/long-task-expected-authority.js +126 -0
- package/dist/lib/long-task-external-confirmation-artifacts.d.ts +9 -0
- package/dist/lib/long-task-external-confirmation-artifacts.js +138 -0
- package/dist/lib/long-task-external-confirmation-attestation.d.ts +20 -0
- package/dist/lib/long-task-external-confirmation-attestation.js +115 -0
- package/dist/lib/long-task-external-confirmation-challenge.d.ts +23 -0
- package/dist/lib/long-task-external-confirmation-challenge.js +164 -0
- package/dist/lib/long-task-external-confirmation-context.d.ts +14 -0
- package/dist/lib/long-task-external-confirmation-context.js +53 -0
- package/dist/lib/long-task-external-confirmation-evaluation.d.ts +11 -0
- package/dist/lib/long-task-external-confirmation-evaluation.js +454 -0
- package/dist/lib/long-task-external-confirmation-expected.d.ts +8 -0
- package/dist/lib/long-task-external-confirmation-expected.js +200 -0
- package/dist/lib/long-task-external-confirmation-identity.d.ts +10 -0
- package/dist/lib/long-task-external-confirmation-identity.js +77 -0
- package/dist/lib/long-task-external-confirmation-plan.d.ts +25 -0
- package/dist/lib/long-task-external-confirmation-plan.js +148 -0
- package/dist/lib/long-task-external-confirmation-preparation.d.ts +4 -0
- package/dist/lib/long-task-external-confirmation-preparation.js +100 -0
- package/dist/lib/long-task-external-confirmation-shape.d.ts +8 -0
- package/dist/lib/long-task-external-confirmation-shape.js +387 -0
- package/dist/lib/long-task-external-confirmation-state.d.ts +10 -0
- package/dist/lib/long-task-external-confirmation-state.js +109 -0
- package/dist/lib/long-task-external-confirmation-types.d.ts +195 -0
- package/dist/lib/long-task-external-confirmation-types.js +1 -0
- package/dist/lib/long-task-final-integrity.d.ts +2 -0
- package/dist/lib/long-task-final-integrity.js +21 -10
- package/dist/lib/long-task-final-v2.d.ts +7 -2
- package/dist/lib/long-task-final-v2.js +179 -55
- package/dist/lib/long-task-finalization-identity.d.ts +27 -0
- package/dist/lib/long-task-finalization-identity.js +58 -0
- package/dist/lib/long-task-finding-context.d.ts +1 -1
- package/dist/lib/long-task-finding-context.js +139 -13
- package/dist/lib/long-task-freshness.d.ts +27 -0
- package/dist/lib/long-task-freshness.js +128 -5
- package/dist/lib/long-task-git.js +3 -3
- package/dist/lib/long-task-material-input-closure.d.ts +3 -0
- package/dist/lib/long-task-material-input-closure.js +92 -0
- package/dist/lib/long-task-obligation-authority-resolution.d.ts +12 -0
- package/dist/lib/long-task-obligation-authority-resolution.js +57 -0
- package/dist/lib/long-task-obligation-semantic-identity.d.ts +16 -0
- package/dist/lib/long-task-obligation-semantic-identity.js +116 -0
- package/dist/lib/long-task-observation-authority.d.ts +11 -0
- package/dist/lib/long-task-observation-authority.js +137 -6
- package/dist/lib/long-task-process-table.d.ts +2 -5
- package/dist/lib/long-task-process-table.js +21 -53
- package/dist/lib/long-task-process-tree.d.ts +0 -1
- package/dist/lib/long-task-process-tree.js +24 -54
- package/dist/lib/long-task-proof-adequacy.d.ts +12 -0
- package/dist/lib/long-task-proof-adequacy.js +57 -0
- package/dist/lib/long-task-proof-capability-floor.d.ts +6 -0
- package/dist/lib/long-task-proof-capability-floor.js +137 -0
- package/dist/lib/long-task-repair-frontier-checks.d.ts +8 -0
- package/dist/lib/long-task-repair-frontier-checks.js +93 -0
- package/dist/lib/long-task-repair-frontier-groups.d.ts +2 -0
- package/dist/lib/long-task-repair-frontier-groups.js +64 -0
- package/dist/lib/long-task-repair-frontier-utils.d.ts +6 -0
- package/dist/lib/long-task-repair-frontier-utils.js +27 -0
- package/dist/lib/long-task-repair-frontier.d.ts +14 -0
- package/dist/lib/long-task-repair-frontier.js +132 -0
- package/dist/lib/long-task-risk.d.ts +3 -2
- package/dist/lib/long-task-risk.js +73 -24
- package/dist/lib/long-task-root-shape.js +148 -8
- package/dist/lib/long-task-runner-freeze.d.ts +2 -1
- package/dist/lib/long-task-runner-freeze.js +23 -8
- package/dist/lib/long-task-runtime-types.d.ts +34 -40
- package/dist/lib/long-task-semantic-assurance-policy.js +2 -11
- package/dist/lib/long-task-semantic-contract-types.d.ts +2 -1
- package/dist/lib/long-task-semantic-drift-migration.js +48 -2
- package/dist/lib/long-task-semantic-fact-binding-types.d.ts +20 -0
- package/dist/lib/long-task-semantic-fact-closure.d.ts +5 -1
- package/dist/lib/long-task-semantic-fact-closure.js +33 -5
- package/dist/lib/long-task-semantic-fact-contract-closure.js +176 -1
- package/dist/lib/long-task-semantic-fact-contract-proofs.js +18 -1
- package/dist/lib/long-task-semantic-fact-input-closure.d.ts +16 -2
- package/dist/lib/long-task-semantic-fact-input-closure.js +138 -15
- package/dist/lib/long-task-semantic-fact-provenance-closure.js +1 -1
- package/dist/lib/long-task-semantic-fact-shape.d.ts +2 -1
- package/dist/lib/long-task-semantic-fact-shape.js +35 -1
- package/dist/lib/long-task-semantic-proof-adequacy.d.ts +2 -0
- package/dist/lib/long-task-semantic-proof-adequacy.js +19 -0
- package/dist/lib/long-task-semantic-proof-profile.d.ts +5 -0
- package/dist/lib/long-task-semantic-proof-profile.js +187 -0
- package/dist/lib/long-task-shape-primitives.d.ts +1 -1
- package/dist/lib/long-task-shape-primitives.js +5 -0
- package/dist/lib/long-task-source-anchors.d.ts +10 -0
- package/dist/lib/long-task-source-anchors.js +102 -0
- package/dist/lib/long-task-source-authority-types.d.ts +46 -0
- package/dist/lib/long-task-source-claim-validation.js +36 -0
- package/dist/lib/long-task-source-conservation-facts.d.ts +8 -0
- package/dist/lib/long-task-source-conservation-facts.js +57 -0
- package/dist/lib/long-task-source-conservation-types.d.ts +34 -0
- package/dist/lib/long-task-source-conservation-types.js +1 -0
- package/dist/lib/long-task-source-conservation.d.ts +7 -0
- package/dist/lib/long-task-source-conservation.js +110 -0
- package/dist/lib/long-task-source-fragments.d.ts +6 -0
- package/dist/lib/long-task-source-fragments.js +219 -0
- package/dist/lib/long-task-source-projection-resolution.d.ts +5 -0
- package/dist/lib/long-task-source-projection-resolution.js +57 -0
- package/dist/lib/long-task-source-projection-validation.d.ts +17 -0
- package/dist/lib/long-task-source-projection-validation.js +154 -0
- package/dist/lib/long-task-source-shape.js +14 -6
- package/dist/lib/long-task-source-supersession.d.ts +5 -0
- package/dist/lib/long-task-source-supersession.js +138 -0
- package/dist/lib/long-task-stage-policy.d.ts +7 -2
- package/dist/lib/long-task-stage-policy.js +67 -23
- package/dist/lib/long-task-state.d.ts +18 -4
- package/dist/lib/long-task-state.js +319 -33
- package/dist/lib/long-task-static-observation-freeze.js +4 -3
- package/dist/lib/long-task-status-projection.d.ts +3 -1
- package/dist/lib/long-task-status-projection.js +44 -13
- package/dist/lib/long-task-status-v2.d.ts +10 -6
- package/dist/lib/long-task-status-v2.js +70 -58
- package/dist/lib/long-task-target-policy.d.ts +8 -3
- package/dist/lib/long-task-target-policy.js +40 -9
- package/dist/lib/long-task-terminal-finalization.d.ts +12 -0
- package/dist/lib/long-task-terminal-finalization.js +190 -0
- package/dist/lib/long-task-ui-design-policy.js +15 -4
- package/dist/lib/long-task-verifier-counterfactuals.d.ts +11 -0
- package/dist/lib/long-task-verifier-counterfactuals.js +96 -0
- package/dist/lib/long-task-verifier-execution.d.ts +9 -0
- package/dist/lib/long-task-verifier-execution.js +67 -0
- package/dist/lib/long-task-verifier-identity.js +16 -5
- package/dist/lib/long-task-verifier-v2.js +52 -65
- package/dist/lib/long-task-windows-job-supervisor-helper.d.ts +1 -0
- package/dist/lib/long-task-windows-job-supervisor-helper.js +104 -0
- package/dist/lib/long-task-windows-job-supervisor-protocol.d.ts +28 -0
- package/dist/lib/long-task-windows-job-supervisor-protocol.js +124 -0
- package/dist/lib/long-task-windows-job-supervisor-result.d.ts +11 -0
- package/dist/lib/long-task-windows-job-supervisor-result.js +152 -0
- package/dist/lib/long-task-windows-job-supervisor.d.ts +2 -0
- package/dist/lib/long-task-windows-job-supervisor.js +126 -0
- package/dist/lib/long-task-workspace-scope.d.ts +1 -0
- package/dist/lib/long-task-workspace-scope.js +4 -1
- package/dist/lib/long-task-workspace.d.ts +1 -0
- package/dist/lib/long-task-workspace.js +10 -0
- package/dist/lib/migrations.js +43 -2
- package/dist/lib/repository-path-safety.d.ts +1 -0
- package/dist/lib/repository-path-safety.js +3 -3
- package/dist/lib/semantic-fact-input-shape.d.ts +7 -2
- package/dist/lib/semantic-fact-input-shape.js +25 -1
- package/dist/lib/semantic-fact-inventory-types.d.ts +8 -2
- package/dist/lib/semantic-fact-policy-census.d.ts +1 -1
- package/dist/lib/semantic-fact-policy-census.js +5 -2
- package/dist/lib/semantic-fact-policy.d.ts +1 -1
- package/dist/lib/semantic-fact-policy.js +2 -2
- package/dist/lib/semantic-fact-proof-shape.d.ts +1 -1
- package/dist/lib/semantic-fact-property-shape.d.ts +1 -1
- package/dist/lib/validators.d.ts +3 -0
- package/dist/lib/validators.js +45 -157
- package/dist/public-api-core.d.ts +12 -0
- package/dist/public-api-core.js +12 -0
- package/dist/public-api-long-task.d.ts +10 -0
- package/dist/public-api-long-task.js +10 -0
- package/dist/public-types.d.ts +5 -1
- package/dist/schemas/design-authority-delta-assessment-v1.schema.json +191 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +166 -2
- package/dist/schemas/long-task-external-confirmation-record-v1.schema.json +155 -0
- package/dist/schemas/long-task-external-confirmation-record-v2.schema.json +209 -0
- package/migrations/README.md +99 -0
- package/package.json +7 -5
- package/source-mappings.yaml +18 -0
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
from pathlib import Path, PureWindowsPath
|
|
5
5
|
import json
|
|
6
|
+
import os
|
|
6
7
|
import re
|
|
7
8
|
import subprocess
|
|
8
9
|
import sys
|
|
10
|
+
import unicodedata
|
|
9
11
|
|
|
10
12
|
try:
|
|
11
13
|
import tomllib
|
|
@@ -16,6 +18,54 @@ except ImportError: # Python 3.10 compatibility; Node is already required by ty
|
|
|
16
18
|
ROOT = Path.cwd().resolve()
|
|
17
19
|
CONTEXT_ROOT = ROOT / "project_context"
|
|
18
20
|
|
|
21
|
+
# The portable validator is a UTF-8 command-line surface on every supported
|
|
22
|
+
# platform. Windows pipe encodings otherwise depend on the active locale and
|
|
23
|
+
# can corrupt the canonical NFC paths that TypeScript and Python are required
|
|
24
|
+
# to report identically.
|
|
25
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
26
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="strict")
|
|
27
|
+
if hasattr(sys.stderr, "reconfigure"):
|
|
28
|
+
sys.stderr.reconfigure(encoding="utf-8", errors="strict")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def load_context_rules():
|
|
32
|
+
rules_path = Path(__file__).resolve().with_name("context_rules.json")
|
|
33
|
+
try:
|
|
34
|
+
value = json.loads(rules_path.read_text(encoding="utf-8"))
|
|
35
|
+
except (OSError, UnicodeError, json.JSONDecodeError) as error:
|
|
36
|
+
raise RuntimeError(f"unable to load portable Context rules from {rules_path.name}: {error}") from error
|
|
37
|
+
required_arrays = (
|
|
38
|
+
"roles",
|
|
39
|
+
"read_policies",
|
|
40
|
+
"legacy_read_policies",
|
|
41
|
+
"top_level_fields",
|
|
42
|
+
"area_fields",
|
|
43
|
+
"context_fields",
|
|
44
|
+
)
|
|
45
|
+
for field in required_arrays:
|
|
46
|
+
entries = value.get(field)
|
|
47
|
+
if (
|
|
48
|
+
not isinstance(entries, list)
|
|
49
|
+
or any(not isinstance(entry, str) or not entry.strip() for entry in entries)
|
|
50
|
+
or len(entries) != len(set(entries))
|
|
51
|
+
):
|
|
52
|
+
raise RuntimeError(f"portable Context rules field {field} must contain unique non-empty strings")
|
|
53
|
+
aliases = value.get("role_aliases")
|
|
54
|
+
if not isinstance(aliases, dict) or any(
|
|
55
|
+
not isinstance(key, str)
|
|
56
|
+
or not key.strip()
|
|
57
|
+
or not isinstance(target, str)
|
|
58
|
+
or target not in value["roles"]
|
|
59
|
+
for key, target in aliases.items()
|
|
60
|
+
):
|
|
61
|
+
raise RuntimeError("portable Context rules role_aliases are invalid")
|
|
62
|
+
if any(policy not in value["read_policies"] for policy in value["legacy_read_policies"]):
|
|
63
|
+
raise RuntimeError("portable Context legacy read policies must be a subset of read_policies")
|
|
64
|
+
return value
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
CONTEXT_RULES = load_context_rules()
|
|
68
|
+
|
|
19
69
|
GLOBAL_CHECKS = [
|
|
20
70
|
("project goal", ["project goal", "项目目标", "目标"]),
|
|
21
71
|
("boundaries", ["non-goals", "boundaries", "非目标", "边界"]),
|
|
@@ -35,28 +85,13 @@ ARCHITECTURE_CHECKS = [
|
|
|
35
85
|
("verification implications", ["verification implications", "验证影响", "验证入口"]),
|
|
36
86
|
]
|
|
37
87
|
|
|
38
|
-
VALID_ROLES =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"archive",
|
|
46
|
-
"contract",
|
|
47
|
-
"verification",
|
|
48
|
-
"deployment",
|
|
49
|
-
"implementation-index",
|
|
50
|
-
"decision-rationale",
|
|
51
|
-
}
|
|
52
|
-
ROLE_ALIASES = {
|
|
53
|
-
"implementation_index": "implementation-index",
|
|
54
|
-
"decision_rationale": "decision-rationale",
|
|
55
|
-
}
|
|
56
|
-
READ_POLICIES = {"default", "always", "optional", "on-demand", "never-default"}
|
|
57
|
-
TOP_LEVEL_FIELDS = {"areas", "context"}
|
|
58
|
-
AREA_FIELDS = {"id", "root", "context", "kind", "default", "forbidden_runtime_dependencies"}
|
|
59
|
-
CONTEXT_FIELDS = {"path", "role", "read_when", "read_policy", "triggers", "default_children"}
|
|
88
|
+
VALID_ROLES = set(CONTEXT_RULES["roles"])
|
|
89
|
+
ROLE_ALIASES = CONTEXT_RULES["role_aliases"]
|
|
90
|
+
READ_POLICIES = set(CONTEXT_RULES["read_policies"])
|
|
91
|
+
LEGACY_READ_POLICIES = set(CONTEXT_RULES["legacy_read_policies"])
|
|
92
|
+
TOP_LEVEL_FIELDS = set(CONTEXT_RULES["top_level_fields"])
|
|
93
|
+
AREA_FIELDS = set(CONTEXT_RULES["area_fields"])
|
|
94
|
+
CONTEXT_FIELDS = set(CONTEXT_RULES["context_fields"])
|
|
60
95
|
CONFIG_CANDIDATES = [
|
|
61
96
|
".agent/config.yaml",
|
|
62
97
|
".codex/config.yaml",
|
|
@@ -89,10 +124,18 @@ def normalize_role(value):
|
|
|
89
124
|
return role if role in VALID_ROLES else None
|
|
90
125
|
|
|
91
126
|
|
|
92
|
-
def
|
|
127
|
+
def normalize_context_path_spelling(value):
|
|
93
128
|
return value.replace("\\", "/").removeprefix("./")
|
|
94
129
|
|
|
95
130
|
|
|
131
|
+
def normalize_context_path(value):
|
|
132
|
+
return unicodedata.normalize("NFC", normalize_context_path_spelling(value))
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def portable_context_path_case_key(value):
|
|
136
|
+
return normalize_context_path(value).lower()
|
|
137
|
+
|
|
138
|
+
|
|
96
139
|
def parse_front_matter(text):
|
|
97
140
|
lines = text.splitlines()
|
|
98
141
|
if not lines or lines[0].strip() != "---":
|
|
@@ -149,13 +192,45 @@ def parse_toml(content):
|
|
|
149
192
|
return tomllib.loads(content)
|
|
150
193
|
except tomllib.TOMLDecodeError as error:
|
|
151
194
|
raise ValueError(str(error)) from error
|
|
152
|
-
script = "
|
|
195
|
+
script = """
|
|
196
|
+
import('node:module').then(async ({ createRequire }) => {
|
|
197
|
+
const { pathToFileURL } = await import('node:url');
|
|
198
|
+
const { resolve } = await import('node:path');
|
|
199
|
+
const roots = JSON.parse(process.env.TY_CONTEXT_NODE_SEARCH_ROOTS || '[]');
|
|
200
|
+
let modulePath;
|
|
201
|
+
for (const root of roots) {
|
|
202
|
+
try {
|
|
203
|
+
modulePath = createRequire(resolve(root, 'package.json')).resolve('smol-toml');
|
|
204
|
+
break;
|
|
205
|
+
} catch {}
|
|
206
|
+
}
|
|
207
|
+
if (!modulePath) throw new Error('unable to resolve smol-toml from the project or portable-tool ancestors');
|
|
208
|
+
const { parse } = await import(pathToFileURL(modulePath).href);
|
|
209
|
+
let source = '';
|
|
210
|
+
process.stdin.setEncoding('utf8');
|
|
211
|
+
process.stdin.on('data', chunk => source += chunk);
|
|
212
|
+
process.stdin.on('end', () => process.stdout.write(JSON.stringify(parse(source))));
|
|
213
|
+
}).catch(error => {
|
|
214
|
+
console.error(error.message);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
});
|
|
217
|
+
"""
|
|
218
|
+
search_roots = []
|
|
219
|
+
for candidate in (ROOT, *Path(__file__).resolve().parents):
|
|
220
|
+
value = str(candidate)
|
|
221
|
+
if value not in search_roots:
|
|
222
|
+
search_roots.append(value)
|
|
223
|
+
environment = dict(os.environ)
|
|
224
|
+
environment["TY_CONTEXT_NODE_SEARCH_ROOTS"] = json.dumps(search_roots)
|
|
153
225
|
result = subprocess.run(
|
|
154
226
|
["node", "--input-type=module", "--eval", script],
|
|
155
227
|
input=content,
|
|
156
228
|
text=True,
|
|
229
|
+
encoding="utf-8",
|
|
230
|
+
errors="strict",
|
|
157
231
|
capture_output=True,
|
|
158
232
|
cwd=ROOT,
|
|
233
|
+
env=environment,
|
|
159
234
|
check=False,
|
|
160
235
|
)
|
|
161
236
|
if result.returncode != 0:
|
|
@@ -186,8 +261,6 @@ def string_array(entry, key, errors):
|
|
|
186
261
|
if not isinstance(value, list) or any(not isinstance(item, str) or not item.strip() for item in value):
|
|
187
262
|
errors.append(f"project_context/context.toml line {entry['line']} {key} must be an array of non-empty strings")
|
|
188
263
|
return []
|
|
189
|
-
if len(value) != len(set(value)):
|
|
190
|
-
errors.append(f"project_context/context.toml line {entry['line']} {key} must not contain duplicates")
|
|
191
264
|
return value
|
|
192
265
|
|
|
193
266
|
|
|
@@ -199,12 +272,18 @@ def is_relative_to(target, root):
|
|
|
199
272
|
return False
|
|
200
273
|
|
|
201
274
|
|
|
202
|
-
def safe_manifest_path(raw, allowed_root, label, expected, errors):
|
|
203
|
-
normalized = raw
|
|
275
|
+
def safe_manifest_path(raw, allowed_root, label, expected, errors, physical_files=None):
|
|
276
|
+
normalized = normalize_context_path_spelling(raw)
|
|
204
277
|
if Path(raw).is_absolute() or PureWindowsPath(raw).is_absolute() or ".." in normalized.split("/"):
|
|
205
278
|
errors.append(f"project_context/context.toml {label} path must be relative and must not contain '..': {raw}")
|
|
206
279
|
return None
|
|
207
|
-
target =
|
|
280
|
+
target = (
|
|
281
|
+
physical_files.get(normalize_context_path(raw))
|
|
282
|
+
if expected == "context file" and physical_files is not None
|
|
283
|
+
else None
|
|
284
|
+
)
|
|
285
|
+
if target is None:
|
|
286
|
+
target = ROOT.joinpath(*normalized.split("/"))
|
|
208
287
|
if not target.exists():
|
|
209
288
|
errors.append(f"project_context/context.toml references missing {expected}: {normalized}")
|
|
210
289
|
return None
|
|
@@ -222,7 +301,96 @@ def safe_manifest_path(raw, allowed_root, label, expected, errors):
|
|
|
222
301
|
return resolved_target
|
|
223
302
|
|
|
224
303
|
|
|
225
|
-
def
|
|
304
|
+
def validate_area_entry(area, area_ids, registered, roles, policies, errors, physical_files):
|
|
305
|
+
area_id = required_string(area, "id", errors)
|
|
306
|
+
area_root = required_string(area, "root", errors)
|
|
307
|
+
context_path = required_string(area, "context", errors)
|
|
308
|
+
optional_string(area, "kind", errors)
|
|
309
|
+
if "default" in area and not isinstance(area["default"], bool):
|
|
310
|
+
errors.append(f"project_context/context.toml line {area['line']} default must be a boolean")
|
|
311
|
+
string_array(area, "forbidden_runtime_dependencies", errors)
|
|
312
|
+
if area_id:
|
|
313
|
+
canonical_area_id = unicodedata.normalize("NFC", area_id)
|
|
314
|
+
previous_area_id = area_ids.get(canonical_area_id)
|
|
315
|
+
if previous_area_id is not None:
|
|
316
|
+
if previous_area_id == area_id:
|
|
317
|
+
errors.append(f"project_context/context.toml has duplicate area id: {area_id}")
|
|
318
|
+
else:
|
|
319
|
+
aliases = sorted((previous_area_id, area_id), key=lambda value: value.encode("utf-8"))
|
|
320
|
+
errors.append(
|
|
321
|
+
"project_context/context.toml area ids "
|
|
322
|
+
f"{', '.join(aliases)} normalize to the same NFC id {canonical_area_id}"
|
|
323
|
+
)
|
|
324
|
+
else:
|
|
325
|
+
area_ids[canonical_area_id] = area_id
|
|
326
|
+
label = f"area {area_id or area['line']}"
|
|
327
|
+
if area_root:
|
|
328
|
+
safe_manifest_path(area_root, ROOT, f"{label} root", "area root", errors)
|
|
329
|
+
if context_path:
|
|
330
|
+
register_context_path(
|
|
331
|
+
context_path,
|
|
332
|
+
"area",
|
|
333
|
+
None,
|
|
334
|
+
label,
|
|
335
|
+
registered,
|
|
336
|
+
roles,
|
|
337
|
+
policies,
|
|
338
|
+
errors,
|
|
339
|
+
physical_files,
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def validate_context_entry(entry, registered, roles, policies, errors, warnings, physical_files):
|
|
344
|
+
context_path = required_string(entry, "path", errors)
|
|
345
|
+
raw_role = required_string(entry, "role", errors)
|
|
346
|
+
optional_string(entry, "read_when", errors)
|
|
347
|
+
read_policy = optional_string(entry, "read_policy", errors)
|
|
348
|
+
string_array(entry, "triggers", errors)
|
|
349
|
+
string_array(entry, "default_children", errors)
|
|
350
|
+
role = normalize_role(raw_role) if raw_role else None
|
|
351
|
+
if raw_role and role is None:
|
|
352
|
+
errors.append(f"project_context/context.toml line {entry['line']} has unsupported context role: {raw_role}")
|
|
353
|
+
if read_policy and read_policy not in READ_POLICIES:
|
|
354
|
+
errors.append(f"project_context/context.toml line {entry['line']} has unsupported read_policy: {read_policy}")
|
|
355
|
+
if read_policy in LEGACY_READ_POLICIES:
|
|
356
|
+
warnings.append(
|
|
357
|
+
f"project_context/context.toml line {entry['line']} uses legacy read_policy {read_policy}; "
|
|
358
|
+
"Schema v4 preserves its current selection behavior and migration must be explicit"
|
|
359
|
+
)
|
|
360
|
+
if context_path and role:
|
|
361
|
+
register_context_path(
|
|
362
|
+
context_path,
|
|
363
|
+
role,
|
|
364
|
+
read_policy,
|
|
365
|
+
f"context {context_path}",
|
|
366
|
+
registered,
|
|
367
|
+
roles,
|
|
368
|
+
policies,
|
|
369
|
+
errors,
|
|
370
|
+
physical_files,
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
def validate_default_children(contexts, registered, errors, warnings):
|
|
375
|
+
contexts_by_path = {
|
|
376
|
+
normalize_context_path(entry["path"]): entry
|
|
377
|
+
for entry in contexts
|
|
378
|
+
if isinstance(entry.get("path"), str) and entry["path"].strip()
|
|
379
|
+
}
|
|
380
|
+
for entry in contexts:
|
|
381
|
+
for child in entry.get("default_children", []):
|
|
382
|
+
normalized = normalize_context_path(child)
|
|
383
|
+
if normalized not in registered["paths"]:
|
|
384
|
+
errors.append(f"project_context/context.toml line {entry['line']} default_children references unregistered Context path: {child}")
|
|
385
|
+
elif contexts_by_path.get(normalized, {}).get("read_policy") == "never-default":
|
|
386
|
+
warnings.append(
|
|
387
|
+
f"project_context/context.toml line {entry['line']} default_children selects {normalized} even though its current "
|
|
388
|
+
"read_policy is never-default; Schema v4 preserves this behavior and a future migration must remove the edge or "
|
|
389
|
+
"change the policy explicitly"
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def validate_manifest(errors, warnings, physical_files):
|
|
226
394
|
manifest_path = CONTEXT_ROOT / "context.toml"
|
|
227
395
|
roles = {}
|
|
228
396
|
policies = {}
|
|
@@ -238,59 +406,64 @@ def validate_manifest(errors):
|
|
|
238
406
|
defaults = [entry for entry in areas if entry.get("default") is True]
|
|
239
407
|
if areas and len(defaults) != 1:
|
|
240
408
|
errors.append(f"project_context/context.toml must mark exactly one [[areas]] entry with default = true; found {len(defaults)}")
|
|
241
|
-
area_ids =
|
|
242
|
-
|
|
409
|
+
area_ids = {}
|
|
410
|
+
registered = {"paths": set(), "spellings": {}, "cases": {}}
|
|
243
411
|
|
|
244
412
|
for area in areas:
|
|
245
|
-
|
|
246
|
-
area_root = required_string(area, "root", errors)
|
|
247
|
-
context_path = required_string(area, "context", errors)
|
|
248
|
-
optional_string(area, "kind", errors)
|
|
249
|
-
if "default" in area and not isinstance(area["default"], bool):
|
|
250
|
-
errors.append(f"project_context/context.toml line {area['line']} default must be a boolean")
|
|
251
|
-
string_array(area, "forbidden_runtime_dependencies", errors)
|
|
252
|
-
if area_id:
|
|
253
|
-
if area_id in area_ids:
|
|
254
|
-
errors.append(f"project_context/context.toml has duplicate area id: {area_id}")
|
|
255
|
-
area_ids.add(area_id)
|
|
256
|
-
if area_root:
|
|
257
|
-
safe_manifest_path(area_root, ROOT, f"area {area_id or area['line']} root", "area root", errors)
|
|
258
|
-
if context_path:
|
|
259
|
-
register_context_path(context_path, "area", None, f"area {area_id or area['line']}", registered_paths, roles, policies, errors)
|
|
260
|
-
|
|
261
|
-
for entry in contexts:
|
|
262
|
-
context_path = required_string(entry, "path", errors)
|
|
263
|
-
raw_role = required_string(entry, "role", errors)
|
|
264
|
-
optional_string(entry, "read_when", errors)
|
|
265
|
-
read_policy = optional_string(entry, "read_policy", errors)
|
|
266
|
-
string_array(entry, "triggers", errors)
|
|
267
|
-
string_array(entry, "default_children", errors)
|
|
268
|
-
role = normalize_role(raw_role) if raw_role else None
|
|
269
|
-
if raw_role and role is None:
|
|
270
|
-
errors.append(f"project_context/context.toml line {entry['line']} has unsupported context role: {raw_role}")
|
|
271
|
-
if read_policy and read_policy not in READ_POLICIES:
|
|
272
|
-
errors.append(f"project_context/context.toml line {entry['line']} has unsupported read_policy: {read_policy}")
|
|
273
|
-
if context_path and role:
|
|
274
|
-
register_context_path(context_path, role, read_policy, f"context {context_path}", registered_paths, roles, policies, errors)
|
|
275
|
-
|
|
413
|
+
validate_area_entry(area, area_ids, registered, roles, policies, errors, physical_files)
|
|
276
414
|
for entry in contexts:
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if normalized not in registered_paths:
|
|
280
|
-
errors.append(f"project_context/context.toml line {entry['line']} default_children references unregistered Context path: {child}")
|
|
415
|
+
validate_context_entry(entry, registered, roles, policies, errors, warnings, physical_files)
|
|
416
|
+
validate_default_children(contexts, registered, errors, warnings)
|
|
281
417
|
return roles, policies
|
|
282
418
|
|
|
283
419
|
|
|
284
|
-
def register_context_path(
|
|
420
|
+
def register_context_path(
|
|
421
|
+
raw,
|
|
422
|
+
role,
|
|
423
|
+
read_policy,
|
|
424
|
+
label,
|
|
425
|
+
registered,
|
|
426
|
+
roles,
|
|
427
|
+
policies,
|
|
428
|
+
errors,
|
|
429
|
+
physical_files,
|
|
430
|
+
):
|
|
285
431
|
normalized = normalize_context_path(raw)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
432
|
+
raw_spelling = normalize_context_path_spelling(raw)
|
|
433
|
+
previous = registered["spellings"].get(normalized)
|
|
434
|
+
if previous is not None:
|
|
435
|
+
if previous == raw_spelling:
|
|
436
|
+
errors.append(f"project_context/context.toml has duplicate Context path: {normalized}")
|
|
437
|
+
else:
|
|
438
|
+
aliases = sorted((previous, raw_spelling), key=lambda value: value.encode("utf-8"))
|
|
439
|
+
errors.append(
|
|
440
|
+
"project_context/context.toml Context paths "
|
|
441
|
+
f"{', '.join(aliases)} normalize to the same NFC repository path {normalized}"
|
|
442
|
+
)
|
|
443
|
+
else:
|
|
444
|
+
registered["spellings"][normalized] = raw_spelling
|
|
445
|
+
case_key = portable_context_path_case_key(normalized)
|
|
446
|
+
previous_case = registered["cases"].get(case_key)
|
|
447
|
+
if previous_case is not None and previous_case != normalized:
|
|
448
|
+
aliases = sorted((previous_case, normalized), key=lambda value: value.encode("utf-8"))
|
|
449
|
+
errors.append(
|
|
450
|
+
"project_context/context.toml Context paths "
|
|
451
|
+
f"{', '.join(aliases)} collide on a case-insensitive filesystem"
|
|
452
|
+
)
|
|
453
|
+
else:
|
|
454
|
+
registered["cases"][case_key] = normalized
|
|
455
|
+
registered["paths"].add(normalized)
|
|
290
456
|
if not normalized.startswith("project_context/") or not normalized.endswith(".md"):
|
|
291
457
|
errors.append(f"project_context/context.toml {label} must reference a markdown file under project_context/: {raw}")
|
|
292
458
|
return
|
|
293
|
-
if safe_manifest_path(
|
|
459
|
+
if safe_manifest_path(
|
|
460
|
+
raw,
|
|
461
|
+
CONTEXT_ROOT,
|
|
462
|
+
label,
|
|
463
|
+
"context file",
|
|
464
|
+
errors,
|
|
465
|
+
physical_files,
|
|
466
|
+
) is None:
|
|
294
467
|
return
|
|
295
468
|
roles[normalized] = role
|
|
296
469
|
if read_policy:
|
|
@@ -382,6 +555,55 @@ def validate_context_file(rel, text, role, errors):
|
|
|
382
555
|
validate_role_recoverability(rel, text, role, errors)
|
|
383
556
|
|
|
384
557
|
|
|
558
|
+
def discover_context_markdown(errors):
|
|
559
|
+
paths = (
|
|
560
|
+
[
|
|
561
|
+
candidate
|
|
562
|
+
for candidate in CONTEXT_ROOT.rglob("*")
|
|
563
|
+
if candidate.is_file() and candidate.suffix.lower() == ".md"
|
|
564
|
+
]
|
|
565
|
+
if CONTEXT_ROOT.exists()
|
|
566
|
+
else []
|
|
567
|
+
)
|
|
568
|
+
rows = []
|
|
569
|
+
for context_path in paths:
|
|
570
|
+
physical = context_path.relative_to(ROOT).as_posix()
|
|
571
|
+
canonical = normalize_context_path(physical)
|
|
572
|
+
rows.append((canonical, physical, context_path))
|
|
573
|
+
rows.sort(key=lambda row: (row[0].encode("utf-8"), row[1].encode("utf-8")))
|
|
574
|
+
|
|
575
|
+
grouped = {}
|
|
576
|
+
for canonical, physical, context_path in rows:
|
|
577
|
+
grouped.setdefault(canonical, []).append((physical, context_path))
|
|
578
|
+
|
|
579
|
+
public_rows = []
|
|
580
|
+
physical_files = {}
|
|
581
|
+
case_groups = {}
|
|
582
|
+
for canonical in sorted(grouped, key=lambda value: value.encode("utf-8")):
|
|
583
|
+
candidates = sorted(
|
|
584
|
+
grouped[canonical],
|
|
585
|
+
key=lambda row: row[0].encode("utf-8"),
|
|
586
|
+
)
|
|
587
|
+
spellings = [physical for physical, _path in candidates]
|
|
588
|
+
if len(spellings) > 1:
|
|
589
|
+
errors.append(
|
|
590
|
+
f"Context files {', '.join(spellings)} normalize to the same NFC repository path {canonical}"
|
|
591
|
+
)
|
|
592
|
+
physical, context_path = candidates[0]
|
|
593
|
+
public_rows.append((canonical, physical, context_path))
|
|
594
|
+
physical_files[canonical] = context_path
|
|
595
|
+
case_key = portable_context_path_case_key(canonical)
|
|
596
|
+
case_groups.setdefault(case_key, []).append(canonical)
|
|
597
|
+
|
|
598
|
+
for canonical_paths in case_groups.values():
|
|
599
|
+
aliases = sorted(set(canonical_paths), key=lambda value: value.encode("utf-8"))
|
|
600
|
+
if len(aliases) > 1:
|
|
601
|
+
errors.append(
|
|
602
|
+
f"Context files {', '.join(aliases)} collide on a case-insensitive filesystem"
|
|
603
|
+
)
|
|
604
|
+
return public_rows, physical_files
|
|
605
|
+
|
|
606
|
+
|
|
385
607
|
def main():
|
|
386
608
|
errors = []
|
|
387
609
|
warnings = []
|
|
@@ -400,11 +622,14 @@ def main():
|
|
|
400
622
|
validate_checks("project_context/architecture.md", text, ARCHITECTURE_CHECKS, errors)
|
|
401
623
|
validate_context_file("project_context/architecture.md", text, "architecture", errors)
|
|
402
624
|
|
|
403
|
-
|
|
625
|
+
context_rows, physical_files = discover_context_markdown(errors)
|
|
626
|
+
manifest_roles, manifest_policies = validate_manifest(
|
|
627
|
+
errors,
|
|
628
|
+
warnings,
|
|
629
|
+
physical_files,
|
|
630
|
+
)
|
|
404
631
|
checked = 0
|
|
405
|
-
|
|
406
|
-
for path in context_files:
|
|
407
|
-
rel = path.relative_to(ROOT).as_posix()
|
|
632
|
+
for rel, _physical, path in context_rows:
|
|
408
633
|
if rel in {"project_context/global.md", "project_context/architecture.md"}:
|
|
409
634
|
continue
|
|
410
635
|
text = path.read_text(encoding="utf-8")
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { commands } from "./commands/index.js";
|
|
3
|
+
import { cliExitCode } from "./lib/cli-exit.js";
|
|
3
4
|
const [command = "help", ...args] = process.argv.slice(2);
|
|
4
5
|
async function main() {
|
|
5
6
|
const handler = commands[command];
|
|
@@ -10,5 +11,5 @@ async function main() {
|
|
|
10
11
|
main().catch((error) => {
|
|
11
12
|
const message = error instanceof Error ? error.message : String(error);
|
|
12
13
|
console.error(`ty-context: ${message}`);
|
|
13
|
-
process.exitCode = 1;
|
|
14
|
+
process.exitCode = cliExitCode(error) ?? 1;
|
|
14
15
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function contextCreate(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { CLI_EXIT_CODES, CliCommandError } from "../lib/cli-exit.js";
|
|
2
|
+
import { createContextScaffold } from "../lib/context-create/context-create.js";
|
|
3
|
+
export async function contextCreate(args) {
|
|
4
|
+
const options = parseCreateArgs(args);
|
|
5
|
+
if (options.help) {
|
|
6
|
+
console.log(contextCreateHelp());
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (!options.path || !options.role)
|
|
10
|
+
throw new CliCommandError(CLI_EXIT_CODES.arguments, "context create requires --path and --role");
|
|
11
|
+
let result;
|
|
12
|
+
try {
|
|
13
|
+
result = await createContextScaffold({
|
|
14
|
+
project_root: process.cwd(),
|
|
15
|
+
context_path: options.path,
|
|
16
|
+
role: options.role,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
if (error instanceof CliCommandError)
|
|
21
|
+
throw error;
|
|
22
|
+
throw new CliCommandError(CLI_EXIT_CODES.internal, `context create failed internally: ${message(error)}`, { cause: error });
|
|
23
|
+
}
|
|
24
|
+
if (options.format === "json")
|
|
25
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
26
|
+
else
|
|
27
|
+
process.stdout.write(renderContextCreateText(result));
|
|
28
|
+
}
|
|
29
|
+
function parseCreateArgs(args) {
|
|
30
|
+
const options = { format: "text", help: false };
|
|
31
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
32
|
+
const argument = args[index];
|
|
33
|
+
if (argument === "--help" || argument === "-h")
|
|
34
|
+
options.help = true;
|
|
35
|
+
else if (argument === "--json")
|
|
36
|
+
options.format = "json";
|
|
37
|
+
else if (argument === "--path")
|
|
38
|
+
index = readValue(args, index, argument, (value) => {
|
|
39
|
+
options.path = singleValue(options.path, value, argument);
|
|
40
|
+
});
|
|
41
|
+
else if (argument === "--role")
|
|
42
|
+
index = readValue(args, index, argument, (value) => {
|
|
43
|
+
options.role = singleValue(options.role, value, argument);
|
|
44
|
+
});
|
|
45
|
+
else if (argument === "--format")
|
|
46
|
+
index = readValue(args, index, argument, (value) => {
|
|
47
|
+
if (value !== "text" && value !== "json")
|
|
48
|
+
throw new CliCommandError(CLI_EXIT_CODES.arguments, "context create --format must be text or json");
|
|
49
|
+
options.format = value;
|
|
50
|
+
});
|
|
51
|
+
else
|
|
52
|
+
throw new CliCommandError(CLI_EXIT_CODES.arguments, `unknown context create argument: ${argument}`);
|
|
53
|
+
}
|
|
54
|
+
return options;
|
|
55
|
+
}
|
|
56
|
+
function readValue(args, index, flag, apply) {
|
|
57
|
+
const value = args[index + 1];
|
|
58
|
+
if (value === undefined || value.startsWith("--") || value.length === 0)
|
|
59
|
+
throw new CliCommandError(CLI_EXIT_CODES.arguments, `context create ${flag} requires a value`);
|
|
60
|
+
apply(value);
|
|
61
|
+
return index + 1;
|
|
62
|
+
}
|
|
63
|
+
function singleValue(current, value, flag) {
|
|
64
|
+
if (current !== undefined)
|
|
65
|
+
throw new CliCommandError(CLI_EXIT_CODES.arguments, `context create accepts ${flag} exactly once`);
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
function renderContextCreateText(result) {
|
|
69
|
+
return [
|
|
70
|
+
`Created unregistered Context scaffold: ${result.path}`,
|
|
71
|
+
`Role: ${result.role}`,
|
|
72
|
+
`Bytes: ${result.bytes}`,
|
|
73
|
+
"Manifest modified: no",
|
|
74
|
+
`Default footprint: unchanged (${result.default_footprint.before.path_count} paths, ${result.default_footprint.before.bytes} bytes)`,
|
|
75
|
+
"Next:",
|
|
76
|
+
...result.next_steps.map((step) => `- ${step}`),
|
|
77
|
+
"",
|
|
78
|
+
].join("\n");
|
|
79
|
+
}
|
|
80
|
+
function contextCreateHelp() {
|
|
81
|
+
return `ty-context context create --path <project_context/file.md> --role <role>
|
|
82
|
+
[--format text|json]
|
|
83
|
+
|
|
84
|
+
Creates one Role-specific TODO-only scaffold as an unregistered Context file.
|
|
85
|
+
It refuses collisions and unsafe paths, never edits context.toml and never
|
|
86
|
+
provides a create-and-register or force-overwrite option.`;
|
|
87
|
+
}
|
|
88
|
+
function message(error) {
|
|
89
|
+
return error instanceof Error ? error.message : String(error);
|
|
90
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function contextInspect(args: string[]): Promise<void>;
|