@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,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The model of every service a feature's archive CREATES — one the feature
|
|
3
|
+
* carries `specs/<svc>/` for, the fleet does not enumerate, and the map the
|
|
4
|
+
* merge leaves will draw — as the EMPTY extending model the archive writes
|
|
5
|
+
* beside its first documents.
|
|
6
|
+
*
|
|
7
|
+
* Drawn by the merged map, because the model extends the element that stands
|
|
8
|
+
* for the service there, and only a service the map draws has one: the living
|
|
9
|
+
* map's elements plus the delta's TAGGED ones, which is exactly what the map
|
|
10
|
+
* holds once the merge lands. A context element the delta quotes is merged
|
|
11
|
+
* nowhere, and counting it gave a model to a service nothing would draw — two
|
|
12
|
+
* `landscape.service-unmodelled` on the next `validate --all` (review,
|
|
13
|
+
* 2026-10-22). A `specs/<svc>/` nothing draws is, more often than not, a typo
|
|
14
|
+
* the gate already calls an unknown service; forced through with `--approve`,
|
|
15
|
+
* writing a model there would fabricate a service directory out of it, which
|
|
16
|
+
* the spec merge is careful never to do (it creates no empty living spec
|
|
17
|
+
* either).
|
|
18
|
+
*
|
|
19
|
+
* ## Why the archive writes it
|
|
20
|
+
*
|
|
21
|
+
* It used to leave the file out and say so (`service.no-model`, an error the
|
|
22
|
+
* next `validate --all` repeated), because writing a container model would have
|
|
23
|
+
* been inventing one. An EMPTY extending model invents nothing: LikeC4 reads it
|
|
24
|
+
* as the map's own box with nothing drawn inside, and SCHEMA.md calls an empty
|
|
25
|
+
* file a legal extending model. What it changes is real. The new service's first
|
|
26
|
+
* `validate --all` grades it instead of stopping at a missing file, and the
|
|
27
|
+
* interior a delta draws inside the new service lands in the model — routed like
|
|
28
|
+
* any extending model's — where until now it rode onto the map, because no model
|
|
29
|
+
* existed to own it, and stayed there as interior the map is not supposed to
|
|
30
|
+
* hold. A team that pre-placed an empty model got exactly this (measured on a
|
|
31
|
+
* real fleet, 2026-10); now nobody has to know to. SCHEMA.md, "Which document an
|
|
32
|
+
* addition lands in", records the decision.
|
|
33
|
+
*
|
|
34
|
+
* ## Why it is not beside the archive
|
|
35
|
+
*
|
|
36
|
+
* Two readers, and they must agree. `loam archive` writes these models; the
|
|
37
|
+
* merge PREVIEW every feature-side gate grades against (`../../project/staged.ts`)
|
|
38
|
+
* has to route the new service's interior the same way, or a feature flow
|
|
39
|
+
* hopping to `<new-service-fqn>.<container>` resolves in the preview, passes the
|
|
40
|
+
* gate, and lands in `architecture/usecases/` naming a container the map no
|
|
41
|
+
* longer holds — the outcome the fleet-model list beside this
|
|
42
|
+
* (`../fleet/extending.ts`) exists to prevent. That list could not host this
|
|
43
|
+
* either: `../fleet/` reads the shape scan, which imports `../../project/`, so
|
|
44
|
+
* the preview importing it would be a package cycle. The one part of `core/c4/`
|
|
45
|
+
* this package imports as a value is `../../resolve/`, the binding join, which
|
|
46
|
+
* imports neither the shape scan nor the project.
|
|
47
|
+
*
|
|
48
|
+
* ## Unfiled, always
|
|
49
|
+
*
|
|
50
|
+
* The path is `services/<svc>/`, the spelling the spec merges write a new
|
|
51
|
+
* service's documents to. The archive never reads a subsystem off the map's
|
|
52
|
+
* group nesting or off a delta's metadata — the tree and the map stay
|
|
53
|
+
* independent — so a new service lands in a subsystem only when its directory is
|
|
54
|
+
* already there, and then it is enumerated and not created here at all.
|
|
55
|
+
*/
|
|
56
|
+
import { existsSync } from "node:fs";
|
|
57
|
+
import { elementService } from "../../resolve/service.js";
|
|
58
|
+
import { parseServiceId } from "../../../kernel/ids/service.js";
|
|
59
|
+
import { repoPath } from "../../../envelope/json.js";
|
|
60
|
+
import { unfiledServicePaths } from "../../../repo/paths.js";
|
|
61
|
+
import { featureSpecServices } from "../../../repo/repo.js";
|
|
62
|
+
import { enumeratedServiceIds } from "../../../repo/service-target.js";
|
|
63
|
+
export async function createdServiceModels(req) {
|
|
64
|
+
const enumerated = new Set(await enumeratedServiceIds(req.docsDir, req.fleet));
|
|
65
|
+
// Binding first, title as the fallback: the join every check resolves an
|
|
66
|
+
// element to its directory through.
|
|
67
|
+
const drawn = new Set(req.drawn.map((e) => elementService(e)));
|
|
68
|
+
const models = [];
|
|
69
|
+
for (const raw of await featureSpecServices(req.featureDir, req.fleet)) {
|
|
70
|
+
// An id the service grammar refuses never reaches a path; the gate refuses
|
|
71
|
+
// the feature for it before an archive is planned.
|
|
72
|
+
const parsed = parseServiceId(raw);
|
|
73
|
+
if (!parsed.ok || enumerated.has(parsed.id) || !drawn.has(parsed.id))
|
|
74
|
+
continue;
|
|
75
|
+
const paths = unfiledServicePaths(req.docsDir, parsed.id);
|
|
76
|
+
if (existsSync(paths.model))
|
|
77
|
+
continue;
|
|
78
|
+
models.push({ service: parsed.id, path: repoPath(req.docsDir, paths.model), text: emptyModel(parsed.id, req.featureId) });
|
|
79
|
+
}
|
|
80
|
+
return models;
|
|
81
|
+
}
|
|
82
|
+
/** The model a created service starts with: a header saying what the file is for, and an empty `model { }`. */
|
|
83
|
+
function emptyModel(svc, featureId) {
|
|
84
|
+
return [
|
|
85
|
+
`// ${svc}'s own C4 — what is inside the element the fleet map binds to this`,
|
|
86
|
+
`// directory. \`loam archive ${featureId}\` created it with the service, holding`,
|
|
87
|
+
`// only what that feature's delta drew inside it. It EXTENDS the map: it declares`,
|
|
88
|
+
`// no kinds and no partners, and draws the service's containers inside an`,
|
|
89
|
+
"// `extend <fqn> { … }` block, <fqn> being that element's fully-qualified id.",
|
|
90
|
+
`// SCHEMA.md, "Two shapes of a service model".`,
|
|
91
|
+
"model {",
|
|
92
|
+
"}",
|
|
93
|
+
"",
|
|
94
|
+
].join("\n");
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../../src/core/c4/service-model/created/models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI1D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAYvE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAyB;IAClE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,MAAM,oBAAoB,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACvF,yEAAyE;IACzE,oCAAoC;IACpC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAS,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,KAAK,MAAM,GAAG,IAAI,MAAM,mBAAmB,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvE,2EAA2E;QAC3E,mDAAmD;QACnD,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAAE,SAAS;QAC/E,MAAM,KAAK,GAAG,mBAAmB,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1D,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,SAAS;QACtC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC5H,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,+GAA+G;AAC/G,SAAS,UAAU,CAAC,GAAW,EAAE,SAAiB;IAChD,OAAO;QACL,MAAM,GAAG,oEAAoE;QAC7E,gCAAgC,SAAS,yCAAyC;QAClF,mFAAmF;QACnF,2EAA2E;QAC3E,+EAA+E;QAC/E,gDAAgD;QAChD,SAAS;QACT,GAAG;QACH,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC","sourcesContent":["/**\n * The model of every service a feature's archive CREATES — one the feature\n * carries `specs/<svc>/` for, the fleet does not enumerate, and the map the\n * merge leaves will draw — as the EMPTY extending model the archive writes\n * beside its first documents.\n *\n * Drawn by the merged map, because the model extends the element that stands\n * for the service there, and only a service the map draws has one: the living\n * map's elements plus the delta's TAGGED ones, which is exactly what the map\n * holds once the merge lands. A context element the delta quotes is merged\n * nowhere, and counting it gave a model to a service nothing would draw — two\n * `landscape.service-unmodelled` on the next `validate --all` (review,\n * 2026-10-22). A `specs/<svc>/` nothing draws is, more often than not, a typo\n * the gate already calls an unknown service; forced through with `--approve`,\n * writing a model there would fabricate a service directory out of it, which\n * the spec merge is careful never to do (it creates no empty living spec\n * either).\n *\n * ## Why the archive writes it\n *\n * It used to leave the file out and say so (`service.no-model`, an error the\n * next `validate --all` repeated), because writing a container model would have\n * been inventing one. An EMPTY extending model invents nothing: LikeC4 reads it\n * as the map's own box with nothing drawn inside, and SCHEMA.md calls an empty\n * file a legal extending model. What it changes is real. The new service's first\n * `validate --all` grades it instead of stopping at a missing file, and the\n * interior a delta draws inside the new service lands in the model — routed like\n * any extending model's — where until now it rode onto the map, because no model\n * existed to own it, and stayed there as interior the map is not supposed to\n * hold. A team that pre-placed an empty model got exactly this (measured on a\n * real fleet, 2026-10); now nobody has to know to. SCHEMA.md, \"Which document an\n * addition lands in\", records the decision.\n *\n * ## Why it is not beside the archive\n *\n * Two readers, and they must agree. `loam archive` writes these models; the\n * merge PREVIEW every feature-side gate grades against (`../../project/staged.ts`)\n * has to route the new service's interior the same way, or a feature flow\n * hopping to `<new-service-fqn>.<container>` resolves in the preview, passes the\n * gate, and lands in `architecture/usecases/` naming a container the map no\n * longer holds — the outcome the fleet-model list beside this\n * (`../fleet/extending.ts`) exists to prevent. That list could not host this\n * either: `../fleet/` reads the shape scan, which imports `../../project/`, so\n * the preview importing it would be a package cycle. The one part of `core/c4/`\n * this package imports as a value is `../../resolve/`, the binding join, which\n * imports neither the shape scan nor the project.\n *\n * ## Unfiled, always\n *\n * The path is `services/<svc>/`, the spelling the spec merges write a new\n * service's documents to. The archive never reads a subsystem off the map's\n * group nesting or off a delta's metadata — the tree and the map stay\n * independent — so a new service lands in a subsystem only when its directory is\n * already there, and then it is enumerated and not created here at all.\n */\nimport { existsSync } from \"node:fs\";\nimport type { Elem } from \"../../likec4.js\";\nimport { elementService } from \"../../resolve/service.js\";\nimport type { ExtendingModel } from \"../../splice/contract.js\";\nimport type { FleetContext } from \"../../../fleet-context.js\";\nimport type { DocsDir, FeatureDir } from \"../../../kernel/ids/dirs.js\";\nimport { parseServiceId } from \"../../../kernel/ids/service.js\";\nimport { repoPath } from \"../../../envelope/json.js\";\nimport { unfiledServicePaths } from \"../../../repo/paths.js\";\nimport { featureSpecServices } from \"../../../repo/repo.js\";\nimport { enumeratedServiceIds } from \"../../../repo/service-target.js\";\n\nexport interface CreatedModelsRequest {\n docsDir: DocsDir;\n featureDir: FeatureDir;\n /** The feature the header names as the model's origin. */\n featureId: string;\n /** The elements the map holds once the merge lands: the living map's, and the delta's tagged ones. */\n drawn: readonly Elem[];\n fleet?: FleetContext;\n}\n\nexport async function createdServiceModels(req: CreatedModelsRequest): Promise<ExtendingModel[]> {\n const enumerated = new Set<string>(await enumeratedServiceIds(req.docsDir, req.fleet));\n // Binding first, title as the fallback: the join every check resolves an\n // element to its directory through.\n const drawn = new Set<string>(req.drawn.map((e) => elementService(e)));\n const models: ExtendingModel[] = [];\n for (const raw of await featureSpecServices(req.featureDir, req.fleet)) {\n // An id the service grammar refuses never reaches a path; the gate refuses\n // the feature for it before an archive is planned.\n const parsed = parseServiceId(raw);\n if (!parsed.ok || enumerated.has(parsed.id) || !drawn.has(parsed.id)) continue;\n const paths = unfiledServicePaths(req.docsDir, parsed.id);\n if (existsSync(paths.model)) continue;\n models.push({ service: parsed.id, path: repoPath(req.docsDir, paths.model), text: emptyModel(parsed.id, req.featureId) });\n }\n return models;\n}\n\n/** The model a created service starts with: a header saying what the file is for, and an empty `model { }`. */\nfunction emptyModel(svc: string, featureId: string): string {\n return [\n `// ${svc}'s own C4 — what is inside the element the fleet map binds to this`,\n `// directory. \\`loam archive ${featureId}\\` created it with the service, holding`,\n `// only what that feature's delta drew inside it. It EXTENDS the map: it declares`,\n `// no kinds and no partners, and draws the service's containers inside an`,\n \"// `extend <fqn> { … }` block, <fqn> being that element's fully-qualified id.\",\n `// SCHEMA.md, \"Two shapes of a service model\".`,\n \"model {\",\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { architectureProjectDocuments } from "../project/architecture.js";
|
|
2
|
+
import { architectureDocuments } from "../project/documents.js";
|
|
3
|
+
/**
|
|
4
|
+
* The fleet map's project, plus one service model: the set an extending model
|
|
5
|
+
* is graded in.
|
|
6
|
+
*
|
|
7
|
+
* The model is appended rather than merged in through a walk, because it is
|
|
8
|
+
* named — not everything under `services/<tree>/` belongs in this project, and
|
|
9
|
+
* in particular a sibling use-case file does not: it is read separately (see
|
|
10
|
+
* below) so that a broken flow cannot blank the model that the whole service
|
|
11
|
+
* target is graded against.
|
|
12
|
+
*/
|
|
13
|
+
export async function modelProjectDocuments(docsDir, modelPath) {
|
|
14
|
+
const sets = await modelProjectSets(docsDir, [modelPath]);
|
|
15
|
+
// One set in, one set out — spelled as a flatMap rather than an index so the
|
|
16
|
+
// empty case is impossible rather than asserted away.
|
|
17
|
+
return sets.flatMap((set) => set.paths);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The same set for MANY models, with exactly ONE walk of `architecture/`
|
|
21
|
+
* between them.
|
|
22
|
+
*
|
|
23
|
+
* The fleet's prefetch stages one project per extending model, and asking the
|
|
24
|
+
* single-model form above per service would readdir the map's directory once
|
|
25
|
+
* per service — 56 walks of the same tree on the 56-service shape this axis was
|
|
26
|
+
* measured against, for one answer that cannot differ between them.
|
|
27
|
+
*/
|
|
28
|
+
export async function modelProjectSets(docsDir, models) {
|
|
29
|
+
const architecture = await architectureProjectDocuments(docsDir);
|
|
30
|
+
return models.map((model) => ({ model, paths: [...architecture, model] }));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The same set plus every OTHER `.likec4` under the service's own directory —
|
|
34
|
+
* the project a service's use cases are declared in.
|
|
35
|
+
*
|
|
36
|
+
* `architectureDocuments` is the walk in both cases (it is "every `.likec4`
|
|
37
|
+
* under a directory, sorted, minus a skip list", and the name is about where it
|
|
38
|
+
* first ran rather than about `architecture/`), skipping the model so the
|
|
39
|
+
* concatenation cannot list it twice: a document staged twice at one relative
|
|
40
|
+
* path is one file, but the second copy would overwrite the first and the
|
|
41
|
+
* ordering would decide which — a coin flip loam must not build on.
|
|
42
|
+
*/
|
|
43
|
+
export async function serviceFlowDocuments(docsDir, paths) {
|
|
44
|
+
const siblings = await architectureDocuments(paths.dir, [paths.model]);
|
|
45
|
+
return [...(await modelProjectDocuments(docsDir, paths.model)), ...siblings];
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=documents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documents.js","sourceRoot":"","sources":["../../../../src/core/c4/service-model/documents.ts"],"names":[],"mappings":"AA6BA,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAgB,EAAE,SAAiB;IAC7E,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1D,6EAA6E;IAC7E,sDAAsD;IACtD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAgB,EAChB,MAAyB;IAEzB,MAAM,YAAY,GAAG,MAAM,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACjE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,GAAG,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAgB,EAAE,KAAmB;IAC9E,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,MAAM,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC;AAC/E,CAAC","sourcesContent":["/**\n * Which documents a service model is parsed WITH.\n *\n * An extending model declares no element kinds and names the map's elements\n * directly (`extend marketplace.orderService { … }`, an edge to\n * `kafka.orderEvents`), so the set it parses in is not a directory — it is the\n * fleet map's project plus this one file. Measured at the 1.59.2 pin: staged\n * that way the model parses, its containers land under the landscape's element,\n * and every parse error is attributed to `services/<svc>/model.likec4` with a\n * line of its own — including a missing kind, which is ONE error on the model\n * rather than a cascade on the map.\n *\n * Two sets, because two questions are asked of a model. The first is what the\n * model itself says (`modelProjectDocuments`); the second adds every `.likec4`\n * sitting beside it, which is how a service's own use cases are read — a flow\n * file declares views over the model's containers and does not parse alone, the\n * same reason `../project/load.ts` exists at fleet altitude.\n *\n * A CONTRACT ON THE CALLER, since neither function stages anything itself:\n * both sets must be loaded with `base` = the DOCS ROOT, never `architecture/`\n * or the service directory. LikeC4 reports a view's `sourcePath` relative to\n * the project root, so mirroring from the docs root is what makes a view come\n * back spelled `services/<tree>/model.likec4` — the spelling `./load.ts`\n * filters the model's own views by, and the spelling a person reads in a\n * finding. Staged from anywhere else the filter matches nothing and every\n * service reports that it declares no views.\n */\nimport type { DocsDir } from \"../../kernel/ids/dirs.js\";\nimport type { ServicePaths } from \"../../repo/paths.js\";\nimport { architectureProjectDocuments } from \"../project/architecture.js\";\nimport { architectureDocuments } from \"../project/documents.js\";\n\n/**\n * The fleet map's project, plus one service model: the set an extending model\n * is graded in.\n *\n * The model is appended rather than merged in through a walk, because it is\n * named — not everything under `services/<tree>/` belongs in this project, and\n * in particular a sibling use-case file does not: it is read separately (see\n * below) so that a broken flow cannot blank the model that the whole service\n * target is graded against.\n */\nexport async function modelProjectDocuments(docsDir: DocsDir, modelPath: string): Promise<string[]> {\n const sets = await modelProjectSets(docsDir, [modelPath]);\n // One set in, one set out — spelled as a flatMap rather than an index so the\n // empty case is impossible rather than asserted away.\n return sets.flatMap((set) => set.paths);\n}\n\n/**\n * The same set for MANY models, with exactly ONE walk of `architecture/`\n * between them.\n *\n * The fleet's prefetch stages one project per extending model, and asking the\n * single-model form above per service would readdir the map's directory once\n * per service — 56 walks of the same tree on the 56-service shape this axis was\n * measured against, for one answer that cannot differ between them.\n */\nexport async function modelProjectSets(\n docsDir: DocsDir,\n models: readonly string[],\n): Promise<{ model: string; paths: string[] }[]> {\n const architecture = await architectureProjectDocuments(docsDir);\n return models.map((model) => ({ model, paths: [...architecture, model] }));\n}\n\n/**\n * The same set plus every OTHER `.likec4` under the service's own directory —\n * the project a service's use cases are declared in.\n *\n * `architectureDocuments` is the walk in both cases (it is \"every `.likec4`\n * under a directory, sorted, minus a skip list\", and the name is about where it\n * first ran rather than about `architecture/`), skipping the model so the\n * concatenation cannot list it twice: a document staged twice at one relative\n * path is one file, but the second copy would overwrite the first and the\n * ordering would decide which — a coin flip loam must not build on.\n */\nexport async function serviceFlowDocuments(docsDir: DocsDir, paths: ServicePaths): Promise<string[]> {\n const siblings = await architectureDocuments(paths.dir, [paths.model]);\n return [...(await modelProjectDocuments(docsDir, paths.model)), ...siblings];\n}\n"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every service whose `model.likec4` EXTENDS the fleet map, with its living
|
|
3
|
+
* source in hand — the list the landscape merge routes a nested addition
|
|
4
|
+
* through.
|
|
5
|
+
*
|
|
6
|
+
* ## Why it is here and not beside the archive
|
|
7
|
+
*
|
|
8
|
+
* It was `commands/archive/plan/model/extending.ts`'s, beside the proof that
|
|
9
|
+
* the merged model parses, and for one merge that was the right seam: reading
|
|
10
|
+
* the fleet and deciding to write belong to the command, `core/c4/splice/` is a
|
|
11
|
+
* pure text-to-text computation, and nothing else needed the list.
|
|
12
|
+
*
|
|
13
|
+
* Then the archive stopped being the only reader. `../../project/staged.ts`
|
|
14
|
+
* previews the map a feature's own merge would leave, and every feature-side
|
|
15
|
+
* gate rests on that preview — `usecase.flow-invalid` and
|
|
16
|
+
* `deployment.doc-invalid` both refuse on it, and `--approve` reaches neither.
|
|
17
|
+
* A preview computed without this list previews the WRONG map: it holds
|
|
18
|
+
* interior the archive routes into `services/<…>/model.likec4`, so a
|
|
19
|
+
* feature-local flow hopping to `<service-fqn>.<container>` resolved against it,
|
|
20
|
+
* passed the gate, and was copied verbatim into `architecture/usecases/`, where
|
|
21
|
+
* it resolves against nothing (verification 2026-09-04, review finding F8;
|
|
22
|
+
* measured: `loam archive --approve` at exit 0, then `loam validate --all` with
|
|
23
|
+
* one `landscape.invalid` and one `spine.landscape-invalid` per service).
|
|
24
|
+
*
|
|
25
|
+
* A reader in `commands/` cannot close that: `core/` may never import
|
|
26
|
+
* `commands/`. Nor could it live in `../../project/` beside the staging that
|
|
27
|
+
* needs it — the shape scan is `../shape.ts`, and `../` imports
|
|
28
|
+
* `../../project/`, so the edge would be a package cycle
|
|
29
|
+
* (`node scripts/package-graph.mjs` refuses it). So it sits one level BELOW the
|
|
30
|
+
* shape scan it calls, in a package that nothing in `core/c4/` imports back:
|
|
31
|
+
* `core/delta/`, `core/coherence/` and the archive all reach it, and the graph
|
|
32
|
+
* stays acyclic.
|
|
33
|
+
*
|
|
34
|
+
* ## The shape decision is not this file's
|
|
35
|
+
*
|
|
36
|
+
* `../shape.ts` owns it: a model declaring an element kind is STANDALONE, is
|
|
37
|
+
* parsed alone, and owns no share of the merge — the map draws its containers
|
|
38
|
+
* exactly as it did before the extending shape existed. A model that cannot be
|
|
39
|
+
* read is not in the list either, which is the same conservative arm the shape
|
|
40
|
+
* reader takes.
|
|
41
|
+
*/
|
|
42
|
+
import { readFile } from "node:fs/promises";
|
|
43
|
+
import { resolve } from "node:path";
|
|
44
|
+
import { inOrder } from "../../../kernel/concurrency.js";
|
|
45
|
+
import { repoPath } from "../../../envelope/json.js";
|
|
46
|
+
import { servicePathsAt } from "../../../repo/paths.js";
|
|
47
|
+
import { enumeratedServices } from "../../../repo/service-target.js";
|
|
48
|
+
import { readModelShapes } from "../shape.js";
|
|
49
|
+
/**
|
|
50
|
+
* The fleet's extending models, ordered by the enumeration.
|
|
51
|
+
*
|
|
52
|
+
* `fleet` is OPTIONAL for the reason `enumeratedServices` makes it optional:
|
|
53
|
+
* the callers are three, and only two of them run inside an invocation index.
|
|
54
|
+
* With one, the enumeration and the shape scan are memo hits and this costs one
|
|
55
|
+
* small read per extending model; without one, the same bulk scan runs directly
|
|
56
|
+
* (`readModelShapes`) and the answer is identical. What must never differ
|
|
57
|
+
* between the two is the LIST — a gate that routed differently depending on
|
|
58
|
+
* whether its caller happened to hold a read index would be a gate nobody could
|
|
59
|
+
* reproduce.
|
|
60
|
+
*/
|
|
61
|
+
export async function extendingModels(docsDir, fleet) {
|
|
62
|
+
const services = await enumeratedServices(docsDir, fleet);
|
|
63
|
+
if (services.length === 0)
|
|
64
|
+
return [];
|
|
65
|
+
const paths = services.map((entry) => servicePathsAt(entry.dir).model);
|
|
66
|
+
const shapes = fleet === undefined ? await readModelShapes(paths) : await fleet.modelShapes(paths);
|
|
67
|
+
const found = await inOrder(services, async (entry) => {
|
|
68
|
+
const path = servicePathsAt(entry.dir).model;
|
|
69
|
+
if (shapes.get(resolve(path)) !== "extending")
|
|
70
|
+
return null;
|
|
71
|
+
try {
|
|
72
|
+
return { service: entry.id, path: repoPath(docsDir, path), text: await readFile(path, "utf8") };
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Unreadable is not extending: the merge would be splicing into bytes it
|
|
76
|
+
// never saw, and the map's arm is the honest fallback.
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
return found.filter((model) => model !== null);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=extending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extending.js","sourceRoot":"","sources":["../../../../../src/core/c4/service-model/fleet/extending.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAIzD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAgB,EAAE,KAAoB;IAC1E,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACnG,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAkC,EAAE;QACpF,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QAC7C,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QAC3D,IAAI,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAClG,CAAC;QAAC,MAAM,CAAC;YACP,yEAAyE;YACzE,uDAAuD;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAA2B,EAAE,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;AAC1E,CAAC","sourcesContent":["/**\n * Every service whose `model.likec4` EXTENDS the fleet map, with its living\n * source in hand — the list the landscape merge routes a nested addition\n * through.\n *\n * ## Why it is here and not beside the archive\n *\n * It was `commands/archive/plan/model/extending.ts`'s, beside the proof that\n * the merged model parses, and for one merge that was the right seam: reading\n * the fleet and deciding to write belong to the command, `core/c4/splice/` is a\n * pure text-to-text computation, and nothing else needed the list.\n *\n * Then the archive stopped being the only reader. `../../project/staged.ts`\n * previews the map a feature's own merge would leave, and every feature-side\n * gate rests on that preview — `usecase.flow-invalid` and\n * `deployment.doc-invalid` both refuse on it, and `--approve` reaches neither.\n * A preview computed without this list previews the WRONG map: it holds\n * interior the archive routes into `services/<…>/model.likec4`, so a\n * feature-local flow hopping to `<service-fqn>.<container>` resolved against it,\n * passed the gate, and was copied verbatim into `architecture/usecases/`, where\n * it resolves against nothing (verification 2026-09-04, review finding F8;\n * measured: `loam archive --approve` at exit 0, then `loam validate --all` with\n * one `landscape.invalid` and one `spine.landscape-invalid` per service).\n *\n * A reader in `commands/` cannot close that: `core/` may never import\n * `commands/`. Nor could it live in `../../project/` beside the staging that\n * needs it — the shape scan is `../shape.ts`, and `../` imports\n * `../../project/`, so the edge would be a package cycle\n * (`node scripts/package-graph.mjs` refuses it). So it sits one level BELOW the\n * shape scan it calls, in a package that nothing in `core/c4/` imports back:\n * `core/delta/`, `core/coherence/` and the archive all reach it, and the graph\n * stays acyclic.\n *\n * ## The shape decision is not this file's\n *\n * `../shape.ts` owns it: a model declaring an element kind is STANDALONE, is\n * parsed alone, and owns no share of the merge — the map draws its containers\n * exactly as it did before the extending shape existed. A model that cannot be\n * read is not in the list either, which is the same conservative arm the shape\n * reader takes.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { inOrder } from \"../../../kernel/concurrency.js\";\nimport type { ExtendingModel } from \"../../splice/contract.js\";\nimport type { DocsDir } from \"../../../kernel/ids/dirs.js\";\nimport type { FleetContext } from \"../../../fleet-context.js\";\nimport { repoPath } from \"../../../envelope/json.js\";\nimport { servicePathsAt } from \"../../../repo/paths.js\";\nimport { enumeratedServices } from \"../../../repo/service-target.js\";\nimport { readModelShapes } from \"../shape.js\";\n\n/**\n * The fleet's extending models, ordered by the enumeration.\n *\n * `fleet` is OPTIONAL for the reason `enumeratedServices` makes it optional:\n * the callers are three, and only two of them run inside an invocation index.\n * With one, the enumeration and the shape scan are memo hits and this costs one\n * small read per extending model; without one, the same bulk scan runs directly\n * (`readModelShapes`) and the answer is identical. What must never differ\n * between the two is the LIST — a gate that routed differently depending on\n * whether its caller happened to hold a read index would be a gate nobody could\n * reproduce.\n */\nexport async function extendingModels(docsDir: DocsDir, fleet?: FleetContext): Promise<ExtendingModel[]> {\n const services = await enumeratedServices(docsDir, fleet);\n if (services.length === 0) return [];\n const paths = services.map((entry) => servicePathsAt(entry.dir).model);\n const shapes = fleet === undefined ? await readModelShapes(paths) : await fleet.modelShapes(paths);\n const found = await inOrder(services, async (entry): Promise<ExtendingModel | null> => {\n const path = servicePathsAt(entry.dir).model;\n if (shapes.get(resolve(path)) !== \"extending\") return null;\n try {\n return { service: entry.id, path: repoPath(docsDir, path), text: await readFile(path, \"utf8\") };\n } catch {\n // Unreadable is not extending: the merge would be splicing into bytes it\n // never saw, and the map's arm is the honest fallback.\n return null;\n }\n });\n return found.filter((model): model is ExtendingModel => model !== null);\n}\n"]}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a `model.likec4` is read — the entry point every reader of a service
|
|
3
|
+
* model goes through, whichever shape the file has.
|
|
4
|
+
*
|
|
5
|
+
* One function rather than a branch at each call site, because the branch is
|
|
6
|
+
* not local: a standalone model is a file, an extending model is a project, and
|
|
7
|
+
* the six readers that open `model.likec4` (the service target, the isolation
|
|
8
|
+
* scan, arch coverage, `loam show`, the adopt brief, the service's use cases)
|
|
9
|
+
* all want the same thing out of either — the errors, the service's own
|
|
10
|
+
* elements and relationships, and the views the file itself declares. Making
|
|
11
|
+
* each of them ask "which shape is this?" is how five of them would come to
|
|
12
|
+
* answer it differently.
|
|
13
|
+
*
|
|
14
|
+
* The FOUR arms below are the whole of the contract, and each exists because
|
|
15
|
+
* one of them is a state a fleet is actually in:
|
|
16
|
+
*
|
|
17
|
+
* - standalone: today's behaviour, byte for byte. The file is parsed alone.
|
|
18
|
+
* - the map does not parse: the model extends something unreadable, so it
|
|
19
|
+
* cannot be read at all. NOT an error against the model — the fleet already
|
|
20
|
+
* has `spine.landscape-invalid` for this, and a second finding here would
|
|
21
|
+
* blame every service for one broken document.
|
|
22
|
+
* - the project has errors: every one of them is this model's, including an
|
|
23
|
+
* error LikeC4 blames on the landscape. That is sound because the map was
|
|
24
|
+
* parsed alone first and came back clean — measured: a duplicate declaration
|
|
25
|
+
* is reported against BOTH files, so the map's copy of the error exists only
|
|
26
|
+
* because this model was added to the set.
|
|
27
|
+
* - clean: the model's own slice (`./slice.ts`), its own views, and the
|
|
28
|
+
* project's specification, in the shape a standalone model's `LoadedDoc`
|
|
29
|
+
* already had.
|
|
30
|
+
*
|
|
31
|
+
* Nothing here is memoised. `../prefetch/fleet.ts` is the request-scoped memo
|
|
32
|
+
* over all of it — one instance per command invocation, owned by
|
|
33
|
+
* `core/fleet-context.ts` — because a loader that caches is a loader a test
|
|
34
|
+
* cannot ask twice.
|
|
35
|
+
*/
|
|
36
|
+
import { basename, relative, resolve } from "node:path";
|
|
37
|
+
import { asLoadedDoc } from "../project/load.js";
|
|
38
|
+
import { loadProjectBatch } from "../project/batch.js";
|
|
39
|
+
import { modelProjectSets } from "./documents.js";
|
|
40
|
+
import { sliceForService } from "./slice.js";
|
|
41
|
+
/**
|
|
42
|
+
* `loadServiceModel` addressed by a service's paths — the two derivations that
|
|
43
|
+
* decide whether the slice and the views filter find anything at all, spelled
|
|
44
|
+
* here rather than at the caller.
|
|
45
|
+
*
|
|
46
|
+
* The SERVICE is the leaf directory name, which `ServiceEntry` defines as the
|
|
47
|
+
* canonical id at whatever depth the tree walk found the service; it is what an
|
|
48
|
+
* element's `metadata { service '…' }` binding names and what the element→
|
|
49
|
+
* service resolver answers, so a slice keyed on anything else is empty.
|
|
50
|
+
*
|
|
51
|
+
* The MODEL PATH is made docs-relative and `/`-separated, because that is how
|
|
52
|
+
* LikeC4 spells a view's `sourcePath` inside a project staged from the docs
|
|
53
|
+
* root — on Windows the native separator would miss every view, silently
|
|
54
|
+
* turning "this model declares no diagrams" into a fact about the operating
|
|
55
|
+
* system.
|
|
56
|
+
*/
|
|
57
|
+
export function serviceModelAt(sources) {
|
|
58
|
+
return loadServiceModel({
|
|
59
|
+
shape: sources.shape,
|
|
60
|
+
service: basename(sources.paths.dir),
|
|
61
|
+
modelPath: relative(sources.docsDir, sources.paths.model).split(/[\\/]/).join("/"),
|
|
62
|
+
known: sources.known,
|
|
63
|
+
architecture: sources.architecture,
|
|
64
|
+
standalone: sources.standalone,
|
|
65
|
+
project: sources.project,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* A `LoadedDoc` carrying nothing — the shape a model that could not be read
|
|
70
|
+
* answers with. A FUNCTION rather than a shared constant: the arrays reach
|
|
71
|
+
* every caller, and one that pushed a finding into a module-level literal would
|
|
72
|
+
* corrupt the answer for every other service in the run.
|
|
73
|
+
*/
|
|
74
|
+
function noModel() {
|
|
75
|
+
return { errors: [], elements: [], relationships: [] };
|
|
76
|
+
}
|
|
77
|
+
export async function loadServiceModel(req) {
|
|
78
|
+
if (req.shape === "standalone") {
|
|
79
|
+
// Before the map is asked for, deliberately: a standalone model is a file
|
|
80
|
+
// parsed alone, so a reader of one must not pay for the `architecture/`
|
|
81
|
+
// project — nor inherit its failures.
|
|
82
|
+
return { shape: req.shape, doc: await req.standalone(), project: null, unowned: [], mapUnreadable: false };
|
|
83
|
+
}
|
|
84
|
+
const architecture = await req.architecture();
|
|
85
|
+
if (architecture.errors.length > 0) {
|
|
86
|
+
return { shape: req.shape, doc: noModel(), project: null, unowned: [], mapUnreadable: true };
|
|
87
|
+
}
|
|
88
|
+
const project = await req.project();
|
|
89
|
+
if (project.errors.length > 0) {
|
|
90
|
+
// Every error, not the ones whose path is the model's. The map parsed alone
|
|
91
|
+
// and came back clean, so an error now blamed on the landscape exists only
|
|
92
|
+
// because this model joined the set — and dropping it would grade the model
|
|
93
|
+
// valid while the renderer, reading the same two documents together,
|
|
94
|
+
// refuses to draw anything.
|
|
95
|
+
return {
|
|
96
|
+
shape: req.shape,
|
|
97
|
+
doc: { errors: project.errors, elements: [], relationships: [] },
|
|
98
|
+
project: null,
|
|
99
|
+
unowned: [],
|
|
100
|
+
mapUnreadable: false,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const slice = sliceForService({
|
|
104
|
+
project,
|
|
105
|
+
architecture,
|
|
106
|
+
service: req.service,
|
|
107
|
+
known: req.known,
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
shape: req.shape,
|
|
111
|
+
doc: {
|
|
112
|
+
errors: [],
|
|
113
|
+
elements: slice.elements,
|
|
114
|
+
relationships: slice.relationships,
|
|
115
|
+
// The model file's OWN views, by the file each was written in. A service
|
|
116
|
+
// renders its own diagrams and the fleet's use cases are drawn over the
|
|
117
|
+
// same elements, so without the filter every service in the fleet would
|
|
118
|
+
// report every fleet-level view as one of its own.
|
|
119
|
+
views: (project.views ?? []).filter((view) => view.sourcePath === req.modelPath),
|
|
120
|
+
// The PROJECT's specification, deliberately: an extending model takes the
|
|
121
|
+
// map's kinds and tags, so "what this model can use" is the project's
|
|
122
|
+
// table, and a tags-only block of its own has already been merged into it.
|
|
123
|
+
...(project.specification === undefined ? {} : { specification: project.specification }),
|
|
124
|
+
},
|
|
125
|
+
project,
|
|
126
|
+
unowned: slice.unowned,
|
|
127
|
+
mapUnreadable: false,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Every extending model's per-service project, parsed in ONE workspace — the
|
|
132
|
+
* engine under `../prefetch/fleet.ts`'s `prefetch`.
|
|
133
|
+
*
|
|
134
|
+
* Keyed by the RESOLVED model path, which is the key that memo files
|
|
135
|
+
* per-service projects under; a second spelling would be a memo the prefetch
|
|
136
|
+
* fills and no reader ever hits.
|
|
137
|
+
*
|
|
138
|
+
* A batch-infrastructure failure answers with an EMPTY map rather than
|
|
139
|
+
* rejecting: the prefetch is an accelerator and nothing more, so a workspace
|
|
140
|
+
* that could not be created must cost the run its speed and never one finding
|
|
141
|
+
* (`FleetContext.prefetchLikeC4` has behaved this way since the batch loader
|
|
142
|
+
* landed, and the two must not differ — a run that degrades one way and not the
|
|
143
|
+
* other is a run whose report depends on the tmpdir).
|
|
144
|
+
*/
|
|
145
|
+
export async function batchServiceProjects(docsDir, models) {
|
|
146
|
+
const out = new Map();
|
|
147
|
+
if (models.length === 0)
|
|
148
|
+
return out;
|
|
149
|
+
const requests = (await modelProjectSets(docsDir, models)).map((set) => ({
|
|
150
|
+
key: resolve(set.model),
|
|
151
|
+
base: docsDir,
|
|
152
|
+
paths: set.paths,
|
|
153
|
+
}));
|
|
154
|
+
try {
|
|
155
|
+
for (const [key, doc] of await loadProjectBatch(requests))
|
|
156
|
+
out.set(key, asLoadedDoc(doc));
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Unreadable is not invalid: the caller seeds nothing and every reader
|
|
160
|
+
// falls back to its own per-project load.
|
|
161
|
+
return new Map();
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../../src/core/c4/service-model/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIxD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgF7C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAAC,OAA4B;IACzD,OAAO,gBAAgB,CAAC;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC;QACpC,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAClF,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,OAAO;IACd,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAwB;IAC7D,IAAI,GAAG,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;QAC/B,0EAA0E;QAC1E,wEAAwE;QACxE,sCAAsC;QACtC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,UAAU,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IAC7G,CAAC;IACD,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;IAC9C,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IAC/F,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,4EAA4E;QAC5E,2EAA2E;QAC3E,4EAA4E;QAC5E,qEAAqE;QACrE,4BAA4B;QAC5B,OAAO;YACL,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE;YAChE,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,EAAE;YACX,aAAa,EAAE,KAAK;SACrB,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,eAAe,CAAC;QAC5B,OAAO;QACP,YAAY;QACZ,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC,CAAC;IACH,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,EAAE;YACH,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,yEAAyE;YACzE,wEAAwE;YACxE,wEAAwE;YACxE,mDAAmD;YACnD,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,GAAG,CAAC,SAAS,CAAC;YAChF,0EAA0E;YAC1E,sEAAsE;YACtE,2EAA2E;YAC3E,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;SACzF;QACD,OAAO;QACP,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,aAAa,EAAE,KAAK;KACrB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB,EAChB,MAAyB;IAEzB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAqB,CAAC;IACzC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACpC,MAAM,QAAQ,GAAG,CAAC,MAAM,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACvE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;QACvB,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC,CAAC,CAAC;IACJ,IAAI,CAAC;QACH,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,gBAAgB,CAAC,QAAQ,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5F,CAAC;IAAC,MAAM,CAAC;QACP,uEAAuE;QACvE,0CAA0C;QAC1C,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["/**\n * How a `model.likec4` is read — the entry point every reader of a service\n * model goes through, whichever shape the file has.\n *\n * One function rather than a branch at each call site, because the branch is\n * not local: a standalone model is a file, an extending model is a project, and\n * the six readers that open `model.likec4` (the service target, the isolation\n * scan, arch coverage, `loam show`, the adopt brief, the service's use cases)\n * all want the same thing out of either — the errors, the service's own\n * elements and relationships, and the views the file itself declares. Making\n * each of them ask \"which shape is this?\" is how five of them would come to\n * answer it differently.\n *\n * The FOUR arms below are the whole of the contract, and each exists because\n * one of them is a state a fleet is actually in:\n *\n * - standalone: today's behaviour, byte for byte. The file is parsed alone.\n * - the map does not parse: the model extends something unreadable, so it\n * cannot be read at all. NOT an error against the model — the fleet already\n * has `spine.landscape-invalid` for this, and a second finding here would\n * blame every service for one broken document.\n * - the project has errors: every one of them is this model's, including an\n * error LikeC4 blames on the landscape. That is sound because the map was\n * parsed alone first and came back clean — measured: a duplicate declaration\n * is reported against BOTH files, so the map's copy of the error exists only\n * because this model was added to the set.\n * - clean: the model's own slice (`./slice.ts`), its own views, and the\n * project's specification, in the shape a standalone model's `LoadedDoc`\n * already had.\n *\n * Nothing here is memoised. `../prefetch/fleet.ts` is the request-scoped memo\n * over all of it — one instance per command invocation, owned by\n * `core/fleet-context.ts` — because a loader that caches is a loader a test\n * cannot ask twice.\n */\nimport { basename, relative, resolve } from \"node:path\";\nimport type { DocsDir } from \"../../kernel/ids/dirs.js\";\nimport type { ServicePaths } from \"../../repo/paths.js\";\nimport type { Elem, LoadedDoc } from \"../likec4.js\";\nimport { asLoadedDoc } from \"../project/load.js\";\nimport { loadProjectBatch } from \"../project/batch.js\";\nimport { modelProjectSets } from \"./documents.js\";\nimport type { ModelShape } from \"./shape.js\";\nimport { sliceForService } from \"./slice.js\";\n\nexport interface ServiceModel {\n shape: ModelShape;\n /**\n * Errors, the OWN elements and relationships, and the model file's own views\n * — what every model-dependent check reads, in the shape it read when a model\n * was always one self-contained file. For a standalone model it is exactly\n * what parsing that file returns.\n */\n doc: LoadedDoc;\n /**\n * Extending only: the whole per-service project, map and model together —\n * the scope a `Covers:` line and a use-case step resolve against, because\n * both may legitimately name an element the map declares. Null for a\n * standalone model, for a model that did not parse, and when the map itself\n * is unreadable.\n */\n project: LoadedDoc | null;\n /**\n * Extending only: the elements the model adds OUTSIDE the element that\n * resolves to it — `c4.element-unowned`, one finding each. Empty otherwise,\n * including for a standalone model, whose partner copies are a different\n * grade (`c4.declaration-diverged`) asking a different question.\n */\n unowned: Elem[];\n /**\n * The architecture project itself does not parse, so an extending model could\n * not be read at all. `doc` then carries no errors and no model, and the\n * finding is the fleet's `spine.landscape-invalid` rather than anything about\n * this service's file.\n */\n mapUnreadable: boolean;\n}\n\nexport interface ServiceModelRequest {\n shape: ModelShape;\n /** The `services/<…>/<id>` directory name — what the model's elements must resolve to. */\n service: string;\n /**\n * The model's path RELATIVE TO THE DOCS ROOT, `/`-separated: the spelling\n * LikeC4 gives a view's `sourcePath` inside a project staged from that root,\n * and therefore the only spelling the views filter below can join on.\n */\n modelPath: string;\n /** Every service directory that exists, for the element→service resolver. */\n known: ReadonlySet<string>;\n /**\n * Parse the architecture documents WITHOUT this model — both the gate on\n * whether an extending model can be read and the diff's other half.\n *\n * A THUNK, like the two below, and awaited only in the extending branch. It\n * arrived as a value and every caller therefore paid for the whole\n * `architecture/` project before the shape was even consulted: `loam show` and\n * the adopt brief over a fleet whose models all stand alone spun a LikeC4\n * workspace they never read a byte of, and a `loadProject` failure in it\n * propagated out of commands whose model read is one `readFile`. A standalone\n * model is parsed alone, so the map is not part of its answer at all.\n */\n architecture: () => Promise<LoadedDoc>;\n /** Parse the model file alone. Called for a standalone model and never otherwise. */\n standalone: () => Promise<LoadedDoc>;\n /** Parse the per-service project (map + model). Memoised and batched by the caller. */\n project: () => Promise<LoadedDoc>;\n}\n\n/**\n * The DOCS-REPO facts a request is derived from, for the caller that holds\n * paths rather than the derived spellings.\n */\nexport interface ServiceModelSources {\n docsDir: DocsDir;\n paths: ServicePaths;\n shape: ModelShape;\n known: ReadonlySet<string>;\n architecture: () => Promise<LoadedDoc>;\n standalone: () => Promise<LoadedDoc>;\n project: () => Promise<LoadedDoc>;\n}\n\n/**\n * `loadServiceModel` addressed by a service's paths — the two derivations that\n * decide whether the slice and the views filter find anything at all, spelled\n * here rather than at the caller.\n *\n * The SERVICE is the leaf directory name, which `ServiceEntry` defines as the\n * canonical id at whatever depth the tree walk found the service; it is what an\n * element's `metadata { service '…' }` binding names and what the element→\n * service resolver answers, so a slice keyed on anything else is empty.\n *\n * The MODEL PATH is made docs-relative and `/`-separated, because that is how\n * LikeC4 spells a view's `sourcePath` inside a project staged from the docs\n * root — on Windows the native separator would miss every view, silently\n * turning \"this model declares no diagrams\" into a fact about the operating\n * system.\n */\nexport function serviceModelAt(sources: ServiceModelSources): Promise<ServiceModel> {\n return loadServiceModel({\n shape: sources.shape,\n service: basename(sources.paths.dir),\n modelPath: relative(sources.docsDir, sources.paths.model).split(/[\\\\/]/).join(\"/\"),\n known: sources.known,\n architecture: sources.architecture,\n standalone: sources.standalone,\n project: sources.project,\n });\n}\n\n/**\n * A `LoadedDoc` carrying nothing — the shape a model that could not be read\n * answers with. A FUNCTION rather than a shared constant: the arrays reach\n * every caller, and one that pushed a finding into a module-level literal would\n * corrupt the answer for every other service in the run.\n */\nfunction noModel(): LoadedDoc {\n return { errors: [], elements: [], relationships: [] };\n}\n\nexport async function loadServiceModel(req: ServiceModelRequest): Promise<ServiceModel> {\n if (req.shape === \"standalone\") {\n // Before the map is asked for, deliberately: a standalone model is a file\n // parsed alone, so a reader of one must not pay for the `architecture/`\n // project — nor inherit its failures.\n return { shape: req.shape, doc: await req.standalone(), project: null, unowned: [], mapUnreadable: false };\n }\n const architecture = await req.architecture();\n if (architecture.errors.length > 0) {\n return { shape: req.shape, doc: noModel(), project: null, unowned: [], mapUnreadable: true };\n }\n const project = await req.project();\n if (project.errors.length > 0) {\n // Every error, not the ones whose path is the model's. The map parsed alone\n // and came back clean, so an error now blamed on the landscape exists only\n // because this model joined the set — and dropping it would grade the model\n // valid while the renderer, reading the same two documents together,\n // refuses to draw anything.\n return {\n shape: req.shape,\n doc: { errors: project.errors, elements: [], relationships: [] },\n project: null,\n unowned: [],\n mapUnreadable: false,\n };\n }\n const slice = sliceForService({\n project,\n architecture,\n service: req.service,\n known: req.known,\n });\n return {\n shape: req.shape,\n doc: {\n errors: [],\n elements: slice.elements,\n relationships: slice.relationships,\n // The model file's OWN views, by the file each was written in. A service\n // renders its own diagrams and the fleet's use cases are drawn over the\n // same elements, so without the filter every service in the fleet would\n // report every fleet-level view as one of its own.\n views: (project.views ?? []).filter((view) => view.sourcePath === req.modelPath),\n // The PROJECT's specification, deliberately: an extending model takes the\n // map's kinds and tags, so \"what this model can use\" is the project's\n // table, and a tags-only block of its own has already been merged into it.\n ...(project.specification === undefined ? {} : { specification: project.specification }),\n },\n project,\n unowned: slice.unowned,\n mapUnreadable: false,\n };\n}\n\n/**\n * Every extending model's per-service project, parsed in ONE workspace — the\n * engine under `../prefetch/fleet.ts`'s `prefetch`.\n *\n * Keyed by the RESOLVED model path, which is the key that memo files\n * per-service projects under; a second spelling would be a memo the prefetch\n * fills and no reader ever hits.\n *\n * A batch-infrastructure failure answers with an EMPTY map rather than\n * rejecting: the prefetch is an accelerator and nothing more, so a workspace\n * that could not be created must cost the run its speed and never one finding\n * (`FleetContext.prefetchLikeC4` has behaved this way since the batch loader\n * landed, and the two must not differ — a run that degrades one way and not the\n * other is a run whose report depends on the tmpdir).\n */\nexport async function batchServiceProjects(\n docsDir: DocsDir,\n models: readonly string[],\n): Promise<Map<string, LoadedDoc>> {\n const out = new Map<string, LoadedDoc>();\n if (models.length === 0) return out;\n const requests = (await modelProjectSets(docsDir, models)).map((set) => ({\n key: resolve(set.model),\n base: docsDir,\n paths: set.paths,\n }));\n try {\n for (const [key, doc] of await loadProjectBatch(requests)) out.set(key, asLoadedDoc(doc));\n } catch {\n // Unreadable is not invalid: the caller seeds nothing and every reader\n // falls back to its own per-project load.\n return new Map();\n }\n return out;\n}\n"]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `exclude` list `loam subsystem sync` WRITES back into the root
|
|
3
|
+
* `likec4.config.json` — the write half of the one file loam otherwise only
|
|
4
|
+
* reads. The read half, and the matcher that decides whether an entry hides a
|
|
5
|
+
* directory, are `../root-project/exclude.ts`: they moved down there when the
|
|
6
|
+
* project loader became a reader of the same list, and this module is the only
|
|
7
|
+
* thing left that computes new bytes for it.
|
|
8
|
+
*
|
|
9
|
+
* The ownership rule is stated once and holds for both halves: `exclude` is a
|
|
10
|
+
* glob list in a tool's own config, the team owns the file, and loam maintains
|
|
11
|
+
* exactly the `services/` entries that decide whether a model is renderable. An
|
|
12
|
+
* entry loam does not recognise is left exactly where the team put it.
|
|
13
|
+
*/
|
|
14
|
+
import { excludedDirectory, excludingEntry } from "../root-project/exclude.js";
|
|
15
|
+
/** The `services/` prefix every tree path is spelled under, in the config and on disk alike. */
|
|
16
|
+
const SERVICES = "services";
|
|
17
|
+
/**
|
|
18
|
+
* The `exclude` list `loam subsystem sync` writes: loam's own entries
|
|
19
|
+
* recomputed from the shapes on disk, everybody else's kept exactly as written
|
|
20
|
+
* and in that order.
|
|
21
|
+
*
|
|
22
|
+
* WHICH ENTRIES ARE LOAM'S is the careful half, and it is decided by two
|
|
23
|
+
* different questions rather than one.
|
|
24
|
+
*
|
|
25
|
+
* The first is AUTHORSHIP: the whole `services/` tree is loam's (it wrote that
|
|
26
|
+
* entry into every scaffold before this axis), and so is any entry naming a
|
|
27
|
+
* `services/<tree>` the enumeration actually found — those are the entries this
|
|
28
|
+
* function produced on an earlier sync, and one of them must disappear the
|
|
29
|
+
* moment that service's model becomes extending. This is why the enumeration is
|
|
30
|
+
* a parameter rather than something inferred from the entries themselves: an
|
|
31
|
+
* entry cannot say who wrote it, but the tree can say whether it names a service.
|
|
32
|
+
*
|
|
33
|
+
* The second is EFFECT, and it is the half that was missing. An entry only has
|
|
34
|
+
* to cover an ANCESTOR of a tree to hide it — `excludingEntry` says so, because
|
|
35
|
+
* that is how the renderer reads the list — so a root config saying
|
|
36
|
+
* `services/platform/**` hides `services/platform/identity-service` just as
|
|
37
|
+
* completely as `services/**` does, while naming a directory the enumeration
|
|
38
|
+
* never returns as a service. Left alone it warned `service.model-excluded`
|
|
39
|
+
* forever and `sync` answered `updated: false`: a repair loop that never closed,
|
|
40
|
+
* with the message naming the command that would not perform it. So an entry
|
|
41
|
+
* that covers a tree whose model EXTENDS the map is dropped as well — the
|
|
42
|
+
* standalone trees such an entry also covered get their own entries back through
|
|
43
|
+
* the append below.
|
|
44
|
+
*
|
|
45
|
+
* THE TWO QUESTIONS ARE ASKED THROUGH DIFFERENT FUNCTIONS, and that is the
|
|
46
|
+
* correction this round made (verification 2026-09-04, review C). AUTHORSHIP is
|
|
47
|
+
* about the directory an entry NAMES, so it goes through `excludedDirectory`,
|
|
48
|
+
* which answers null for an entry naming no plain directory at all (a starred
|
|
49
|
+
* middle segment, the `node_modules` glob). EFFECT is about what an entry HIDES,
|
|
50
|
+
* so it goes through `excludingEntry` — the same matcher the read side uses,
|
|
51
|
+
* whatever the entry's spelling. Asking effect through `excludedDirectory` too
|
|
52
|
+
* meant an entry with a star where the subsystem name goes was `kept`
|
|
53
|
+
* unconditionally: it hid an extending model forever while
|
|
54
|
+
* `service.model-excluded` named this command as the repair, which is the very
|
|
55
|
+
* loop the effect rule was added to close.
|
|
56
|
+
*
|
|
57
|
+
* Everything else survives untouched, INCLUDING a `services/legacy/**` for a
|
|
58
|
+
* directory that is not a service at all, and including a covering entry that
|
|
59
|
+
* hides only standalone trees: those are the team's own globs about their own
|
|
60
|
+
* tree, they hide nothing that needs to be visible, and a sync that ate one
|
|
61
|
+
* would be loam deleting a line it never wrote. Only the entries that make a
|
|
62
|
+
* renderable model unrenderable are taken.
|
|
63
|
+
*
|
|
64
|
+
* A standalone model MUST be excluded: it declares its own kinds, so inside the
|
|
65
|
+
* root project every one of them is a duplicate blamed on the fleet map as
|
|
66
|
+
* well, which blanks the whole project. An extending model must NOT be: the
|
|
67
|
+
* root project is the only place it parses at all.
|
|
68
|
+
*
|
|
69
|
+
* NOTHING IS APPENDED FOR A TREE THE SURVIVING LIST ALREADY COVERS. A second
|
|
70
|
+
* entry would be a line a person did not write appearing in a file they own,
|
|
71
|
+
* for a directory the renderer already skips — and SCHEMA.md promises exactly
|
|
72
|
+
* that ("a directory the list already covers in any of those spellings earns no
|
|
73
|
+
* second entry"). The risk it leaves is real and it is the recoverable one: if
|
|
74
|
+
* the team narrows their covering glob tomorrow, the standalone model becomes
|
|
75
|
+
* visible in the root project, `validate --all` says so as
|
|
76
|
+
* `service.model-unexcluded`, and the next sync writes the entry. A duplicate
|
|
77
|
+
* cannot be un-written by any command at all.
|
|
78
|
+
*
|
|
79
|
+
* The appended entries are sorted rather than kept in tree order because the
|
|
80
|
+
* file is a diff a person reads: a service adopted into the middle of a
|
|
81
|
+
* subsystem would otherwise move every line after it.
|
|
82
|
+
*/
|
|
83
|
+
export function standaloneExclude(exclude, trees) {
|
|
84
|
+
const enumerated = new Set(trees.enumerated.map(treeUnderServices));
|
|
85
|
+
const kept = exclude.filter((entry) => {
|
|
86
|
+
// EFFECT first, and through the matcher rather than through the directory
|
|
87
|
+
// the entry names: an entry that hides a model which only parses inside the
|
|
88
|
+
// root project has to go whatever its spelling, and the authorship half
|
|
89
|
+
// below cannot see half of those spellings.
|
|
90
|
+
if (trees.extending.some((tree) => excludingEntry([entry], tree) !== null))
|
|
91
|
+
return false;
|
|
92
|
+
const dir = servicesTreeOf(entry);
|
|
93
|
+
if (dir === null)
|
|
94
|
+
return true;
|
|
95
|
+
// The whole `services/` tree, however spelled: loam wrote that entry into
|
|
96
|
+
// every scaffold before the extending shape existed, and it is the one this
|
|
97
|
+
// rewrite exists to take back.
|
|
98
|
+
if (dir === "")
|
|
99
|
+
return false;
|
|
100
|
+
return !enumerated.has(dir);
|
|
101
|
+
});
|
|
102
|
+
const owed = [...new Set(trees.standalone.map(treeUnderServices))].sort();
|
|
103
|
+
return [...kept, ...owed.filter((tree) => excludingEntry(kept, tree) === null).map((tree) => `${SERVICES}/${tree}/**`)];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The service tree an entry names — the part under `services/` — or null when
|
|
107
|
+
* the entry is about something else entirely. `""` is the `services/` root
|
|
108
|
+
* itself.
|
|
109
|
+
*
|
|
110
|
+
* An entry that names no plain directory — a wildcard segment between two
|
|
111
|
+
* literal ones, or the leading doubled star of the `node_modules` glob —
|
|
112
|
+
* answers null: loam cannot say which trees such a line is about, so it is
|
|
113
|
+
* never loam's to rewrite, whatever it happens to cover.
|
|
114
|
+
*/
|
|
115
|
+
function servicesTreeOf(entry) {
|
|
116
|
+
const dir = excludedDirectory(entry);
|
|
117
|
+
if (dir === null)
|
|
118
|
+
return null;
|
|
119
|
+
if (dir === SERVICES)
|
|
120
|
+
return "";
|
|
121
|
+
return dir.startsWith(`${SERVICES}/`) ? dir.slice(SERVICES.length + 1) : null;
|
|
122
|
+
}
|
|
123
|
+
/** A tree path with the `services/` prefix stripped if the caller spelled it — `excludingEntry`'s normalisation, one level down. */
|
|
124
|
+
function treeUnderServices(tree) {
|
|
125
|
+
const spelled = tree.split(/[\\/]/).filter((s) => s.length > 0).join("/");
|
|
126
|
+
return spelled.startsWith(`${SERVICES}/`) ? spelled.slice(SERVICES.length + 1) : spelled;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../../../src/core/c4/service-model/renderer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE/E,gGAAgG;AAChG,MAAM,QAAQ,GAAG,UAAU,CAAC;AAe5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA0B,EAAE,KAAmB;IAC/E,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACpC,0EAA0E;QAC1E,4EAA4E;QAC5E,wEAAwE;QACxE,4CAA4C;QAC5C,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACzF,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAC9B,0EAA0E;QAC1E,4EAA4E;QAC5E,+BAA+B;QAC/B,IAAI,GAAG,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;QAC7B,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1E,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,QAAQ,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;AAC1H,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,oIAAoI;AACpI,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1E,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AAC3F,CAAC","sourcesContent":["/**\n * The `exclude` list `loam subsystem sync` WRITES back into the root\n * `likec4.config.json` — the write half of the one file loam otherwise only\n * reads. The read half, and the matcher that decides whether an entry hides a\n * directory, are `../root-project/exclude.ts`: they moved down there when the\n * project loader became a reader of the same list, and this module is the only\n * thing left that computes new bytes for it.\n *\n * The ownership rule is stated once and holds for both halves: `exclude` is a\n * glob list in a tool's own config, the team owns the file, and loam maintains\n * exactly the `services/` entries that decide whether a model is renderable. An\n * entry loam does not recognise is left exactly where the team put it.\n */\nimport { excludedDirectory, excludingEntry } from \"../root-project/exclude.js\";\n\n/** The `services/` prefix every tree path is spelled under, in the config and on disk alike. */\nconst SERVICES = \"services\";\n\n/** The service trees a rewrite is computed against: which stand alone, and which exist at all. */\nexport interface ExcludeTrees {\n /** Every service whose model declares its own kinds, and so must be excluded. */\n standalone: readonly string[];\n /**\n * Every service whose model EXTENDS the map, and so must NOT be excluded by\n * anything — the trees a covering entry is measured against below.\n */\n extending: readonly string[];\n /** Every service the enumeration found — the domain loam's own entries are drawn from. */\n enumerated: readonly string[];\n}\n\n/**\n * The `exclude` list `loam subsystem sync` writes: loam's own entries\n * recomputed from the shapes on disk, everybody else's kept exactly as written\n * and in that order.\n *\n * WHICH ENTRIES ARE LOAM'S is the careful half, and it is decided by two\n * different questions rather than one.\n *\n * The first is AUTHORSHIP: the whole `services/` tree is loam's (it wrote that\n * entry into every scaffold before this axis), and so is any entry naming a\n * `services/<tree>` the enumeration actually found — those are the entries this\n * function produced on an earlier sync, and one of them must disappear the\n * moment that service's model becomes extending. This is why the enumeration is\n * a parameter rather than something inferred from the entries themselves: an\n * entry cannot say who wrote it, but the tree can say whether it names a service.\n *\n * The second is EFFECT, and it is the half that was missing. An entry only has\n * to cover an ANCESTOR of a tree to hide it — `excludingEntry` says so, because\n * that is how the renderer reads the list — so a root config saying\n * `services/platform/**` hides `services/platform/identity-service` just as\n * completely as `services/**` does, while naming a directory the enumeration\n * never returns as a service. Left alone it warned `service.model-excluded`\n * forever and `sync` answered `updated: false`: a repair loop that never closed,\n * with the message naming the command that would not perform it. So an entry\n * that covers a tree whose model EXTENDS the map is dropped as well — the\n * standalone trees such an entry also covered get their own entries back through\n * the append below.\n *\n * THE TWO QUESTIONS ARE ASKED THROUGH DIFFERENT FUNCTIONS, and that is the\n * correction this round made (verification 2026-09-04, review C). AUTHORSHIP is\n * about the directory an entry NAMES, so it goes through `excludedDirectory`,\n * which answers null for an entry naming no plain directory at all (a starred\n * middle segment, the `node_modules` glob). EFFECT is about what an entry HIDES,\n * so it goes through `excludingEntry` — the same matcher the read side uses,\n * whatever the entry's spelling. Asking effect through `excludedDirectory` too\n * meant an entry with a star where the subsystem name goes was `kept`\n * unconditionally: it hid an extending model forever while\n * `service.model-excluded` named this command as the repair, which is the very\n * loop the effect rule was added to close.\n *\n * Everything else survives untouched, INCLUDING a `services/legacy/**` for a\n * directory that is not a service at all, and including a covering entry that\n * hides only standalone trees: those are the team's own globs about their own\n * tree, they hide nothing that needs to be visible, and a sync that ate one\n * would be loam deleting a line it never wrote. Only the entries that make a\n * renderable model unrenderable are taken.\n *\n * A standalone model MUST be excluded: it declares its own kinds, so inside the\n * root project every one of them is a duplicate blamed on the fleet map as\n * well, which blanks the whole project. An extending model must NOT be: the\n * root project is the only place it parses at all.\n *\n * NOTHING IS APPENDED FOR A TREE THE SURVIVING LIST ALREADY COVERS. A second\n * entry would be a line a person did not write appearing in a file they own,\n * for a directory the renderer already skips — and SCHEMA.md promises exactly\n * that (\"a directory the list already covers in any of those spellings earns no\n * second entry\"). The risk it leaves is real and it is the recoverable one: if\n * the team narrows their covering glob tomorrow, the standalone model becomes\n * visible in the root project, `validate --all` says so as\n * `service.model-unexcluded`, and the next sync writes the entry. A duplicate\n * cannot be un-written by any command at all.\n *\n * The appended entries are sorted rather than kept in tree order because the\n * file is a diff a person reads: a service adopted into the middle of a\n * subsystem would otherwise move every line after it.\n */\nexport function standaloneExclude(exclude: readonly string[], trees: ExcludeTrees): string[] {\n const enumerated = new Set(trees.enumerated.map(treeUnderServices));\n const kept = exclude.filter((entry) => {\n // EFFECT first, and through the matcher rather than through the directory\n // the entry names: an entry that hides a model which only parses inside the\n // root project has to go whatever its spelling, and the authorship half\n // below cannot see half of those spellings.\n if (trees.extending.some((tree) => excludingEntry([entry], tree) !== null)) return false;\n const dir = servicesTreeOf(entry);\n if (dir === null) return true;\n // The whole `services/` tree, however spelled: loam wrote that entry into\n // every scaffold before the extending shape existed, and it is the one this\n // rewrite exists to take back.\n if (dir === \"\") return false;\n return !enumerated.has(dir);\n });\n const owed = [...new Set(trees.standalone.map(treeUnderServices))].sort();\n return [...kept, ...owed.filter((tree) => excludingEntry(kept, tree) === null).map((tree) => `${SERVICES}/${tree}/**`)];\n}\n\n/**\n * The service tree an entry names — the part under `services/` — or null when\n * the entry is about something else entirely. `\"\"` is the `services/` root\n * itself.\n *\n * An entry that names no plain directory — a wildcard segment between two\n * literal ones, or the leading doubled star of the `node_modules` glob —\n * answers null: loam cannot say which trees such a line is about, so it is\n * never loam's to rewrite, whatever it happens to cover.\n */\nfunction servicesTreeOf(entry: string): string | null {\n const dir = excludedDirectory(entry);\n if (dir === null) return null;\n if (dir === SERVICES) return \"\";\n return dir.startsWith(`${SERVICES}/`) ? dir.slice(SERVICES.length + 1) : null;\n}\n\n/** A tree path with the `services/` prefix stripped if the caller spelled it — `excludingEntry`'s normalisation, one level down. */\nfunction treeUnderServices(tree: string): string {\n const spelled = tree.split(/[\\\\/]/).filter((s) => s.length > 0).join(\"/\");\n return spelled.startsWith(`${SERVICES}/`) ? spelled.slice(SERVICES.length + 1) : spelled;\n}\n"]}
|