@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,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fleet target: `services/` and architecture/landscape.likec4 graded
|
|
3
|
+
* against each other, plus the two exemptions that decide which drawn element
|
|
4
|
+
* answers for a service directory at all.
|
|
5
|
+
*
|
|
6
|
+
* The landscape is the one artifact no service owns — parsed once for the whole
|
|
7
|
+
* run and graded on a target of its own, outside the dispatcher's `guarded`.
|
|
8
|
+
* That is why its IO containment lives in this package instead: see
|
|
9
|
+
* `unreadableLandscape` in `./load.ts`.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
12
|
+
import { readFile } from "node:fs/promises";
|
|
13
|
+
import {} from "../../../core/c4/likec4.js";
|
|
14
|
+
import { serviceResolver } from "../../../core/c4/resolve/service.js";
|
|
15
|
+
import { landscapePath as landscapeFile, servicePathsAt } from "../../../core/repo/paths.js";
|
|
16
|
+
import { serviceIdFindings } from "../../../core/repo/entries.js";
|
|
17
|
+
import { listFleetTree, listServices } from "../../../core/repo/repo.js";
|
|
18
|
+
import {} from "../../../core/vocabulary/report.js";
|
|
19
|
+
import { landscapeConflictFinding } from "../../../core/conflict-markers.js";
|
|
20
|
+
import { FleetContext } from "../../../core/fleet-context.js";
|
|
21
|
+
import { capabilityFleetFindings, fleetShapeFindings, permissionFindings } from "../checks/fleet-shape.js";
|
|
22
|
+
import { fleetLinkFindings } from "../links/corpus.js";
|
|
23
|
+
import { glossaryFindings } from "../links/glossary.js";
|
|
24
|
+
import { obligationFindings, obligationVocabularyFindings } from "./obligations.js";
|
|
25
|
+
import { readObligations } from "../../../core/obligations/obligations.js";
|
|
26
|
+
import { obligationsPath } from "../../../core/repo/paths.js";
|
|
27
|
+
import { EXTERNAL_TAG } from "../../../core/vocabulary/maturity.js";
|
|
28
|
+
import { brokenDocumentPaths, errorText } from "../../../core/c4/likec4.js";
|
|
29
|
+
import { serviceTreePath } from "../../../core/kernel/ids/dirs.js";
|
|
30
|
+
import { drawnSystems, serviceLevelElements, standsForService } from "./census.js";
|
|
31
|
+
import { unreadableLandscape } from "./load.js";
|
|
32
|
+
import { kindTagFindings } from "./kind-tags.js";
|
|
33
|
+
import { mapAttestation } from "./map/attest.js";
|
|
34
|
+
import { bindingFindings } from "./map/bindings.js";
|
|
35
|
+
import { consumerCensus, datastoreFindings } from "./map/consumers.js";
|
|
36
|
+
import { isolationFindings } from "./map/isolation.js";
|
|
37
|
+
import { fleetUseCaseFindings } from "./map/usecases.js";
|
|
38
|
+
import { viewIdFindings } from "./views/ids.js";
|
|
39
|
+
import { viewsStaleFindings } from "./views/stale.js";
|
|
40
|
+
import { projectFindings } from "./views/projects.js";
|
|
41
|
+
import { fleetProjectFindings } from "./views/fleet-project.js";
|
|
42
|
+
import { isUseCase } from "../../../core/usecases/fleet.js";
|
|
43
|
+
/**
|
|
44
|
+
* The fleet's flows as a grade may read them, or `null` when loam cannot see
|
|
45
|
+
* them at all — the same `null`-suspends idiom `gradableCapabilityIds` uses,
|
|
46
|
+
* and here it guards one specific wrong answer.
|
|
47
|
+
*
|
|
48
|
+
* `capability.requirement-unrealized` says a business promise is kept by
|
|
49
|
+
* nobody. A use case is one of the two things that can keep it, so a run that
|
|
50
|
+
* could not read the flows must not make that claim: no map at all (`null`)
|
|
51
|
+
* and a project that did not parse are both "loam did not look", never
|
|
52
|
+
* "there is nothing there". A preload that DID parse and declares no views is a
|
|
53
|
+
* real, empty answer and grades normally.
|
|
54
|
+
*
|
|
55
|
+
* Filtered through `isUseCase` — the same opt-in `readUseCases` applies before
|
|
56
|
+
* `loam list capabilities` asks this question — because the two surfaces must
|
|
57
|
+
* never disagree about `keptBy`. Handing the unfiltered preload over was
|
|
58
|
+
* harmless only by luck: an untagged view yields no claims, so the answers
|
|
59
|
+
* matched for want of an input that could tell them apart. A `#req-`-only view
|
|
60
|
+
* is exactly that input.
|
|
61
|
+
*/
|
|
62
|
+
function gradableFlows(preloaded) {
|
|
63
|
+
if (preloaded === null || preloaded.errors.length > 0)
|
|
64
|
+
return null;
|
|
65
|
+
return (preloaded.views ?? []).filter(isUseCase);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The fleet cross-check: `services/` and the landscape both claim to name the
|
|
69
|
+
* fleet, and nothing used to compare them. A directory nobody drew and an element
|
|
70
|
+
* with nothing behind it were equally invisible.
|
|
71
|
+
*
|
|
72
|
+
* The two directions are graded differently because the evidence differs. A
|
|
73
|
+
* directory that exists is a fact, so a landscape missing it is an error — every
|
|
74
|
+
* view derived from that landscape is then incomplete. An element with no
|
|
75
|
+
* directory may legitimately be someone else's system, so it warns, and
|
|
76
|
+
* `#external` says "deliberately not ours" and silences it. An explicit
|
|
77
|
+
* `metadata { service '<id>' }` naming nothing is an error either way: a binding
|
|
78
|
+
* is a claim about this repo, not a guess at one.
|
|
79
|
+
*
|
|
80
|
+
* An ABSENT landscape is a finding, not a skipped check. It used to return null
|
|
81
|
+
* — no target, no findings, and a fleet gate that went green over a docs repo
|
|
82
|
+
* with no fleet map at all, which is the single artifact every derived view and
|
|
83
|
+
* every spine check is computed from. It is graded by what its absence proves:
|
|
84
|
+
* with services in `services/` it is an ERROR (a fleet that exists is undrawn),
|
|
85
|
+
* with none it is a WARNING (a docs repo before its first adopt legitimately
|
|
86
|
+
* has nothing to draw, but the file still belongs there — `loam init` scaffolds
|
|
87
|
+
* it, and a repo missing it will silently accept never getting one).
|
|
88
|
+
*
|
|
89
|
+
* `preloaded` is the already-parsed landscape under --all — the same doc every
|
|
90
|
+
* service check gets.
|
|
91
|
+
*/
|
|
92
|
+
export async function validateLandscape(docsDir, preloaded, fleet) {
|
|
93
|
+
const path = landscapeFile(docsDir);
|
|
94
|
+
const findings = [];
|
|
95
|
+
const report = {
|
|
96
|
+
kind: "landscape",
|
|
97
|
+
id: "landscape",
|
|
98
|
+
path: "architecture/landscape.likec4",
|
|
99
|
+
findings,
|
|
100
|
+
};
|
|
101
|
+
// The SET of service directories is this target's other subject, so it is
|
|
102
|
+
// graded before the map is even opened: `service.id-invalid` is a fact about
|
|
103
|
+
// `services/` that holds whether or not a landscape exists or parses, and
|
|
104
|
+
// both of those return early below. Emitted here and nowhere else — the
|
|
105
|
+
// enumeration is what makes the id a question, and one finding per fleet is
|
|
106
|
+
// what the rename fixes.
|
|
107
|
+
const entries = await listServices(docsDir, fleet);
|
|
108
|
+
findings.push(...serviceIdFindings(entries));
|
|
109
|
+
// The tree walk's own findings ride the same fleet target, before the map's
|
|
110
|
+
// early returns for the same reason `service.id-invalid` does: a stranded,
|
|
111
|
+
// colliding or mismarked directory is a fact about `services/` that holds
|
|
112
|
+
// whether or not a landscape exists or parses — and a broken tree must make
|
|
113
|
+
// the fleet gate refuse while still naming every service it found.
|
|
114
|
+
const tree = await listFleetTree(docsDir, fleet);
|
|
115
|
+
findings.push(...tree.findings);
|
|
116
|
+
// Which SHAPE each model has, read once for the whole target: it decides four
|
|
117
|
+
// of the grades below (`views/projects.ts`) and which documents the merged
|
|
118
|
+
// project holds (`views/fleet-project.ts`). Over the full enumeration, which
|
|
119
|
+
// is what `entries` is here even under `--base` — `validate --all` narrows the
|
|
120
|
+
// TARGETS it grades and never the fleet the renderer would load.
|
|
121
|
+
const models = entries.map((entry) => servicePathsAt(entry.dir).model);
|
|
122
|
+
const shapes = await fleet.modelShapes(models);
|
|
123
|
+
// A model and the renderer's project files disagreeing is a fact about
|
|
124
|
+
// `services/` too, graded here for `service.id-invalid`'s reason: it holds
|
|
125
|
+
// whether or not the map parses. One warning per service per disagreement;
|
|
126
|
+
// views/projects.ts says why a warning, why this run and not `doctor`, why
|
|
127
|
+
// the root-file gate, and why the grade is KEPT rather than spread and
|
|
128
|
+
// dropped — one of the five gates the merged-project load below, and
|
|
129
|
+
// re-deriving that fact there would let a cause and its 161-warning cascade
|
|
130
|
+
// disagree about which state the run is in.
|
|
131
|
+
const projects = await projectFindings(docsDir, entries, shapes);
|
|
132
|
+
findings.push(...projects.findings);
|
|
133
|
+
// Before the landscape's own early returns: the authorization and capability
|
|
134
|
+
// vocabularies are fleet facts that do not depend on the map existing or parsing.
|
|
135
|
+
findings.push(...(await permissionFindings(docsDir, entries, fleet)));
|
|
136
|
+
findings.push(...(await capabilityFleetFindings(docsDir, entries, fleet, gradableFlows(preloaded))));
|
|
137
|
+
// The documents that belong to no service and no feature — the fleet's ADRs
|
|
138
|
+
// and the living capability tree — are graded for their links here, once,
|
|
139
|
+
// for the same reason the two vocabularies above are: a fleet fact repeated
|
|
140
|
+
// on every service target is the report.
|
|
141
|
+
findings.push(...(await fleetLinkFindings({ docsDir, fleet })));
|
|
142
|
+
// The glossary is graded on who cites it, which is a question only the whole
|
|
143
|
+
// repository answers — so it belongs here, beside the two vocabularies, and
|
|
144
|
+
// nowhere else.
|
|
145
|
+
findings.push(...(await glossaryFindings(docsDir, fleet)));
|
|
146
|
+
// The architectural obligation vocabulary, read ONCE here and handed to the
|
|
147
|
+
// map half below: its own two verdicts hold whether or not the landscape
|
|
148
|
+
// exists or parses, and a run where somebody is fixing the map must still be
|
|
149
|
+
// told that this file does not read.
|
|
150
|
+
const obligations = await readObligations(obligationsPath(docsDir));
|
|
151
|
+
findings.push(...obligationVocabularyFindings(docsDir, obligations));
|
|
152
|
+
if (!existsSync(path)) {
|
|
153
|
+
const count = entries.length;
|
|
154
|
+
findings.push({
|
|
155
|
+
severity: count > 0 ? "error" : "warn",
|
|
156
|
+
code: "landscape.missing",
|
|
157
|
+
message: `landscape: architecture/landscape.likec4 does not exist — ` +
|
|
158
|
+
(count > 0
|
|
159
|
+
? `${count} service(s) are adopted and nothing draws the fleet. `
|
|
160
|
+
: "nothing draws the fleet. ") +
|
|
161
|
+
"It is the one map every derived view and the C4↔API spine are computed from: " +
|
|
162
|
+
"write a `specification { element softwareSystem }` + `model { … }` document there " +
|
|
163
|
+
"with one element per services/<id>/, bound with `metadata { service '<id>' }`.",
|
|
164
|
+
});
|
|
165
|
+
return report;
|
|
166
|
+
}
|
|
167
|
+
// Conflict markers before the parse — `loam doctor`'s order, and for its
|
|
168
|
+
// reason: the markers are the cause and the parse errors are the cascade.
|
|
169
|
+
// Nothing may be concluded from a file that is two halves of two different
|
|
170
|
+
// maps, least of all that a service nobody drew is unmodelled, so this
|
|
171
|
+
// returns the way `landscape.invalid` does. An error, gating by the default
|
|
172
|
+
// rule and deliberately not carrying `gates` — that field is coherence's,
|
|
173
|
+
// and the archive gate has to ask this question itself (it does not yet).
|
|
174
|
+
// Read plainly rather than through FleetContext: this target runs outside
|
|
175
|
+
// `guarded`, and a document refused for its encoding would surface here as
|
|
176
|
+
// the whole run's `repository-unavailable` instead of one finding.
|
|
177
|
+
//
|
|
178
|
+
// Both reads are contained for that same reason — see `unreadableLandscape`.
|
|
179
|
+
// The conflict-marker read is the FIRST touch of the file, so it is the one
|
|
180
|
+
// that fails when the file cannot be opened at all, and it runs before
|
|
181
|
+
// `preloaded ??` can spare it.
|
|
182
|
+
let land;
|
|
183
|
+
try {
|
|
184
|
+
const conflict = landscapeConflictFinding("architecture/landscape.likec4", await readFile(path, "utf8"));
|
|
185
|
+
if (conflict !== null) {
|
|
186
|
+
findings.push(conflict);
|
|
187
|
+
return report;
|
|
188
|
+
}
|
|
189
|
+
land = preloaded ?? (await fleet.loadLikeC4(path));
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
land = unreadableLandscape(err);
|
|
193
|
+
}
|
|
194
|
+
if (land.errors.length > 0) {
|
|
195
|
+
// Nothing may be concluded from a document that did not parse — in particular
|
|
196
|
+
// not that every service is unmodelled.
|
|
197
|
+
//
|
|
198
|
+
// The fleet map is a PROJECT now, not a file: `architecture/landscape.likec4`
|
|
199
|
+
// plus every `architecture/usecases/*.likec4`, merged the way the renderer
|
|
200
|
+
// merges them. So the message names the FILES that broke rather than the
|
|
201
|
+
// landscape by default — a use case with a typo'd element used to be
|
|
202
|
+
// reported as the landscape having errors, which sent the author to the
|
|
203
|
+
// wrong file with a line number that pointed at somebody else's text.
|
|
204
|
+
const broken = brokenDocumentPaths(docsDir, land.errors);
|
|
205
|
+
const named = broken.length === 0 ? "architecture/landscape.likec4" : broken.join(", ");
|
|
206
|
+
// The verb agrees with the LIST, not with the count after it: `named` is a
|
|
207
|
+
// comma-joined series once two documents broke, and "a, b has 6 error(s)"
|
|
208
|
+
// is a sentence a reader trips over. The service arm (`service/spine.ts`)
|
|
209
|
+
// picks the verb the same way off the same list, and these two messages are
|
|
210
|
+
// read side by side in one report — a run where the fleet line says "has"
|
|
211
|
+
// and the service line says "have" about the same two files reads as two
|
|
212
|
+
// different findings.
|
|
213
|
+
const verb = broken.length > 1 ? "have" : "has";
|
|
214
|
+
findings.push({
|
|
215
|
+
severity: "error",
|
|
216
|
+
code: "landscape.invalid",
|
|
217
|
+
// The tail is general on purpose. It used to speak about use-case flows
|
|
218
|
+
// alone, so an author whose MODEL EDGE named a container was told to move
|
|
219
|
+
// a flow that does not exist (#01). Both shapes are the same defect: loam
|
|
220
|
+
// grades the `architecture/` project, the renderer loads that project plus
|
|
221
|
+
// every extending model, and a reference to a container only the model
|
|
222
|
+
// declares therefore resolves there and not here.
|
|
223
|
+
message: `landscape: ${named} ${verb} ${land.errors.length} error(s) — cross-check with services/ impossible. ` +
|
|
224
|
+
"An unresolved name that a service's extending model declares — a use-case hop or an edge " +
|
|
225
|
+
"naming `<service-fqn>.<container>` — renders for the renderer and resolves for nobody here: " +
|
|
226
|
+
"name the SERVICE on the map, and the container in that service's own model (a container-level " +
|
|
227
|
+
"flow lives beside the model that declares it)",
|
|
228
|
+
// Every line carries its own file, because one project's errors can come
|
|
229
|
+
// from more than one document and a bare `L8:` is unactionable then. The
|
|
230
|
+
// prefix is `brokenDocumentPaths`'s spelling of that one error's document,
|
|
231
|
+
// so the message's file list and each line's prefix are one rule.
|
|
232
|
+
details: land.errors.map((e) => {
|
|
233
|
+
const [file] = broken.length < 2 ? [] : brokenDocumentPaths(docsDir, [e]);
|
|
234
|
+
return file === undefined ? errorText(e) : `${file} ${errorText(e)}`;
|
|
235
|
+
}),
|
|
236
|
+
});
|
|
237
|
+
return report;
|
|
238
|
+
}
|
|
239
|
+
// The generated views files, graded only now that the landscape has parsed:
|
|
240
|
+
// the expected bytes are a function of (tree, landscape elements, the global
|
|
241
|
+
// style ids the map declares) — the whole doc goes across so the grader and
|
|
242
|
+
// `sync` read one record. There are TWO generated files now
|
|
243
|
+
// (`subsystems.likec4` and `services.likec4`) and this pushes ONE error PER
|
|
244
|
+
// STALE FILE, each naming its own file; `views/stale.ts` says why a content
|
|
245
|
+
// compare, and why two files share one code but never one finding.
|
|
246
|
+
findings.push(...(await viewsStaleFindings(docsDir, tree, land)));
|
|
247
|
+
// The renderer's own reading of the tree: the map, every extending model and
|
|
248
|
+
// every `.likec4` beside one, merged into ONE project. It answers two
|
|
249
|
+
// questions at once and only one of them can be true at a time — either that
|
|
250
|
+
// project does not parse (`c4.fleet-project-invalid`), or it parsed and its
|
|
251
|
+
// view-id census is the real one.
|
|
252
|
+
const merged = await fleetProjectFindings({
|
|
253
|
+
docsDir, entries, shapes, fleet, tree,
|
|
254
|
+
architecture: land,
|
|
255
|
+
mapExcluded: projects.mapExcluded,
|
|
256
|
+
known: new Set(entries.map((s) => s.id)),
|
|
257
|
+
});
|
|
258
|
+
if (merged.kind === "invalid")
|
|
259
|
+
findings.push(...merged.findings);
|
|
260
|
+
// Beside staleness, and for the same file: an authored view id that collides
|
|
261
|
+
// with one loam mints into it takes the whole root project down in the
|
|
262
|
+
// renderer while every check here stays green — see views/ids.ts. The census
|
|
263
|
+
// is the merged project's when there is one; otherwise the `architecture/`
|
|
264
|
+
// project's alone, whose claims are spelled relative to that directory and are
|
|
265
|
+
// made docs-relative here.
|
|
266
|
+
// `land` goes across for the SERVICE half of the reservation: an id is minted
|
|
267
|
+
// per service the map DRAWS, so the census needs the render's own element join.
|
|
268
|
+
const claims = merged.kind === "clean"
|
|
269
|
+
? merged.viewIds
|
|
270
|
+
: land.viewIds?.map((claim) => ({ ...claim, sourcePath: `architecture/${claim.sourcePath}` }));
|
|
271
|
+
findings.push(...viewIdFindings(claims, tree, land));
|
|
272
|
+
// The three obligation questions that need the map — where each declared rule
|
|
273
|
+
// is applied, which tags resolve to nothing, and which applications no living
|
|
274
|
+
// arch requirement covers. Here rather than beside the vocabulary above
|
|
275
|
+
// because all three are about the parsed landscape, and `land` is only
|
|
276
|
+
// trustworthy past this point.
|
|
277
|
+
findings.push(...(await obligationFindings({ docsDir, vocabulary: obligations, land, services: entries, fleet })));
|
|
278
|
+
const services = new Set(entries.map((s) => s.id));
|
|
279
|
+
// Where each service actually sits, for every finding below that names a
|
|
280
|
+
// directory a reader is meant to open. `services/<id>/` is right only for an
|
|
281
|
+
// unfiled fleet; a filed service lives at `services/<subsystem>/…/<id>/`, and
|
|
282
|
+
// a finding pointing at the root form sends the fix to a path that does not
|
|
283
|
+
// exist. Built once here because three checks below need the same answer.
|
|
284
|
+
const pathOf = (id) => {
|
|
285
|
+
const entry = entries.find((s) => s.id === id);
|
|
286
|
+
return entry === undefined ? `services/${id}` : serviceTreePath(entry);
|
|
287
|
+
};
|
|
288
|
+
// Ahead of every exemption below, because it is the one defect that can make
|
|
289
|
+
// all of them lie at once: a tag loam grades on, declared on a KIND, landing
|
|
290
|
+
// on an element that stands for one of our own directories — see kind-tags.ts.
|
|
291
|
+
findings.push(...kindTagFindings({ specification: land.specification, elements: land.elements, services }));
|
|
292
|
+
const drawn = serviceLevelElements(land.elements, services);
|
|
293
|
+
// Which services the landscape models, answered by the same resolver every
|
|
294
|
+
// edge join uses — so "modelled" here and "inbound edge" in the spine check
|
|
295
|
+
// can never disagree about what an element stands for.
|
|
296
|
+
const landSvcOf = serviceResolver(land.elements, services);
|
|
297
|
+
const modelled = new Set(land.elements.map((e) => landSvcOf(e.id)));
|
|
298
|
+
// The same set with `#external` removed — the isolation check's input, and
|
|
299
|
+
// NOT `service-unmodelled`'s: a foreign box bound to one of our directories
|
|
300
|
+
// still means the directory is drawn, but "deliberately not ours" must not
|
|
301
|
+
// make it a subject of an advisory about our own map (R4/W12). The two
|
|
302
|
+
// binding passes have always skipped the tag; this is the third.
|
|
303
|
+
const external = new Set(land.elements.filter((e) => e.tags.includes(EXTERNAL_TAG)).map((e) => e.id));
|
|
304
|
+
const ours = new Set(land.elements.filter((e) => !external.has(e.id)).map((e) => landSvcOf(e.id)));
|
|
305
|
+
// The element↔directory passes: two boxes for one directory, a directory
|
|
306
|
+
// nobody drew, a binding naming nothing, and an element nobody owns.
|
|
307
|
+
const systems = drawnSystems(land.elements, services);
|
|
308
|
+
findings.push(...bindingFindings({ elements: land.elements, drawn, systems, services, modelled, pathOf }));
|
|
309
|
+
// What the fleet's own models say, read once for the two checks below that
|
|
310
|
+
// need it: a map edge is not the only evidence that a service consumes
|
|
311
|
+
// something, nor the only evidence that it calls out (map/attest.ts).
|
|
312
|
+
const drawnIds = new Set(drawn.map((e) => e.id));
|
|
313
|
+
// `census.ts`'s predicate, handed down rather than respelled: a `fleet/map/`
|
|
314
|
+
// module may not import `fleet/`, and the store grades were skipping a
|
|
315
|
+
// datastore that IS a service in one of their two halves only.
|
|
316
|
+
const isService = (e) => standsForService(e, services);
|
|
317
|
+
const attestation = await mapAttestation({
|
|
318
|
+
docsDir,
|
|
319
|
+
entries,
|
|
320
|
+
services,
|
|
321
|
+
resolve: landSvcOf,
|
|
322
|
+
standsForService: isService,
|
|
323
|
+
drawnIds,
|
|
324
|
+
fleet,
|
|
325
|
+
});
|
|
326
|
+
const attested = attestation.models;
|
|
327
|
+
const mapFacts = { relationships: land.relationships, elements: land.elements, services, resolve: landSvcOf };
|
|
328
|
+
const consumers = consumerCensus({ ...mapFacts, standsForService: isService, attested });
|
|
329
|
+
// The shape advisories run LAST, over the same drawn set and resolver the
|
|
330
|
+
// structural checks used. Any one of them suppresses `landscape.matched`
|
|
331
|
+
// below on purpose: a map with a shape warning did not fully "agree".
|
|
332
|
+
findings.push(...fleetShapeFindings({ drawn, services, consumers }));
|
|
333
|
+
const { nestedStores } = attestation;
|
|
334
|
+
findings.push(...datastoreFindings({
|
|
335
|
+
drawn,
|
|
336
|
+
elements: land.elements,
|
|
337
|
+
nestedStores,
|
|
338
|
+
services,
|
|
339
|
+
resolve: landSvcOf,
|
|
340
|
+
standsForService: isService,
|
|
341
|
+
consumers,
|
|
342
|
+
}));
|
|
343
|
+
// A drawn service nothing reaches, graded only where its own model attests
|
|
344
|
+
// a call across its boundary — map/isolation.ts says why the evidence gate.
|
|
345
|
+
findings.push(...isolationFindings({ land, modelled: ours, external, attested, resolve: landSvcOf, pathOf }));
|
|
346
|
+
// The use cases the SAME `architecture/` project declares — every
|
|
347
|
+
// `dynamic view` in the landscape and in every `architecture/usecases/*.likec4`
|
|
348
|
+
// — graded against the model above (`map/usecases.ts` holds the call and the
|
|
349
|
+
// two vocabulary reads it needs; `core/usecases/grade/usecases.ts` owns the opt-in and
|
|
350
|
+
// the grades). They ride this target for `viewsStaleFindings`' reason: a view
|
|
351
|
+
// belongs to no service, and only the fleet run has both the whole model and
|
|
352
|
+
// the enumerated `services/` in view at once.
|
|
353
|
+
findings.push(...(await fleetUseCaseFindings({
|
|
354
|
+
docsDir,
|
|
355
|
+
views: preloaded?.views ?? [],
|
|
356
|
+
elements: land.elements,
|
|
357
|
+
relationships: land.relationships,
|
|
358
|
+
services,
|
|
359
|
+
resolve: landSvcOf,
|
|
360
|
+
fleet,
|
|
361
|
+
})));
|
|
362
|
+
if (findings.length === 0) {
|
|
363
|
+
findings.push({
|
|
364
|
+
severity: "ok",
|
|
365
|
+
code: "landscape.matched",
|
|
366
|
+
message: `landscape: ${services.size} service(s) modelled — architecture/landscape.likec4 and services/ agree`,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
return report;
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=landscape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"landscape.js","sourceRoot":"","sources":["../../../../src/commands/validate/fleet/landscape.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The fleet target: `services/` and architecture/landscape.likec4 graded\n * against each other, plus the two exemptions that decide which drawn element\n * answers for a service directory at all.\n *\n * The landscape is the one artifact no service owns — parsed once for the whole\n * run and graded on a target of its own, outside the dispatcher's `guarded`.\n * That is why its IO containment lives in this package instead: see\n * `unreadableLandscape` in `./load.ts`.\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { type Elem, type LoadedDoc } from \"../../../core/c4/likec4.js\";\nimport { serviceResolver } from \"../../../core/c4/resolve/service.js\";\nimport { landscapePath as landscapeFile, servicePathsAt } from \"../../../core/repo/paths.js\";\nimport { serviceIdFindings } from \"../../../core/repo/entries.js\";\nimport { listFleetTree, listServices } from \"../../../core/repo/repo.js\";\nimport { type Finding, type TargetReport } from \"../../../core/vocabulary/report.js\";\nimport { landscapeConflictFinding } from \"../../../core/conflict-markers.js\";\nimport { FleetContext } from \"../../../core/fleet-context.js\";\nimport { capabilityFleetFindings, fleetShapeFindings, permissionFindings } from \"../checks/fleet-shape.js\";\nimport { fleetLinkFindings } from \"../links/corpus.js\";\nimport { glossaryFindings } from \"../links/glossary.js\";\nimport { obligationFindings, obligationVocabularyFindings } from \"./obligations.js\";\nimport { readObligations } from \"../../../core/obligations/obligations.js\";\nimport { obligationsPath } from \"../../../core/repo/paths.js\";\nimport { EXTERNAL_TAG } from \"../../../core/vocabulary/maturity.js\";\nimport { brokenDocumentPaths, errorText } from \"../../../core/c4/likec4.js\";\nimport { serviceTreePath, type DocsDir } from \"../../../core/kernel/ids/dirs.js\";\nimport { drawnSystems, serviceLevelElements, standsForService } from \"./census.js\";\nimport { unreadableLandscape } from \"./load.js\";\nimport { kindTagFindings } from \"./kind-tags.js\";\nimport { mapAttestation } from \"./map/attest.js\";\nimport { bindingFindings } from \"./map/bindings.js\";\nimport { consumerCensus, datastoreFindings } from \"./map/consumers.js\";\nimport { isolationFindings } from \"./map/isolation.js\";\nimport { fleetUseCaseFindings } from \"./map/usecases.js\";\nimport { viewIdFindings } from \"./views/ids.js\";\nimport { viewsStaleFindings } from \"./views/stale.js\";\nimport { projectFindings } from \"./views/projects.js\";\nimport { fleetProjectFindings } from \"./views/fleet-project.js\";\nimport type { ParsedView } from \"../../../core/c4/parsed/dynamic-views.js\";\nimport { isUseCase } from \"../../../core/usecases/fleet.js\";\n\n/**\n * The fleet's flows as a grade may read them, or `null` when loam cannot see\n * them at all — the same `null`-suspends idiom `gradableCapabilityIds` uses,\n * and here it guards one specific wrong answer.\n *\n * `capability.requirement-unrealized` says a business promise is kept by\n * nobody. A use case is one of the two things that can keep it, so a run that\n * could not read the flows must not make that claim: no map at all (`null`)\n * and a project that did not parse are both \"loam did not look\", never\n * \"there is nothing there\". A preload that DID parse and declares no views is a\n * real, empty answer and grades normally.\n *\n * Filtered through `isUseCase` — the same opt-in `readUseCases` applies before\n * `loam list capabilities` asks this question — because the two surfaces must\n * never disagree about `keptBy`. Handing the unfiltered preload over was\n * harmless only by luck: an untagged view yields no claims, so the answers\n * matched for want of an input that could tell them apart. A `#req-`-only view\n * is exactly that input.\n */\nfunction gradableFlows(preloaded: LoadedDoc | null): readonly ParsedView[] | null {\n if (preloaded === null || preloaded.errors.length > 0) return null;\n return (preloaded.views ?? []).filter(isUseCase);\n}\n\n/**\n * The fleet cross-check: `services/` and the landscape both claim to name the\n * fleet, and nothing used to compare them. A directory nobody drew and an element\n * with nothing behind it were equally invisible.\n *\n * The two directions are graded differently because the evidence differs. A\n * directory that exists is a fact, so a landscape missing it is an error — every\n * view derived from that landscape is then incomplete. An element with no\n * directory may legitimately be someone else's system, so it warns, and\n * `#external` says \"deliberately not ours\" and silences it. An explicit\n * `metadata { service '<id>' }` naming nothing is an error either way: a binding\n * is a claim about this repo, not a guess at one.\n *\n * An ABSENT landscape is a finding, not a skipped check. It used to return null\n * — no target, no findings, and a fleet gate that went green over a docs repo\n * with no fleet map at all, which is the single artifact every derived view and\n * every spine check is computed from. It is graded by what its absence proves:\n * with services in `services/` it is an ERROR (a fleet that exists is undrawn),\n * with none it is a WARNING (a docs repo before its first adopt legitimately\n * has nothing to draw, but the file still belongs there — `loam init` scaffolds\n * it, and a repo missing it will silently accept never getting one).\n *\n * `preloaded` is the already-parsed landscape under --all — the same doc every\n * service check gets.\n */\nexport async function validateLandscape(\n docsDir: DocsDir,\n preloaded: LoadedDoc | null,\n fleet: FleetContext,\n): Promise<TargetReport> {\n const path = landscapeFile(docsDir);\n const findings: Finding[] = [];\n const report: TargetReport = {\n kind: \"landscape\",\n id: \"landscape\",\n path: \"architecture/landscape.likec4\",\n findings,\n };\n\n // The SET of service directories is this target's other subject, so it is\n // graded before the map is even opened: `service.id-invalid` is a fact about\n // `services/` that holds whether or not a landscape exists or parses, and\n // both of those return early below. Emitted here and nowhere else — the\n // enumeration is what makes the id a question, and one finding per fleet is\n // what the rename fixes.\n const entries = await listServices(docsDir, fleet);\n findings.push(...serviceIdFindings(entries));\n // The tree walk's own findings ride the same fleet target, before the map's\n // early returns for the same reason `service.id-invalid` does: a stranded,\n // colliding or mismarked directory is a fact about `services/` that holds\n // whether or not a landscape exists or parses — and a broken tree must make\n // the fleet gate refuse while still naming every service it found.\n const tree = await listFleetTree(docsDir, fleet);\n findings.push(...tree.findings);\n // Which SHAPE each model has, read once for the whole target: it decides four\n // of the grades below (`views/projects.ts`) and which documents the merged\n // project holds (`views/fleet-project.ts`). Over the full enumeration, which\n // is what `entries` is here even under `--base` — `validate --all` narrows the\n // TARGETS it grades and never the fleet the renderer would load.\n const models = entries.map((entry) => servicePathsAt(entry.dir).model);\n const shapes = await fleet.modelShapes(models);\n // A model and the renderer's project files disagreeing is a fact about\n // `services/` too, graded here for `service.id-invalid`'s reason: it holds\n // whether or not the map parses. One warning per service per disagreement;\n // views/projects.ts says why a warning, why this run and not `doctor`, why\n // the root-file gate, and why the grade is KEPT rather than spread and\n // dropped — one of the five gates the merged-project load below, and\n // re-deriving that fact there would let a cause and its 161-warning cascade\n // disagree about which state the run is in.\n const projects = await projectFindings(docsDir, entries, shapes);\n findings.push(...projects.findings);\n // Before the landscape's own early returns: the authorization and capability\n // vocabularies are fleet facts that do not depend on the map existing or parsing.\n findings.push(...(await permissionFindings(docsDir, entries, fleet)));\n findings.push(...(await capabilityFleetFindings(docsDir, entries, fleet, gradableFlows(preloaded))));\n // The documents that belong to no service and no feature — the fleet's ADRs\n // and the living capability tree — are graded for their links here, once,\n // for the same reason the two vocabularies above are: a fleet fact repeated\n // on every service target is the report.\n findings.push(...(await fleetLinkFindings({ docsDir, fleet })));\n // The glossary is graded on who cites it, which is a question only the whole\n // repository answers — so it belongs here, beside the two vocabularies, and\n // nowhere else.\n findings.push(...(await glossaryFindings(docsDir, fleet)));\n // The architectural obligation vocabulary, read ONCE here and handed to the\n // map half below: its own two verdicts hold whether or not the landscape\n // exists or parses, and a run where somebody is fixing the map must still be\n // told that this file does not read.\n const obligations = await readObligations(obligationsPath(docsDir));\n findings.push(...obligationVocabularyFindings(docsDir, obligations));\n\n if (!existsSync(path)) {\n const count = entries.length;\n findings.push({\n severity: count > 0 ? \"error\" : \"warn\",\n code: \"landscape.missing\",\n message:\n `landscape: architecture/landscape.likec4 does not exist — ` +\n (count > 0\n ? `${count} service(s) are adopted and nothing draws the fleet. `\n : \"nothing draws the fleet. \") +\n \"It is the one map every derived view and the C4↔API spine are computed from: \" +\n \"write a `specification { element softwareSystem }` + `model { … }` document there \" +\n \"with one element per services/<id>/, bound with `metadata { service '<id>' }`.\",\n });\n return report;\n }\n\n // Conflict markers before the parse — `loam doctor`'s order, and for its\n // reason: the markers are the cause and the parse errors are the cascade.\n // Nothing may be concluded from a file that is two halves of two different\n // maps, least of all that a service nobody drew is unmodelled, so this\n // returns the way `landscape.invalid` does. An error, gating by the default\n // rule and deliberately not carrying `gates` — that field is coherence's,\n // and the archive gate has to ask this question itself (it does not yet).\n // Read plainly rather than through FleetContext: this target runs outside\n // `guarded`, and a document refused for its encoding would surface here as\n // the whole run's `repository-unavailable` instead of one finding.\n //\n // Both reads are contained for that same reason — see `unreadableLandscape`.\n // The conflict-marker read is the FIRST touch of the file, so it is the one\n // that fails when the file cannot be opened at all, and it runs before\n // `preloaded ??` can spare it.\n let land: LoadedDoc;\n try {\n const conflict = landscapeConflictFinding(\n \"architecture/landscape.likec4\",\n await readFile(path, \"utf8\"),\n );\n if (conflict !== null) {\n findings.push(conflict);\n return report;\n }\n land = preloaded ?? (await fleet.loadLikeC4(path));\n } catch (err) {\n land = unreadableLandscape(err);\n }\n if (land.errors.length > 0) {\n // Nothing may be concluded from a document that did not parse — in particular\n // not that every service is unmodelled.\n //\n // The fleet map is a PROJECT now, not a file: `architecture/landscape.likec4`\n // plus every `architecture/usecases/*.likec4`, merged the way the renderer\n // merges them. So the message names the FILES that broke rather than the\n // landscape by default — a use case with a typo'd element used to be\n // reported as the landscape having errors, which sent the author to the\n // wrong file with a line number that pointed at somebody else's text.\n const broken = brokenDocumentPaths(docsDir, land.errors);\n const named = broken.length === 0 ? \"architecture/landscape.likec4\" : broken.join(\", \");\n // The verb agrees with the LIST, not with the count after it: `named` is a\n // comma-joined series once two documents broke, and \"a, b has 6 error(s)\"\n // is a sentence a reader trips over. The service arm (`service/spine.ts`)\n // picks the verb the same way off the same list, and these two messages are\n // read side by side in one report — a run where the fleet line says \"has\"\n // and the service line says \"have\" about the same two files reads as two\n // different findings.\n const verb = broken.length > 1 ? \"have\" : \"has\";\n findings.push({\n severity: \"error\",\n code: \"landscape.invalid\",\n // The tail is general on purpose. It used to speak about use-case flows\n // alone, so an author whose MODEL EDGE named a container was told to move\n // a flow that does not exist (#01). Both shapes are the same defect: loam\n // grades the `architecture/` project, the renderer loads that project plus\n // every extending model, and a reference to a container only the model\n // declares therefore resolves there and not here.\n message:\n `landscape: ${named} ${verb} ${land.errors.length} error(s) — cross-check with services/ impossible. ` +\n \"An unresolved name that a service's extending model declares — a use-case hop or an edge \" +\n \"naming `<service-fqn>.<container>` — renders for the renderer and resolves for nobody here: \" +\n \"name the SERVICE on the map, and the container in that service's own model (a container-level \" +\n \"flow lives beside the model that declares it)\",\n // Every line carries its own file, because one project's errors can come\n // from more than one document and a bare `L8:` is unactionable then. The\n // prefix is `brokenDocumentPaths`'s spelling of that one error's document,\n // so the message's file list and each line's prefix are one rule.\n details: land.errors.map((e) => {\n const [file] = broken.length < 2 ? [] : brokenDocumentPaths(docsDir, [e]);\n return file === undefined ? errorText(e) : `${file} ${errorText(e)}`;\n }),\n });\n return report;\n }\n\n // The generated views files, graded only now that the landscape has parsed:\n // the expected bytes are a function of (tree, landscape elements, the global\n // style ids the map declares) — the whole doc goes across so the grader and\n // `sync` read one record. There are TWO generated files now\n // (`subsystems.likec4` and `services.likec4`) and this pushes ONE error PER\n // STALE FILE, each naming its own file; `views/stale.ts` says why a content\n // compare, and why two files share one code but never one finding.\n findings.push(...(await viewsStaleFindings(docsDir, tree, land)));\n // The renderer's own reading of the tree: the map, every extending model and\n // every `.likec4` beside one, merged into ONE project. It answers two\n // questions at once and only one of them can be true at a time — either that\n // project does not parse (`c4.fleet-project-invalid`), or it parsed and its\n // view-id census is the real one.\n const merged = await fleetProjectFindings({\n docsDir, entries, shapes, fleet, tree,\n architecture: land,\n mapExcluded: projects.mapExcluded,\n known: new Set(entries.map((s) => s.id)),\n });\n if (merged.kind === \"invalid\") findings.push(...merged.findings);\n // Beside staleness, and for the same file: an authored view id that collides\n // with one loam mints into it takes the whole root project down in the\n // renderer while every check here stays green — see views/ids.ts. The census\n // is the merged project's when there is one; otherwise the `architecture/`\n // project's alone, whose claims are spelled relative to that directory and are\n // made docs-relative here.\n // `land` goes across for the SERVICE half of the reservation: an id is minted\n // per service the map DRAWS, so the census needs the render's own element join.\n const claims =\n merged.kind === \"clean\"\n ? merged.viewIds\n : land.viewIds?.map((claim) => ({ ...claim, sourcePath: `architecture/${claim.sourcePath}` }));\n findings.push(...viewIdFindings(claims, tree, land));\n // The three obligation questions that need the map — where each declared rule\n // is applied, which tags resolve to nothing, and which applications no living\n // arch requirement covers. Here rather than beside the vocabulary above\n // because all three are about the parsed landscape, and `land` is only\n // trustworthy past this point.\n findings.push(...(await obligationFindings({ docsDir, vocabulary: obligations, land, services: entries, fleet })));\n\n const services: ReadonlySet<string> = new Set(entries.map((s) => s.id));\n // Where each service actually sits, for every finding below that names a\n // directory a reader is meant to open. `services/<id>/` is right only for an\n // unfiled fleet; a filed service lives at `services/<subsystem>/…/<id>/`, and\n // a finding pointing at the root form sends the fix to a path that does not\n // exist. Built once here because three checks below need the same answer.\n const pathOf = (id: string): string => {\n const entry = entries.find((s) => s.id === id);\n return entry === undefined ? `services/${id}` : serviceTreePath(entry);\n };\n // Ahead of every exemption below, because it is the one defect that can make\n // all of them lie at once: a tag loam grades on, declared on a KIND, landing\n // on an element that stands for one of our own directories — see kind-tags.ts.\n findings.push(...kindTagFindings({ specification: land.specification, elements: land.elements, services }));\n const drawn = serviceLevelElements(land.elements, services);\n // Which services the landscape models, answered by the same resolver every\n // edge join uses — so \"modelled\" here and \"inbound edge\" in the spine check\n // can never disagree about what an element stands for.\n const landSvcOf = serviceResolver(land.elements, services);\n const modelled: ReadonlySet<string> = new Set(land.elements.map((e) => landSvcOf(e.id)));\n // The same set with `#external` removed — the isolation check's input, and\n // NOT `service-unmodelled`'s: a foreign box bound to one of our directories\n // still means the directory is drawn, but \"deliberately not ours\" must not\n // make it a subject of an advisory about our own map (R4/W12). The two\n // binding passes have always skipped the tag; this is the third.\n const external: ReadonlySet<string> = new Set(\n land.elements.filter((e) => e.tags.includes(EXTERNAL_TAG)).map((e) => e.id),\n );\n const ours: ReadonlySet<string> = new Set(\n land.elements.filter((e) => !external.has(e.id)).map((e) => landSvcOf(e.id)),\n );\n\n // The element↔directory passes: two boxes for one directory, a directory\n // nobody drew, a binding naming nothing, and an element nobody owns.\n const systems = drawnSystems(land.elements, services);\n findings.push(...bindingFindings({ elements: land.elements, drawn, systems, services, modelled, pathOf }));\n\n // What the fleet's own models say, read once for the two checks below that\n // need it: a map edge is not the only evidence that a service consumes\n // something, nor the only evidence that it calls out (map/attest.ts).\n const drawnIds: ReadonlySet<string> = new Set(drawn.map((e) => e.id));\n // `census.ts`'s predicate, handed down rather than respelled: a `fleet/map/`\n // module may not import `fleet/`, and the store grades were skipping a\n // datastore that IS a service in one of their two halves only.\n const isService = (e: Elem): boolean => standsForService(e, services);\n const attestation = await mapAttestation({\n docsDir,\n entries,\n services,\n resolve: landSvcOf,\n standsForService: isService,\n drawnIds,\n fleet,\n });\n const attested = attestation.models;\n const mapFacts = { relationships: land.relationships, elements: land.elements, services, resolve: landSvcOf };\n const consumers = consumerCensus({ ...mapFacts, standsForService: isService, attested });\n // The shape advisories run LAST, over the same drawn set and resolver the\n // structural checks used. Any one of them suppresses `landscape.matched`\n // below on purpose: a map with a shape warning did not fully \"agree\".\n findings.push(...fleetShapeFindings({ drawn, services, consumers }));\n const { nestedStores } = attestation;\n findings.push(\n ...datastoreFindings({\n drawn,\n elements: land.elements,\n nestedStores,\n services,\n resolve: landSvcOf,\n standsForService: isService,\n consumers,\n }),\n );\n // A drawn service nothing reaches, graded only where its own model attests\n // a call across its boundary — map/isolation.ts says why the evidence gate.\n findings.push(...isolationFindings({ land, modelled: ours, external, attested, resolve: landSvcOf, pathOf }));\n\n // The use cases the SAME `architecture/` project declares — every\n // `dynamic view` in the landscape and in every `architecture/usecases/*.likec4`\n // — graded against the model above (`map/usecases.ts` holds the call and the\n // two vocabulary reads it needs; `core/usecases/grade/usecases.ts` owns the opt-in and\n // the grades). They ride this target for `viewsStaleFindings`' reason: a view\n // belongs to no service, and only the fleet run has both the whole model and\n // the enumerated `services/` in view at once.\n findings.push(\n ...(await fleetUseCaseFindings({\n docsDir,\n views: preloaded?.views ?? [],\n elements: land.elements,\n relationships: land.relationships,\n services,\n resolve: landSvcOf,\n fleet,\n })),\n );\n\n if (findings.length === 0) {\n findings.push({\n severity: \"ok\",\n code: \"landscape.matched\",\n message: `landscape: ${services.size} service(s) modelled — architecture/landscape.likec4 and services/ agree`,\n });\n }\n return report;\n}\n"]}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The landscape's contained load path — the one phase of the fleet target that
|
|
3
|
+
* touches the filesystem before anything can be graded. Split from
|
|
4
|
+
* `./landscape.ts` when the fleet target grew past the line limit; the
|
|
5
|
+
* containment DOCTRINE below travelled with the functions it explains.
|
|
6
|
+
*
|
|
7
|
+
* The load ITSELF is no longer here. `loadArchitecture` moved to
|
|
8
|
+
* `core/c4/project/architecture.ts` when the use-case axis grew a second reader
|
|
9
|
+
* of it, and that module's banner records why; what stayed is the containment,
|
|
10
|
+
* which is command-layer business because it is about which validate TARGET a
|
|
11
|
+
* failed read is filed against.
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { resolve } from "node:path";
|
|
15
|
+
import { FleetContext } from "../../../core/fleet-context.js";
|
|
16
|
+
import { featurePaths, landscapePath, servicePathsAt } from "../../../core/repo/paths.js";
|
|
17
|
+
/**
|
|
18
|
+
* A landscape that could not be READ, shaped as one that did not PARSE.
|
|
19
|
+
*
|
|
20
|
+
* The landscape is the one artifact no target owns: it is read once for the
|
|
21
|
+
* whole run and it is graded on a target of its own, which runs OUTSIDE
|
|
22
|
+
* `guarded`. So a landscape.likec4 that is a directory, or that carries a
|
|
23
|
+
* permission bit this process cannot open, escaped every per-target catch and
|
|
24
|
+
* became the whole run's `repository-unavailable` — one file, and a fleet gate
|
|
25
|
+
* that said nothing about the ninety-nine services that are fine. A DANGLING
|
|
26
|
+
* symlink is not one of those shapes and never was: every read of the file is
|
|
27
|
+
* gated on an `existsSync` that follows the link, so a broken one resolves as
|
|
28
|
+
* `landscape.missing` long before anything opens it.
|
|
29
|
+
*
|
|
30
|
+
* What this contains is the FLEET-level reads, and only those: the `--all`
|
|
31
|
+
* preload, and both reads inside `validateLandscape` — the conflict-marker
|
|
32
|
+
* `readFile` and the parse. `loam validate --service <id>` and
|
|
33
|
+
* `loam validate --feature <id>` hand in no preloaded doc, so `validateService`
|
|
34
|
+
* and `validateFeature` open the same file again on demand, unwrapped and
|
|
35
|
+
* INSIDE `guarded`: an EISDIR there is still reported as `service.unreadable`
|
|
36
|
+
* or `feature.unreadable`, which files the fleet map's failure against the one
|
|
37
|
+
* target the caller happened to name. That is the wrong subject on a finding
|
|
38
|
+
* that does at least carry the offending path, and it costs those runs nothing
|
|
39
|
+
* further — they grade a single target either way, so there is no report left
|
|
40
|
+
* unwritten — which is why the remainder was left for the change that gives the
|
|
41
|
+
* landscape one load path instead of three.
|
|
42
|
+
*
|
|
43
|
+
* `guarded` is deliberately NOT widened to cover the landscape target instead.
|
|
44
|
+
* Its code ternary knows only services and features, so it would file the fleet
|
|
45
|
+
* map's failure as `feature.unreadable`; and a guarded failure yields no
|
|
46
|
+
* document, so all N services would go on to re-open the same broken file
|
|
47
|
+
* inside their own guards and emit N copies of it. Containing the IO here needs
|
|
48
|
+
* no new code and no new sentence: "could not be read" and "did not parse" have
|
|
49
|
+
* the same consequence — nothing may be concluded from this file — and
|
|
50
|
+
* `landscape.invalid` is already how that is said.
|
|
51
|
+
*/
|
|
52
|
+
export function unreadableLandscape(err) {
|
|
53
|
+
return {
|
|
54
|
+
errors: [{ message: err instanceof Error ? err.message : String(err) }],
|
|
55
|
+
elements: [],
|
|
56
|
+
relationships: [],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** One landscape load, answering with `unreadableLandscape` rather than throwing. */
|
|
60
|
+
export async function readLandscape(load) {
|
|
61
|
+
try {
|
|
62
|
+
return await load();
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
return unreadableLandscape(err);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* ONE workspace per document KIND for the whole `--all` run.
|
|
70
|
+
*
|
|
71
|
+
* The per-path load pays a fresh Langium workspace per document (~100 ms each
|
|
72
|
+
* even warm), which made the fleet's main CI command O(documents) workspace
|
|
73
|
+
* spins — 13.7 s median over the 120-service benchmark (docs/BENCHMARKS.md). So
|
|
74
|
+
* `--all` enumerates its documents up front and batch-parses them into the
|
|
75
|
+
* fleet context's memo; every load below, the landscape read included, is then a
|
|
76
|
+
* seeded hit. The enumerations are the same memoised promises the target loops
|
|
77
|
+
* reuse.
|
|
78
|
+
*
|
|
79
|
+
* TWO WORKSPACES, because the fleet's models no longer parse the same way as
|
|
80
|
+
* each other: a model that EXTENDS the map is a PROJECT (the map plus that
|
|
81
|
+
* file) and a model that stands alone is a document. So the shapes are read
|
|
82
|
+
* first, the DOCUMENT batch is asked for everything that is one — the landscape,
|
|
83
|
+
* every feature delta, every standalone model — and `prefetchServiceModels`
|
|
84
|
+
* then batches the extending half as projects, finding its own standalone list
|
|
85
|
+
* already memoised and asking for nothing.
|
|
86
|
+
*
|
|
87
|
+
* The order is load-bearing rather than tidy. `prefetchLikeC4` returns without a
|
|
88
|
+
* workspace when fewer than two documents are missing (one document gains
|
|
89
|
+
* nothing from batch isolation it already has), so splitting the documents
|
|
90
|
+
* across two calls is how a fleet of one service and one feature ends up
|
|
91
|
+
* batching the feature and parsing the model in a workspace of its own — the
|
|
92
|
+
* exact per-document spin this function exists to remove, and what
|
|
93
|
+
* `test/validate-batch-fallback.test.ts` counts.
|
|
94
|
+
*
|
|
95
|
+
* If a batch CANNOT run — a sandbox denying tmpdir writes — the prefetch seeds
|
|
96
|
+
* nothing and every load falls back to today's per-path parse: identical
|
|
97
|
+
* findings, the old speed. Single-service `validate` and `list` keep their
|
|
98
|
+
* untouched code paths on purpose, so the ≤10% regression bound in
|
|
99
|
+
* docs/BENCHMARKS.md holds by construction.
|
|
100
|
+
*
|
|
101
|
+
* It lives HERE rather than in `../validate.ts` because it is fleet-loading
|
|
102
|
+
* business and that module is the argument grammar and the target dispatch; the
|
|
103
|
+
* block also took that file to its line limit, which is the ceiling asking the
|
|
104
|
+
* question it exists to ask.
|
|
105
|
+
*/
|
|
106
|
+
export async function prefetchFleetDocuments(input) {
|
|
107
|
+
const { docsDir, fleet } = input;
|
|
108
|
+
const paths = input.services.filter((svc) => svc.has.model).map((svc) => servicePathsAt(svc.dir));
|
|
109
|
+
const shapes = await fleet.modelShapes(paths.map((p) => p.model));
|
|
110
|
+
const landscape = landscapePath(docsDir);
|
|
111
|
+
await fleet.prefetchLikeC4([
|
|
112
|
+
...(existsSync(landscape) ? [landscape] : []),
|
|
113
|
+
...input.features.filter((feat) => feat.has.delta).map((feat) => featurePaths(feat.dir).delta),
|
|
114
|
+
...paths.filter((p) => shapes.get(resolve(p.model)) !== "extending").map((p) => p.model),
|
|
115
|
+
]);
|
|
116
|
+
await fleet.prefetchServiceModels(docsDir, paths);
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../../src/commands/validate/fleet/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAG9D,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,OAAO;QACL,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACvE,QAAQ,EAAE,EAAE;QACZ,aAAa,EAAE,EAAE;KAClB,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAA8B;IAChE,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,KAAoB;IAC/D,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACjC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAClG,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,KAAK,CAAC,cAAc,CAAC;QACzB,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QAC9F,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;KACzF,CAAC,CAAC;IACH,MAAM,KAAK,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACpD,CAAC","sourcesContent":["/**\n * The landscape's contained load path — the one phase of the fleet target that\n * touches the filesystem before anything can be graded. Split from\n * `./landscape.ts` when the fleet target grew past the line limit; the\n * containment DOCTRINE below travelled with the functions it explains.\n *\n * The load ITSELF is no longer here. `loadArchitecture` moved to\n * `core/c4/project/architecture.ts` when the use-case axis grew a second reader\n * of it, and that module's banner records why; what stayed is the containment,\n * which is command-layer business because it is about which validate TARGET a\n * failed read is filed against.\n */\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { LoadedDoc } from \"../../../core/c4/likec4.js\";\nimport { FleetContext } from \"../../../core/fleet-context.js\";\nimport type { DocsDir } from \"../../../core/kernel/ids/dirs.js\";\nimport type { FeatureEntry, ServiceEntry } from \"../../../core/repo/entries.js\";\nimport { featurePaths, landscapePath, servicePathsAt } from \"../../../core/repo/paths.js\";\n\n/**\n * A landscape that could not be READ, shaped as one that did not PARSE.\n *\n * The landscape is the one artifact no target owns: it is read once for the\n * whole run and it is graded on a target of its own, which runs OUTSIDE\n * `guarded`. So a landscape.likec4 that is a directory, or that carries a\n * permission bit this process cannot open, escaped every per-target catch and\n * became the whole run's `repository-unavailable` — one file, and a fleet gate\n * that said nothing about the ninety-nine services that are fine. A DANGLING\n * symlink is not one of those shapes and never was: every read of the file is\n * gated on an `existsSync` that follows the link, so a broken one resolves as\n * `landscape.missing` long before anything opens it.\n *\n * What this contains is the FLEET-level reads, and only those: the `--all`\n * preload, and both reads inside `validateLandscape` — the conflict-marker\n * `readFile` and the parse. `loam validate --service <id>` and\n * `loam validate --feature <id>` hand in no preloaded doc, so `validateService`\n * and `validateFeature` open the same file again on demand, unwrapped and\n * INSIDE `guarded`: an EISDIR there is still reported as `service.unreadable`\n * or `feature.unreadable`, which files the fleet map's failure against the one\n * target the caller happened to name. That is the wrong subject on a finding\n * that does at least carry the offending path, and it costs those runs nothing\n * further — they grade a single target either way, so there is no report left\n * unwritten — which is why the remainder was left for the change that gives the\n * landscape one load path instead of three.\n *\n * `guarded` is deliberately NOT widened to cover the landscape target instead.\n * Its code ternary knows only services and features, so it would file the fleet\n * map's failure as `feature.unreadable`; and a guarded failure yields no\n * document, so all N services would go on to re-open the same broken file\n * inside their own guards and emit N copies of it. Containing the IO here needs\n * no new code and no new sentence: \"could not be read\" and \"did not parse\" have\n * the same consequence — nothing may be concluded from this file — and\n * `landscape.invalid` is already how that is said.\n */\nexport function unreadableLandscape(err: unknown): LoadedDoc {\n return {\n errors: [{ message: err instanceof Error ? err.message : String(err) }],\n elements: [],\n relationships: [],\n };\n}\n\n/** One landscape load, answering with `unreadableLandscape` rather than throwing. */\nexport async function readLandscape(load: () => Promise<LoadedDoc>): Promise<LoadedDoc> {\n try {\n return await load();\n } catch (err) {\n return unreadableLandscape(err);\n }\n}\n\n/** Everything a `--all` run parses up front, and the enumerations it was narrowed to. */\nexport interface FleetPrefetch {\n docsDir: DocsDir;\n fleet: FleetContext;\n /** The services this run grades — the `--base` narrowing when there is one. */\n services: readonly ServiceEntry[];\n /** The active features this run grades, likewise. */\n features: readonly FeatureEntry[];\n}\n\n/**\n * ONE workspace per document KIND for the whole `--all` run.\n *\n * The per-path load pays a fresh Langium workspace per document (~100 ms each\n * even warm), which made the fleet's main CI command O(documents) workspace\n * spins — 13.7 s median over the 120-service benchmark (docs/BENCHMARKS.md). So\n * `--all` enumerates its documents up front and batch-parses them into the\n * fleet context's memo; every load below, the landscape read included, is then a\n * seeded hit. The enumerations are the same memoised promises the target loops\n * reuse.\n *\n * TWO WORKSPACES, because the fleet's models no longer parse the same way as\n * each other: a model that EXTENDS the map is a PROJECT (the map plus that\n * file) and a model that stands alone is a document. So the shapes are read\n * first, the DOCUMENT batch is asked for everything that is one — the landscape,\n * every feature delta, every standalone model — and `prefetchServiceModels`\n * then batches the extending half as projects, finding its own standalone list\n * already memoised and asking for nothing.\n *\n * The order is load-bearing rather than tidy. `prefetchLikeC4` returns without a\n * workspace when fewer than two documents are missing (one document gains\n * nothing from batch isolation it already has), so splitting the documents\n * across two calls is how a fleet of one service and one feature ends up\n * batching the feature and parsing the model in a workspace of its own — the\n * exact per-document spin this function exists to remove, and what\n * `test/validate-batch-fallback.test.ts` counts.\n *\n * If a batch CANNOT run — a sandbox denying tmpdir writes — the prefetch seeds\n * nothing and every load falls back to today's per-path parse: identical\n * findings, the old speed. Single-service `validate` and `list` keep their\n * untouched code paths on purpose, so the ≤10% regression bound in\n * docs/BENCHMARKS.md holds by construction.\n *\n * It lives HERE rather than in `../validate.ts` because it is fleet-loading\n * business and that module is the argument grammar and the target dispatch; the\n * block also took that file to its line limit, which is the ceiling asking the\n * question it exists to ask.\n */\nexport async function prefetchFleetDocuments(input: FleetPrefetch): Promise<void> {\n const { docsDir, fleet } = input;\n const paths = input.services.filter((svc) => svc.has.model).map((svc) => servicePathsAt(svc.dir));\n const shapes = await fleet.modelShapes(paths.map((p) => p.model));\n const landscape = landscapePath(docsDir);\n await fleet.prefetchLikeC4([\n ...(existsSync(landscape) ? [landscape] : []),\n ...input.features.filter((feat) => feat.has.delta).map((feat) => featurePaths(feat.dir).delta),\n ...paths.filter((p) => shapes.get(resolve(p.model)) !== \"extending\").map((p) => p.model),\n ]);\n await fleet.prefetchServiceModels(docsDir, paths);\n}\n"]}
|