@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,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fleet map merge, the flows drawn over it, and the services this archive
|
|
3
|
+
* brings into existence.
|
|
4
|
+
*
|
|
5
|
+
* The landscape is the one document every feature writes into, so it is spliced
|
|
6
|
+
* rather than rewritten: the authored file keeps its shape and the delta's
|
|
7
|
+
* elements are placed into it. A service arriving on the architecture axis alone
|
|
8
|
+
* has no `model.likec4` yet, and the finding for that is carried out of the plan
|
|
9
|
+
* — `validate` would report it next, at the same severity, and reporting it here
|
|
10
|
+
* is what stops that being a surprise.
|
|
11
|
+
*
|
|
12
|
+
* The map is not the only document the C4 axis writes. What a delta nests
|
|
13
|
+
* INSIDE a service belongs to that service's `model.likec4` when the model
|
|
14
|
+
* extends the map — the splicer routes it there, this stages the write, and
|
|
15
|
+
* `./model/extending.ts` proves the result parses beside the merged map before
|
|
16
|
+
* anything lands.
|
|
17
|
+
*
|
|
18
|
+
* `planFlows` at the bottom is the other half of the same axis and shares this
|
|
19
|
+
* module for that reason rather than for the file cap: both write into
|
|
20
|
+
* `architecture/`, and the two merges are read together — the map gains the
|
|
21
|
+
* elements, the flow gains the ordered hops over them. It is a whole-file copy
|
|
22
|
+
* where the landscape is a splice, because a flow is a document of its own and
|
|
23
|
+
* there is nothing to merge partially.
|
|
24
|
+
*/
|
|
25
|
+
import { existsSync } from "node:fs";
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
import { planWrite, readUtf8 } from "../../../core/staging/writes.js";
|
|
28
|
+
import { planLandscapeMerge } from "../../../core/c4/splice/landscape-merge.js";
|
|
29
|
+
import { spliceModel } from "../../../core/c4/splice/model/merge.js";
|
|
30
|
+
import { titleOf } from "../../../core/c4/splice/identity/edges.js";
|
|
31
|
+
import { parseServiceId } from "../../../core/kernel/ids/service.js";
|
|
32
|
+
import { isPathInside } from "../../../core/kernel/path-safety.js";
|
|
33
|
+
import { landscapePath as landscapeFile, unfiledServicePaths } from "../../../core/repo/paths.js";
|
|
34
|
+
import { enumeratedServiceIds } from "../../../core/repo/service-target.js";
|
|
35
|
+
import { createdServiceModels } from "../../../core/c4/service-model/created/models.js";
|
|
36
|
+
import { extendingModels } from "../../../core/c4/service-model/fleet/extending.js";
|
|
37
|
+
import { modelMergeErrors } from "./model/extending.js";
|
|
38
|
+
import {} from "./state.js";
|
|
39
|
+
import { CodedFailure } from "../../../core/envelope/json.js";
|
|
40
|
+
import { featurePaths } from "../../../core/repo/paths.js";
|
|
41
|
+
import { featureFlows, livingFlowPath, USECASE_SUBDIR } from "../../../core/usecases/delta/flows.js";
|
|
42
|
+
import { featureDeployments, livingDeploymentPath } from "../../../core/deployment/delta.js";
|
|
43
|
+
export async function planLandscape(config, gated, plan, say) {
|
|
44
|
+
const { id, featureDir, deltaDoc, deltaServices } = gated;
|
|
45
|
+
const deltaLikec4 = featurePaths(featureDir).delta;
|
|
46
|
+
const { writes, planWarns, architectureServices } = plan;
|
|
47
|
+
const landscapePath = landscapeFile(config.docsDir);
|
|
48
|
+
// "New" is enumeration membership, not an existsSync of services/<svc>/ at
|
|
49
|
+
// the root: a FILED service exists wherever the tree walk found it, and the
|
|
50
|
+
// root probe would grade every filed service as newly created here.
|
|
51
|
+
const enumerated = new Set(await enumeratedServiceIds(config.docsDir));
|
|
52
|
+
// The empty extending model of every service this archive creates and the
|
|
53
|
+
// merged map draws — the rule, and the case for writing it, are
|
|
54
|
+
// `createdServiceModels`'s. With no delta or no map there is no merge, and
|
|
55
|
+
// no model.
|
|
56
|
+
const fresh = deltaDoc === undefined || !existsSync(landscapePath)
|
|
57
|
+
? []
|
|
58
|
+
: await createdServiceModels({
|
|
59
|
+
docsDir: config.docsDir,
|
|
60
|
+
featureDir,
|
|
61
|
+
featureId: id,
|
|
62
|
+
drawn: [...(await config.fleet.loadLikeC4(landscapePath)).elements, ...deltaDoc.elements.filter((e) => e.tags.includes(id))],
|
|
63
|
+
fleet: config.fleet,
|
|
64
|
+
});
|
|
65
|
+
// The services that leave this archive with a model.likec4 it wrote.
|
|
66
|
+
const modelled = new Set();
|
|
67
|
+
if (deltaDoc !== undefined) {
|
|
68
|
+
const delta = deltaDoc;
|
|
69
|
+
if (delta.errors.length > 0) {
|
|
70
|
+
// --approve overrides loam's JUDGMENT about coherence, never its ability to
|
|
71
|
+
// read an axis. Skipping here would silently drop one merge axis in the one
|
|
72
|
+
// command engineered against quiet partial merges — same rule as an
|
|
73
|
+
// unparseable landscape or openapi: the plan stops before anything is written.
|
|
74
|
+
throw new CodedFailure("merge-failed", `delta.likec4 has ${delta.errors.length} parse error(s) — the architecture axis cannot be merged; fix it (\`loam validate --feature ${id}\`) or delete the file`);
|
|
75
|
+
}
|
|
76
|
+
// The feature tag is the whole selection mechanism of this merge, and since
|
|
77
|
+
// LikeC4 1.59.0 a specification KIND can carry a tag that every element or
|
|
78
|
+
// edge of that kind then inherits. A delta declaring its own feature tag on
|
|
79
|
+
// a kind makes `newEls`/`newRels` below select the entire document —
|
|
80
|
+
// including the context declarations the scaffold ships commented out
|
|
81
|
+
// precisely so they are NOT merged — and archive would splice somebody
|
|
82
|
+
// else's services into the fleet map at exit 0. Mechanical, so `--approve`
|
|
83
|
+
// does not reach it, and refused before the merge is even planned.
|
|
84
|
+
const kindTagged = [
|
|
85
|
+
...Object.entries(delta.specification?.elementKindTags ?? {}),
|
|
86
|
+
...Object.entries(delta.specification?.relationshipKindTags ?? {}),
|
|
87
|
+
].find(([, tags]) => tags.includes(id));
|
|
88
|
+
if (kindTagged !== undefined) {
|
|
89
|
+
throw new CodedFailure("merge-failed", `delta.likec4 declares the feature tag '#${id}' on kind '${kindTagged[0]}' in its specification block, so every ` +
|
|
90
|
+
`'${kindTagged[0]}' in the file inherits it — the merge would treat the whole document as this feature's ` +
|
|
91
|
+
`additions, context elements included, and splice them into architecture/landscape.likec4. Nothing was ` +
|
|
92
|
+
`written. Remove '#${id}' from the kind and tag only the declarations ${id} actually adds.`);
|
|
93
|
+
}
|
|
94
|
+
const newEls = delta.elements.filter((e) => e.tags.includes(id));
|
|
95
|
+
const newRels = delta.relationships.filter((r) => r.tags.includes(id));
|
|
96
|
+
if (existsSync(landscapePath)) {
|
|
97
|
+
const deltaText = await readUtf8(deltaLikec4);
|
|
98
|
+
const plan = await planLandscapeMerge({
|
|
99
|
+
landscapeText: await readUtf8(landscapePath),
|
|
100
|
+
deltaText,
|
|
101
|
+
deltaElements: delta.elements,
|
|
102
|
+
newEls,
|
|
103
|
+
newRels,
|
|
104
|
+
featureId: id,
|
|
105
|
+
// The tags a relationship kind gives every edge of it: the parsed
|
|
106
|
+
// additions carry them, the delta's statements do not.
|
|
107
|
+
deltaKindTags: delta.specification?.relationshipKindTags ?? {},
|
|
108
|
+
// A service whose model EXTENDS the map owns its own interior, so the
|
|
109
|
+
// merge routes what is nested under it into that model instead of the
|
|
110
|
+
// map (verification 2026-09-04, E1) — and so does a service this
|
|
111
|
+
// archive creates, whose model is written below.
|
|
112
|
+
models: [...(await extendingModels(config.docsDir, config.fleet)), ...fresh],
|
|
113
|
+
});
|
|
114
|
+
// A service can arrive on the ARCHITECTURE axis alone: an element this
|
|
115
|
+
// merge ADDS, carrying a `metadata { service }` binding, with no
|
|
116
|
+
// `specs/<svc>/` anywhere in the feature. It is a service the fleet gate
|
|
117
|
+
// will demand a directory for the moment this merge lands, so it owes the
|
|
118
|
+
// same warning as one arriving with a requirement delta — and until it
|
|
119
|
+
// did, the closing "complete + current" line printed over a landscape
|
|
120
|
+
// this very archive had just made red. Read off the ADDED elements, not
|
|
121
|
+
// the tagged ones: an element the living landscape already had is not
|
|
122
|
+
// arriving, and one that is never merged is not there to demand anything.
|
|
123
|
+
// A binding is document text, which the service path builders no longer accept.
|
|
124
|
+
// The parse cannot actually filter anything here: an illegal binding is
|
|
125
|
+
// `c4.service-binding-invalid`, a coherence ERROR `--approve` does not
|
|
126
|
+
// override, refused before any merge is planned — so the `ok` test only
|
|
127
|
+
// carries the compiler's proof that document text never reaches a path.
|
|
128
|
+
for (const e of plan.addedEls) {
|
|
129
|
+
const parsed = e.service === undefined ? undefined : parseServiceId(e.service);
|
|
130
|
+
if (parsed?.ok === true)
|
|
131
|
+
architectureServices.add(parsed.id);
|
|
132
|
+
}
|
|
133
|
+
if (plan.content !== null)
|
|
134
|
+
writes.push(planWrite(landscapePath, plan.content));
|
|
135
|
+
say(`\n architecture: merged into landscape.likec4 — +${plan.addedEls.length} element(s), +${plan.addedRels.length} relationship(s)`);
|
|
136
|
+
for (const e of plan.addedEls)
|
|
137
|
+
say(` + ${e.title} (${e.kind})`);
|
|
138
|
+
for (const r of plan.addedRels) {
|
|
139
|
+
say(` + ${titleOf(delta.elements, r.source)} -> ${titleOf(delta.elements, r.target)} "${r.title ?? ""}"`);
|
|
140
|
+
}
|
|
141
|
+
for (const additions of plan.models) {
|
|
142
|
+
const content = spliceModel({
|
|
143
|
+
additions,
|
|
144
|
+
deltaText,
|
|
145
|
+
featureId: id,
|
|
146
|
+
deltaKindTags: delta.specification?.relationshipKindTags ?? {},
|
|
147
|
+
});
|
|
148
|
+
// The model's own parse net, and it has to be a PROJECT one: an
|
|
149
|
+
// extending model resolves against the map, and against the map this
|
|
150
|
+
// very archive would leave — so the merged landscape goes into the set
|
|
151
|
+
// beside it. Refused here, at plan time, nothing written, exactly as an
|
|
152
|
+
// unparseable merged landscape is.
|
|
153
|
+
const errors = await modelMergeErrors({
|
|
154
|
+
docsDir: config.docsDir,
|
|
155
|
+
landscape: plan.content,
|
|
156
|
+
model: { path: additions.model.path, content },
|
|
157
|
+
});
|
|
158
|
+
if (errors.length > 0) {
|
|
159
|
+
throw new CodedFailure("merge-failed", `the merged ${additions.model.path} would not parse (${errors.length} error(s): ${errors.slice(0, 3).join("; ")}) — ` +
|
|
160
|
+
`nothing was written. This model is read beside architecture/landscape.likec4 and nothing else, so an addition ` +
|
|
161
|
+
`fits only if the map declares its kind and every element it names. Most often it is a kind or tag missing from ` +
|
|
162
|
+
`the map's specification block, or a reference to ANOTHER service's interior, which lives in that service's own ` +
|
|
163
|
+
`model and is not in this project — draw that call service to service on the map instead. Fix the map's ` +
|
|
164
|
+
`specification or the delta, then re-run`);
|
|
165
|
+
}
|
|
166
|
+
writes.push(planWrite(join(config.docsDir, ...additions.model.path.split("/")), content));
|
|
167
|
+
const created = fresh.some((m) => m.path === additions.model.path);
|
|
168
|
+
if (created)
|
|
169
|
+
modelled.add(additions.model.service);
|
|
170
|
+
say(` architecture: ${created ? "created" : "merged into"} ${additions.model.path} — ` +
|
|
171
|
+
`+${additions.els.length} element(s), +${additions.rels.length} relationship(s)`);
|
|
172
|
+
for (const e of additions.els)
|
|
173
|
+
say(` + ${e.title} (${e.kind})`);
|
|
174
|
+
for (const r of additions.rels) {
|
|
175
|
+
say(` + ${titleOf(delta.elements, r.source)} -> ${titleOf(delta.elements, r.target)} "${r.title ?? ""}"`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
say(`\n architecture: no landscape.likec4 — ${newEls.length} element(s) not merged`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// A created service the delta drew no interior for still gets its model:
|
|
184
|
+
// empty, which is the whole of what the archive knows about its inside.
|
|
185
|
+
for (const model of fresh.filter((m) => !modelled.has(m.service))) {
|
|
186
|
+
writes.push(planWrite(join(config.docsDir, ...model.path.split("/")), model.text));
|
|
187
|
+
modelled.add(model.service);
|
|
188
|
+
say(` architecture: created ${model.path} — empty; ${model.service}'s containers go in an \`extend\` block there`);
|
|
189
|
+
}
|
|
190
|
+
// A service this archive BRINGS INTO EXISTENCE without writing its model
|
|
191
|
+
// arrives without the one file `validate` demands of every service. Two
|
|
192
|
+
// shapes: one arriving on the architecture axis alone — a binding the map
|
|
193
|
+
// gains with no `specs/<svc>/` in the feature, so no directory either, and a
|
|
194
|
+
// model would be the one document in a directory the archive invented — and
|
|
195
|
+
// a `specs/<svc>/` the merged map never draws, which the gate calls an unknown
|
|
196
|
+
// service and only `--approve` brings here. The archive says so instead, and
|
|
197
|
+
// stops claiming the docs are complete. Non-gating: the merge is correct;
|
|
198
|
+
// what is missing is the next step, and refusing here would make onboarding
|
|
199
|
+
// a new service impossible in one command.
|
|
200
|
+
const newServices = [...new Set([...deltaServices, ...architectureServices])].filter((svc) => !enumerated.has(svc));
|
|
201
|
+
await sayUnfiled(config, fresh.map((m) => m.service), say);
|
|
202
|
+
// Whether a planned write lands in the service's would-be directory — the
|
|
203
|
+
// spec merge writes nothing for a delta that leaves no requirements, and then
|
|
204
|
+
// there is no directory to speak of.
|
|
205
|
+
const createsDir = (svc) => {
|
|
206
|
+
const dir = unfiledServicePaths(config.docsDir, svc).dir;
|
|
207
|
+
return writes.some((w) => w.content !== null && isPathInside(dir, w.path));
|
|
208
|
+
};
|
|
209
|
+
for (const svc of newServices.filter((s) => !modelled.has(s))) {
|
|
210
|
+
// `validate --all` reports the two under different codes, both errors: the
|
|
211
|
+
// directory a requirement delta creates with no model in it is the service
|
|
212
|
+
// target's `service.no-model`; a binding with no directory behind it, the
|
|
213
|
+
// fleet map's `landscape.binding-unknown`. The message names the one that
|
|
214
|
+
// fires, and a service for which neither lands is owed nothing.
|
|
215
|
+
const createsItsDir = deltaServices.some((d) => d === svc) && createsDir(svc);
|
|
216
|
+
if (!createsItsDir && !architectureServices.has(svc))
|
|
217
|
+
continue;
|
|
218
|
+
const owed = createsItsDir
|
|
219
|
+
? { creates: `this archive creates services/${svc}/, but nothing writes services/${svc}/model.likec4`, reports: "service.no-model" }
|
|
220
|
+
: { creates: `this archive puts '${svc}' in the landscape, but the fleet has no services/${svc}/ at all`, reports: "landscape.binding-unknown" };
|
|
221
|
+
// An ERROR that does not gate — the two questions `Issue` keeps apart
|
|
222
|
+
// (core/vocabulary/issue.ts). Severity says whether the documents are valid,
|
|
223
|
+
// and validate files either shape as an error: the plan used to call it a
|
|
224
|
+
// warning, so the same fact read as advice here and as a failure one
|
|
225
|
+
// command later (the real-fleet review, 2026-10-21). Gating says whether the
|
|
226
|
+
// MERGE is safe, and it is — what is missing is the next step, as above.
|
|
227
|
+
planWarns.push({
|
|
228
|
+
severity: "error",
|
|
229
|
+
gates: false,
|
|
230
|
+
code: "service.no-model",
|
|
231
|
+
subject: svc,
|
|
232
|
+
message: `${svc}: ${owed.creates} — 'loam validate --all' will report ${owed.reports}, an error, until it exists. Run 'loam adopt --service ${svc}' from the service repo, or write the model by hand.`,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The one step left for a service the archive creates in a tree that files its
|
|
238
|
+
* services: moving it there. Printed only when the tree has a subsystem — in a
|
|
239
|
+
* flat tree every service is unfiled and that is normal, never a finding — and
|
|
240
|
+
* never as a guess at WHICH subsystem: the map's nesting is not a placement the
|
|
241
|
+
* tree may read.
|
|
242
|
+
*/
|
|
243
|
+
async function sayUnfiled(config, created, say) {
|
|
244
|
+
// No `services/` yet is a flat tree too — and the walk refuses a docs repo without one.
|
|
245
|
+
if (created.length === 0 || !existsSync(join(config.docsDir, "services")))
|
|
246
|
+
return;
|
|
247
|
+
if ((await config.fleet.fleetTree(config.docsDir)).subsystems.length === 0)
|
|
248
|
+
return;
|
|
249
|
+
for (const svc of created) {
|
|
250
|
+
say(` ${svc}: created unfiled, at services/${svc}/ — 'loam subsystem move ${svc} --into <subsystem>' files it`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* The flows this feature brings, copied into `architecture/usecases/`.
|
|
255
|
+
*
|
|
256
|
+
* A create-only whole-file copy, and the smallest merge in the command: the
|
|
257
|
+
* document is views-only, it names nothing the landscape merge has not already
|
|
258
|
+
* placed (`planFlowOverlay` in the gate is what proves that, before this runs),
|
|
259
|
+
* and a flow the living tree already holds was refused at the gate
|
|
260
|
+
* (`usecase.flow-exists`, `core/usecases/delta/flows.ts` has the reasoning). So
|
|
261
|
+
* by the time this runs every path here is a file that does not exist, and
|
|
262
|
+
* `planWrite` marks it `exclusive` — a race that created it between the gate and
|
|
263
|
+
* the commit fails the write rather than overwriting somebody.
|
|
264
|
+
*
|
|
265
|
+
* It lives beside `planLandscape` rather than beside the requirement merges
|
|
266
|
+
* because it writes into `architecture/`, and the two merges are read together:
|
|
267
|
+
* the landscape gains the elements, the flow gains the hops over them.
|
|
268
|
+
* `unarchive` needs nothing new — a create is undone by deleting, which the
|
|
269
|
+
* snapshot manifest already records for every write in the plan.
|
|
270
|
+
*/
|
|
271
|
+
export async function planFlows(config, gated, plan, say) {
|
|
272
|
+
const flows = await featureFlows(gated.featureDir);
|
|
273
|
+
if (flows.length === 0)
|
|
274
|
+
return;
|
|
275
|
+
for (const flow of flows) {
|
|
276
|
+
plan.writes.push(planWrite(livingFlowPath(config.docsDir, flow.rel), await readUtf8(flow.path)));
|
|
277
|
+
say(` use case: ${flow.rel} — created architecture/${USECASE_SUBDIR}/${flow.rel}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* The same copy for the third whole-file axis: the topology a feature brings.
|
|
282
|
+
*
|
|
283
|
+
* Beside `planFlows` rather than folded into it, because the two write to
|
|
284
|
+
* different places — a flow into `architecture/usecases/`, a topology straight
|
|
285
|
+
* into `architecture/` — and one function taking a subdirectory argument would
|
|
286
|
+
* make that difference a parameter instead of a decision each axis states.
|
|
287
|
+
* `unarchive` needs nothing here either: a create is undone by deleting.
|
|
288
|
+
*/
|
|
289
|
+
export async function planDeployments(config, gated, plan, say) {
|
|
290
|
+
const docs = await featureDeployments(gated.featureDir);
|
|
291
|
+
if (docs.length === 0)
|
|
292
|
+
return;
|
|
293
|
+
for (const doc of docs) {
|
|
294
|
+
plan.writes.push(planWrite(livingDeploymentPath(config.docsDir, doc.rel), await readUtf8(doc.path)));
|
|
295
|
+
say(` deployment: ${doc.rel} — created architecture/${doc.rel}`);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=landscape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"landscape.js","sourceRoot":"","sources":["../../../../src/commands/archive/plan/landscape.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The fleet map merge, the flows drawn over it, and the services this archive\n * brings into existence.\n *\n * The landscape is the one document every feature writes into, so it is spliced\n * rather than rewritten: the authored file keeps its shape and the delta's\n * elements are placed into it. A service arriving on the architecture axis alone\n * has no `model.likec4` yet, and the finding for that is carried out of the plan\n * — `validate` would report it next, at the same severity, and reporting it here\n * is what stops that being a surprise.\n *\n * The map is not the only document the C4 axis writes. What a delta nests\n * INSIDE a service belongs to that service's `model.likec4` when the model\n * extends the map — the splicer routes it there, this stages the write, and\n * `./model/extending.ts` proves the result parses beside the merged map before\n * anything lands.\n *\n * `planFlows` at the bottom is the other half of the same axis and shares this\n * module for that reason rather than for the file cap: both write into\n * `architecture/`, and the two merges are read together — the map gains the\n * elements, the flow gains the ordered hops over them. It is a whole-file copy\n * where the landscape is a splice, because a flow is a document of its own and\n * there is nothing to merge partially.\n */\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { planWrite, readUtf8 } from \"../../../core/staging/writes.js\";\nimport { planLandscapeMerge } from \"../../../core/c4/splice/landscape-merge.js\";\nimport { spliceModel } from \"../../../core/c4/splice/model/merge.js\";\nimport { titleOf } from \"../../../core/c4/splice/identity/edges.js\";\nimport { parseServiceId, type PathableService } from \"../../../core/kernel/ids/service.js\";\nimport { isPathInside } from \"../../../core/kernel/path-safety.js\";\nimport { landscapePath as landscapeFile, unfiledServicePaths } from \"../../../core/repo/paths.js\";\nimport { enumeratedServiceIds } from \"../../../core/repo/service-target.js\";\nimport { createdServiceModels } from \"../../../core/c4/service-model/created/models.js\";\nimport { extendingModels } from \"../../../core/c4/service-model/fleet/extending.js\";\nimport { modelMergeErrors } from \"./model/extending.js\";\nimport { type Gated, type Plan } from \"./state.js\";\nimport { CodedFailure } from \"../../../core/envelope/json.js\";\nimport { featurePaths } from \"../../../core/repo/paths.js\";\nimport { featureFlows, livingFlowPath, USECASE_SUBDIR } from \"../../../core/usecases/delta/flows.js\";\nimport { featureDeployments, livingDeploymentPath } from \"../../../core/deployment/delta.js\";\nimport type { DocsDir } from \"../../../core/kernel/ids/dirs.js\";\nimport type { FleetContext } from \"../../../core/fleet-context.js\";\n\nexport async function planLandscape(\n config: { docsDir: DocsDir; fleet: FleetContext },\n gated: Gated,\n plan: Plan,\n say: (line?: string) => void,\n): Promise<void> {\n const { id, featureDir, deltaDoc, deltaServices } = gated;\n const deltaLikec4 = featurePaths(featureDir).delta;\n const { writes, planWarns, architectureServices } = plan;\n const landscapePath = landscapeFile(config.docsDir);\n // \"New\" is enumeration membership, not an existsSync of services/<svc>/ at\n // the root: a FILED service exists wherever the tree walk found it, and the\n // root probe would grade every filed service as newly created here.\n const enumerated = new Set<string>(await enumeratedServiceIds(config.docsDir));\n // The empty extending model of every service this archive creates and the\n // merged map draws — the rule, and the case for writing it, are\n // `createdServiceModels`'s. With no delta or no map there is no merge, and\n // no model.\n const fresh =\n deltaDoc === undefined || !existsSync(landscapePath)\n ? []\n : await createdServiceModels({\n docsDir: config.docsDir,\n featureDir,\n featureId: id,\n drawn: [...(await config.fleet.loadLikeC4(landscapePath)).elements, ...deltaDoc.elements.filter((e) => e.tags.includes(id))],\n fleet: config.fleet,\n });\n // The services that leave this archive with a model.likec4 it wrote.\n const modelled = new Set<string>();\n if (deltaDoc !== undefined) {\n const delta = deltaDoc;\n if (delta.errors.length > 0) {\n // --approve overrides loam's JUDGMENT about coherence, never its ability to\n // read an axis. Skipping here would silently drop one merge axis in the one\n // command engineered against quiet partial merges — same rule as an\n // unparseable landscape or openapi: the plan stops before anything is written.\n throw new CodedFailure(\n \"merge-failed\",\n `delta.likec4 has ${delta.errors.length} parse error(s) — the architecture axis cannot be merged; fix it (\\`loam validate --feature ${id}\\`) or delete the file`,\n );\n }\n // The feature tag is the whole selection mechanism of this merge, and since\n // LikeC4 1.59.0 a specification KIND can carry a tag that every element or\n // edge of that kind then inherits. A delta declaring its own feature tag on\n // a kind makes `newEls`/`newRels` below select the entire document —\n // including the context declarations the scaffold ships commented out\n // precisely so they are NOT merged — and archive would splice somebody\n // else's services into the fleet map at exit 0. Mechanical, so `--approve`\n // does not reach it, and refused before the merge is even planned.\n const kindTagged = [\n ...Object.entries(delta.specification?.elementKindTags ?? {}),\n ...Object.entries(delta.specification?.relationshipKindTags ?? {}),\n ].find(([, tags]) => tags.includes(id));\n if (kindTagged !== undefined) {\n throw new CodedFailure(\n \"merge-failed\",\n `delta.likec4 declares the feature tag '#${id}' on kind '${kindTagged[0]}' in its specification block, so every ` +\n `'${kindTagged[0]}' in the file inherits it — the merge would treat the whole document as this feature's ` +\n `additions, context elements included, and splice them into architecture/landscape.likec4. Nothing was ` +\n `written. Remove '#${id}' from the kind and tag only the declarations ${id} actually adds.`,\n );\n }\n const newEls = delta.elements.filter((e) => e.tags.includes(id));\n const newRels = delta.relationships.filter((r) => r.tags.includes(id));\n if (existsSync(landscapePath)) {\n const deltaText = await readUtf8(deltaLikec4);\n const plan = await planLandscapeMerge({\n landscapeText: await readUtf8(landscapePath),\n deltaText,\n deltaElements: delta.elements,\n newEls,\n newRels,\n featureId: id,\n // The tags a relationship kind gives every edge of it: the parsed\n // additions carry them, the delta's statements do not.\n deltaKindTags: delta.specification?.relationshipKindTags ?? {},\n // A service whose model EXTENDS the map owns its own interior, so the\n // merge routes what is nested under it into that model instead of the\n // map (verification 2026-09-04, E1) — and so does a service this\n // archive creates, whose model is written below.\n models: [...(await extendingModels(config.docsDir, config.fleet)), ...fresh],\n });\n // A service can arrive on the ARCHITECTURE axis alone: an element this\n // merge ADDS, carrying a `metadata { service }` binding, with no\n // `specs/<svc>/` anywhere in the feature. It is a service the fleet gate\n // will demand a directory for the moment this merge lands, so it owes the\n // same warning as one arriving with a requirement delta — and until it\n // did, the closing \"complete + current\" line printed over a landscape\n // this very archive had just made red. Read off the ADDED elements, not\n // the tagged ones: an element the living landscape already had is not\n // arriving, and one that is never merged is not there to demand anything.\n // A binding is document text, which the service path builders no longer accept.\n // The parse cannot actually filter anything here: an illegal binding is\n // `c4.service-binding-invalid`, a coherence ERROR `--approve` does not\n // override, refused before any merge is planned — so the `ok` test only\n // carries the compiler's proof that document text never reaches a path.\n for (const e of plan.addedEls) {\n const parsed = e.service === undefined ? undefined : parseServiceId(e.service);\n if (parsed?.ok === true) architectureServices.add(parsed.id);\n }\n if (plan.content !== null) writes.push(planWrite(landscapePath, plan.content));\n say(`\\n architecture: merged into landscape.likec4 — +${plan.addedEls.length} element(s), +${plan.addedRels.length} relationship(s)`);\n for (const e of plan.addedEls) say(` + ${e.title} (${e.kind})`);\n for (const r of plan.addedRels) {\n say(` + ${titleOf(delta.elements, r.source)} -> ${titleOf(delta.elements, r.target)} \"${r.title ?? \"\"}\"`);\n }\n for (const additions of plan.models) {\n const content = spliceModel({\n additions,\n deltaText,\n featureId: id,\n deltaKindTags: delta.specification?.relationshipKindTags ?? {},\n });\n // The model's own parse net, and it has to be a PROJECT one: an\n // extending model resolves against the map, and against the map this\n // very archive would leave — so the merged landscape goes into the set\n // beside it. Refused here, at plan time, nothing written, exactly as an\n // unparseable merged landscape is.\n const errors = await modelMergeErrors({\n docsDir: config.docsDir,\n landscape: plan.content,\n model: { path: additions.model.path, content },\n });\n if (errors.length > 0) {\n throw new CodedFailure(\n \"merge-failed\",\n `the merged ${additions.model.path} would not parse (${errors.length} error(s): ${errors.slice(0, 3).join(\"; \")}) — ` +\n `nothing was written. This model is read beside architecture/landscape.likec4 and nothing else, so an addition ` +\n `fits only if the map declares its kind and every element it names. Most often it is a kind or tag missing from ` +\n `the map's specification block, or a reference to ANOTHER service's interior, which lives in that service's own ` +\n `model and is not in this project — draw that call service to service on the map instead. Fix the map's ` +\n `specification or the delta, then re-run`,\n );\n }\n writes.push(planWrite(join(config.docsDir, ...additions.model.path.split(\"/\")), content));\n const created = fresh.some((m) => m.path === additions.model.path);\n if (created) modelled.add(additions.model.service);\n say(\n ` architecture: ${created ? \"created\" : \"merged into\"} ${additions.model.path} — ` +\n `+${additions.els.length} element(s), +${additions.rels.length} relationship(s)`,\n );\n for (const e of additions.els) say(` + ${e.title} (${e.kind})`);\n for (const r of additions.rels) {\n say(` + ${titleOf(delta.elements, r.source)} -> ${titleOf(delta.elements, r.target)} \"${r.title ?? \"\"}\"`);\n }\n }\n } else {\n say(`\\n architecture: no landscape.likec4 — ${newEls.length} element(s) not merged`);\n }\n }\n // A created service the delta drew no interior for still gets its model:\n // empty, which is the whole of what the archive knows about its inside.\n for (const model of fresh.filter((m) => !modelled.has(m.service))) {\n writes.push(planWrite(join(config.docsDir, ...model.path.split(\"/\")), model.text));\n modelled.add(model.service);\n say(` architecture: created ${model.path} — empty; ${model.service}'s containers go in an \\`extend\\` block there`);\n }\n\n // A service this archive BRINGS INTO EXISTENCE without writing its model\n // arrives without the one file `validate` demands of every service. Two\n // shapes: one arriving on the architecture axis alone — a binding the map\n // gains with no `specs/<svc>/` in the feature, so no directory either, and a\n // model would be the one document in a directory the archive invented — and\n // a `specs/<svc>/` the merged map never draws, which the gate calls an unknown\n // service and only `--approve` brings here. The archive says so instead, and\n // stops claiming the docs are complete. Non-gating: the merge is correct;\n // what is missing is the next step, and refusing here would make onboarding\n // a new service impossible in one command.\n const newServices = [...new Set([...deltaServices, ...architectureServices])].filter(\n (svc) => !enumerated.has(svc),\n );\n await sayUnfiled(config, fresh.map((m) => m.service), say);\n // Whether a planned write lands in the service's would-be directory — the\n // spec merge writes nothing for a delta that leaves no requirements, and then\n // there is no directory to speak of.\n const createsDir = (svc: PathableService): boolean => {\n const dir = unfiledServicePaths(config.docsDir, svc).dir;\n return writes.some((w) => w.content !== null && isPathInside(dir, w.path));\n };\n for (const svc of newServices.filter((s) => !modelled.has(s))) {\n // `validate --all` reports the two under different codes, both errors: the\n // directory a requirement delta creates with no model in it is the service\n // target's `service.no-model`; a binding with no directory behind it, the\n // fleet map's `landscape.binding-unknown`. The message names the one that\n // fires, and a service for which neither lands is owed nothing.\n const createsItsDir = deltaServices.some((d) => d === svc) && createsDir(svc);\n if (!createsItsDir && !architectureServices.has(svc)) continue;\n const owed = createsItsDir\n ? { creates: `this archive creates services/${svc}/, but nothing writes services/${svc}/model.likec4`, reports: \"service.no-model\" }\n : { creates: `this archive puts '${svc}' in the landscape, but the fleet has no services/${svc}/ at all`, reports: \"landscape.binding-unknown\" };\n // An ERROR that does not gate — the two questions `Issue` keeps apart\n // (core/vocabulary/issue.ts). Severity says whether the documents are valid,\n // and validate files either shape as an error: the plan used to call it a\n // warning, so the same fact read as advice here and as a failure one\n // command later (the real-fleet review, 2026-10-21). Gating says whether the\n // MERGE is safe, and it is — what is missing is the next step, as above.\n planWarns.push({\n severity: \"error\",\n gates: false,\n code: \"service.no-model\",\n subject: svc,\n message: `${svc}: ${owed.creates} — 'loam validate --all' will report ${owed.reports}, an error, until it exists. Run 'loam adopt --service ${svc}' from the service repo, or write the model by hand.`,\n });\n }\n}\n\n/**\n * The one step left for a service the archive creates in a tree that files its\n * services: moving it there. Printed only when the tree has a subsystem — in a\n * flat tree every service is unfiled and that is normal, never a finding — and\n * never as a guess at WHICH subsystem: the map's nesting is not a placement the\n * tree may read.\n */\nasync function sayUnfiled(config: { docsDir: DocsDir; fleet: FleetContext }, created: string[], say: (line?: string) => void): Promise<void> {\n // No `services/` yet is a flat tree too — and the walk refuses a docs repo without one.\n if (created.length === 0 || !existsSync(join(config.docsDir, \"services\"))) return;\n if ((await config.fleet.fleetTree(config.docsDir)).subsystems.length === 0) return;\n for (const svc of created) {\n say(` ${svc}: created unfiled, at services/${svc}/ — 'loam subsystem move ${svc} --into <subsystem>' files it`);\n }\n}\n\n/**\n * The flows this feature brings, copied into `architecture/usecases/`.\n *\n * A create-only whole-file copy, and the smallest merge in the command: the\n * document is views-only, it names nothing the landscape merge has not already\n * placed (`planFlowOverlay` in the gate is what proves that, before this runs),\n * and a flow the living tree already holds was refused at the gate\n * (`usecase.flow-exists`, `core/usecases/delta/flows.ts` has the reasoning). So\n * by the time this runs every path here is a file that does not exist, and\n * `planWrite` marks it `exclusive` — a race that created it between the gate and\n * the commit fails the write rather than overwriting somebody.\n *\n * It lives beside `planLandscape` rather than beside the requirement merges\n * because it writes into `architecture/`, and the two merges are read together:\n * the landscape gains the elements, the flow gains the hops over them.\n * `unarchive` needs nothing new — a create is undone by deleting, which the\n * snapshot manifest already records for every write in the plan.\n */\nexport async function planFlows(\n config: { docsDir: DocsDir },\n gated: Gated,\n plan: Plan,\n say: (line?: string) => void,\n): Promise<void> {\n const flows = await featureFlows(gated.featureDir);\n if (flows.length === 0) return;\n for (const flow of flows) {\n plan.writes.push(planWrite(livingFlowPath(config.docsDir, flow.rel), await readUtf8(flow.path)));\n say(` use case: ${flow.rel} — created architecture/${USECASE_SUBDIR}/${flow.rel}`);\n }\n}\n\n/**\n * The same copy for the third whole-file axis: the topology a feature brings.\n *\n * Beside `planFlows` rather than folded into it, because the two write to\n * different places — a flow into `architecture/usecases/`, a topology straight\n * into `architecture/` — and one function taking a subdirectory argument would\n * make that difference a parameter instead of a decision each axis states.\n * `unarchive` needs nothing here either: a create is undone by deleting.\n */\nexport async function planDeployments(\n config: { docsDir: DocsDir },\n gated: Gated,\n plan: Plan,\n say: (line?: string) => void,\n): Promise<void> {\n const docs = await featureDeployments(gated.featureDir);\n if (docs.length === 0) return;\n for (const doc of docs) {\n plan.writes.push(planWrite(livingDeploymentPath(config.docsDir, doc.rel), await readUtf8(doc.path)));\n say(` deployment: ${doc.rel} — created architecture/${doc.rel}`);\n }\n}\n"]}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the model this merge would leave behind is one LikeC4 can read.
|
|
3
|
+
*
|
|
4
|
+
* It is here because this is the seam that HAS the other document: an extending
|
|
5
|
+
* model is never parsed alone, it is parsed beside the `architecture/` project,
|
|
6
|
+
* and the project the merge must be proven against is the one this very archive
|
|
7
|
+
* would leave behind — the merged map, not the living one. `core/c4/splice` is
|
|
8
|
+
* a pure text-to-text computation — texts in, texts out — so proving the result
|
|
9
|
+
* stays with the command that decides to write.
|
|
10
|
+
*
|
|
11
|
+
* READING the fleet's extending models used to be here too, as the other half
|
|
12
|
+
* of one seam. It moved to `core/c4/service-model/fleet/extending.ts` when the
|
|
13
|
+
* archive stopped being the only reader: `core/c4/project/staged.ts` previews
|
|
14
|
+
* the same merge for every feature-side gate, and `core/` may not import
|
|
15
|
+
* `commands/`. That module's header carries the fail-open the move closes.
|
|
16
|
+
*/
|
|
17
|
+
import { copyFile, mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
18
|
+
import { tmpdir } from "node:os";
|
|
19
|
+
import { dirname, join, resolve } from "node:path";
|
|
20
|
+
import { errorText } from "../../../../core/c4/likec4.js";
|
|
21
|
+
import { architectureProjectDocuments } from "../../../../core/c4/project/architecture.js";
|
|
22
|
+
import { asLoadedDoc, loadProject } from "../../../../core/c4/project/load.js";
|
|
23
|
+
import { repoPath } from "../../../../core/envelope/json.js";
|
|
24
|
+
import { landscapePath } from "../../../../core/repo/paths.js";
|
|
25
|
+
/**
|
|
26
|
+
* What LikeC4 says about the model this merge would leave, read the way the
|
|
27
|
+
* per-service grade reads it — the `architecture/` project plus this one file.
|
|
28
|
+
*
|
|
29
|
+
* Empty means clean. Anything else refuses the archive at plan time, with
|
|
30
|
+
* nothing written, for the reason the landscape's own parse net exists:
|
|
31
|
+
* splicing is text surgery, and a document that does not parse takes a whole
|
|
32
|
+
* service's grade down (`c4.invalid`) the moment it lands.
|
|
33
|
+
*
|
|
34
|
+
* Errors carry the path the author wrote rather than the staged copy's, and a
|
|
35
|
+
* staging failure is reported as an error rather than swallowed: a merge that
|
|
36
|
+
* could not be proven is not one that passed.
|
|
37
|
+
*/
|
|
38
|
+
export async function modelMergeErrors(proof) {
|
|
39
|
+
const { docsDir, landscape, model } = proof;
|
|
40
|
+
let root;
|
|
41
|
+
try {
|
|
42
|
+
root = await mkdtemp(join(tmpdir(), "loam-model-merge-"));
|
|
43
|
+
const map = resolve(landscapePath(docsDir));
|
|
44
|
+
const authored = new Map();
|
|
45
|
+
const staged = [];
|
|
46
|
+
for (const path of await architectureProjectDocuments(docsDir)) {
|
|
47
|
+
const rel = repoPath(docsDir, path);
|
|
48
|
+
const at = landscape !== null && resolve(path) === map
|
|
49
|
+
? await write(root, rel, landscape)
|
|
50
|
+
: await copy(root, rel, path);
|
|
51
|
+
authored.set(at, rel);
|
|
52
|
+
staged.push(at);
|
|
53
|
+
}
|
|
54
|
+
const at = await write(root, model.path, model.content);
|
|
55
|
+
authored.set(at, model.path);
|
|
56
|
+
staged.push(at);
|
|
57
|
+
const doc = asLoadedDoc(await loadProject(root, staged));
|
|
58
|
+
return doc.errors.map((e) => {
|
|
59
|
+
const where = e.sourceFsPath === undefined ? undefined : authored.get(resolve(e.sourceFsPath));
|
|
60
|
+
return where === undefined ? errorText(e) : `${where} ${errorText(e)}`;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
return [err instanceof Error ? err.message : String(err)];
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
if (root !== undefined)
|
|
68
|
+
await rm(root, { recursive: true, force: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Mirror one authored document into the staged tree at its docs-relative path. */
|
|
72
|
+
async function copy(root, rel, path) {
|
|
73
|
+
const dest = join(root, ...rel.split("/"));
|
|
74
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
75
|
+
await copyFile(path, dest);
|
|
76
|
+
return resolve(dest);
|
|
77
|
+
}
|
|
78
|
+
/** The same for bytes loam holds rather than a file — the merge previews. */
|
|
79
|
+
async function write(root, rel, content) {
|
|
80
|
+
const dest = join(root, ...rel.split("/"));
|
|
81
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
82
|
+
await writeFile(dest, content, "utf8");
|
|
83
|
+
return resolve(dest);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=extending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extending.js","sourceRoot":"","sources":["../../../../../src/commands/archive/plan/model/extending.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Whether the model this merge would leave behind is one LikeC4 can read.\n *\n * It is here because this is the seam that HAS the other document: an extending\n * model is never parsed alone, it is parsed beside the `architecture/` project,\n * and the project the merge must be proven against is the one this very archive\n * would leave behind — the merged map, not the living one. `core/c4/splice` is\n * a pure text-to-text computation — texts in, texts out — so proving the result\n * stays with the command that decides to write.\n *\n * READING the fleet's extending models used to be here too, as the other half\n * of one seam. It moved to `core/c4/service-model/fleet/extending.ts` when the\n * archive stopped being the only reader: `core/c4/project/staged.ts` previews\n * the same merge for every feature-side gate, and `core/` may not import\n * `commands/`. That module's header carries the fail-open the move closes.\n */\nimport { copyFile, mkdir, mkdtemp, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { errorText } from \"../../../../core/c4/likec4.js\";\nimport { architectureProjectDocuments } from \"../../../../core/c4/project/architecture.js\";\nimport { asLoadedDoc, loadProject } from \"../../../../core/c4/project/load.js\";\nimport type { DocsDir } from \"../../../../core/kernel/ids/dirs.js\";\nimport { repoPath } from \"../../../../core/envelope/json.js\";\nimport { landscapePath } from \"../../../../core/repo/paths.js\";\n\nexport interface ModelProof {\n docsDir: DocsDir;\n /** The merged landscape, or null when this archive leaves the map as it is. */\n landscape: string | null;\n /** The merged model: repo-relative path, and the text the archive would write. */\n model: { path: string; content: string };\n}\n\n/**\n * What LikeC4 says about the model this merge would leave, read the way the\n * per-service grade reads it — the `architecture/` project plus this one file.\n *\n * Empty means clean. Anything else refuses the archive at plan time, with\n * nothing written, for the reason the landscape's own parse net exists:\n * splicing is text surgery, and a document that does not parse takes a whole\n * service's grade down (`c4.invalid`) the moment it lands.\n *\n * Errors carry the path the author wrote rather than the staged copy's, and a\n * staging failure is reported as an error rather than swallowed: a merge that\n * could not be proven is not one that passed.\n */\nexport async function modelMergeErrors(proof: ModelProof): Promise<string[]> {\n const { docsDir, landscape, model } = proof;\n let root: string | undefined;\n try {\n root = await mkdtemp(join(tmpdir(), \"loam-model-merge-\"));\n const map = resolve(landscapePath(docsDir));\n const authored = new Map<string, string>();\n const staged: string[] = [];\n for (const path of await architectureProjectDocuments(docsDir)) {\n const rel = repoPath(docsDir, path);\n const at =\n landscape !== null && resolve(path) === map\n ? await write(root, rel, landscape)\n : await copy(root, rel, path);\n authored.set(at, rel);\n staged.push(at);\n }\n const at = await write(root, model.path, model.content);\n authored.set(at, model.path);\n staged.push(at);\n const doc = asLoadedDoc(await loadProject(root, staged));\n return doc.errors.map((e) => {\n const where = e.sourceFsPath === undefined ? undefined : authored.get(resolve(e.sourceFsPath));\n return where === undefined ? errorText(e) : `${where} ${errorText(e)}`;\n });\n } catch (err) {\n return [err instanceof Error ? err.message : String(err)];\n } finally {\n if (root !== undefined) await rm(root, { recursive: true, force: true });\n }\n}\n\n/** Mirror one authored document into the staged tree at its docs-relative path. */\nasync function copy(root: string, rel: string, path: string): Promise<string> {\n const dest = join(root, ...rel.split(\"/\"));\n await mkdir(dirname(dest), { recursive: true });\n await copyFile(path, dest);\n return resolve(dest);\n}\n\n/** The same for bytes loam holds rather than a file — the merge previews. */\nasync function write(root: string, rel: string, content: string): Promise<string> {\n const dest = join(root, ...rel.split(\"/\"));\n await mkdir(dirname(dest), { recursive: true });\n await writeFile(dest, content, \"utf8\");\n return resolve(dest);\n}\n"]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How `loam archive` refuses, and what a refusal prints.
|
|
3
|
+
*
|
|
4
|
+
* Every arm here keeps one property: a refusal means nothing was written. The
|
|
5
|
+
* `--json` shapes carry the issues that caused it so an agent can act on the
|
|
6
|
+
* list rather than on the sentence, and a refusal thrown from below is a
|
|
7
|
+
* `CodedFailure` (core/envelope/json.ts) so a merge that could not be computed
|
|
8
|
+
* reports as a merge failure rather than as `internal` — a read-only directory
|
|
9
|
+
* or an unreadable pre-image is not a bug in loam, and saying so sends the
|
|
10
|
+
* reader looking for one.
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { emitJsonError, repoPath } from "../../../core/envelope/json.js";
|
|
14
|
+
import { approveOverrides, issueFinding, } from "../../../core/vocabulary/issue.js";
|
|
15
|
+
import {} from "../../../core/staging/interrupted.js";
|
|
16
|
+
import {} from "../../../core/staging/writes.js";
|
|
17
|
+
import { findingJson } from "../../../core/vocabulary/report.js";
|
|
18
|
+
/**
|
|
19
|
+
* An Issue as the `--json` envelope spells it — the whole Finding shape, `details`
|
|
20
|
+
* included (`[]` when the issue carries none; the overwrite warnings list their
|
|
21
|
+
* current consumers there), plus `overridable`.
|
|
22
|
+
* `gates` and `overridable` are always present and already resolved: a consumer
|
|
23
|
+
* must not have to re-implement the severity default to know what blocks
|
|
24
|
+
* archive, nor keep a code list to know what `--approve` can move.
|
|
25
|
+
*/
|
|
26
|
+
export function issueJson(i, scope) {
|
|
27
|
+
return {
|
|
28
|
+
...findingJson(issueFinding(i), scope === undefined ? undefined : { path: scope, role: "scope" }),
|
|
29
|
+
overridable: approveOverrides(i),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** The failure envelope plus the issues that caused it, so a caller need not re-run validate. */
|
|
33
|
+
export function refuseJson(code, msg, issues, scope) {
|
|
34
|
+
emitJsonError(code, msg, { issues: issues.map((issue) => issueJson(issue, scope)) });
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The same envelope for a refusal computed from `Finding`s rather than
|
|
38
|
+
* `Issue`s — the plan-time checks whose codes are not coherence's (they belong
|
|
39
|
+
* to the LIVING documents, not to the feature) and so are not `IssueCode`s.
|
|
40
|
+
*
|
|
41
|
+
* `gates: true` is asserted rather than derived: every finding listed in a
|
|
42
|
+
* refusal is a reason archive stopped, which is what the field means. Nothing
|
|
43
|
+
* advisory reaches here.
|
|
44
|
+
*/
|
|
45
|
+
export function refuseFindings(code, msg, findings, scope) {
|
|
46
|
+
emitJsonError(code, msg, {
|
|
47
|
+
issues: findings.map((finding) => ({
|
|
48
|
+
...findingJson(finding, scope === undefined ? undefined : { path: scope, role: "scope" }),
|
|
49
|
+
gates: true,
|
|
50
|
+
})),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Take the docs repo's advisory lock for the WHOLE plan+commit window, then
|
|
55
|
+
* archive.
|
|
56
|
+
*
|
|
57
|
+
* The window is the point. Two archives that overlap do not fight over a
|
|
58
|
+
* rename: they each read the living landscape, each splice their additions into
|
|
59
|
+
* the bytes they read, and the second write replaces the first — both exit 0,
|
|
60
|
+
* and `validate` stays green over a landscape that is missing one feature's
|
|
61
|
+
* architecture, because a document with fewer elements is not an invalid one.
|
|
62
|
+
* That is the only silent-loss path in loam that a later command cannot even
|
|
63
|
+
* detect, so it is closed at the coarsest possible granularity: one writer per
|
|
64
|
+
* docs repo, refusing rather than queueing, because a CLI that blocks for an
|
|
65
|
+
* unknown time is worse for an agent than one that says `docs-busy`.
|
|
66
|
+
*/
|
|
67
|
+
/**
|
|
68
|
+
* What the recovery did, before this command's own output — a docs repo that
|
|
69
|
+
* changed under the caller is the first thing they have to be told, not a
|
|
70
|
+
* footnote. Shared by archive and unarchive through the same CommitRecovery.
|
|
71
|
+
*/
|
|
72
|
+
export function sayRecovery(r) {
|
|
73
|
+
const what = `an interrupted \`loam ${r.command} ${r.feature}\``;
|
|
74
|
+
if (r.outcome === "completed") {
|
|
75
|
+
console.log(`⚠ ${what} had in fact finished — cleared its commit record.\n`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (r.outcome === "consistent") {
|
|
79
|
+
console.log(`⚠ ${what} was rolled back before it wrote anything — cleared its commit record.\n`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// An interrupted archive is UNDONE and an interrupted unarchive is FINISHED —
|
|
83
|
+
// the merged text a restore was replacing is written down nowhere, so there is
|
|
84
|
+
// nothing to go back to. Say which happened; the paths are the same either way.
|
|
85
|
+
const what_ = r.command === "archive" ? "put them back from" : "finished them from";
|
|
86
|
+
console.log(`⚠ ${what} left ${r.repaired.length} file(s) half-written; ${what_} its snapshot:`);
|
|
87
|
+
for (const p of r.repaired)
|
|
88
|
+
console.log(` ↩ ${p}`);
|
|
89
|
+
console.log("");
|
|
90
|
+
}
|
|
91
|
+
/** The full plan, as files: what a dry run shows instead of doing. */
|
|
92
|
+
export function printPlan(docsDir, writes, dirName, owed) {
|
|
93
|
+
console.log(`\n plan — ${writes.length} file(s):`);
|
|
94
|
+
for (const w of writes) {
|
|
95
|
+
const verb = existsSync(w.path) ? "update" : "create";
|
|
96
|
+
console.log(` ${verb} ${repoPath(docsDir, w.path)}`);
|
|
97
|
+
}
|
|
98
|
+
console.log(` move features/${dirName} → features/archive/${dirName}`);
|
|
99
|
+
// What the real run would print in place of "complete + current" (../closing.ts).
|
|
100
|
+
if (owed.length > 0)
|
|
101
|
+
console.log("");
|
|
102
|
+
for (const line of owed)
|
|
103
|
+
console.log(line);
|
|
104
|
+
console.log("\n dry run — nothing was written.");
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=refusal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refusal.js","sourceRoot":"","sources":["../../../../src/commands/archive/plan/refusal.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * How `loam archive` refuses, and what a refusal prints.\n *\n * Every arm here keeps one property: a refusal means nothing was written. The\n * `--json` shapes carry the issues that caused it so an agent can act on the\n * list rather than on the sentence, and a refusal thrown from below is a\n * `CodedFailure` (core/envelope/json.ts) so a merge that could not be computed\n * reports as a merge failure rather than as `internal` — a read-only directory\n * or an unreadable pre-image is not a bug in loam, and saying so sends the\n * reader looking for one.\n */\nimport { existsSync } from \"node:fs\";\nimport { emitJsonError, repoPath, type ErrorCode } from \"../../../core/envelope/json.js\";\nimport {\n approveOverrides,\n issueFinding,\n type Issue,\n} from \"../../../core/vocabulary/issue.js\";\nimport { type CommitRecovery } from \"../../../core/staging/interrupted.js\";\nimport { type PlannedWrite } from \"../../../core/staging/writes.js\";\nimport { findingJson, type Finding } from \"../../../core/vocabulary/report.js\";\n\nexport interface ArchiveOptions {\n approve?: boolean;\n dryRun?: boolean;\n json?: boolean;\n}\n\n/**\n * An Issue as the `--json` envelope spells it — the whole Finding shape, `details`\n * included (`[]` when the issue carries none; the overwrite warnings list their\n * current consumers there), plus `overridable`.\n * `gates` and `overridable` are always present and already resolved: a consumer\n * must not have to re-implement the severity default to know what blocks\n * archive, nor keep a code list to know what `--approve` can move.\n */\nexport function issueJson(i: Issue, scope?: string): Record<string, unknown> {\n return {\n ...findingJson(\n issueFinding(i),\n scope === undefined ? undefined : { path: scope, role: \"scope\" },\n ),\n overridable: approveOverrides(i),\n };\n}\n\n/** The failure envelope plus the issues that caused it, so a caller need not re-run validate. */\nexport function refuseJson(code: ErrorCode, msg: string, issues: Issue[], scope?: string): void {\n emitJsonError(code, msg, { issues: issues.map((issue) => issueJson(issue, scope)) });\n}\n\n/**\n * The same envelope for a refusal computed from `Finding`s rather than\n * `Issue`s — the plan-time checks whose codes are not coherence's (they belong\n * to the LIVING documents, not to the feature) and so are not `IssueCode`s.\n *\n * `gates: true` is asserted rather than derived: every finding listed in a\n * refusal is a reason archive stopped, which is what the field means. Nothing\n * advisory reaches here.\n */\nexport function refuseFindings(\n code: ErrorCode,\n msg: string,\n findings: Finding[],\n scope?: string,\n): void {\n emitJsonError(code, msg, {\n issues: findings.map((finding) => ({\n ...findingJson(\n finding,\n scope === undefined ? undefined : { path: scope, role: \"scope\" },\n ),\n gates: true,\n })),\n });\n}\n\n/**\n * Take the docs repo's advisory lock for the WHOLE plan+commit window, then\n * archive.\n *\n * The window is the point. Two archives that overlap do not fight over a\n * rename: they each read the living landscape, each splice their additions into\n * the bytes they read, and the second write replaces the first — both exit 0,\n * and `validate` stays green over a landscape that is missing one feature's\n * architecture, because a document with fewer elements is not an invalid one.\n * That is the only silent-loss path in loam that a later command cannot even\n * detect, so it is closed at the coarsest possible granularity: one writer per\n * docs repo, refusing rather than queueing, because a CLI that blocks for an\n * unknown time is worse for an agent than one that says `docs-busy`.\n */\n\n/**\n * What the recovery did, before this command's own output — a docs repo that\n * changed under the caller is the first thing they have to be told, not a\n * footnote. Shared by archive and unarchive through the same CommitRecovery.\n */\nexport function sayRecovery(r: CommitRecovery): void {\n const what = `an interrupted \\`loam ${r.command} ${r.feature}\\``;\n if (r.outcome === \"completed\") {\n console.log(`⚠ ${what} had in fact finished — cleared its commit record.\\n`);\n return;\n }\n if (r.outcome === \"consistent\") {\n console.log(`⚠ ${what} was rolled back before it wrote anything — cleared its commit record.\\n`);\n return;\n }\n // An interrupted archive is UNDONE and an interrupted unarchive is FINISHED —\n // the merged text a restore was replacing is written down nowhere, so there is\n // nothing to go back to. Say which happened; the paths are the same either way.\n const what_ = r.command === \"archive\" ? \"put them back from\" : \"finished them from\";\n console.log(`⚠ ${what} left ${r.repaired.length} file(s) half-written; ${what_} its snapshot:`);\n for (const p of r.repaired) console.log(` ↩ ${p}`);\n console.log(\"\");\n}\n\n/** The full plan, as files: what a dry run shows instead of doing. */\nexport function printPlan(docsDir: string, writes: PlannedWrite[], dirName: string, owed: readonly string[]): void {\n console.log(`\\n plan — ${writes.length} file(s):`);\n for (const w of writes) {\n const verb = existsSync(w.path) ? \"update\" : \"create\";\n console.log(` ${verb} ${repoPath(docsDir, w.path)}`);\n }\n console.log(` move features/${dirName} → features/archive/${dirName}`);\n // What the real run would print in place of \"complete + current\" (../closing.ts).\n if (owed.length > 0) console.log(\"\");\n for (const line of owed) console.log(line);\n console.log(\"\\n dry run — nothing was written.\");\n}\n"]}
|