@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5992 -82
- package/COMPARISON.md +168 -63
- package/CONTRIBUTING.md +121 -0
- package/MIGRATING-from-OpenSpec.md +238 -55
- package/QUICKSTART.md +302 -0
- package/README.md +653 -144
- package/ROADMAP.md +1035 -0
- package/SCHEMA.md +3916 -263
- package/SECURITY.md +21 -3
- package/WORKFLOW.md +927 -0
- package/dist/cli.js +133 -21
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +204 -0
- package/dist/commands/adopt/adopt.js.map +1 -0
- package/dist/commands/adopt/render.js +309 -0
- package/dist/commands/adopt/render.js.map +1 -0
- package/dist/commands/archive/archive.js +74 -0
- package/dist/commands/archive/archive.js.map +1 -0
- package/dist/commands/archive/closing.js +42 -0
- package/dist/commands/archive/closing.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/consumers.js +56 -0
- package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +193 -0
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
- package/dist/commands/archive/plan/document/head.js +151 -0
- package/dist/commands/archive/plan/document/head.js.map +1 -0
- package/dist/commands/archive/plan/document/links.js +284 -0
- package/dist/commands/archive/plan/document/links.js.map +1 -0
- package/dist/commands/archive/plan/document/run.js +136 -0
- package/dist/commands/archive/plan/document/run.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +319 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +298 -0
- package/dist/commands/archive/plan/landscape.js.map +1 -0
- package/dist/commands/archive/plan/model/extending.js +85 -0
- package/dist/commands/archive/plan/model/extending.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +106 -0
- package/dist/commands/archive/plan/refusal.js.map +1 -0
- package/dist/commands/archive/plan/specs.js +318 -0
- package/dist/commands/archive/plan/specs.js.map +1 -0
- package/dist/commands/archive/plan/state.js +30 -0
- package/dist/commands/archive/plan/state.js.map +1 -0
- package/dist/commands/archive/run.js +355 -0
- package/dist/commands/archive/run.js.map +1 -0
- package/dist/commands/archive/shipped.js +49 -0
- package/dist/commands/archive/shipped.js.map +1 -0
- package/dist/commands/context/context.js +166 -0
- package/dist/commands/context/context.js.map +1 -0
- package/dist/commands/context/print.js +305 -0
- package/dist/commands/context/print.js.map +1 -0
- package/dist/commands/delta/delta.js +367 -0
- package/dist/commands/delta/delta.js.map +1 -0
- package/dist/commands/delta/print.js +221 -0
- package/dist/commands/delta/print.js.map +1 -0
- package/dist/commands/dependencies.js +6 -8
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +86 -0
- package/dist/commands/diff/diff.js.map +1 -0
- package/dist/commands/diff/print.js +38 -0
- package/dist/commands/diff/print.js.map +1 -0
- package/dist/commands/doctor.js +65 -5
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +227 -0
- package/dist/commands/explain/explain.js.map +1 -0
- package/dist/commands/explore.js +39 -28
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +152 -0
- package/dist/commands/gate/gate.js.map +1 -0
- package/dist/commands/gate/print.js +66 -0
- package/dist/commands/gate/print.js.map +1 -0
- package/dist/commands/gherkin/commit.js +105 -0
- package/dist/commands/gherkin/commit.js.map +1 -0
- package/dist/commands/gherkin/gherkin.js +262 -0
- package/dist/commands/gherkin/gherkin.js.map +1 -0
- package/dist/commands/gherkin/reconcile.js +146 -0
- package/dist/commands/gherkin/reconcile.js.map +1 -0
- package/dist/commands/gherkin/render.js +77 -0
- package/dist/commands/gherkin/render.js.map +1 -0
- package/dist/commands/init/example.js +204 -0
- package/dist/commands/init/example.js.map +1 -0
- package/dist/commands/init/first-hour.js +72 -0
- package/dist/commands/init/first-hour.js.map +1 -0
- package/dist/commands/{init.js → init/init.js} +142 -71
- package/dist/commands/init/init.js.map +1 -0
- package/dist/commands/init/mcp.js +131 -0
- package/dist/commands/init/mcp.js.map +1 -0
- package/dist/commands/init/options.js +78 -0
- package/dist/commands/init/options.js.map +1 -0
- package/dist/commands/instructions.js +72 -14
- package/dist/commands/instructions.js.map +1 -1
- package/dist/commands/list/campaign/campaign.js +63 -0
- package/dist/commands/list/campaign/campaign.js.map +1 -0
- package/dist/commands/list/campaign/owners.js +65 -0
- package/dist/commands/list/campaign/owners.js.map +1 -0
- package/dist/commands/list/json.js +155 -0
- package/dist/commands/list/json.js.map +1 -0
- package/dist/commands/list/list.js +358 -0
- package/dist/commands/list/list.js.map +1 -0
- package/dist/commands/list/print.js +344 -0
- package/dist/commands/list/print.js.map +1 -0
- package/dist/commands/list/review.js +120 -0
- package/dist/commands/list/review.js.map +1 -0
- package/dist/commands/list/suites/suites.js +140 -0
- package/dist/commands/list/suites/suites.js.map +1 -0
- package/dist/commands/list/views.js +108 -0
- package/dist/commands/list/views.js.map +1 -0
- package/dist/commands/mcp/dispatch.js +238 -0
- package/dist/commands/mcp/dispatch.js.map +1 -0
- package/dist/commands/mcp/mcp.js +75 -0
- package/dist/commands/mcp/mcp.js.map +1 -0
- package/dist/commands/mcp/serve.js +55 -0
- package/dist/commands/mcp/serve.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/active.js +175 -0
- package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
- package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/living.js +62 -0
- package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
- package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/target.js +219 -0
- package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/error.js +18 -0
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
- package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/read.js +49 -0
- package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
- package/dist/commands/migrate-openspec/print.js +89 -0
- package/dist/commands/migrate-openspec/print.js.map +1 -0
- package/dist/commands/new/capability-template.js +118 -0
- package/dist/commands/new/capability-template.js.map +1 -0
- package/dist/commands/new/commit.js +62 -0
- package/dist/commands/new/commit.js.map +1 -0
- package/dist/commands/new/modifies.js +206 -0
- package/dist/commands/new/modifies.js.map +1 -0
- package/dist/commands/new/new.js +328 -0
- package/dist/commands/new/new.js.map +1 -0
- package/dist/commands/new/templates.js +279 -0
- package/dist/commands/new/templates.js.map +1 -0
- package/dist/commands/open.js +199 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/policy/format.js +152 -0
- package/dist/commands/policy/format.js.map +1 -0
- package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
- package/dist/commands/policy/gate.js.map +1 -0
- package/dist/commands/rebase/edit.js +106 -0
- package/dist/commands/rebase/edit.js.map +1 -0
- package/dist/commands/rebase/living.js +185 -0
- package/dist/commands/rebase/living.js.map +1 -0
- package/dist/commands/rebase/plan.js +245 -0
- package/dist/commands/rebase/plan.js.map +1 -0
- package/dist/commands/rebase/rebase.js +300 -0
- package/dist/commands/rebase/rebase.js.map +1 -0
- package/dist/commands/seed/commit.js +221 -0
- package/dist/commands/seed/commit.js.map +1 -0
- package/dist/commands/seed/plan.js +278 -0
- package/dist/commands/seed/plan.js.map +1 -0
- package/dist/commands/seed/seed.js +174 -0
- package/dist/commands/seed/seed.js.map +1 -0
- package/dist/commands/show/feature.js +182 -0
- package/dist/commands/show/feature.js.map +1 -0
- package/dist/commands/show/introduced.js +157 -0
- package/dist/commands/show/introduced.js.map +1 -0
- package/dist/commands/show/marks.js +53 -0
- package/dist/commands/show/marks.js.map +1 -0
- package/dist/commands/show/service.js +239 -0
- package/dist/commands/show/service.js.map +1 -0
- package/dist/commands/show/show.js +87 -0
- package/dist/commands/show/show.js.map +1 -0
- package/dist/commands/status/fleet-next.js +90 -0
- package/dist/commands/status/fleet-next.js.map +1 -0
- package/dist/commands/status/json.js +47 -0
- package/dist/commands/status/json.js.map +1 -0
- package/dist/commands/status/print.js +209 -0
- package/dist/commands/status/print.js.map +1 -0
- package/dist/commands/status/status.js +115 -0
- package/dist/commands/status/status.js.map +1 -0
- package/dist/commands/steps/steps.js +269 -0
- package/dist/commands/steps/steps.js.map +1 -0
- package/dist/commands/subsystem/edit.js +192 -0
- package/dist/commands/subsystem/edit.js.map +1 -0
- package/dist/commands/subsystem/move.js +325 -0
- package/dist/commands/subsystem/move.js.map +1 -0
- package/dist/commands/subsystem/query.js +113 -0
- package/dist/commands/subsystem/query.js.map +1 -0
- package/dist/commands/subsystem/subsystem.js +98 -0
- package/dist/commands/subsystem/subsystem.js.map +1 -0
- package/dist/commands/subsystem/sync.js +318 -0
- package/dist/commands/subsystem/sync.js.map +1 -0
- package/dist/commands/subsystem/txn/exclude.js +132 -0
- package/dist/commands/subsystem/txn/exclude.js.map +1 -0
- package/dist/commands/subsystem/txn/links.js +128 -0
- package/dist/commands/subsystem/txn/links.js.map +1 -0
- package/dist/commands/subsystem/txn/report.js +174 -0
- package/dist/commands/subsystem/txn/report.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +196 -0
- package/dist/commands/subsystem/txn/txn.js.map +1 -0
- package/dist/commands/subsystem/txn/views.js +249 -0
- package/dist/commands/subsystem/txn/views.js.map +1 -0
- package/dist/commands/tasks/actions.js +107 -0
- package/dist/commands/tasks/actions.js.map +1 -0
- package/dist/commands/tasks/render.js +253 -0
- package/dist/commands/tasks/render.js.map +1 -0
- package/dist/commands/tasks/tasks.js +119 -0
- package/dist/commands/tasks/tasks.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +176 -0
- package/dist/commands/unarchive/manifest.js.map +1 -0
- package/dist/commands/unarchive/restore.js +254 -0
- package/dist/commands/unarchive/restore.js.map +1 -0
- package/dist/commands/unarchive/unarchive.js +59 -0
- package/dist/commands/unarchive/unarchive.js.map +1 -0
- package/dist/commands/validate/arch-coverage.js +245 -0
- package/dist/commands/validate/arch-coverage.js.map +1 -0
- package/dist/commands/validate/checks/fleet-shape.js +204 -0
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
- package/dist/commands/validate/checks/health-deps.js +58 -0
- package/dist/commands/validate/checks/health-deps.js.map +1 -0
- package/dist/commands/validate/checks/introduced.js +102 -0
- package/dist/commands/validate/checks/introduced.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +264 -0
- package/dist/commands/validate/checks/requirements.js.map +1 -0
- package/dist/commands/validate/checks/sources.js +85 -0
- package/dist/commands/validate/checks/sources.js.map +1 -0
- package/dist/commands/validate/coverage/covers-after.js +105 -0
- package/dist/commands/validate/coverage/covers-after.js.map +1 -0
- package/dist/commands/validate/feature.js +222 -0
- package/dist/commands/validate/feature.js.map +1 -0
- package/dist/commands/validate/fleet/census.js +93 -0
- package/dist/commands/validate/fleet/census.js.map +1 -0
- package/dist/commands/validate/fleet/kind-tags.js +39 -0
- package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
- package/dist/commands/validate/fleet/landscape.js +371 -0
- package/dist/commands/validate/fleet/landscape.js.map +1 -0
- package/dist/commands/validate/fleet/load.js +118 -0
- package/dist/commands/validate/fleet/load.js.map +1 -0
- package/dist/commands/validate/fleet/map/attest.js +98 -0
- package/dist/commands/validate/fleet/map/attest.js.map +1 -0
- package/dist/commands/validate/fleet/map/bindings.js +107 -0
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
- package/dist/commands/validate/fleet/map/consumers.js +244 -0
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
- package/dist/commands/validate/fleet/map/isolation.js +116 -0
- package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
- package/dist/commands/validate/fleet/map/usecases.js +54 -0
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +266 -0
- package/dist/commands/validate/fleet/obligations.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/print.js +71 -0
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/place.js +13 -0
- package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
- package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +75 -0
- package/dist/commands/validate/fleet/views/ids.js.map +1 -0
- package/dist/commands/validate/fleet/views/projects.js +278 -0
- package/dist/commands/validate/fleet/views/projects.js.map +1 -0
- package/dist/commands/validate/fleet/views/root-documents.js +83 -0
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +52 -0
- package/dist/commands/validate/fleet/views/stale.js.map +1 -0
- package/dist/commands/validate/links/corpus.js +89 -0
- package/dist/commands/validate/links/corpus.js.map +1 -0
- package/dist/commands/validate/links/glossary.js +75 -0
- package/dist/commands/validate/links/glossary.js.map +1 -0
- package/dist/commands/validate/render/repeats.js +63 -0
- package/dist/commands/validate/render/repeats.js.map +1 -0
- package/dist/commands/validate/render/rollups.js +115 -0
- package/dist/commands/validate/render/rollups.js.map +1 -0
- package/dist/commands/validate/render/text.js +199 -0
- package/dist/commands/validate/render/text.js.map +1 -0
- package/dist/commands/validate/report.js +145 -0
- package/dist/commands/validate/report.js.map +1 -0
- package/dist/commands/validate/scope.js +113 -0
- package/dist/commands/validate/scope.js.map +1 -0
- package/dist/commands/validate/service/api.js +252 -0
- package/dist/commands/validate/service/api.js.map +1 -0
- package/dist/commands/validate/service/contracts/generated.js +134 -0
- package/dist/commands/validate/service/contracts/generated.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +241 -0
- package/dist/commands/validate/service/events/events.js.map +1 -0
- package/dist/commands/validate/service/events/message-producers.js +77 -0
- package/dist/commands/validate/service/events/message-producers.js.map +1 -0
- package/dist/commands/validate/service/evidence-pins.js +177 -0
- package/dist/commands/validate/service/evidence-pins.js.map +1 -0
- package/dist/commands/validate/service/model/diverged.js +226 -0
- package/dist/commands/validate/service/model/diverged.js.map +1 -0
- package/dist/commands/validate/service/model/grade.js +163 -0
- package/dist/commands/validate/service/model/grade.js.map +1 -0
- package/dist/commands/validate/service/service.js +310 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +279 -0
- package/dist/commands/validate/service/specs.js.map +1 -0
- package/dist/commands/validate/service/spine.js +148 -0
- package/dist/commands/validate/service/spine.js.map +1 -0
- package/dist/commands/validate/service/usecases/tags.js +113 -0
- package/dist/commands/validate/service/usecases/tags.js.map +1 -0
- package/dist/commands/validate/service/usecases/usecases.js +209 -0
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/validate.js +363 -0
- package/dist/commands/validate/validate.js.map +1 -0
- package/dist/commands/verify/cross/diff.js +178 -0
- package/dist/commands/verify/cross/diff.js.map +1 -0
- package/dist/commands/verify/evidence/contract.js +32 -0
- package/dist/commands/verify/evidence/contract.js.map +1 -0
- package/dist/commands/verify/evidence/pins.js +52 -0
- package/dist/commands/verify/evidence/pins.js.map +1 -0
- package/dist/commands/verify/evidence/read.js +81 -0
- package/dist/commands/verify/evidence/read.js.map +1 -0
- package/dist/commands/verify/frozen.js +263 -0
- package/dist/commands/verify/frozen.js.map +1 -0
- package/dist/commands/verify/record.js +278 -0
- package/dist/commands/verify/record.js.map +1 -0
- package/dist/commands/verify/report.js +206 -0
- package/dist/commands/verify/report.js.map +1 -0
- package/dist/commands/verify/results.js +328 -0
- package/dist/commands/verify/results.js.map +1 -0
- package/dist/commands/verify/verify.js +220 -0
- package/dist/commands/verify/verify.js.map +1 -0
- package/dist/commands/vouch/contract.js +11 -0
- package/dist/commands/vouch/contract.js.map +1 -0
- package/dist/commands/vouch/pack/contract.js +2 -0
- package/dist/commands/vouch/pack/contract.js.map +1 -0
- package/dist/commands/vouch/pack/pack.js +266 -0
- package/dist/commands/vouch/pack/pack.js.map +1 -0
- package/dist/commands/vouch/pack/print.js +266 -0
- package/dist/commands/vouch/pack/print.js.map +1 -0
- package/dist/commands/vouch/pack/sections.js +141 -0
- package/dist/commands/vouch/pack/sections.js.map +1 -0
- package/dist/commands/vouch/prompt/confirm.js +46 -0
- package/dist/commands/vouch/prompt/confirm.js.map +1 -0
- package/dist/commands/vouch/report.js +101 -0
- package/dist/commands/vouch/report.js.map +1 -0
- package/dist/commands/vouch/run.js +230 -0
- package/dist/commands/vouch/run.js.map +1 -0
- package/dist/commands/vouch/sample/plan.js +111 -0
- package/dist/commands/vouch/sample/plan.js.map +1 -0
- package/dist/commands/vouch/sample/print.js +109 -0
- package/dist/commands/vouch/sample/print.js.map +1 -0
- package/dist/commands/vouch/vet/verify.js +155 -0
- package/dist/commands/vouch/vet/verify.js.map +1 -0
- package/dist/commands/vouch/vouch.js +169 -0
- package/dist/commands/vouch/vouch.js.map +1 -0
- package/dist/core/agent/agents-md/command-map.js +299 -0
- package/dist/core/agent/agents-md/command-map.js.map +1 -0
- package/dist/core/agent/agents-md/map/explain.js +46 -0
- package/dist/core/agent/agents-md/map/explain.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
- package/dist/core/agent/agents-md/map/mcp.js +44 -0
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
- package/dist/core/agent/agents-md/map/status.js +78 -0
- package/dist/core/agent/agents-md/map/status.js.map +1 -0
- package/dist/core/agent/agents-md/map/subsystem.js +104 -0
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
- package/dist/core/agent/agents-md/map/usecases.js +138 -0
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
- package/dist/core/agent/agents-md/refusals.js +273 -0
- package/dist/core/agent/agents-md/refusals.js.map +1 -0
- package/dist/core/agent/agents-md.js +203 -0
- package/dist/core/agent/agents-md.js.map +1 -0
- package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
- package/dist/core/agent/agents-stamp.js.map +1 -0
- package/dist/core/agent/contract.js +2 -0
- package/dist/core/agent/contract.js.map +1 -0
- package/dist/core/agent/protocol.js +193 -0
- package/dist/core/agent/protocol.js.map +1 -0
- package/dist/core/agent/scaffold.js +254 -0
- package/dist/core/agent/scaffold.js.map +1 -0
- package/dist/core/agent/support/report.js +144 -0
- package/dist/core/agent/support/report.js.map +1 -0
- package/dist/core/agent/tools/dialects.js +151 -0
- package/dist/core/agent/tools/dialects.js.map +1 -0
- package/dist/core/agent/tools/registry.js +193 -0
- package/dist/core/agent/tools/registry.js.map +1 -0
- package/dist/core/agent/workflows/adopt.js +280 -0
- package/dist/core/agent/workflows/adopt.js.map +1 -0
- package/dist/core/agent/workflows/check.js +373 -0
- package/dist/core/agent/workflows/check.js.map +1 -0
- package/dist/core/agent/workflows/closing.js +323 -0
- package/dist/core/agent/workflows/closing.js.map +1 -0
- package/dist/core/agent/workflows/feature.js +220 -0
- package/dist/core/agent/workflows/feature.js.map +1 -0
- package/dist/core/agent/workflows/implement.js +188 -0
- package/dist/core/agent/workflows/implement.js.map +1 -0
- package/dist/core/agent/workflows/reference/authoring.js +311 -0
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
- package/dist/core/agent/workflows/reference/codes.js +67 -0
- package/dist/core/agent/workflows/reference/codes.js.map +1 -0
- package/dist/core/agent/workflows/reference/done-check.js +210 -0
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +19 -0
- package/dist/core/agent/workflows/reference/reference.js.map +1 -0
- package/dist/core/agent/workflows/reference/spine.js +338 -0
- package/dist/core/agent/workflows/reference/spine.js.map +1 -0
- package/dist/core/asyncapi/baseline/plan.js +43 -0
- package/dist/core/asyncapi/baseline/plan.js.map +1 -0
- package/dist/core/asyncapi/baseline/surfaces.js +54 -0
- package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
- package/dist/core/asyncapi/depth.js +164 -0
- package/dist/core/asyncapi/depth.js.map +1 -0
- package/dist/core/asyncapi/digest.js +146 -0
- package/dist/core/asyncapi/digest.js.map +1 -0
- package/dist/core/asyncapi/merge/components.js +92 -0
- package/dist/core/asyncapi/merge/components.js.map +1 -0
- package/dist/core/asyncapi/merge/error.js +38 -0
- package/dist/core/asyncapi/merge/error.js.map +1 -0
- package/dist/core/asyncapi/merge/markers.js +290 -0
- package/dist/core/asyncapi/merge/markers.js.map +1 -0
- package/dist/core/asyncapi/merge/merge.js +195 -0
- package/dist/core/asyncapi/merge/merge.js.map +1 -0
- package/dist/core/asyncapi/merge/pin.js +83 -0
- package/dist/core/asyncapi/merge/pin.js.map +1 -0
- package/dist/core/asyncapi/model.js +11 -0
- package/dist/core/asyncapi/model.js.map +1 -0
- package/dist/core/asyncapi/producers.js +50 -0
- package/dist/core/asyncapi/producers.js.map +1 -0
- package/dist/core/asyncapi/read.js +263 -0
- package/dist/core/asyncapi/read.js.map +1 -0
- package/dist/core/brief/brief.js +285 -0
- package/dist/core/brief/brief.js.map +1 -0
- package/dist/core/brief/checks.js +385 -0
- package/dist/core/brief/checks.js.map +1 -0
- package/dist/core/brief/landscape.js +273 -0
- package/dist/core/brief/landscape.js.map +1 -0
- package/dist/core/brief/map/extend.js +84 -0
- package/dist/core/brief/map/extend.js.map +1 -0
- package/dist/core/brief/map/owed.js +266 -0
- package/dist/core/brief/map/owed.js.map +1 -0
- package/dist/core/brief/targets.js +304 -0
- package/dist/core/brief/targets.js.map +1 -0
- package/dist/core/brief/unchecked.js +58 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +190 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/direction/direction.js +114 -0
- package/dist/core/c4/direction/direction.js.map +1 -0
- package/dist/core/c4/likec4.js +243 -0
- package/dist/core/c4/likec4.js.map +1 -0
- package/dist/core/c4/locate/unlocated.js +150 -0
- package/dist/core/c4/locate/unlocated.js.map +1 -0
- package/dist/core/c4/parsed/deployment.js +160 -0
- package/dist/core/c4/parsed/deployment.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js +132 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
- package/dist/core/c4/parsed/specification.js +78 -0
- package/dist/core/c4/parsed/specification.js.map +1 -0
- package/dist/core/c4/parsed/values.js +110 -0
- package/dist/core/c4/parsed/values.js.map +1 -0
- package/dist/core/c4/parsed/view-ids.js +113 -0
- package/dist/core/c4/parsed/view-ids.js.map +1 -0
- package/dist/core/c4/prefetch/fleet.js +134 -0
- package/dist/core/c4/prefetch/fleet.js.map +1 -0
- package/dist/core/c4/project/architecture.js +161 -0
- package/dist/core/c4/project/architecture.js.map +1 -0
- package/dist/core/c4/project/batch.js +140 -0
- package/dist/core/c4/project/batch.js.map +1 -0
- package/dist/core/c4/project/documents.js +89 -0
- package/dist/core/c4/project/documents.js.map +1 -0
- package/dist/core/c4/project/load.js +219 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/project/staged.js +277 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/attested.js +0 -0
- package/dist/core/c4/resolve/attested.js.map +1 -0
- package/dist/core/c4/resolve/external.js +51 -0
- package/dist/core/c4/resolve/external.js.map +1 -0
- package/dist/core/c4/resolve/service.js +174 -0
- package/dist/core/c4/resolve/service.js.map +1 -0
- package/dist/core/c4/resolve/steps.js +290 -0
- package/dist/core/c4/resolve/steps.js.map +1 -0
- package/dist/core/c4/resolve/systems.js +154 -0
- package/dist/core/c4/resolve/systems.js.map +1 -0
- package/dist/core/c4/root-project/exclude.js +352 -0
- package/dist/core/c4/root-project/exclude.js.map +1 -0
- package/dist/core/c4/seed/fleet-file.js +201 -0
- package/dist/core/c4/seed/fleet-file.js.map +1 -0
- package/dist/core/c4/seed/items.js +91 -0
- package/dist/core/c4/seed/items.js.map +1 -0
- package/dist/core/c4/seed/stamp.js +48 -0
- package/dist/core/c4/seed/stamp.js.map +1 -0
- package/dist/core/c4/seed/template.js +173 -0
- package/dist/core/c4/seed/template.js.map +1 -0
- package/dist/core/c4/service-model/created/models.js +96 -0
- package/dist/core/c4/service-model/created/models.js.map +1 -0
- package/dist/core/c4/service-model/documents.js +47 -0
- package/dist/core/c4/service-model/documents.js.map +1 -0
- package/dist/core/c4/service-model/fleet/extending.js +82 -0
- package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
- package/dist/core/c4/service-model/load.js +165 -0
- package/dist/core/c4/service-model/load.js.map +1 -0
- package/dist/core/c4/service-model/renderer.js +128 -0
- package/dist/core/c4/service-model/renderer.js.map +1 -0
- package/dist/core/c4/service-model/shape.js +106 -0
- package/dist/core/c4/service-model/shape.js.map +1 -0
- package/dist/core/c4/service-model/slice.js +188 -0
- package/dist/core/c4/service-model/slice.js.map +1 -0
- package/dist/core/c4/source-mask.js +369 -0
- package/dist/core/c4/source-mask.js.map +1 -0
- package/dist/core/c4/source-scan.js +308 -0
- package/dist/core/c4/source-scan.js.map +1 -0
- package/dist/core/c4/splice/authored-source.js +167 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -0
- package/dist/core/c4/splice/contract.js +30 -0
- package/dist/core/c4/splice/contract.js.map +1 -0
- package/dist/core/c4/splice/delta-blocks.js +126 -0
- package/dist/core/c4/splice/delta-blocks.js.map +1 -0
- package/dist/core/c4/splice/identity/declared.js +87 -0
- package/dist/core/c4/splice/identity/declared.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +73 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -0
- package/dist/core/c4/splice/identity/existing.js +80 -0
- package/dist/core/c4/splice/identity/existing.js.map +1 -0
- package/dist/core/c4/splice/identity/interior.js +80 -0
- package/dist/core/c4/splice/identity/interior.js.map +1 -0
- package/dist/core/c4/splice/identity/owner.js +50 -0
- package/dist/core/c4/splice/identity/owner.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +337 -0
- package/dist/core/c4/splice/landscape-merge.js.map +1 -0
- package/dist/core/c4/splice/model/merge.js +151 -0
- package/dist/core/c4/splice/model/merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +298 -0
- package/dist/core/c4/splice/placement.js.map +1 -0
- package/dist/core/c4/splice/text/spot.js +131 -0
- package/dist/core/c4/splice/text/spot.js.map +1 -0
- package/dist/core/c4/workspace.js +166 -0
- package/dist/core/c4/workspace.js.map +1 -0
- package/dist/core/capabilities/authoring/notes.js +141 -0
- package/dist/core/capabilities/authoring/notes.js.map +1 -0
- package/dist/core/capabilities/capabilities.js +124 -0
- package/dist/core/capabilities/capabilities.js.map +1 -0
- package/dist/core/capabilities/delta/doc.js +47 -0
- package/dist/core/capabilities/delta/doc.js.map +1 -0
- package/dist/core/capabilities/delta/overlay.js +129 -0
- package/dist/core/capabilities/delta/overlay.js.map +1 -0
- package/dist/core/capabilities/delta/summary.js +57 -0
- package/dist/core/capabilities/delta/summary.js.map +1 -0
- package/dist/core/capabilities/delta/tree.js +43 -0
- package/dist/core/capabilities/delta/tree.js.map +1 -0
- package/dist/core/capabilities/delta/uncovered.js +222 -0
- package/dist/core/capabilities/delta/uncovered.js.map +1 -0
- package/dist/core/capabilities/findings.js +338 -0
- package/dist/core/capabilities/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/findings.js +174 -0
- package/dist/core/capabilities/realizes/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/join.js +123 -0
- package/dist/core/capabilities/realizes/join.js.map +1 -0
- package/dist/core/capabilities/rollup.js +205 -0
- package/dist/core/capabilities/rollup.js.map +1 -0
- package/dist/core/capabilities/tree.js +104 -0
- package/dist/core/capabilities/tree.js.map +1 -0
- package/dist/core/capabilities/usecase-join.js +267 -0
- package/dist/core/capabilities/usecase-join.js.map +1 -0
- package/dist/core/coherence/authoring/scaffold.js +185 -0
- package/dist/core/coherence/authoring/scaffold.js.map +1 -0
- package/dist/core/coherence/authoring/sentinels.js +75 -0
- package/dist/core/coherence/authoring/sentinels.js.map +1 -0
- package/dist/core/coherence/calls/called.js +52 -0
- package/dist/core/coherence/calls/called.js.map +1 -0
- package/dist/core/coherence/coherence.js +332 -0
- package/dist/core/coherence/coherence.js.map +1 -0
- package/dist/core/coherence/consumed/operations.js +70 -0
- package/dist/core/coherence/consumed/operations.js.map +1 -0
- package/dist/core/coherence/consumed/refusal.js +38 -0
- package/dist/core/coherence/consumed/refusal.js.map +1 -0
- package/dist/core/coherence/covers/health.js +85 -0
- package/dist/core/coherence/covers/health.js.map +1 -0
- package/dist/core/coherence/declared.js +295 -0
- package/dist/core/coherence/declared.js.map +1 -0
- package/dist/core/coherence/events/declared.js +191 -0
- package/dist/core/coherence/events/declared.js.map +1 -0
- package/dist/core/coherence/events/events.js +335 -0
- package/dist/core/coherence/events/events.js.map +1 -0
- package/dist/core/coherence/events/grades.js +189 -0
- package/dist/core/coherence/events/grades.js.map +1 -0
- package/dist/core/coherence/events/lookups.js +63 -0
- package/dist/core/coherence/events/lookups.js.map +1 -0
- package/dist/core/coherence/events/produced.js +100 -0
- package/dist/core/coherence/events/produced.js.map +1 -0
- package/dist/core/coherence/living.js +198 -0
- package/dist/core/coherence/living.js.map +1 -0
- package/dist/core/coherence/lookups.js +95 -0
- package/dist/core/coherence/lookups.js.map +1 -0
- package/dist/core/coherence/pending.js +39 -0
- package/dist/core/coherence/pending.js.map +1 -0
- package/dist/core/coherence/retired/archived.js +285 -0
- package/dist/core/coherence/retired/archived.js.map +1 -0
- package/dist/core/coherence/retired/event-pair.js +62 -0
- package/dist/core/coherence/retired/event-pair.js.map +1 -0
- package/dist/core/coherence/retired/merged.js +79 -0
- package/dist/core/coherence/retired/merged.js.map +1 -0
- package/dist/core/coherence/retired/retirement.js +49 -0
- package/dist/core/coherence/retired/retirement.js.map +1 -0
- package/dist/core/coherence/retired/revival/arrivals.js +131 -0
- package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
- package/dist/core/coherence/retired/revival/revived.js +297 -0
- package/dist/core/coherence/retired/revival/revived.js.map +1 -0
- package/dist/core/conflict-markers.js +60 -0
- package/dist/core/conflict-markers.js.map +1 -0
- package/dist/core/consumers/after.js +113 -0
- package/dist/core/consumers/after.js.map +1 -0
- package/dist/core/consumers/consumers.js +296 -0
- package/dist/core/consumers/consumers.js.map +1 -0
- package/dist/core/consumers/current.js +211 -0
- package/dist/core/consumers/current.js.map +1 -0
- package/dist/core/consumers/scan.js +46 -0
- package/dist/core/consumers/scan.js.map +1 -0
- package/dist/core/consumers/state.js +27 -0
- package/dist/core/consumers/state.js.map +1 -0
- package/dist/core/delta/claims.js +73 -0
- package/dist/core/delta/claims.js.map +1 -0
- package/dist/core/delta/delta.js +341 -0
- package/dist/core/delta/delta.js.map +1 -0
- package/dist/core/delta/document.js +177 -0
- package/dist/core/delta/document.js.map +1 -0
- package/dist/core/delta/scope.js +48 -0
- package/dist/core/delta/scope.js.map +1 -0
- package/dist/core/delta/select.js +237 -0
- package/dist/core/delta/select.js.map +1 -0
- package/dist/core/dependencies/dependencies.js +141 -0
- package/dist/core/dependencies/dependencies.js.map +1 -0
- package/dist/core/dependencies/facts.js +165 -0
- package/dist/core/dependencies/facts.js.map +1 -0
- package/dist/core/dependencies/fanin.js +88 -0
- package/dist/core/dependencies/fanin.js.map +1 -0
- package/dist/core/dependencies/graph.js +106 -0
- package/dist/core/dependencies/graph.js.map +1 -0
- package/dist/core/deployment/delta.js +191 -0
- package/dist/core/deployment/delta.js.map +1 -0
- package/dist/core/deployment/objects.js +145 -0
- package/dist/core/deployment/objects.js.map +1 -0
- package/dist/core/diff/base-git.js +230 -0
- package/dist/core/diff/base-git.js.map +1 -0
- package/dist/core/diff/base-state.js +237 -0
- package/dist/core/diff/base-state.js.map +1 -0
- package/dist/core/diff/joins.js +136 -0
- package/dist/core/diff/joins.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +204 -0
- package/dist/core/diff/scope/changed-paths.js.map +1 -0
- package/dist/core/diff/scope/edges.js +82 -0
- package/dist/core/diff/scope/edges.js.map +1 -0
- package/dist/core/diff/semantic.js +312 -0
- package/dist/core/diff/semantic.js.map +1 -0
- package/dist/core/docs.js +37 -85
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +238 -0
- package/dist/core/doctor/agents.js.map +1 -0
- package/dist/core/doctor/config.js +139 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/doctor.js +355 -0
- package/dist/core/doctor/doctor.js.map +1 -0
- package/dist/core/doctor/report.js +13 -0
- package/dist/core/doctor/report.js.map +1 -0
- package/dist/core/doctor/reports/scan.js +242 -0
- package/dist/core/doctor/reports/scan.js.map +1 -0
- package/dist/core/doctor/residue.js +110 -0
- package/dist/core/doctor/residue.js.map +1 -0
- package/dist/core/document/apply.js +224 -0
- package/dist/core/document/apply.js.map +1 -0
- package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
- package/dist/core/document/frontmatter.js.map +1 -0
- package/dist/core/document/grammar/directives.js +143 -0
- package/dist/core/document/grammar/directives.js.map +1 -0
- package/dist/core/document/parse.js +286 -0
- package/dist/core/document/parse.js.map +1 -0
- package/dist/core/document/scenarios.js +238 -0
- package/dist/core/document/scenarios.js.map +1 -0
- package/dist/core/document/spec.js +234 -0
- package/dist/core/document/spec.js.map +1 -0
- package/dist/core/{config.js → envelope/config.js} +89 -18
- package/dist/core/envelope/config.js.map +1 -0
- package/dist/core/envelope/json.js +209 -0
- package/dist/core/envelope/json.js.map +1 -0
- package/dist/core/{version.js → envelope/version.js} +3 -3
- package/dist/core/envelope/version.js.map +1 -0
- package/dist/core/explain/families.js +180 -0
- package/dist/core/explain/families.js.map +1 -0
- package/dist/core/explain/fix-tables.js +178 -0
- package/dist/core/explain/fix-tables.js.map +1 -0
- package/dist/core/explain/lookup.js +194 -0
- package/dist/core/explain/lookup.js.map +1 -0
- package/dist/core/explain/refusals.js +49 -0
- package/dist/core/explain/refusals.js.map +1 -0
- package/dist/core/explain/terms/documents.js +227 -0
- package/dist/core/explain/terms/documents.js.map +1 -0
- package/dist/core/explain/terms/done-check.js +144 -0
- package/dist/core/explain/terms/done-check.js.map +1 -0
- package/dist/core/explain/terms/entry.js +14 -0
- package/dist/core/explain/terms/entry.js.map +1 -0
- package/dist/core/explain/terms/stages.js +71 -0
- package/dist/core/explain/terms/stages.js.map +1 -0
- package/dist/core/explain/terms/tasks.js +97 -0
- package/dist/core/explain/terms/tasks.js.map +1 -0
- package/dist/core/explain/terms.js +103 -0
- package/dist/core/explain/terms.js.map +1 -0
- package/dist/core/explore/describe.js +105 -0
- package/dist/core/explore/describe.js.map +1 -0
- package/dist/core/explore/explore.js +204 -0
- package/dist/core/explore/explore.js.map +1 -0
- package/dist/core/fleet-context.js +174 -146
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +208 -0
- package/dist/core/gate/checks.js.map +1 -0
- package/dist/core/gate/partners.js +246 -0
- package/dist/core/gate/partners.js.map +1 -0
- package/dist/core/gate/report.js +47 -0
- package/dist/core/gate/report.js.map +1 -0
- package/dist/core/gate/verification.js +176 -0
- package/dist/core/gate/verification.js.map +1 -0
- package/dist/core/gherkin/digest.js +60 -0
- package/dist/core/gherkin/digest.js.map +1 -0
- package/dist/core/gherkin/emit.js +177 -0
- package/dist/core/gherkin/emit.js.map +1 -0
- package/dist/core/gherkin/read.js +76 -0
- package/dist/core/gherkin/read.js.map +1 -0
- package/dist/core/gherkin/stale.js +210 -0
- package/dist/core/gherkin/stale.js.map +1 -0
- package/dist/core/gherkin/stamp.js +77 -0
- package/dist/core/gherkin/stamp.js.map +1 -0
- package/dist/core/gherkin/steps/catalogue.js +154 -0
- package/dist/core/gherkin/steps/catalogue.js.map +1 -0
- package/dist/core/gherkin/steps/inventory.js +98 -0
- package/dist/core/gherkin/steps/inventory.js.map +1 -0
- package/dist/core/gherkin/steps/phrase.js +72 -0
- package/dist/core/gherkin/steps/phrase.js.map +1 -0
- package/dist/core/glossary/delta.js +109 -0
- package/dist/core/glossary/delta.js.map +1 -0
- package/dist/core/glossary/tree.js +73 -0
- package/dist/core/glossary/tree.js.map +1 -0
- package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
- package/dist/core/kernel/concurrency.js.map +1 -0
- package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
- package/dist/core/kernel/document-bytes.js.map +1 -0
- package/dist/core/kernel/fences.js +42 -0
- package/dist/core/kernel/fences.js.map +1 -0
- package/dist/core/kernel/ids/capability.js +72 -0
- package/dist/core/kernel/ids/capability.js.map +1 -0
- package/dist/core/kernel/ids/dirs.js +33 -0
- package/dist/core/kernel/ids/dirs.js.map +1 -0
- package/dist/core/kernel/ids/feature.js +75 -0
- package/dist/core/kernel/ids/feature.js.map +1 -0
- package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
- package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
- package/dist/core/kernel/ids/service.js +156 -0
- package/dist/core/kernel/ids/service.js.map +1 -0
- package/dist/core/kernel/ids/subsystem.js +63 -0
- package/dist/core/kernel/ids/subsystem.js.map +1 -0
- package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
- package/dist/core/kernel/path-safety.js.map +1 -0
- package/dist/core/{records.js → kernel/records.js} +11 -0
- package/dist/core/kernel/records.js.map +1 -0
- package/dist/core/links/backlinks.js +66 -0
- package/dist/core/links/backlinks.js.map +1 -0
- package/dist/core/links/case.js +74 -0
- package/dist/core/links/case.js.map +1 -0
- package/dist/core/links/corpus.js +118 -0
- package/dist/core/links/corpus.js.map +1 -0
- package/dist/core/links/findings.js +110 -0
- package/dist/core/links/findings.js.map +1 -0
- package/dist/core/links/parse.js +265 -0
- package/dist/core/links/parse.js.map +1 -0
- package/dist/core/mcp/argv.js +212 -0
- package/dist/core/mcp/argv.js.map +1 -0
- package/dist/core/mcp/author-tools.js +73 -0
- package/dist/core/mcp/author-tools.js.map +1 -0
- package/dist/core/mcp/framing.js +46 -0
- package/dist/core/mcp/framing.js.map +1 -0
- package/dist/core/mcp/protocol.js +280 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/tools.js +324 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/obligations/obligations.js +106 -0
- package/dist/core/obligations/obligations.js.map +1 -0
- package/dist/core/openapi/baseline/gate.js +207 -0
- package/dist/core/openapi/baseline/gate.js.map +1 -0
- package/dist/core/openapi/baseline/plan.js +142 -0
- package/dist/core/openapi/baseline/plan.js.map +1 -0
- package/dist/core/openapi/baseline/record.js +174 -0
- package/dist/core/openapi/baseline/record.js.map +1 -0
- package/dist/core/openapi/contract-text.js +33 -0
- package/dist/core/openapi/contract-text.js.map +1 -0
- package/dist/core/openapi/contract-tree.js +301 -0
- package/dist/core/openapi/contract-tree.js.map +1 -0
- package/dist/core/openapi/depth.js +136 -0
- package/dist/core/openapi/depth.js.map +1 -0
- package/dist/core/openapi/digest.js +239 -0
- package/dist/core/openapi/digest.js.map +1 -0
- package/dist/core/{openapi.js → openapi/doc.js} +54 -108
- package/dist/core/openapi/doc.js.map +1 -0
- package/dist/core/openapi/merge/components.js +199 -0
- package/dist/core/openapi/merge/components.js.map +1 -0
- package/dist/core/openapi/merge/error.js +16 -0
- package/dist/core/openapi/merge/error.js.map +1 -0
- package/dist/core/openapi/merge/markers.js +204 -0
- package/dist/core/openapi/merge/markers.js.map +1 -0
- package/dist/core/openapi/merge/merge.js +232 -0
- package/dist/core/openapi/merge/merge.js.map +1 -0
- package/dist/core/openapi/merge/pin.js +110 -0
- package/dist/core/openapi/merge/pin.js.map +1 -0
- package/dist/core/openspec/decide/capabilities.js +244 -0
- package/dist/core/openspec/decide/capabilities.js.map +1 -0
- package/dist/core/openspec/decide/dispositions.js +63 -0
- package/dist/core/openspec/decide/dispositions.js.map +1 -0
- package/dist/core/openspec/decide/renames.js +179 -0
- package/dist/core/openspec/decide/renames.js.map +1 -0
- package/dist/core/openspec/decide/verdict.js +84 -0
- package/dist/core/openspec/decide/verdict.js.map +1 -0
- package/dist/core/openspec/inventory.js +220 -0
- package/dist/core/openspec/inventory.js.map +1 -0
- package/dist/core/openspec/model/mapping.js +78 -0
- package/dist/core/openspec/model/mapping.js.map +1 -0
- package/dist/core/openspec/model/model.js +70 -0
- package/dist/core/openspec/model/model.js.map +1 -0
- package/dist/core/openspec/scan/changes.js +241 -0
- package/dist/core/openspec/scan/changes.js.map +1 -0
- package/dist/core/openspec/scan/config.js +191 -0
- package/dist/core/openspec/scan/config.js.map +1 -0
- package/dist/core/openspec/scan/shape.js +304 -0
- package/dist/core/openspec/scan/shape.js.map +1 -0
- package/dist/core/openspec/scan/walk.js +116 -0
- package/dist/core/openspec/scan/walk.js.map +1 -0
- package/dist/core/openspec/scan/workspace.js +71 -0
- package/dist/core/openspec/scan/workspace.js.map +1 -0
- package/dist/core/owners/codeowners.js +141 -0
- package/dist/core/owners/codeowners.js.map +1 -0
- package/dist/core/pack/features.js +120 -0
- package/dist/core/pack/features.js.map +1 -0
- package/dist/core/pack/joins.js +112 -0
- package/dist/core/pack/joins.js.map +1 -0
- package/dist/core/pack/living.js +157 -0
- package/dist/core/pack/living.js.map +1 -0
- package/dist/core/pack/pack.js +120 -0
- package/dist/core/pack/pack.js.map +1 -0
- package/dist/core/permissions/permissions.js +87 -0
- package/dist/core/permissions/permissions.js.map +1 -0
- package/dist/core/projection/api.js +84 -0
- package/dist/core/projection/api.js.map +1 -0
- package/dist/core/projection/arch-slice.js +63 -0
- package/dist/core/projection/arch-slice.js.map +1 -0
- package/dist/core/projection/events.js +34 -0
- package/dist/core/projection/events.js.map +1 -0
- package/dist/core/projection/introduced.js +14 -0
- package/dist/core/projection/introduced.js.map +1 -0
- package/dist/core/provenance/findings.js +244 -0
- package/dist/core/provenance/findings.js.map +1 -0
- package/dist/core/provenance/git.js +201 -0
- package/dist/core/provenance/git.js.map +1 -0
- package/dist/core/provenance/gitq/moves.js +139 -0
- package/dist/core/provenance/gitq/moves.js.map +1 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
- package/dist/core/provenance/sample/scope.js +238 -0
- package/dist/core/provenance/sample/scope.js.map +1 -0
- package/dist/core/provenance/sample/sections.js +61 -0
- package/dist/core/provenance/sample/sections.js.map +1 -0
- package/dist/core/provenance/sources.js +280 -0
- package/dist/core/provenance/sources.js.map +1 -0
- package/dist/core/provenance/stamp.js +220 -0
- package/dist/core/provenance/stamp.js.map +1 -0
- package/dist/core/provenance/walk.js +157 -0
- package/dist/core/provenance/walk.js.map +1 -0
- package/dist/core/repo/authored/paths.js +210 -0
- package/dist/core/repo/authored/paths.js.map +1 -0
- package/dist/core/repo/entries.js +126 -0
- package/dist/core/repo/entries.js.map +1 -0
- package/dist/core/repo/paths.js +322 -0
- package/dist/core/repo/paths.js.map +1 -0
- package/dist/core/repo/repo.js +308 -0
- package/dist/core/repo/repo.js.map +1 -0
- package/dist/core/repo/service-target.js +153 -0
- package/dist/core/repo/service-target.js.map +1 -0
- package/dist/core/repo/state.js +58 -0
- package/dist/core/repo/state.js.map +1 -0
- package/dist/core/repo/tree/find.js +61 -0
- package/dist/core/repo/tree/find.js.map +1 -0
- package/dist/core/repo/tree/fs.js +90 -0
- package/dist/core/repo/tree/fs.js.map +1 -0
- package/dist/core/repo/tree/marker.js +61 -0
- package/dist/core/repo/tree/marker.js.map +1 -0
- package/dist/core/repo/tree/render/body.js +258 -0
- package/dist/core/repo/tree/render/body.js.map +1 -0
- package/dist/core/repo/tree/render/projects.js +182 -0
- package/dist/core/repo/tree/render/projects.js.map +1 -0
- package/dist/core/repo/tree/render/service/header.js +125 -0
- package/dist/core/repo/tree/render/service/header.js.map +1 -0
- package/dist/core/repo/tree/render/service/peers.js +28 -0
- package/dist/core/repo/tree/render/service/peers.js.map +1 -0
- package/dist/core/repo/tree/render/service/view-id.js +67 -0
- package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
- package/dist/core/repo/tree/render/service/views.js +78 -0
- package/dist/core/repo/tree/render/service/views.js.map +1 -0
- package/dist/core/repo/tree/render/stale.js +42 -0
- package/dist/core/repo/tree/render/stale.js.map +1 -0
- package/dist/core/repo/tree/render/text.js +84 -0
- package/dist/core/repo/tree/render/text.js.map +1 -0
- package/dist/core/repo/tree/render/views.js +293 -0
- package/dist/core/repo/tree/render/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +255 -0
- package/dist/core/repo/tree/walk.js.map +1 -0
- package/dist/core/results.js +146 -14
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +239 -0
- package/dist/core/scaffold/landscape.js.map +1 -0
- package/dist/core/scaffold/legacy.js +271 -0
- package/dist/core/scaffold/legacy.js.map +1 -0
- package/dist/core/scaffold/readme.js +84 -0
- package/dist/core/scaffold/readme.js.map +1 -0
- package/dist/core/staging/commit.js +252 -0
- package/dist/core/staging/commit.js.map +1 -0
- package/dist/core/staging/interrupted.js +96 -0
- package/dist/core/staging/interrupted.js.map +1 -0
- package/dist/core/staging/lock.js +268 -0
- package/dist/core/staging/lock.js.map +1 -0
- package/dist/core/staging/recovery/finding.js +35 -0
- package/dist/core/staging/recovery/finding.js.map +1 -0
- package/dist/core/staging/recovery/intent.js +95 -0
- package/dist/core/staging/recovery/intent.js.map +1 -0
- package/dist/core/staging/recovery/recover.js +204 -0
- package/dist/core/staging/recovery/recover.js.map +1 -0
- package/dist/core/staging/recovery/residue.js +62 -0
- package/dist/core/staging/recovery/residue.js.map +1 -0
- package/dist/core/staging/snapshot/manifest.js +188 -0
- package/dist/core/staging/snapshot/manifest.js.map +1 -0
- package/dist/core/staging/snapshot/snapshot.js +196 -0
- package/dist/core/staging/snapshot/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +181 -0
- package/dist/core/staging/txn/forward.js.map +1 -0
- package/dist/core/staging/txn/journal.js +139 -0
- package/dist/core/staging/txn/journal.js.map +1 -0
- package/dist/core/staging/txn/transaction.js +75 -0
- package/dist/core/staging/txn/transaction.js.map +1 -0
- package/dist/core/staging/writes.js +113 -0
- package/dist/core/staging/writes.js.map +1 -0
- package/dist/core/status/actions/execution.js +60 -0
- package/dist/core/status/actions/execution.js.map +1 -0
- package/dist/core/status/contracts.js +126 -0
- package/dist/core/status/contracts.js.map +1 -0
- package/dist/core/status/feature/artifacts.js +196 -0
- package/dist/core/status/feature/artifacts.js.map +1 -0
- package/dist/core/status/feature/feature.js +214 -0
- package/dist/core/status/feature/feature.js.map +1 -0
- package/dist/core/status/feature/next.js +163 -0
- package/dist/core/status/feature/next.js.map +1 -0
- package/dist/core/status/feature/state.js +21 -0
- package/dist/core/status/feature/state.js.map +1 -0
- package/dist/core/status/feature/words.js +96 -0
- package/dist/core/status/feature/words.js.map +1 -0
- package/dist/core/status/fleet/fleet.js +216 -0
- package/dist/core/status/fleet/fleet.js.map +1 -0
- package/dist/core/status/fleet/next.js +302 -0
- package/dist/core/status/fleet/next.js.map +1 -0
- package/dist/core/status/interrupted.js +97 -0
- package/dist/core/status/interrupted.js.map +1 -0
- package/dist/core/status/report.js +31 -0
- package/dist/core/status/report.js.map +1 -0
- package/dist/core/status/scan.js +41 -0
- package/dist/core/status/scan.js.map +1 -0
- package/dist/core/status/verification.js +216 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/tasks/packet.js +199 -0
- package/dist/core/tasks/packet.js.map +1 -0
- package/dist/core/tasks/record.js +43 -0
- package/dist/core/tasks/record.js.map +1 -0
- package/dist/core/tasks/sources.js +181 -0
- package/dist/core/tasks/sources.js.map +1 -0
- package/dist/core/tasks/stamps.js +76 -0
- package/dist/core/tasks/stamps.js.map +1 -0
- package/dist/core/tasks/unit.js +0 -0
- package/dist/core/tasks/unit.js.map +1 -0
- package/dist/core/usecases/capability.js +166 -0
- package/dist/core/usecases/capability.js.map +1 -0
- package/dist/core/usecases/delta/claims.js +140 -0
- package/dist/core/usecases/delta/claims.js.map +1 -0
- package/dist/core/usecases/delta/flows.js +101 -0
- package/dist/core/usecases/delta/flows.js.map +1 -0
- package/dist/core/usecases/delta/modified.js +315 -0
- package/dist/core/usecases/delta/modified.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +76 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -0
- package/dist/core/usecases/fleet.js +296 -0
- package/dist/core/usecases/fleet.js.map +1 -0
- package/dist/core/usecases/grade/capability-tag.js +93 -0
- package/dist/core/usecases/grade/capability-tag.js.map +1 -0
- package/dist/core/usecases/grade/feature.js +88 -0
- package/dist/core/usecases/grade/feature.js.map +1 -0
- package/dist/core/usecases/grade/requirement-tag.js +94 -0
- package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
- package/dist/core/usecases/grade/steps.js +266 -0
- package/dist/core/usecases/grade/steps.js.map +1 -0
- package/dist/core/usecases/grade/usecases.js +112 -0
- package/dist/core/usecases/grade/usecases.js.map +1 -0
- package/dist/core/usecases/operations.js +123 -0
- package/dist/core/usecases/operations.js.map +1 -0
- package/dist/core/usecases/place.js +44 -0
- package/dist/core/usecases/place.js.map +1 -0
- package/dist/core/usecases/service/exclude.js +119 -0
- package/dist/core/usecases/service/exclude.js.map +1 -0
- package/dist/core/usecases/service/flows.js +164 -0
- package/dist/core/usecases/service/flows.js.map +1 -0
- package/dist/core/usecases/suites/participants.js +83 -0
- package/dist/core/usecases/suites/participants.js.map +1 -0
- package/dist/core/usecases/suites/suites.js +45 -0
- package/dist/core/usecases/suites/suites.js.map +1 -0
- package/dist/core/usecases/touch.js +101 -0
- package/dist/core/usecases/touch.js.map +1 -0
- package/dist/core/verify/answers.js +180 -0
- package/dist/core/verify/answers.js.map +1 -0
- package/dist/core/verify/build.js +170 -0
- package/dist/core/verify/build.js.map +1 -0
- package/dist/core/verify/checklist.js +259 -0
- package/dist/core/verify/checklist.js.map +1 -0
- package/dist/core/verify/claims/identity.js +61 -0
- package/dist/core/verify/claims/identity.js.map +1 -0
- package/dist/core/verify/cross/diff.js +97 -0
- package/dist/core/verify/cross/diff.js.map +1 -0
- package/dist/core/verify/evidence/contract.js +169 -0
- package/dist/core/verify/evidence/contract.js.map +1 -0
- package/dist/core/verify/location.js +67 -0
- package/dist/core/verify/location.js.map +1 -0
- package/dist/core/verify/pins/lint.js +158 -0
- package/dist/core/verify/pins/lint.js.map +1 -0
- package/dist/core/verify/pins/pin.js +95 -0
- package/dist/core/verify/pins/pin.js.map +1 -0
- package/dist/core/verify/read/file.js +224 -0
- package/dist/core/verify/read/file.js.map +1 -0
- package/dist/core/verify/read/shape.js +169 -0
- package/dist/core/verify/read/shape.js.map +1 -0
- package/dist/core/verify/read/union.js +105 -0
- package/dist/core/verify/read/union.js.map +1 -0
- package/dist/core/verify/record.js +165 -0
- package/dist/core/verify/record.js.map +1 -0
- package/dist/core/verify/store/commit.js +99 -0
- package/dist/core/verify/store/commit.js.map +1 -0
- package/dist/core/verify/store/render.js +61 -0
- package/dist/core/verify/store/render.js.map +1 -0
- package/dist/core/vocabulary/health.js +91 -0
- package/dist/core/vocabulary/health.js.map +1 -0
- package/dist/core/vocabulary/issue.js +59 -0
- package/dist/core/vocabulary/issue.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +216 -0
- package/dist/core/vocabulary/maturity.js.map +1 -0
- package/dist/core/vocabulary/report.js +90 -0
- package/dist/core/vocabulary/report.js.map +1 -0
- package/dist/core/vocabulary/steps.js +266 -0
- package/dist/core/vocabulary/steps.js.map +1 -0
- package/dist/core/workspace/discover.js +239 -0
- package/dist/core/workspace/discover.js.map +1 -0
- package/dist/core/workspace/render.js +52 -0
- package/dist/core/workspace/render.js.map +1 -0
- package/examples/README.md +232 -0
- package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
- package/examples/docs/architecture/capabilities.yaml +31 -0
- package/examples/docs/architecture/landscape.likec4 +336 -0
- package/examples/docs/architecture/obligations.yaml +23 -0
- package/examples/docs/architecture/permissions.yaml +50 -0
- package/examples/docs/architecture/services.likec4 +70 -0
- package/examples/docs/architecture/subsystems.likec4 +18 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
- package/examples/docs/capabilities/checkout/spec.md +55 -0
- package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
- package/examples/docs/capabilities/order-notifications/spec.md +43 -0
- package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
- package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
- package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
- package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
- package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
- package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
- package/examples/docs/glossary/order.md +15 -0
- package/examples/docs/glossary/payments/authorization.md +14 -0
- package/examples/docs/likec4.config.json +8 -0
- package/examples/docs/loam.json +3 -0
- package/examples/docs/services/checkout-web/model.likec4 +92 -0
- package/examples/docs/services/checkout-web/spec.md +91 -0
- package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
- package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
- package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
- package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
- package/examples/docs/services/order-service/arch.spec.md +134 -0
- package/examples/docs/services/order-service/asyncapi.yaml +109 -0
- package/examples/docs/services/order-service/health.yaml +57 -0
- package/examples/docs/services/order-service/model.likec4 +126 -0
- package/examples/docs/services/order-service/openapi.yaml +257 -0
- package/examples/docs/services/order-service/runbook.md +62 -0
- package/examples/docs/services/order-service/spec.md +134 -0
- package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
- package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
- package/examples/docs/services/payment-service/arch.spec.md +76 -0
- package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
- package/examples/docs/services/payment-service/health.yaml +39 -0
- package/examples/docs/services/payment-service/model.likec4 +68 -0
- package/examples/docs/services/payment-service/openapi.yaml +151 -0
- package/examples/docs/services/payment-service/runbook.md +37 -0
- package/examples/docs/services/payment-service/spec.md +88 -0
- package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
- package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
- package/examples/docs/services/platform/identity-service/health.yaml +70 -0
- package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
- package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
- package/examples/docs/services/platform/identity-service/runbook.md +95 -0
- package/examples/docs/services/platform/identity-service/spec.md +119 -0
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
- package/examples/docs/services/platform/notification-service/health.yaml +40 -0
- package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
- package/examples/docs/services/platform/notification-service/runbook.md +48 -0
- package/examples/docs/services/platform/notification-service/spec.md +112 -0
- package/examples/docs/services/platform/subsystem.yaml +2 -0
- package/examples/fleet.yaml +57 -0
- package/package.json +19 -6
- package/dist/commands/adopt.js +0 -240
- package/dist/commands/adopt.js.map +0 -1
- package/dist/commands/archive.js +0 -1313
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/delta.js +0 -388
- package/dist/commands/delta.js.map +0 -1
- package/dist/commands/docs-repo-gate.js.map +0 -1
- package/dist/commands/format.js +0 -17
- package/dist/commands/format.js.map +0 -1
- package/dist/commands/gherkin.js +0 -309
- package/dist/commands/gherkin.js.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list.js +0 -295
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/migrate-openspec.js +0 -950
- package/dist/commands/migrate-openspec.js.map +0 -1
- package/dist/commands/new.js +0 -413
- package/dist/commands/new.js.map +0 -1
- package/dist/commands/rebase.js +0 -356
- package/dist/commands/rebase.js.map +0 -1
- package/dist/commands/show.js +0 -320
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/unarchive.js +0 -317
- package/dist/commands/unarchive.js.map +0 -1
- package/dist/commands/validate.js +0 -1773
- package/dist/commands/validate.js.map +0 -1
- package/dist/commands/verify.js +0 -775
- package/dist/commands/verify.js.map +0 -1
- package/dist/commands/vouch.js +0 -421
- package/dist/commands/vouch.js.map +0 -1
- package/dist/core/agent.js +0 -2173
- package/dist/core/agent.js.map +0 -1
- package/dist/core/agents-stamp.js.map +0 -1
- package/dist/core/arch.js +0 -130
- package/dist/core/arch.js.map +0 -1
- package/dist/core/asyncapi.js +0 -253
- package/dist/core/asyncapi.js.map +0 -1
- package/dist/core/brief.js +0 -755
- package/dist/core/brief.js.map +0 -1
- package/dist/core/coherence.js +0 -577
- package/dist/core/coherence.js.map +0 -1
- package/dist/core/concurrency.js.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/delta.js +0 -476
- package/dist/core/delta.js.map +0 -1
- package/dist/core/dependencies.js +0 -356
- package/dist/core/dependencies.js.map +0 -1
- package/dist/core/doctor.js +0 -596
- package/dist/core/doctor.js.map +0 -1
- package/dist/core/document-bytes.js.map +0 -1
- package/dist/core/explore.js +0 -225
- package/dist/core/explore.js.map +0 -1
- package/dist/core/frontmatter.js.map +0 -1
- package/dist/core/gherkin.js +0 -463
- package/dist/core/gherkin.js.map +0 -1
- package/dist/core/health.js +0 -67
- package/dist/core/health.js.map +0 -1
- package/dist/core/ids.js +0 -122
- package/dist/core/ids.js.map +0 -1
- package/dist/core/issue.js +0 -9
- package/dist/core/issue.js.map +0 -1
- package/dist/core/json.js +0 -74
- package/dist/core/json.js.map +0 -1
- package/dist/core/likec4.js +0 -489
- package/dist/core/likec4.js.map +0 -1
- package/dist/core/maturity.js +0 -66
- package/dist/core/maturity.js.map +0 -1
- package/dist/core/openapi-merge.js +0 -552
- package/dist/core/openapi-merge.js.map +0 -1
- package/dist/core/openapi.js.map +0 -1
- package/dist/core/openspec-inventory.js +0 -1440
- package/dist/core/openspec-inventory.js.map +0 -1
- package/dist/core/path-safety.js.map +0 -1
- package/dist/core/provenance.js +0 -787
- package/dist/core/provenance.js.map +0 -1
- package/dist/core/records.js.map +0 -1
- package/dist/core/repo.js +0 -438
- package/dist/core/repo.js.map +0 -1
- package/dist/core/report.js +0 -47
- package/dist/core/report.js.map +0 -1
- package/dist/core/spec.js +0 -505
- package/dist/core/spec.js.map +0 -1
- package/dist/core/staging.js +0 -890
- package/dist/core/staging.js.map +0 -1
- package/dist/core/status.js +0 -1132
- package/dist/core/status.js.map +0 -1
- package/dist/core/steps.js +0 -72
- package/dist/core/steps.js.map +0 -1
- package/dist/core/verify.js +0 -807
- package/dist/core/verify.js.map +0 -1
- package/dist/core/version.js.map +0 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The journaled commit itself: journal (fsynced) → swap → renames → clear,
|
|
3
|
+
* with archive's ordering on the failure path — the rollback decides the
|
|
4
|
+
* outcome, and only then does the journal have nothing left to describe. A
|
|
5
|
+
* crash anywhere inside leaves either the journal plus a recoverable tree
|
|
6
|
+
* (roll forward finishes it) or a fully rolled-back tree whose stale journal
|
|
7
|
+
* the next recovery reads as the consistent pre-state.
|
|
8
|
+
*
|
|
9
|
+
* Callers stage for themselves before committing, on purpose: vouch's
|
|
10
|
+
* byte-level raced check and gherkin's planned-vs-read compare both have to
|
|
11
|
+
* run BETWEEN staging and the swap, against the pre-images staging read.
|
|
12
|
+
*
|
|
13
|
+
* The DIRECTORY RENAMES (`spec.moves`, `subsystem move`'s half) come after
|
|
14
|
+
* every file swap, deliberately: the generated views file must land in the
|
|
15
|
+
* same commit as the renames or the tree is left failing between two states,
|
|
16
|
+
* and a failure mid-renames still has the swapped files' pre-images in hand
|
|
17
|
+
* to roll everything back together — renames undone newest-first, then the
|
|
18
|
+
* files, one failure list, one verdict.
|
|
19
|
+
*/
|
|
20
|
+
import { rename } from "node:fs/promises";
|
|
21
|
+
import { message, rollbackMessage, rollbackStaged, StagingRaceError, swapStaged } from "../commit.js";
|
|
22
|
+
import {} from "../writes.js";
|
|
23
|
+
import { clearTxnIntent, writeTxnIntent } from "./journal.js";
|
|
24
|
+
/**
|
|
25
|
+
* `what` is the verb the rollback sentence uses for the half-state ("merged",
|
|
26
|
+
* "stamped", "written") — each caller keeps the word its operators already
|
|
27
|
+
* grep their logs for.
|
|
28
|
+
*/
|
|
29
|
+
export async function commitStaged(spec, staged, what) {
|
|
30
|
+
await writeTxnIntent(spec, staged);
|
|
31
|
+
const performed = [];
|
|
32
|
+
try {
|
|
33
|
+
await swapStaged(staged);
|
|
34
|
+
for (const move of spec.moves ?? []) {
|
|
35
|
+
await rename(move.from, move.to);
|
|
36
|
+
performed.push(move);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
// Renames back first, newest-first: each is its own inverse, and a
|
|
41
|
+
// directory that cannot go back is exactly as reportable as a file that
|
|
42
|
+
// cannot — it joins the same failure list and forces the same verdict.
|
|
43
|
+
const failures = [];
|
|
44
|
+
for (const move of [...performed].reverse()) {
|
|
45
|
+
try {
|
|
46
|
+
await rename(move.to, move.from);
|
|
47
|
+
}
|
|
48
|
+
catch (undoErr) {
|
|
49
|
+
failures.push(`${move.to} (${message(undoErr)})`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
failures.push(...(await rollbackStaged(staged)));
|
|
53
|
+
// The journal is cleared only when the rollback HELD. On rollback-incomplete
|
|
54
|
+
// the tree is genuinely half-written and the temps are gone — the journal
|
|
55
|
+
// is the one durable record of which files, so doctor keeps naming them,
|
|
56
|
+
// validate keeps refusing to grade the tree green, and the next writer
|
|
57
|
+
// refuses commit-interrupted instead of writing over the wreckage. Archive
|
|
58
|
+
// pays the same way by retaining its snapshot on this path.
|
|
59
|
+
if (failures.length === 0)
|
|
60
|
+
await clearTxnIntent(spec.root);
|
|
61
|
+
const raced = err instanceof StagingRaceError || err.code === "EEXIST";
|
|
62
|
+
if (failures.length > 0) {
|
|
63
|
+
// NEVER raced, whatever threw: callers remap a raced failure onto their
|
|
64
|
+
// own softer code (vouch-raced, already-exists) with "nothing was
|
|
65
|
+
// written" prose — and here something WAS written and could not be
|
|
66
|
+
// taken back. rollback-incomplete is the one answer that demands a
|
|
67
|
+
// human, and no remap may swallow the file list that says where.
|
|
68
|
+
return { ok: false, code: "rollback-incomplete", message: rollbackMessage(err, failures, what), raced: false };
|
|
69
|
+
}
|
|
70
|
+
return { ok: false, code: "merge-failed", message: `${message(err)} — rolled back, nothing was written`, raced };
|
|
71
|
+
}
|
|
72
|
+
await clearTxnIntent(spec.root);
|
|
73
|
+
return { ok: true };
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../../src/core/staging/txn/transaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACtG,OAAO,EAAoB,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAgB,MAAM,cAAc,CAAC;AAkB5E;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAa,EAAE,MAAqB,EAAE,IAAY;IACnF,MAAM,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,SAAS,GAAmC,EAAE,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACpC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YACjC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,mEAAmE;QACnE,wEAAwE;QACxE,uEAAuE;QACvE,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,CAAC;YAAC,OAAO,OAAO,EAAE,CAAC;gBACjB,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACjD,6EAA6E;QAC7E,0EAA0E;QAC1E,yEAAyE;QACzE,uEAAuE;QACvE,2EAA2E;QAC3E,4DAA4D;QAC5D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,GAAG,YAAY,gBAAgB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,CAAC;QAClG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,wEAAwE;YACxE,kEAAkE;YAClE,mEAAmE;YACnE,mEAAmE;YACnE,iEAAiE;YACjE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACjH,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,KAAK,EAAE,CAAC;IACnH,CAAC;IACD,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC","sourcesContent":["/**\n * The journaled commit itself: journal (fsynced) → swap → renames → clear,\n * with archive's ordering on the failure path — the rollback decides the\n * outcome, and only then does the journal have nothing left to describe. A\n * crash anywhere inside leaves either the journal plus a recoverable tree\n * (roll forward finishes it) or a fully rolled-back tree whose stale journal\n * the next recovery reads as the consistent pre-state.\n *\n * Callers stage for themselves before committing, on purpose: vouch's\n * byte-level raced check and gherkin's planned-vs-read compare both have to\n * run BETWEEN staging and the swap, against the pre-images staging read.\n *\n * The DIRECTORY RENAMES (`spec.moves`, `subsystem move`'s half) come after\n * every file swap, deliberately: the generated views file must land in the\n * same commit as the renames or the tree is left failing between two states,\n * and a failure mid-renames still has the swapped files' pre-images in hand\n * to roll everything back together — renames undone newest-first, then the\n * files, one failure list, one verdict.\n */\nimport { rename } from \"node:fs/promises\";\nimport { message, rollbackMessage, rollbackStaged, StagingRaceError, swapStaged } from \"../commit.js\";\nimport { type StagedWrite } from \"../writes.js\";\nimport { clearTxnIntent, writeTxnIntent, type TxnSpec } from \"./journal.js\";\n\nexport type StagedCommit =\n | { ok: true }\n | {\n ok: false;\n code: \"merge-failed\" | \"rollback-incomplete\";\n message: string;\n /**\n * The failure was another writer winning a race (an exclusive create\n * losing to a concurrent one, or the pre-image compare firing), so the\n * caller may map it to its own stable race code — `new` answers\n * `already-exists`, vouch answers `vouch-raced` — instead of the\n * generic merge failure.\n */\n raced: boolean;\n };\n\n/**\n * `what` is the verb the rollback sentence uses for the half-state (\"merged\",\n * \"stamped\", \"written\") — each caller keeps the word its operators already\n * grep their logs for.\n */\nexport async function commitStaged(spec: TxnSpec, staged: StagedWrite[], what: string): Promise<StagedCommit> {\n await writeTxnIntent(spec, staged);\n const performed: { from: string; to: string }[] = [];\n try {\n await swapStaged(staged);\n for (const move of spec.moves ?? []) {\n await rename(move.from, move.to);\n performed.push(move);\n }\n } catch (err) {\n // Renames back first, newest-first: each is its own inverse, and a\n // directory that cannot go back is exactly as reportable as a file that\n // cannot — it joins the same failure list and forces the same verdict.\n const failures: string[] = [];\n for (const move of [...performed].reverse()) {\n try {\n await rename(move.to, move.from);\n } catch (undoErr) {\n failures.push(`${move.to} (${message(undoErr)})`);\n }\n }\n failures.push(...(await rollbackStaged(staged)));\n // The journal is cleared only when the rollback HELD. On rollback-incomplete\n // the tree is genuinely half-written and the temps are gone — the journal\n // is the one durable record of which files, so doctor keeps naming them,\n // validate keeps refusing to grade the tree green, and the next writer\n // refuses commit-interrupted instead of writing over the wreckage. Archive\n // pays the same way by retaining its snapshot on this path.\n if (failures.length === 0) await clearTxnIntent(spec.root);\n const raced = err instanceof StagingRaceError || (err as NodeJS.ErrnoException).code === \"EEXIST\";\n if (failures.length > 0) {\n // NEVER raced, whatever threw: callers remap a raced failure onto their\n // own softer code (vouch-raced, already-exists) with \"nothing was\n // written\" prose — and here something WAS written and could not be\n // taken back. rollback-incomplete is the one answer that demands a\n // human, and no remap may swallow the file list that says where.\n return { ok: false, code: \"rollback-incomplete\", message: rollbackMessage(err, failures, what), raced: false };\n }\n return { ok: false, code: \"merge-failed\", message: `${message(err)} — rolled back, nothing was written`, raced };\n }\n await clearTxnIntent(spec.root);\n return { ok: true };\n}\n"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a write IS before anything touches disk: the planned record, the staged
|
|
3
|
+
* record, and the bytes both are made of.
|
|
4
|
+
*
|
|
5
|
+
* This is the package's floor. Everything else here — the lock, the swap, the
|
|
6
|
+
* snapshot, the recovery journal — is a rule about WHEN bytes may land; only
|
|
7
|
+
* this module decides what they are. Decoding lives here for the same reason:
|
|
8
|
+
* text is produced only where a parser needs it and `readUtf8` is the one door,
|
|
9
|
+
* so no later addition can reach a docs file through `readFile(…, "utf8")` and
|
|
10
|
+
* silently substitute U+FFFD for bytes loam did not understand.
|
|
11
|
+
*/
|
|
12
|
+
import { isUtf8 } from "node:buffer";
|
|
13
|
+
import { createHash } from "node:crypto";
|
|
14
|
+
import { existsSync } from "node:fs";
|
|
15
|
+
import { readFile } from "node:fs/promises";
|
|
16
|
+
/** The one place a planned write becomes bytes. */
|
|
17
|
+
export function toBytes(content) {
|
|
18
|
+
return typeof content === "string" ? Buffer.from(content, "utf8") : content;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The one place that decides whether a planned write is a CREATE *from the
|
|
22
|
+
* filesystem*. (`core/verify/store/commit.ts` is the deliberate second rule:
|
|
23
|
+
* it decides from the caller's held pre-image instead, because a CAS must
|
|
24
|
+
* follow the read it promised, not what `existsSync` says now.)
|
|
25
|
+
*
|
|
26
|
+
* `exclusive` is a no-clobber create (link(2)), so it can only be asked of a
|
|
27
|
+
* path that does not exist yet: asking it of an overwrite would fail EEXIST on
|
|
28
|
+
* every single run. Deciding here — rather than at each of the dozen
|
|
29
|
+
* `writes.push` sites in archive and unarchive — is what keeps the two commands
|
|
30
|
+
* from disagreeing about which of their writes may safely lose a race. An
|
|
31
|
+
* OVERWRITE is not left unguarded: `swapStaged` compares the target against the
|
|
32
|
+
* pre-image immediately before the rename, so a file another writer changed
|
|
33
|
+
* under us stops the commit instead of silently burying their bytes.
|
|
34
|
+
*/
|
|
35
|
+
export function planWrite(path, content) {
|
|
36
|
+
if (content !== null && !existsSync(path))
|
|
37
|
+
return { path, content, exclusive: true };
|
|
38
|
+
return { path, content };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A file loam must PARSE that does not decode as the UTF-8 text loam owns.
|
|
42
|
+
*
|
|
43
|
+
* Commands map this to `merge-failed`: nothing was written, the file is named,
|
|
44
|
+
* and re-saving it as UTF-8 makes the command work. The read-only migration
|
|
45
|
+
* ingest already refuses non-UTF-8 input outright (core/openspec/) —
|
|
46
|
+
* the destructive path has strictly more to lose, so it refuses the same way
|
|
47
|
+
* rather than substituting U+FFFD and rewriting the file over the author.
|
|
48
|
+
*
|
|
49
|
+
* `reason` says what the bytes actually ARE, because the two ways a document
|
|
50
|
+
* fails this test destroy different things: one substitutes bytes, the other
|
|
51
|
+
* erases the whole document's meaning. A reader told the wrong one goes looking
|
|
52
|
+
* in the wrong place. The advice that follows is the same either way, so it is
|
|
53
|
+
* spelled once, here.
|
|
54
|
+
*/
|
|
55
|
+
export class NotUtf8Error extends Error {
|
|
56
|
+
path;
|
|
57
|
+
name = "NotUtf8Error";
|
|
58
|
+
constructor(path, reason) {
|
|
59
|
+
super(`${path} ${reason} Nothing was written. Re-save it as UTF-8, then re-run.`);
|
|
60
|
+
this.path = path;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Decode bytes a parser is about to be handed, or refuse naming the file.
|
|
65
|
+
*
|
|
66
|
+
* Two tests, the same two the read path makes (document-bytes.ts's
|
|
67
|
+
* `decodeDocument`), because this side has strictly more to lose by missing
|
|
68
|
+
* either. `isUtf8` catches the byte sequences that cannot be UTF-8 at all —
|
|
69
|
+
* which is what a byte-order mark makes UTF-16 into. Without a BOM, UTF-16LE of
|
|
70
|
+
* ASCII is a sequence of perfectly VALID UTF-8 bytes: every other byte is NUL,
|
|
71
|
+
* so `isUtf8` says yes, the file decodes with a U+0000 between every character,
|
|
72
|
+
* and every parser loam owns reads its requirements, frontmatter and headings
|
|
73
|
+
* as absent rather than as unreadable. On the read path that is a document
|
|
74
|
+
* graded green while nothing in it was checked; here it is worse, because
|
|
75
|
+
* `archive` merges against that empty baseline and writes the result back — the
|
|
76
|
+
* author's requirements are not mis-read, they are gone, and the undo snapshot
|
|
77
|
+
* records the same emptiness as the pre-image.
|
|
78
|
+
*/
|
|
79
|
+
function decodeUtf8(bytes, path) {
|
|
80
|
+
if (!isUtf8(bytes)) {
|
|
81
|
+
throw new NotUtf8Error(path, `is not valid UTF-8 — loam parses this file as text and writes it back, which would replace every ` +
|
|
82
|
+
`undecodable byte with U+FFFD, in the living document AND in the undo snapshot.`);
|
|
83
|
+
}
|
|
84
|
+
const text = bytes.toString("utf8");
|
|
85
|
+
if (text.includes("\u0000")) {
|
|
86
|
+
throw new NotUtf8Error(path, `holds NUL characters, which no document loam owns does — almost always UTF-16 saved without a byte-order ` +
|
|
87
|
+
`mark. Its bytes are valid UTF-8, so it decodes without complaint into text whose requirements, ` +
|
|
88
|
+
`frontmatter and headings all parse as ABSENT: the merge would compute over an empty baseline and write ` +
|
|
89
|
+
`that back, taking every requirement in the file with it.`);
|
|
90
|
+
}
|
|
91
|
+
return text;
|
|
92
|
+
}
|
|
93
|
+
/** Read a file loam is going to parse. The only supported way to turn a docs file into a string. */
|
|
94
|
+
export async function readUtf8(path) {
|
|
95
|
+
return decodeUtf8(await readFile(path), path);
|
|
96
|
+
}
|
|
97
|
+
/** Same bytes? Absence is its own value: a file that is gone is not a file that is empty. */
|
|
98
|
+
export function sameBytes(a, b) {
|
|
99
|
+
return a === null || b === null ? a === b : a.equals(b);
|
|
100
|
+
}
|
|
101
|
+
/* ------------------------------------------------------------------ */
|
|
102
|
+
/* Reading loam's own records back off the disk */
|
|
103
|
+
/* ------------------------------------------------------------------ */
|
|
104
|
+
/** The one spelling of a sha256 loam wrote, for reading one back out of a record. */
|
|
105
|
+
export function isDigest(value) {
|
|
106
|
+
return typeof value === "string" && /^[0-9a-f]{64}$/.test(value);
|
|
107
|
+
}
|
|
108
|
+
export function sha256(content) {
|
|
109
|
+
return typeof content === "string"
|
|
110
|
+
? createHash("sha256").update(content, "utf8").digest("hex")
|
|
111
|
+
: createHash("sha256").update(content).digest("hex");
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=writes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writes.js","sourceRoot":"","sources":["../../../src/core/staging/writes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AA+B5C,mDAAmD;AACnD,MAAM,UAAU,OAAO,CAAC,OAA+B;IACrD,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,OAA+B;IACrE,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACrF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAuBD;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAI1B,IAAI;IAHG,IAAI,GAAG,cAAc,CAAC;IAExC,YACW,IAAY,EACrB,MAAc;QAEd,KAAK,CAAC,GAAG,IAAI,IAAI,MAAM,yDAAyD,CAAC,CAAC;oBAHzE,IAAI;IAIf,CAAC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,UAAU,CAAC,KAAa,EAAE,IAAY;IAC7C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,YAAY,CACpB,IAAI,EACJ,mGAAmG;YACjG,gFAAgF,CACnF,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,YAAY,CACpB,IAAI,EACJ,2GAA2G;YACzG,iGAAiG;YACjG,yGAAyG;YACzG,0DAA0D,CAC7D,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oGAAoG;AACpG,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY;IACzC,OAAO,UAAU,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,SAAS,CAAC,CAAgB,EAAE,CAAgB;IAC1D,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,wEAAwE;AACxE,yEAAyE;AACzE,wEAAwE;AAExE,qFAAqF;AACrF,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAwB;IAC7C,OAAO,OAAO,OAAO,KAAK,QAAQ;QAChC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAC5D,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC","sourcesContent":["/**\n * What a write IS before anything touches disk: the planned record, the staged\n * record, and the bytes both are made of.\n *\n * This is the package's floor. Everything else here — the lock, the swap, the\n * snapshot, the recovery journal — is a rule about WHEN bytes may land; only\n * this module decides what they are. Decoding lives here for the same reason:\n * text is produced only where a parser needs it and `readUtf8` is the one door,\n * so no later addition can reach a docs file through `readFile(…, \"utf8\")` and\n * silently substitute U+FFFD for bytes loam did not understand.\n */\nimport { isUtf8 } from \"node:buffer\";\nimport { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\n\n/**\n * A planned file write — the merge is computed fully before anything touches\n * disk. `content: null` means \"delete this file\": `unarchive` takes back a file the\n * archive created, and `subsystem sync` removes the generated views file and a\n * stray per-service project file beside an extending model.\n *\n * BYTES, not text. The whole write path — pre-image, staged content, snapshot,\n * the compare-and-set before each swap — moves Buffers, because a docs repo is\n * not guaranteed to hold text loam can decode: `Buffer.toString(\"utf8\")` never\n * fails, it substitutes U+FFFD, so reading a file as a string and writing the\n * string back is a silent, permanent rewrite of every byte loam did not\n * understand. It reached the snapshot too, so `unarchive` restored the damage\n * and reported success. Text is now produced only where a PARSER needs it, by\n * `decodeUtf8`, which refuses instead of substituting.\n */\nexport interface PlannedWrite {\n path: string;\n /**\n * A `string` is accepted for the callers whose new version IS text they\n * composed from nothing (a re-pinned delta, a restamped spec) and is encoded\n * as UTF-8 once, at staging. A caller holding BYTES — anything derived from a\n * file loam read — must hand over the Buffer: the round trip through a string\n * is the corruption above.\n */\n content: string | Buffer | null;\n /** Create the target atomically without replacing a concurrently created file. */\n exclusive?: boolean;\n}\n\n/** The one place a planned write becomes bytes. */\nexport function toBytes(content: string | Buffer | null): Buffer | null {\n return typeof content === \"string\" ? Buffer.from(content, \"utf8\") : content;\n}\n\n/**\n * The one place that decides whether a planned write is a CREATE *from the\n * filesystem*. (`core/verify/store/commit.ts` is the deliberate second rule:\n * it decides from the caller's held pre-image instead, because a CAS must\n * follow the read it promised, not what `existsSync` says now.)\n *\n * `exclusive` is a no-clobber create (link(2)), so it can only be asked of a\n * path that does not exist yet: asking it of an overwrite would fail EEXIST on\n * every single run. Deciding here — rather than at each of the dozen\n * `writes.push` sites in archive and unarchive — is what keeps the two commands\n * from disagreeing about which of their writes may safely lose a race. An\n * OVERWRITE is not left unguarded: `swapStaged` compares the target against the\n * pre-image immediately before the rename, so a file another writer changed\n * under us stops the commit instead of silently burying their bytes.\n */\nexport function planWrite(path: string, content: string | Buffer | null): PlannedWrite {\n if (content !== null && !existsSync(path)) return { path, content, exclusive: true };\n return { path, content };\n}\n\n/** A planned write with its new bytes parked next to the target, ready to swap in. */\nexport interface StagedWrite {\n write: PlannedWrite;\n /** What this write puts on disk — `write.content` encoded once. Null for a delete. */\n content: Buffer | null;\n /** Temp file holding the new bytes, in the target's OWN directory. Null for a delete. */\n tmp: string | null;\n /** The target's bytes before the swap; null when it did not exist. */\n before: Buffer | null;\n /**\n * Topmost directory this write had to create, if any — a rollback owes the repo\n * its directories back too. An empty `services/<svc>/` left standing is the\n * fleet claiming a service that was never merged. Spelled as\n * `mkdirReportingCreated` returns it, never as Node's raw `mkdir` report.\n */\n createdDir: string | null;\n swapped: boolean;\n}\n\n\n\n/**\n * A file loam must PARSE that does not decode as the UTF-8 text loam owns.\n *\n * Commands map this to `merge-failed`: nothing was written, the file is named,\n * and re-saving it as UTF-8 makes the command work. The read-only migration\n * ingest already refuses non-UTF-8 input outright (core/openspec/) —\n * the destructive path has strictly more to lose, so it refuses the same way\n * rather than substituting U+FFFD and rewriting the file over the author.\n *\n * `reason` says what the bytes actually ARE, because the two ways a document\n * fails this test destroy different things: one substitutes bytes, the other\n * erases the whole document's meaning. A reader told the wrong one goes looking\n * in the wrong place. The advice that follows is the same either way, so it is\n * spelled once, here.\n */\nexport class NotUtf8Error extends Error {\n override readonly name = \"NotUtf8Error\";\n\n constructor(\n readonly path: string,\n reason: string,\n ) {\n super(`${path} ${reason} Nothing was written. Re-save it as UTF-8, then re-run.`);\n }\n}\n\n/**\n * Decode bytes a parser is about to be handed, or refuse naming the file.\n *\n * Two tests, the same two the read path makes (document-bytes.ts's\n * `decodeDocument`), because this side has strictly more to lose by missing\n * either. `isUtf8` catches the byte sequences that cannot be UTF-8 at all —\n * which is what a byte-order mark makes UTF-16 into. Without a BOM, UTF-16LE of\n * ASCII is a sequence of perfectly VALID UTF-8 bytes: every other byte is NUL,\n * so `isUtf8` says yes, the file decodes with a U+0000 between every character,\n * and every parser loam owns reads its requirements, frontmatter and headings\n * as absent rather than as unreadable. On the read path that is a document\n * graded green while nothing in it was checked; here it is worse, because\n * `archive` merges against that empty baseline and writes the result back — the\n * author's requirements are not mis-read, they are gone, and the undo snapshot\n * records the same emptiness as the pre-image.\n */\nfunction decodeUtf8(bytes: Buffer, path: string): string {\n if (!isUtf8(bytes)) {\n throw new NotUtf8Error(\n path,\n `is not valid UTF-8 — loam parses this file as text and writes it back, which would replace every ` +\n `undecodable byte with U+FFFD, in the living document AND in the undo snapshot.`,\n );\n }\n const text = bytes.toString(\"utf8\");\n if (text.includes(\"\\u0000\")) {\n throw new NotUtf8Error(\n path,\n `holds NUL characters, which no document loam owns does — almost always UTF-16 saved without a byte-order ` +\n `mark. Its bytes are valid UTF-8, so it decodes without complaint into text whose requirements, ` +\n `frontmatter and headings all parse as ABSENT: the merge would compute over an empty baseline and write ` +\n `that back, taking every requirement in the file with it.`,\n );\n }\n return text;\n}\n\n/** Read a file loam is going to parse. The only supported way to turn a docs file into a string. */\nexport async function readUtf8(path: string): Promise<string> {\n return decodeUtf8(await readFile(path), path);\n}\n\n/** Same bytes? Absence is its own value: a file that is gone is not a file that is empty. */\nexport function sameBytes(a: Buffer | null, b: Buffer | null): boolean {\n return a === null || b === null ? a === b : a.equals(b);\n}\n\n/* ------------------------------------------------------------------ */\n/* Reading loam's own records back off the disk */\n/* ------------------------------------------------------------------ */\n\n/** The one spelling of a sha256 loam wrote, for reading one back out of a record. */\nexport function isDigest(value: unknown): value is string {\n return typeof value === \"string\" && /^[0-9a-f]{64}$/.test(value);\n}\n\nexport function sha256(content: Buffer | string): string {\n return typeof content === \"string\"\n ? createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\")\n : createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const EDIT_STEPS = new Set([
|
|
2
|
+
"next.author-intent",
|
|
3
|
+
"next.touch-service",
|
|
4
|
+
"next.author-spec",
|
|
5
|
+
"next.author-openapi",
|
|
6
|
+
"next.author-scenarios",
|
|
7
|
+
]);
|
|
8
|
+
const SERVICE_REPO_STEPS = new Set([
|
|
9
|
+
"next.bind-service",
|
|
10
|
+
"next.adopt-first",
|
|
11
|
+
"next.generate-tests",
|
|
12
|
+
"next.verify-unconfirmed",
|
|
13
|
+
"next.attest-service",
|
|
14
|
+
"next.verify-attested",
|
|
15
|
+
]);
|
|
16
|
+
function placeholders(command) {
|
|
17
|
+
return [...command.matchAll(/<([^>]+)>/g)].map((match) => match[1]);
|
|
18
|
+
}
|
|
19
|
+
function execution(step) {
|
|
20
|
+
if (EDIT_STEPS.has(step.code)) {
|
|
21
|
+
return {
|
|
22
|
+
kind: "edit",
|
|
23
|
+
runnable: false,
|
|
24
|
+
cwd: "docs-repo",
|
|
25
|
+
after: step.command,
|
|
26
|
+
needs: [step.path ?? "the artifact named in statement"],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (step.code === "next.recover-commit" && step.command === "loam doctor --json") {
|
|
30
|
+
return {
|
|
31
|
+
kind: "human-review",
|
|
32
|
+
runnable: false,
|
|
33
|
+
cwd: "docs-repo",
|
|
34
|
+
needs: ["compare the living docs with version control"],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// A vouch is a person's act, never an agent's (`loam vouch` refuses without a
|
|
38
|
+
// terminal or `--yes`), so the step is NOT runnable: an agent prepares the
|
|
39
|
+
// reading list with `loam vouch --pack` and hands the stamp to a person.
|
|
40
|
+
if (step.code === "next.revouch") {
|
|
41
|
+
return {
|
|
42
|
+
kind: "human-review",
|
|
43
|
+
runnable: false,
|
|
44
|
+
cwd: "service-repo",
|
|
45
|
+
needs: ["a person who re-reads the moved document and vouches for it from the service's own repository"],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const needs = placeholders(step.command);
|
|
49
|
+
const serviceRepo = SERVICE_REPO_STEPS.has(step.code);
|
|
50
|
+
return {
|
|
51
|
+
kind: serviceRepo ? "external-repo" : "command",
|
|
52
|
+
runnable: needs.length === 0,
|
|
53
|
+
cwd: serviceRepo ? "service-repo" : "configured-repo",
|
|
54
|
+
...(needs.length === 0 ? { command: step.command } : { needs }),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export function executableNext(step) {
|
|
58
|
+
return { ...step, execution: execution(step) };
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../../../src/core/status/actions/execution.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,oBAAoB;IACpB,oBAAoB;IACpB,kBAAkB;IAClB,qBAAqB;IACrB,uBAAuB;CACxB,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;IACjC,mBAAmB;IACnB,kBAAkB;IAClB,qBAAqB;IACrB,yBAAyB;IACzB,qBAAqB;IACrB,sBAAsB;CACvB,CAAC,CAAC;AAEH,SAAS,YAAY,CAAC,OAAe;IACnC,OAAO,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAC/B,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,KAAK;YACf,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,IAAI,CAAC,OAAO;YACnB,KAAK,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,iCAAiC,CAAC;SACxD,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB,IAAI,IAAI,CAAC,OAAO,KAAK,oBAAoB,EAAE,CAAC;QACjF,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,KAAK;YACf,GAAG,EAAE,WAAW;YAChB,KAAK,EAAE,CAAC,8CAA8C,CAAC;SACxD,CAAC;IACJ,CAAC;IACD,8EAA8E;IAC9E,2EAA2E;IAC3E,yEAAyE;IACzE,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QACjC,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,QAAQ,EAAE,KAAK;YACf,GAAG,EAAE,cAAc;YACnB,KAAK,EAAE,CAAC,+FAA+F,CAAC;SACzG,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtD,OAAO;QACL,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;QAC/C,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC;QAC5B,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB;QACrD,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAc;IAC3C,OAAO,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;AACjD,CAAC","sourcesContent":["/** The executable machine contract layered over status's legacy command hint. */\nimport type {\n ExecutableNextStep,\n NextExecution,\n NextStep,\n} from \"../report.js\";\n\nconst EDIT_STEPS = new Set([\n \"next.author-intent\",\n \"next.touch-service\",\n \"next.author-spec\",\n \"next.author-openapi\",\n \"next.author-scenarios\",\n]);\n\nconst SERVICE_REPO_STEPS = new Set([\n \"next.bind-service\",\n \"next.adopt-first\",\n \"next.generate-tests\",\n \"next.verify-unconfirmed\",\n \"next.attest-service\",\n \"next.verify-attested\",\n]);\n\nfunction placeholders(command: string): string[] {\n return [...command.matchAll(/<([^>]+)>/g)].map((match) => match[1]!);\n}\n\nfunction execution(step: NextStep): NextExecution {\n if (EDIT_STEPS.has(step.code)) {\n return {\n kind: \"edit\",\n runnable: false,\n cwd: \"docs-repo\",\n after: step.command,\n needs: [step.path ?? \"the artifact named in statement\"],\n };\n }\n if (step.code === \"next.recover-commit\" && step.command === \"loam doctor --json\") {\n return {\n kind: \"human-review\",\n runnable: false,\n cwd: \"docs-repo\",\n needs: [\"compare the living docs with version control\"],\n };\n }\n // A vouch is a person's act, never an agent's (`loam vouch` refuses without a\n // terminal or `--yes`), so the step is NOT runnable: an agent prepares the\n // reading list with `loam vouch --pack` and hands the stamp to a person.\n if (step.code === \"next.revouch\") {\n return {\n kind: \"human-review\",\n runnable: false,\n cwd: \"service-repo\",\n needs: [\"a person who re-reads the moved document and vouches for it from the service's own repository\"],\n };\n }\n const needs = placeholders(step.command);\n const serviceRepo = SERVICE_REPO_STEPS.has(step.code);\n return {\n kind: serviceRepo ? \"external-repo\" : \"command\",\n runnable: needs.length === 0,\n cwd: serviceRepo ? \"service-repo\" : \"configured-repo\",\n ...(needs.length === 0 ? { command: step.command } : { needs }),\n };\n}\n\nexport function executableNext(step: NextStep): ExecutableNextStep {\n return { ...step, execution: execution(step) };\n}\n"]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who owes a service its `openapi.yaml`, and which features in flight already
|
|
3
|
+
* carry one. Shared between the artifact table and the fleet form, because the
|
|
4
|
+
* two must never disagree about whether a feature owes a contract.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
import { calledServices } from "../coherence/calls/called.js";
|
|
8
|
+
import { featureSpecPaths } from "../repo/paths.js";
|
|
9
|
+
import { listFeatures } from "../repo/repo.js";
|
|
10
|
+
import { governedServices } from "./scan.js";
|
|
11
|
+
/**
|
|
12
|
+
* Does this feature owe `svc` an openapi.yaml?
|
|
13
|
+
*
|
|
14
|
+
* Keyed on the living CONTRACT FILE, never on `services/<svc>/` merely existing
|
|
15
|
+
* as a directory. A service adopted without a contract is precisely the case
|
|
16
|
+
* where a feature that governs operations has to write one, and the directory
|
|
17
|
+
* test answered "none owed" there — printing `(not written — none owed)` beside
|
|
18
|
+
* the `spec-api.op-undefined` finding, in the same payload, about that very
|
|
19
|
+
* file, while suppressing the only step that names it.
|
|
20
|
+
*
|
|
21
|
+
* Two ways to owe nothing, both about somebody else discharging it: the living
|
|
22
|
+
* docs already carry the contract, or another feature in flight brings it — the
|
|
23
|
+
* same softening coherence applies with its `*-pending` codes, where an
|
|
24
|
+
* operation "defined by another feature still in flight" is an ordering fact
|
|
25
|
+
* and not a hole.
|
|
26
|
+
*
|
|
27
|
+
* Otherwise the contract is owed exactly when something this feature wrote
|
|
28
|
+
* already joins into it (`evidence`, see {@link contractEvidence}): a
|
|
29
|
+
* requirement's `Operations:` line, or a tagged delta edge calling an
|
|
30
|
+
* operation on the service. Those are the two links the gates grade against
|
|
31
|
+
* the file — `spec-api.op-undefined` and `c4-api.op-undefined` — and the same
|
|
32
|
+
* two `service.no-openapi` reads once the service is living, where a service
|
|
33
|
+
* nothing joins into is the documented silence. A UI, a worker, a service whose
|
|
34
|
+
* only edges go OUT has no API to write down, and that holds for a service the
|
|
35
|
+
* feature introduces exactly as for an adopted one. Demanding a file from a new
|
|
36
|
+
* one regardless was loam telling an author to invent a contract — and authors
|
|
37
|
+
* did, as `paths: {}` stubs the archive then published as living contracts.
|
|
38
|
+
*
|
|
39
|
+
* The evidence is THIS feature's own, as every gate it mirrors is. Another
|
|
40
|
+
* feature in flight drawing an op-linked edge into a service this one
|
|
41
|
+
* introduces is that feature's `c4-api.op-undefined` (or `-pending`) to raise,
|
|
42
|
+
* on its own status; this one's gate says nothing about it, so neither does
|
|
43
|
+
* this projection.
|
|
44
|
+
*
|
|
45
|
+
* `evidence` undefined means loam could not look — the delta does not parse —
|
|
46
|
+
* and then the old reading stands: owed for a service the living docs have
|
|
47
|
+
* never heard of, not for an adopted one. `delta.invalid` gates either way.
|
|
48
|
+
*/
|
|
49
|
+
export function owesContract(entry, contracted, evidence) {
|
|
50
|
+
// Both living facts come off the ENUMERATION's entry rather than root
|
|
51
|
+
// existsSync probes: a service filed into a subsystem lives wherever the
|
|
52
|
+
// tree walk found it, so the root probe read every filed service as "living
|
|
53
|
+
// docs have never heard of it" and demanded a contract from all of them.
|
|
54
|
+
// `undefined` IS that never-heard-of case — nothing enumerated the id
|
|
55
|
+
// anywhere. `contracted` arrives resolved by the caller, and deliberately
|
|
56
|
+
// not through the entry: another feature in flight discharges the debt for
|
|
57
|
+
// a service the living docs have NOT heard of yet — that is the ordinary
|
|
58
|
+
// introduce-then-build ordering, and it must keep answering "none owed".
|
|
59
|
+
if (entry?.has.openapi === true)
|
|
60
|
+
return false;
|
|
61
|
+
if (contracted)
|
|
62
|
+
return false;
|
|
63
|
+
return evidence ?? entry === undefined;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Per service, whether this feature wrote anything that joins into its
|
|
67
|
+
* contract — `true`/`false`, or `undefined` when the delta could not be read.
|
|
68
|
+
* One function for both status forms, so they cannot disagree about whether a
|
|
69
|
+
* feature owes a contract: the `Operations:` lines come off the scan they have
|
|
70
|
+
* already made, and the op-linked edges off the delta parse they have already
|
|
71
|
+
* paid for (the coherence pass in one, the dependency graph in the other).
|
|
72
|
+
*/
|
|
73
|
+
export async function contractEvidence(docsDir, feature, scans, context) {
|
|
74
|
+
const governs = governedServices(scans);
|
|
75
|
+
const called = await calledServices({ docsDir, featureDir: feature.dir, featureId: feature.id }, context);
|
|
76
|
+
return (service) => (governs.has(service) ? true : called === "unreadable" ? undefined : called.has(service));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Which features in flight carry an `openapi.yaml` for which service — one
|
|
80
|
+
* enumeration of the whole index, service by service.
|
|
81
|
+
*
|
|
82
|
+
* The owners are recorded as feature IDS rather than directories because that
|
|
83
|
+
* is the comparison {@link contractsHeldElsewhere} makes: two directories that
|
|
84
|
+
* spell the same id are one feature as far as this question goes, and an index
|
|
85
|
+
* keyed by directory would let a duplicated id answer "somebody else has it"
|
|
86
|
+
* about its own twin.
|
|
87
|
+
*
|
|
88
|
+
* Enumeration only — the feature list and its `specs/` subdirectories are
|
|
89
|
+
* already in the request-scoped index by the time anything asks.
|
|
90
|
+
*/
|
|
91
|
+
export async function contractOwners(docsDir, context) {
|
|
92
|
+
const out = new Map();
|
|
93
|
+
for (const f of await listFeatures(docsDir, {}, context)) {
|
|
94
|
+
for (const svc of f.services) {
|
|
95
|
+
if (!existsSync(featureSpecPaths(f.dir, svc).openapi))
|
|
96
|
+
continue;
|
|
97
|
+
const owners = out.get(svc);
|
|
98
|
+
if (owners === undefined)
|
|
99
|
+
out.set(svc, new Set([f.id]));
|
|
100
|
+
else
|
|
101
|
+
owners.add(f.id);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Services some OTHER active feature already carries an `openapi.yaml` for.
|
|
108
|
+
*
|
|
109
|
+
* Derived from the shared index rather than re-walked, because the answer for
|
|
110
|
+
* feature A and the answer for feature B are two readings of one enumeration:
|
|
111
|
+
* asking it once per feature made the fleet form pay F²·S `existsSync` calls
|
|
112
|
+
* over the two quantities that actually grow.
|
|
113
|
+
*/
|
|
114
|
+
export function contractsHeldElsewhere(owners, self) {
|
|
115
|
+
const out = new Set();
|
|
116
|
+
for (const [svc, ids] of owners) {
|
|
117
|
+
for (const id of ids) {
|
|
118
|
+
if (id !== self) {
|
|
119
|
+
out.add(svc);
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=contracts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/core/status/contracts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,gBAAgB,EAAkB,MAAM,WAAW,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,UAAU,YAAY,CAC1B,KAA+B,EAC/B,UAAmB,EACnB,QAA6B;IAE7B,sEAAsE;IACtE,yEAAyE;IACzE,4EAA4E;IAC5E,yEAAyE;IACzE,sEAAsE;IACtE,0EAA0E;IAC1E,2EAA2E;IAC3E,yEAAyE;IACzE,yEAAyE;IACzE,IAAI,KAAK,EAAE,GAAG,CAAC,OAAO,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,UAAU;QAAE,OAAO,KAAK,CAAC;IAC7B,OAAO,QAAQ,IAAI,KAAK,KAAK,SAAS,CAAC;AACzC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAgB,EAChB,OAAqB,EACrB,KAA2B,EAC3B,OAAqB;IAErB,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IAC1G,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAChH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAgB,EAAE,OAAqB;IAC1E,MAAM,GAAG,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,MAAM,YAAY,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC;QACzD,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC;gBAAE,SAAS;YAChE,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC5B,IAAI,MAAM,KAAK,SAAS;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;;gBACnD,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAgD,EAAE,IAAY;IACnG,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;QAChC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;gBAChB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACb,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * Who owes a service its `openapi.yaml`, and which features in flight already\n * carry one. Shared between the artifact table and the fleet form, because the\n * two must never disagree about whether a feature owes a contract.\n */\nimport { existsSync } from \"node:fs\";\nimport { calledServices } from \"../coherence/calls/called.js\";\nimport type { FleetContext } from \"../fleet-context.js\";\nimport { featureSpecPaths } from \"../repo/paths.js\";\nimport type { FeatureEntry, ServiceEntry } from \"../repo/entries.js\";\nimport { listFeatures } from \"../repo/repo.js\";\nimport type { DocsDir } from \"../kernel/ids/dirs.js\";\nimport { governedServices, type DeltaScan } from \"./scan.js\";\n\n/**\n * Does this feature owe `svc` an openapi.yaml?\n *\n * Keyed on the living CONTRACT FILE, never on `services/<svc>/` merely existing\n * as a directory. A service adopted without a contract is precisely the case\n * where a feature that governs operations has to write one, and the directory\n * test answered \"none owed\" there — printing `(not written — none owed)` beside\n * the `spec-api.op-undefined` finding, in the same payload, about that very\n * file, while suppressing the only step that names it.\n *\n * Two ways to owe nothing, both about somebody else discharging it: the living\n * docs already carry the contract, or another feature in flight brings it — the\n * same softening coherence applies with its `*-pending` codes, where an\n * operation \"defined by another feature still in flight\" is an ordering fact\n * and not a hole.\n *\n * Otherwise the contract is owed exactly when something this feature wrote\n * already joins into it (`evidence`, see {@link contractEvidence}): a\n * requirement's `Operations:` line, or a tagged delta edge calling an\n * operation on the service. Those are the two links the gates grade against\n * the file — `spec-api.op-undefined` and `c4-api.op-undefined` — and the same\n * two `service.no-openapi` reads once the service is living, where a service\n * nothing joins into is the documented silence. A UI, a worker, a service whose\n * only edges go OUT has no API to write down, and that holds for a service the\n * feature introduces exactly as for an adopted one. Demanding a file from a new\n * one regardless was loam telling an author to invent a contract — and authors\n * did, as `paths: {}` stubs the archive then published as living contracts.\n *\n * The evidence is THIS feature's own, as every gate it mirrors is. Another\n * feature in flight drawing an op-linked edge into a service this one\n * introduces is that feature's `c4-api.op-undefined` (or `-pending`) to raise,\n * on its own status; this one's gate says nothing about it, so neither does\n * this projection.\n *\n * `evidence` undefined means loam could not look — the delta does not parse —\n * and then the old reading stands: owed for a service the living docs have\n * never heard of, not for an adopted one. `delta.invalid` gates either way.\n */\nexport function owesContract(\n entry: ServiceEntry | undefined,\n contracted: boolean,\n evidence: boolean | undefined,\n): boolean {\n // Both living facts come off the ENUMERATION's entry rather than root\n // existsSync probes: a service filed into a subsystem lives wherever the\n // tree walk found it, so the root probe read every filed service as \"living\n // docs have never heard of it\" and demanded a contract from all of them.\n // `undefined` IS that never-heard-of case — nothing enumerated the id\n // anywhere. `contracted` arrives resolved by the caller, and deliberately\n // not through the entry: another feature in flight discharges the debt for\n // a service the living docs have NOT heard of yet — that is the ordinary\n // introduce-then-build ordering, and it must keep answering \"none owed\".\n if (entry?.has.openapi === true) return false;\n if (contracted) return false;\n return evidence ?? entry === undefined;\n}\n\n/**\n * Per service, whether this feature wrote anything that joins into its\n * contract — `true`/`false`, or `undefined` when the delta could not be read.\n * One function for both status forms, so they cannot disagree about whether a\n * feature owes a contract: the `Operations:` lines come off the scan they have\n * already made, and the op-linked edges off the delta parse they have already\n * paid for (the coherence pass in one, the dependency graph in the other).\n */\nexport async function contractEvidence(\n docsDir: DocsDir,\n feature: FeatureEntry,\n scans: readonly DeltaScan[],\n context: FleetContext,\n): Promise<(service: string) => boolean | undefined> {\n const governs = governedServices(scans);\n const called = await calledServices({ docsDir, featureDir: feature.dir, featureId: feature.id }, context);\n return (service) => (governs.has(service) ? true : called === \"unreadable\" ? undefined : called.has(service));\n}\n\n/**\n * Which features in flight carry an `openapi.yaml` for which service — one\n * enumeration of the whole index, service by service.\n *\n * The owners are recorded as feature IDS rather than directories because that\n * is the comparison {@link contractsHeldElsewhere} makes: two directories that\n * spell the same id are one feature as far as this question goes, and an index\n * keyed by directory would let a duplicated id answer \"somebody else has it\"\n * about its own twin.\n *\n * Enumeration only — the feature list and its `specs/` subdirectories are\n * already in the request-scoped index by the time anything asks.\n */\nexport async function contractOwners(docsDir: DocsDir, context: FleetContext): Promise<Map<string, Set<string>>> {\n const out = new Map<string, Set<string>>();\n for (const f of await listFeatures(docsDir, {}, context)) {\n for (const svc of f.services) {\n if (!existsSync(featureSpecPaths(f.dir, svc).openapi)) continue;\n const owners = out.get(svc);\n if (owners === undefined) out.set(svc, new Set([f.id]));\n else owners.add(f.id);\n }\n }\n return out;\n}\n\n/**\n * Services some OTHER active feature already carries an `openapi.yaml` for.\n *\n * Derived from the shared index rather than re-walked, because the answer for\n * feature A and the answer for feature B are two readings of one enumeration:\n * asking it once per feature made the fleet form pay F²·S `existsSync` calls\n * over the two quantities that actually grow.\n */\nexport function contractsHeldElsewhere(owners: ReadonlyMap<string, ReadonlySet<string>>, self: string): Set<string> {\n const out = new Set<string>();\n for (const [svc, ids] of owners) {\n for (const id of ids) {\n if (id !== self) {\n out.add(svc);\n break;\n }\n }\n }\n return out;\n}\n"]}
|