@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,140 @@
|
|
|
1
|
+
import { withFeatureCapabilities } from "../../capabilities/delta/overlay.js";
|
|
2
|
+
import { capabilityRequirementIndex, gradableCapabilityIds } from "../../capabilities/findings.js";
|
|
3
|
+
import { resolveCapabilityTags, resolveRequirementTags } from "../../capabilities/usecase-join.js";
|
|
4
|
+
import { compareIds } from "../../repo/entries.js";
|
|
5
|
+
import { featureFlowIssues } from "../grade/feature.js";
|
|
6
|
+
import { readFeatureFlows } from "./overlay.js";
|
|
7
|
+
/**
|
|
8
|
+
* The promises this feature's own flows keep, read over the post-merge map.
|
|
9
|
+
*
|
|
10
|
+
* A feature with no flow is `read` with nothing kept, which is the ordinary
|
|
11
|
+
* answer and costs one walk over a directory that is not there. The scan is
|
|
12
|
+
* read by the caller (`flowCoverage`), which grades the same flows too — one
|
|
13
|
+
* staged parse for both questions, because it is a Langium workspace spin.
|
|
14
|
+
*/
|
|
15
|
+
export function featureFlowPromises(scan, req) {
|
|
16
|
+
if (scan.kind === "unreadable")
|
|
17
|
+
return { kind: "unreadable", errors: scan.errors };
|
|
18
|
+
// The ladder, and it is `ungraded` rather than an empty answer. Once the
|
|
19
|
+
// feature's own capability deltas are unioned in, `declared` is null for
|
|
20
|
+
// exactly one reason — `architecture/capabilities.yaml` exists and does not
|
|
21
|
+
// read as a vocabulary — so no `#cap-` tag can resolve and no claim can be
|
|
22
|
+
// made either way. Returning "keeps nothing" here is what let
|
|
23
|
+
// `capability.uncovered` convict a flow that does resolve, over a file the
|
|
24
|
+
// feature gate reports nothing else about.
|
|
25
|
+
if (req.declared === null) {
|
|
26
|
+
return {
|
|
27
|
+
kind: "ungraded",
|
|
28
|
+
why: "architecture/capabilities.yaml does not read as a capability vocabulary (`loam validate --all` reports it as capability.invalid)",
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// A real, empty answer: loam read the flows and none of them claims anything.
|
|
32
|
+
if (scan.views.length === 0)
|
|
33
|
+
return { kind: "read", kept: [] };
|
|
34
|
+
const byPromise = new Map();
|
|
35
|
+
for (const view of scan.views) {
|
|
36
|
+
const scope = resolveCapabilityTags(view.tags, req.declared).flatMap((claim) => claim.kind === "resolved" ? [claim.id] : []);
|
|
37
|
+
for (const claim of resolveRequirementTags(view.tags, scope, req.requirementsOf)) {
|
|
38
|
+
if (claim.kind !== "resolved")
|
|
39
|
+
continue;
|
|
40
|
+
// Keyed on the pair, never on a joined string: see the header. The Map is
|
|
41
|
+
// only here to collapse two views keeping one promise into one row.
|
|
42
|
+
const key = JSON.stringify([claim.capability, claim.id]);
|
|
43
|
+
const found = byPromise.get(key);
|
|
44
|
+
if (found === undefined) {
|
|
45
|
+
byPromise.set(key, {
|
|
46
|
+
promise: { capability: claim.capability, requirement: claim.id, flows: [] },
|
|
47
|
+
flows: new Set([view.id]),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
found.flows.add(view.id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Sorted, and the view ids inside each row sorted too: nothing in loam has
|
|
56
|
+
// measured that LikeC4 preserves view declaration order, so a message built
|
|
57
|
+
// from it would reorder under a dependency bump.
|
|
58
|
+
const kept = [...byPromise.values()]
|
|
59
|
+
.map(({ promise, flows }) => ({ ...promise, flows: [...flows].sort(compareIds) }))
|
|
60
|
+
.sort((a, b) => compareIds(a.capability, b.capability) || compareIds(a.requirement, b.requirement));
|
|
61
|
+
return { kind: "read", kept };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* What this feature's own flows keep, resolved against the vocabulary and the
|
|
65
|
+
* requirement ids its own merge would leave behind.
|
|
66
|
+
*
|
|
67
|
+
* THE WIDENING IS THE POINT, and it is `capabilities/delta/overlay.ts`'s
|
|
68
|
+
* judgement applied to the other carrier: an analyst adds `NOTIFY-ONCE` to a
|
|
69
|
+
* capability delta and an architect answers it with a flow in the same change,
|
|
70
|
+
* so a `#req-` tag resolved against the LIVING tree alone names a promise that
|
|
71
|
+
* does not exist yet — and the same archive that would land the flow lands the
|
|
72
|
+
* promise it points at.
|
|
73
|
+
*
|
|
74
|
+
* `requirementsOf` KNOWS ONLY THE CAPABILITIES THIS FEATURE HAS A DELTA FOR, and
|
|
75
|
+
* within those it carries living ∪ ADDED ∪ MODIFIED ids. The narrowing changes
|
|
76
|
+
* no answer, for a reason stronger than "it is probably fine":
|
|
77
|
+
* `uncoveredIssues` grades `r.kind === "ADDED"` and nothing else, and every
|
|
78
|
+
* ADDED requirement it grades lives in one of these documents by construction —
|
|
79
|
+
* so no id outside this map can reach a verdict. The LIVING half is in there
|
|
80
|
+
* because a widening of the graded set must not silently need a second edit
|
|
81
|
+
* here; today it decides nothing. A flow keeping a promise of a capability this
|
|
82
|
+
* feature does NOT touch resolves to `undocumented` and counts for nothing,
|
|
83
|
+
* which is correct: the fleet-scope `capability.requirement-unrealized` grades
|
|
84
|
+
* that join over the whole corpus, and answering it here from a partial index is
|
|
85
|
+
* how two surfaces start disagreeing.
|
|
86
|
+
*
|
|
87
|
+
* `declared` IS NOT NARROWED, and that asymmetry is load-bearing. It is what
|
|
88
|
+
* `resolveCapabilityTags` compares a `#cap-` slug against, and a slug is not
|
|
89
|
+
* injective — `payments/refunds` and `payments-refunds` flatten to one. Handing
|
|
90
|
+
* it a short list would resolve a tag that is genuinely ambiguous fleet-wide and
|
|
91
|
+
* attribute a whole flow to the wrong capability, silently. So the vocabulary is
|
|
92
|
+
* the fleet's whole one, read once by the caller.
|
|
93
|
+
*
|
|
94
|
+
* AND THE SAME FLOWS ARE GRADED, against everything as the merge would leave it
|
|
95
|
+
* (`../grade/feature.ts`): the hops against the staged post-merge map, and the
|
|
96
|
+
* tags against the whole requirement corpus — not the narrowed index above,
|
|
97
|
+
* because a `#req-` tag naming a capability this feature does not touch is
|
|
98
|
+
* exactly as broken after the archive as one naming a capability it does.
|
|
99
|
+
* There REMOVED does subtract: a tag naming a promise this feature retires
|
|
100
|
+
* resolves to nothing the moment the archive lands.
|
|
101
|
+
*/
|
|
102
|
+
export async function flowCoverage(req) {
|
|
103
|
+
const vocab = withFeatureCapabilities(req.vocabulary, req.capabilities.map((doc) => doc.id));
|
|
104
|
+
const byCapability = new Map();
|
|
105
|
+
for (const doc of req.capabilities) {
|
|
106
|
+
const ids = new Set();
|
|
107
|
+
// REMOVED is excluded on both sides — a promise on its way out keeps nothing.
|
|
108
|
+
for (const r of doc.living)
|
|
109
|
+
if (r.kind !== "REMOVED" && r.id !== undefined)
|
|
110
|
+
ids.add(r.id);
|
|
111
|
+
for (const r of doc.reqs)
|
|
112
|
+
if ((r.kind === "ADDED" || r.kind === "MODIFIED") && r.id !== undefined)
|
|
113
|
+
ids.add(r.id);
|
|
114
|
+
byCapability.set(doc.id, ids);
|
|
115
|
+
}
|
|
116
|
+
const scan = await readFeatureFlows({
|
|
117
|
+
docsDir: req.docsDir,
|
|
118
|
+
featureDir: req.featureDir,
|
|
119
|
+
featureId: req.featureId,
|
|
120
|
+
known: req.known,
|
|
121
|
+
...(req.load === undefined ? {} : { load: req.load }),
|
|
122
|
+
...(req.models === undefined ? {} : { models: req.models }),
|
|
123
|
+
});
|
|
124
|
+
const declared = gradableCapabilityIds(vocab);
|
|
125
|
+
const promises = featureFlowPromises(scan, { declared, requirementsOf: (capability) => byCapability.get(capability) });
|
|
126
|
+
if (scan.kind === "unreadable" || scan.views.length === 0)
|
|
127
|
+
return { promises, issues: [] };
|
|
128
|
+
const after = new Map((await capabilityRequirementIndex(req.vocabulary, req.read)).byCapability);
|
|
129
|
+
for (const doc of req.capabilities) {
|
|
130
|
+
const retired = new Set(doc.reqs
|
|
131
|
+
.filter((r) => r.kind === "REMOVED")
|
|
132
|
+
.flatMap((r) => (r.id !== undefined ? [r.id] : doc.living.filter((l) => l.name === r.name).flatMap((l) => (l.id === undefined ? [] : [l.id])))));
|
|
133
|
+
after.set(doc.id, new Set([...(byCapability.get(doc.id) ?? [])].filter((id) => !retired.has(id))));
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
promises,
|
|
137
|
+
issues: featureFlowIssues({ docsDir: req.docsDir, scan, capabilities: declared, requirementsOf: (capability) => after.get(capability) }),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=claims.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claims.js","sourceRoot":"","sources":["../../../../src/core/usecases/delta/claims.ts"],"names":[],"mappings":"AAyCA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAE9E,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACnG,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAEnG,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAiDhD;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAiB,EAAE,GAAwB;IAC7E,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACnF,yEAAyE;IACzE,yEAAyE;IACzE,4EAA4E;IAC5E,2EAA2E;IAC3E,8DAA8D;IAC9D,2EAA2E;IAC3E,2CAA2C;IAC3C,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,kIAAkI;SACxI,CAAC;IACJ,CAAC;IACD,8EAA8E;IAC9E,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IAE/D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwD,CAAC;IAClF,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAC7E,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAC5C,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YACjF,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;gBAAE,SAAS;YACxC,0EAA0E;YAC1E,oEAAoE;YACpE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YACzD,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE;oBACjB,OAAO,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;oBAC3E,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;iBAC1B,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IACD,2EAA2E;IAC3E,4EAA4E;IAC5E,iDAAiD;IACjD,MAAM,IAAI,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;SACjC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;SACjF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACtG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAChC,CAAC;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAwB;IACzD,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7F,MAAM,YAAY,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC5D,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;QAC9B,8EAA8E;QAC9E,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM;YAAE,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;gBAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1F,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI;YAAE,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;gBAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjH,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC;QAClC,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC;QACrD,GAAG,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;KAC5D,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACvH,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC3F,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,0BAA0B,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACjG,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,IAAI,GAAG,CACrB,GAAG,CAAC,IAAI;aACL,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC;aACnC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAClJ,CAAC;QACF,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrG,CAAC;IACD,OAAO;QACL,QAAQ;QACR,MAAM,EAAE,iBAAiB,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;KACzI,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Which of this feature's own promises its own flows keep.\n *\n * A cross-service criterion — \"I enter a login and a password and I am in\" —\n * belongs to no single service's spec, because each service promises only its\n * own part. A `dynamic view` can carry it, because it IS the hop sequence, and\n * that is the whole reason `#req-` exists. Until `./flows.ts` gave a feature a\n * slot for one, this answer could only ever be empty inside a feature window:\n * the flow was a fleet document, so a tag naming a requirement the same change\n * was adding named something that was not living yet.\n *\n * WHAT THIS FEEDS. `capability.uncovered` — the archive gate that refuses a\n * promise nothing keeps. Its message used to end by telling authors to archive\n * with `--approve` and tag the flow AFTERWARDS, which was honest advice about a\n * hole rather than a workflow anybody wanted: it lands the promise first, kept\n * by nothing, and relies on somebody coming back.\n *\n * THE RULE IS `../capability.ts`'s AND MUST STAY SO. Only a RESOLVED claim\n * counts, and both halves must resolve — the `#cap-` tag to exactly one declared\n * capability, the `#req-` tag to exactly one of its requirements. A broken tag\n * of either kind is already an error (`usecase.capability-unresolved`,\n * `usecase.requirement-unresolved`) and must never also mark a promise kept: a\n * typo that silenced the gate would turn a mistake into a green archive. The two\n * resolvers are called directly rather than through\n * `useCaseRequirementClaims` for one reason, and it is not a difference of\n * opinion about the rule — that function flattens its answer to a `<cap>#<id>`\n * string, and `capabilities/delta/uncovered.ts` keys this same join on NUL\n * precisely because a capability id has no grammar forbidding `#`. Handing it a\n * key it has written down a reason not to use would be the wrong kind of reuse.\n *\n * THE LADDER TRAVELS. `declared === null` — an absent or unreadable\n * `architecture/capabilities.yaml` — is an empty answer, not a suspended one, and\n * the caller is already suppressing the whole family behind it. An `unreadable`\n * overlay is different and must NOT be flattened to \"keeps nothing\": loam did not\n * look, which is never the same answer as \"there is nothing there\", and a gate\n * that refused on it would blame the author for a map it could not read.\n */\nimport type { LoadedDoc } from \"../../c4/likec4.js\";\nimport type { ExtendingModel } from \"../../c4/splice/contract.js\";\nimport type { CapabilityVocabulary } from \"../../capabilities/capabilities.js\";\nimport type { Requirement } from \"../../document/spec.js\";\nimport { withFeatureCapabilities } from \"../../capabilities/delta/overlay.js\";\nimport type { CapabilityDeltaDoc } from \"../../capabilities/delta/uncovered.js\";\nimport { capabilityRequirementIndex, gradableCapabilityIds } from \"../../capabilities/findings.js\";\nimport { resolveCapabilityTags, resolveRequirementTags } from \"../../capabilities/usecase-join.js\";\nimport type { DocsDir, FeatureDir } from \"../../kernel/ids/dirs.js\";\nimport { compareIds } from \"../../repo/entries.js\";\nimport type { Issue } from \"../../vocabulary/issue.js\";\nimport type { UseCaseScan } from \"../fleet.js\";\nimport { featureFlowIssues } from \"../grade/feature.js\";\nimport { readFeatureFlows } from \"./overlay.js\";\n\n/** One promise this feature's flows keep, with the flows that keep it. */\nexport interface FlowPromise {\n /** The capability the keeping view's `#cap-` tag resolved to. */\n capability: string;\n /** The `Requirement-ID` its `#req-` tag resolved to, inside that capability. */\n requirement: string;\n /** The view ids keeping it, deduplicated and sorted — message text, never identity. */\n flows: readonly string[];\n}\n\n/**\n * What the feature's flows keep, or one of the two honest refusals to say.\n *\n * THREE ARMS, because the two failures are not the same failure and a caller\n * that merged them would say the wrong thing. `unreadable` is loam unable to\n * READ the flows — a parse error, a hop naming an element the merge does not\n * land — and it earns `usecase.flow-invalid` and a refusal. `ungraded` is loam\n * able to read them and unable to RESOLVE their tags, because the capability\n * vocabulary this feature's merge would leave behind does not parse; the flows\n * are fine, the file they point into is not, and refusing over the flows would\n * name the wrong document.\n *\n * `read` with an empty `kept` is the ordinary answer and a real one: loam\n * looked, and no flow of this feature keeps a promise it adds.\n */\nexport type FlowPromises =\n | { kind: \"read\"; kept: readonly FlowPromise[] }\n | { kind: \"ungraded\"; why: string }\n | { kind: \"unreadable\"; errors: string[] };\n\n/** Everything the join needs beside the flows themselves. */\nexport interface FlowPromisesRequest {\n /**\n * The capability ids to resolve `#cap-` against — the LIVING vocabulary\n * widened with the ids this feature's own capability deltas introduce, which\n * is the same both-corpora rule `Realizes:` follows\n * (`core/capabilities/delta/overlay.ts`). `null` suspends the axis.\n */\n declared: readonly string[] | null;\n /**\n * The requirement ids per capability, widened the same way\n * (`withFeatureRequirements`). `undefined` for a capability with no document\n * at all is a different answer from an empty set, and both are real here.\n */\n requirementsOf: (capability: string) => ReadonlySet<string> | undefined;\n}\n\n/**\n * The promises this feature's own flows keep, read over the post-merge map.\n *\n * A feature with no flow is `read` with nothing kept, which is the ordinary\n * answer and costs one walk over a directory that is not there. The scan is\n * read by the caller (`flowCoverage`), which grades the same flows too — one\n * staged parse for both questions, because it is a Langium workspace spin.\n */\nexport function featureFlowPromises(scan: UseCaseScan, req: FlowPromisesRequest): FlowPromises {\n if (scan.kind === \"unreadable\") return { kind: \"unreadable\", errors: scan.errors };\n // The ladder, and it is `ungraded` rather than an empty answer. Once the\n // feature's own capability deltas are unioned in, `declared` is null for\n // exactly one reason — `architecture/capabilities.yaml` exists and does not\n // read as a vocabulary — so no `#cap-` tag can resolve and no claim can be\n // made either way. Returning \"keeps nothing\" here is what let\n // `capability.uncovered` convict a flow that does resolve, over a file the\n // feature gate reports nothing else about.\n if (req.declared === null) {\n return {\n kind: \"ungraded\",\n why: \"architecture/capabilities.yaml does not read as a capability vocabulary (`loam validate --all` reports it as capability.invalid)\",\n };\n }\n // A real, empty answer: loam read the flows and none of them claims anything.\n if (scan.views.length === 0) return { kind: \"read\", kept: [] };\n\n const byPromise = new Map<string, { promise: FlowPromise; flows: Set<string> }>();\n for (const view of scan.views) {\n const scope = resolveCapabilityTags(view.tags, req.declared).flatMap((claim) =>\n claim.kind === \"resolved\" ? [claim.id] : [],\n );\n for (const claim of resolveRequirementTags(view.tags, scope, req.requirementsOf)) {\n if (claim.kind !== \"resolved\") continue;\n // Keyed on the pair, never on a joined string: see the header. The Map is\n // only here to collapse two views keeping one promise into one row.\n const key = JSON.stringify([claim.capability, claim.id]);\n const found = byPromise.get(key);\n if (found === undefined) {\n byPromise.set(key, {\n promise: { capability: claim.capability, requirement: claim.id, flows: [] },\n flows: new Set([view.id]),\n });\n } else {\n found.flows.add(view.id);\n }\n }\n }\n // Sorted, and the view ids inside each row sorted too: nothing in loam has\n // measured that LikeC4 preserves view declaration order, so a message built\n // from it would reorder under a dependency bump.\n const kept = [...byPromise.values()]\n .map(({ promise, flows }) => ({ ...promise, flows: [...flows].sort(compareIds) }))\n .sort((a, b) => compareIds(a.capability, b.capability) || compareIds(a.requirement, b.requirement));\n return { kind: \"read\", kept };\n}\n\n/** Everything the coverage join needs, and nothing it would have to read twice. */\nexport interface FlowCoverageRequest {\n docsDir: DocsDir;\n featureDir: FeatureDir;\n featureId: string;\n /**\n * The feature's capability deltas, ALREADY PARSED by the caller's walk. They\n * arrive rather than being read because the one caller has just produced them,\n * and re-reading a document to answer a question about it is how two answers\n * about one file appear.\n */\n capabilities: readonly CapabilityDeltaDoc[];\n /** The LIVING capability vocabulary, read by the caller through its own index. */\n vocabulary: CapabilityVocabulary;\n /** The enumerated fleet, for `readFeatureFlows`' resolver and for its reason. */\n known: ReadonlySet<string>;\n /** The caller's memoised LikeC4 read; see `./overlay.ts`. */\n load?: (path: string) => Promise<LoadedDoc>;\n /**\n * How a LIVING capability document's requirements are read — the caller's\n * memo where it has one. Asked only for the grade below, and only once a\n * feature really brings a flow: a `#req-` tag may name ANY capability, so\n * the post-merge index it is resolved in is the whole corpus.\n */\n read: (path: string) => Promise<Requirement[]>;\n /**\n * The fleet's extending models for the merge preview, as a thunk the overlay\n * calls only when this feature really brings a flow; see `./overlay.ts` for\n * why the preview is wrong without them and why it arrives as a function.\n */\n models?: () => Promise<readonly ExtendingModel[]>;\n}\n\n/**\n * What this feature's own flows keep, resolved against the vocabulary and the\n * requirement ids its own merge would leave behind.\n *\n * THE WIDENING IS THE POINT, and it is `capabilities/delta/overlay.ts`'s\n * judgement applied to the other carrier: an analyst adds `NOTIFY-ONCE` to a\n * capability delta and an architect answers it with a flow in the same change,\n * so a `#req-` tag resolved against the LIVING tree alone names a promise that\n * does not exist yet — and the same archive that would land the flow lands the\n * promise it points at.\n *\n * `requirementsOf` KNOWS ONLY THE CAPABILITIES THIS FEATURE HAS A DELTA FOR, and\n * within those it carries living ∪ ADDED ∪ MODIFIED ids. The narrowing changes\n * no answer, for a reason stronger than \"it is probably fine\":\n * `uncoveredIssues` grades `r.kind === \"ADDED\"` and nothing else, and every\n * ADDED requirement it grades lives in one of these documents by construction —\n * so no id outside this map can reach a verdict. The LIVING half is in there\n * because a widening of the graded set must not silently need a second edit\n * here; today it decides nothing. A flow keeping a promise of a capability this\n * feature does NOT touch resolves to `undocumented` and counts for nothing,\n * which is correct: the fleet-scope `capability.requirement-unrealized` grades\n * that join over the whole corpus, and answering it here from a partial index is\n * how two surfaces start disagreeing.\n *\n * `declared` IS NOT NARROWED, and that asymmetry is load-bearing. It is what\n * `resolveCapabilityTags` compares a `#cap-` slug against, and a slug is not\n * injective — `payments/refunds` and `payments-refunds` flatten to one. Handing\n * it a short list would resolve a tag that is genuinely ambiguous fleet-wide and\n * attribute a whole flow to the wrong capability, silently. So the vocabulary is\n * the fleet's whole one, read once by the caller.\n *\n * AND THE SAME FLOWS ARE GRADED, against everything as the merge would leave it\n * (`../grade/feature.ts`): the hops against the staged post-merge map, and the\n * tags against the whole requirement corpus — not the narrowed index above,\n * because a `#req-` tag naming a capability this feature does not touch is\n * exactly as broken after the archive as one naming a capability it does.\n * There REMOVED does subtract: a tag naming a promise this feature retires\n * resolves to nothing the moment the archive lands.\n */\nexport async function flowCoverage(req: FlowCoverageRequest): Promise<{ promises: FlowPromises; issues: Issue[] }> {\n const vocab = withFeatureCapabilities(req.vocabulary, req.capabilities.map((doc) => doc.id));\n const byCapability = new Map<string, ReadonlySet<string>>();\n for (const doc of req.capabilities) {\n const ids = new Set<string>();\n // REMOVED is excluded on both sides — a promise on its way out keeps nothing.\n for (const r of doc.living) if (r.kind !== \"REMOVED\" && r.id !== undefined) ids.add(r.id);\n for (const r of doc.reqs) if ((r.kind === \"ADDED\" || r.kind === \"MODIFIED\") && r.id !== undefined) ids.add(r.id);\n byCapability.set(doc.id, ids);\n }\n const scan = await readFeatureFlows({\n docsDir: req.docsDir,\n featureDir: req.featureDir,\n featureId: req.featureId,\n known: req.known,\n ...(req.load === undefined ? {} : { load: req.load }),\n ...(req.models === undefined ? {} : { models: req.models }),\n });\n const declared = gradableCapabilityIds(vocab);\n const promises = featureFlowPromises(scan, { declared, requirementsOf: (capability) => byCapability.get(capability) });\n if (scan.kind === \"unreadable\" || scan.views.length === 0) return { promises, issues: [] };\n const after = new Map((await capabilityRequirementIndex(req.vocabulary, req.read)).byCapability);\n for (const doc of req.capabilities) {\n const retired = new Set(\n doc.reqs\n .filter((r) => r.kind === \"REMOVED\")\n .flatMap((r) => (r.id !== undefined ? [r.id] : doc.living.filter((l) => l.name === r.name).flatMap((l) => (l.id === undefined ? [] : [l.id])))),\n );\n after.set(doc.id, new Set([...(byCapability.get(doc.id) ?? [])].filter((id) => !retired.has(id))));\n }\n return {\n promises,\n issues: featureFlowIssues({ docsDir: req.docsDir, scan, capabilities: declared, requirementsOf: (capability) => after.get(capability) }),\n };\n}\n"]}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A feature's own flows: `features/<FEAT>/usecases/<name>.likec4`.
|
|
3
|
+
*
|
|
4
|
+
* A `dynamic view` is the only realizer a cross-service promise has, and until
|
|
5
|
+
* this slot existed it was the one realizer no feature could carry. Every other
|
|
6
|
+
* axis had a delta — a C4 delta, a requirement delta on both spec axes, both
|
|
7
|
+
* contract deltas, a capability delta, a glossary term — so the business axis's
|
|
8
|
+
* own headline case had to be written backwards: an analyst adds a capability
|
|
9
|
+
* requirement, the architect answers it with a flow, and the flow could not ship
|
|
10
|
+
* in that change. It merged only after the promise was already living, which
|
|
11
|
+
* meant the promise landed first with nothing keeping it.
|
|
12
|
+
*
|
|
13
|
+
* CREATE-ONLY, for `core/glossary/delta.ts`'s reasons rather than a weaker
|
|
14
|
+
* version of them. A capability document is a DELTA because it merges INTO a
|
|
15
|
+
* living document and two features editing one requirement would otherwise
|
|
16
|
+
* overwrite each other silently. A flow has none of that: the file is one
|
|
17
|
+
* ordered hop sequence, the merge is a whole-file copy, and there is nothing to
|
|
18
|
+
* merge partially. Rewriting a living flow through a feature would be a silent
|
|
19
|
+
* whole-file replacement with no pin to collide on, where editing
|
|
20
|
+
* `architecture/usecases/<name>.likec4` directly in the same pull request
|
|
21
|
+
* produces an ordinary git conflict a human resolves. `usecase.flow-exists`
|
|
22
|
+
* refuses the first and names the second — the same shape, and the same
|
|
23
|
+
* severity, as `glossary.term-exists`.
|
|
24
|
+
*
|
|
25
|
+
* WHY A FILE OF ITS OWN AND NOT `delta.likec4`. The C4 delta is a MODEL delta:
|
|
26
|
+
* it re-declares the landscape's own identifiers to anchor its new edges, and it
|
|
27
|
+
* carries its own `specification` block because LikeC4 parses it standalone.
|
|
28
|
+
* Both make it unstageable beside the landscape in one project — a duplicate
|
|
29
|
+
* specification is an error blamed on both files, and a re-declared element is a
|
|
30
|
+
* duplicate id. A views-only document declares neither, which is exactly why
|
|
31
|
+
* living use cases already live in files of their own; the feature-local slot
|
|
32
|
+
* mirrors that layout so the merge is a copy and the overlay is a stage.
|
|
33
|
+
* `core/c4/splice/delta-blocks.ts` goes on refusing a `dynamic view` inside
|
|
34
|
+
* `delta.likec4` and now names this slot as the place it belongs.
|
|
35
|
+
*
|
|
36
|
+
* ONE CALL for the walk (`relativeDocuments`, which the topology axis in
|
|
37
|
+
* `core/deployment/delta.ts` shares). `architectureDocuments` already implements "every
|
|
38
|
+
* `.likec4` under a directory, recursively, in a stable order, and an absent
|
|
39
|
+
* directory is an empty list" — which is the whole of what a feature's flow
|
|
40
|
+
* directory is. A second walk would be two implementations free to disagree
|
|
41
|
+
* about what a flow file is, and they would disagree first about nesting.
|
|
42
|
+
*/
|
|
43
|
+
import { existsSync } from "node:fs";
|
|
44
|
+
import { join } from "node:path";
|
|
45
|
+
import { relativeDocuments } from "../../c4/project/documents.js";
|
|
46
|
+
import { architectureDir } from "../../c4/project/architecture.js";
|
|
47
|
+
import { featureUseCasesDir } from "../../repo/authored/paths.js";
|
|
48
|
+
import {} from "../../vocabulary/issue.js";
|
|
49
|
+
/** The directory living flows are filed under, inside `architecture/`. */
|
|
50
|
+
export const USECASE_SUBDIR = "usecases";
|
|
51
|
+
/**
|
|
52
|
+
* The flows one feature carries, ordered by path.
|
|
53
|
+
*
|
|
54
|
+
* Zero readdirs when the feature has no `usecases/` directory, which is every
|
|
55
|
+
* feature in a fleet that has not adopted the axis: `architectureDocuments`
|
|
56
|
+
* answers an absent directory with an empty list rather than a throw.
|
|
57
|
+
*/
|
|
58
|
+
export async function featureFlows(featureDir) {
|
|
59
|
+
return relativeDocuments(featureUseCasesDir(featureDir));
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The LIVING path a feature-local flow addresses. Spelled here because three
|
|
63
|
+
* readers need it — the refusal below, the archive merge, and the overlay that
|
|
64
|
+
* grades the flow before either — and a reader resolving it differently would
|
|
65
|
+
* refuse a flow the merge then wrote anyway.
|
|
66
|
+
*
|
|
67
|
+
* `rel` is joined un-split, which `node:path` normalizes. What holds the join is
|
|
68
|
+
* PROVENANCE, exactly as it holds `livingTermPath` one axis over: every `rel`
|
|
69
|
+
* here came out of an `architectureDocuments` walk, so each component is a
|
|
70
|
+
* directory entry that exists. No caller takes one from argv.
|
|
71
|
+
*/
|
|
72
|
+
export function livingFlowPath(docsDir, rel) {
|
|
73
|
+
return join(architectureDir(docsDir), USECASE_SUBDIR, rel);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* `usecase.flow-exists` — a flow this feature introduces that the living
|
|
77
|
+
* `architecture/` already holds.
|
|
78
|
+
*
|
|
79
|
+
* An ERROR and never a warning-that-gates, for `glossary.term-exists`'s reason:
|
|
80
|
+
* there is no legal reading of it. The merge would replace an authored flow
|
|
81
|
+
* wholesale, and no `--approve` makes that a different act than it is. Two
|
|
82
|
+
* features introducing the same flow is the case that makes it load-bearing
|
|
83
|
+
* rather than pedantic — whichever archives first creates the living document,
|
|
84
|
+
* and the second is told before it merges that its own file is the one to
|
|
85
|
+
* delete.
|
|
86
|
+
*/
|
|
87
|
+
export async function flowDeltaIssues(docsDir, featureDir) {
|
|
88
|
+
const flows = await featureFlows(featureDir);
|
|
89
|
+
return flows
|
|
90
|
+
.filter((flow) => existsSync(livingFlowPath(docsDir, flow.rel)))
|
|
91
|
+
.map((flow) => ({
|
|
92
|
+
severity: "error",
|
|
93
|
+
code: "usecase.flow-exists",
|
|
94
|
+
subject: flow.rel,
|
|
95
|
+
message: `architecture/${USECASE_SUBDIR}/${flow.rel} already exists, so this feature's flow would replace an authored one wholesale — ` +
|
|
96
|
+
"a feature-local flow INTRODUCES a use case, it does not rewrite one. " +
|
|
97
|
+
`Delete features/<FEAT>/${USECASE_SUBDIR}/${flow.rel} and edit architecture/${USECASE_SUBDIR}/${flow.rel} directly in this same change, ` +
|
|
98
|
+
"where git produces an ordinary conflict if somebody else is editing it too.",
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=flows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flows.js","sourceRoot":"","sources":["../../../../src/core/usecases/delta/flows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,OAAO,EAAc,MAAM,2BAA2B,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;AAezC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAsB;IACvD,OAAO,iBAAiB,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB,EAAE,GAAW;IAC1D,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAgB,EAAE,UAAsB;IAC5E,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAC7C,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;SAC/D,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE,OAAgB;QAC1B,IAAI,EAAE,qBAA8B;QACpC,OAAO,EAAE,IAAI,CAAC,GAAG;QACjB,OAAO,EACL,gBAAgB,cAAc,IAAI,IAAI,CAAC,GAAG,oFAAoF;YAC9H,uEAAuE;YACvE,0BAA0B,cAAc,IAAI,IAAI,CAAC,GAAG,0BAA0B,cAAc,IAAI,IAAI,CAAC,GAAG,iCAAiC;YACzI,6EAA6E;KAChF,CAAC,CAAC,CAAC;AACR,CAAC","sourcesContent":["/**\n * A feature's own flows: `features/<FEAT>/usecases/<name>.likec4`.\n *\n * A `dynamic view` is the only realizer a cross-service promise has, and until\n * this slot existed it was the one realizer no feature could carry. Every other\n * axis had a delta — a C4 delta, a requirement delta on both spec axes, both\n * contract deltas, a capability delta, a glossary term — so the business axis's\n * own headline case had to be written backwards: an analyst adds a capability\n * requirement, the architect answers it with a flow, and the flow could not ship\n * in that change. It merged only after the promise was already living, which\n * meant the promise landed first with nothing keeping it.\n *\n * CREATE-ONLY, for `core/glossary/delta.ts`'s reasons rather than a weaker\n * version of them. A capability document is a DELTA because it merges INTO a\n * living document and two features editing one requirement would otherwise\n * overwrite each other silently. A flow has none of that: the file is one\n * ordered hop sequence, the merge is a whole-file copy, and there is nothing to\n * merge partially. Rewriting a living flow through a feature would be a silent\n * whole-file replacement with no pin to collide on, where editing\n * `architecture/usecases/<name>.likec4` directly in the same pull request\n * produces an ordinary git conflict a human resolves. `usecase.flow-exists`\n * refuses the first and names the second — the same shape, and the same\n * severity, as `glossary.term-exists`.\n *\n * WHY A FILE OF ITS OWN AND NOT `delta.likec4`. The C4 delta is a MODEL delta:\n * it re-declares the landscape's own identifiers to anchor its new edges, and it\n * carries its own `specification` block because LikeC4 parses it standalone.\n * Both make it unstageable beside the landscape in one project — a duplicate\n * specification is an error blamed on both files, and a re-declared element is a\n * duplicate id. A views-only document declares neither, which is exactly why\n * living use cases already live in files of their own; the feature-local slot\n * mirrors that layout so the merge is a copy and the overlay is a stage.\n * `core/c4/splice/delta-blocks.ts` goes on refusing a `dynamic view` inside\n * `delta.likec4` and now names this slot as the place it belongs.\n *\n * ONE CALL for the walk (`relativeDocuments`, which the topology axis in\n * `core/deployment/delta.ts` shares). `architectureDocuments` already implements \"every\n * `.likec4` under a directory, recursively, in a stable order, and an absent\n * directory is an empty list\" — which is the whole of what a feature's flow\n * directory is. A second walk would be two implementations free to disagree\n * about what a flow file is, and they would disagree first about nesting.\n */\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { relativeDocuments } from \"../../c4/project/documents.js\";\nimport { architectureDir } from \"../../c4/project/architecture.js\";\nimport { featureUseCasesDir } from \"../../repo/authored/paths.js\";\nimport type { DocsDir, FeatureDir } from \"../../kernel/ids/dirs.js\";\nimport { type Issue } from \"../../vocabulary/issue.js\";\n\n/** The directory living flows are filed under, inside `architecture/`. */\nexport const USECASE_SUBDIR = \"usecases\";\n\n/** One flow document a feature carries. */\nexport interface FeatureFlow {\n /**\n * The path INSIDE the feature's `usecases/` directory, `/`-separated — the id\n * this axis has, and the same path the merge writes under\n * `architecture/usecases/`. Nesting is spelled by the tree, as it is for every\n * other authored tree in the repo.\n */\n rel: string;\n /** The absolute path of the authored file. */\n path: string;\n}\n\n/**\n * The flows one feature carries, ordered by path.\n *\n * Zero readdirs when the feature has no `usecases/` directory, which is every\n * feature in a fleet that has not adopted the axis: `architectureDocuments`\n * answers an absent directory with an empty list rather than a throw.\n */\nexport async function featureFlows(featureDir: FeatureDir): Promise<FeatureFlow[]> {\n return relativeDocuments(featureUseCasesDir(featureDir));\n}\n\n/**\n * The LIVING path a feature-local flow addresses. Spelled here because three\n * readers need it — the refusal below, the archive merge, and the overlay that\n * grades the flow before either — and a reader resolving it differently would\n * refuse a flow the merge then wrote anyway.\n *\n * `rel` is joined un-split, which `node:path` normalizes. What holds the join is\n * PROVENANCE, exactly as it holds `livingTermPath` one axis over: every `rel`\n * here came out of an `architectureDocuments` walk, so each component is a\n * directory entry that exists. No caller takes one from argv.\n */\nexport function livingFlowPath(docsDir: DocsDir, rel: string): string {\n return join(architectureDir(docsDir), USECASE_SUBDIR, rel);\n}\n\n/**\n * `usecase.flow-exists` — a flow this feature introduces that the living\n * `architecture/` already holds.\n *\n * An ERROR and never a warning-that-gates, for `glossary.term-exists`'s reason:\n * there is no legal reading of it. The merge would replace an authored flow\n * wholesale, and no `--approve` makes that a different act than it is. Two\n * features introducing the same flow is the case that makes it load-bearing\n * rather than pedantic — whichever archives first creates the living document,\n * and the second is told before it merges that its own file is the one to\n * delete.\n */\nexport async function flowDeltaIssues(docsDir: DocsDir, featureDir: FeatureDir): Promise<Issue[]> {\n const flows = await featureFlows(featureDir);\n return flows\n .filter((flow) => existsSync(livingFlowPath(docsDir, flow.rel)))\n .map((flow) => ({\n severity: \"error\" as const,\n code: \"usecase.flow-exists\" as const,\n subject: flow.rel,\n message:\n `architecture/${USECASE_SUBDIR}/${flow.rel} already exists, so this feature's flow would replace an authored one wholesale — ` +\n \"a feature-local flow INTRODUCES a use case, it does not rewrite one. \" +\n `Delete features/<FEAT>/${USECASE_SUBDIR}/${flow.rel} and edit architecture/${USECASE_SUBDIR}/${flow.rel} directly in this same change, ` +\n \"where git produces an ordinary conflict if somebody else is editing it too.\",\n }));\n}\n"]}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The LIVING flows whose `#req-` tag claims a requirement this feature changes:
|
|
3
|
+
* `usecase.requirement-modified` for one it rewrites, and
|
|
4
|
+
* `usecase.requirement-unresolved` for one it takes away.
|
|
5
|
+
*
|
|
6
|
+
* THE HOLE. A `#req-` tag joins a flow to one named promise, and the join is by
|
|
7
|
+
* id. A MODIFIED requirement keeps its id and replaces its whole text, so after
|
|
8
|
+
* the archive the tag still resolves, every grade of the flow stays green — and
|
|
9
|
+
* the flow can be drawing exactly the behaviour the new wording forbids: an
|
|
10
|
+
* event path the requirement now says is gone, a hop through a service it no
|
|
11
|
+
* longer names. Nothing in loam reads a flow's MEANING, so nothing can say
|
|
12
|
+
* whether the drawing still keeps the promise. What loam can say is that the
|
|
13
|
+
* promise moved under it, and it said nothing.
|
|
14
|
+
*
|
|
15
|
+
* A WARNING, AND IT NEVER GATES. Rewording a promise a flow keeps is ordinary;
|
|
16
|
+
* the flow may well still keep it. This names each flow and the requirement, so
|
|
17
|
+
* the author reads one against the other while the feature is still open — and
|
|
18
|
+
* redraws the flow in the same change where it no longer holds.
|
|
19
|
+
*
|
|
20
|
+
* A REMOVAL IS THE FLEET'S OWN ERROR, ONE ARCHIVE EARLY. The merge deletes the
|
|
21
|
+
* promise and leaves the tag, so the very next `validate --all` reports the flow
|
|
22
|
+
* `usecase.requirement-unresolved` — while the feature gate had said nothing and
|
|
23
|
+
* the archive had exited 0 (the real-fleet review, 2026-10-21). That grade holds
|
|
24
|
+
* no judgement about the drawing: the tag resolves to nothing, whatever the flow
|
|
25
|
+
* shows. So it is raised here under the SAME code, at the same severity, with
|
|
26
|
+
* the VIEW as its subject as at fleet altitude — the fleet's grade predicted,
|
|
27
|
+
* not a second opinion beside it — and as an error it gates the archive.
|
|
28
|
+
* `--approve` may walk past it, for `capability.remove-requirement-realized`'s
|
|
29
|
+
* reason one carrier over: retiring a promise something still claims is the
|
|
30
|
+
* author's call about the feature, loam reads the flow perfectly well (this is
|
|
31
|
+
* no `usecase.flow-invalid` blindness), and the living docs then carry exactly
|
|
32
|
+
* the error this named.
|
|
33
|
+
*
|
|
34
|
+
* GRADED AGAINST WHAT THE MERGE LEAVES, not against the REMOVED list. Each
|
|
35
|
+
* document's after-side is the merge's own fold (`applyRequirementDelta`), so a
|
|
36
|
+
* removal the same delta re-spells under an id that flattens to the same tag
|
|
37
|
+
* leaves the tag resolving and earns nothing, exactly as the fleet will grade
|
|
38
|
+
* it. The same verdict is asked of a MODIFIED: it keeps its id, but
|
|
39
|
+
* an id this feature adds beside it may flatten to the same tag, and then the
|
|
40
|
+
* merge breaks the tag too — the error, not the warning, whose "the tag will
|
|
41
|
+
* still resolve" would be false. And only a claim that resolves TODAY is asked
|
|
42
|
+
* about: one that is already broken is `validate --all`'s finding now, and
|
|
43
|
+
* reporting it again here would be one mistake counted twice.
|
|
44
|
+
*
|
|
45
|
+
* TWO ALTITUDES, TWO SCOPES — the ones `validate --all` resolves the tag with.
|
|
46
|
+
* A flow in `architecture/` keeps a BUSINESS promise: its `#req-` tag is scoped
|
|
47
|
+
* by its `#cap-` tag to a capability document (`core/capabilities/usecase-join.ts`),
|
|
48
|
+
* so it is asked about the capability requirements this feature changes. A
|
|
49
|
+
* flow beside a service's model keeps that SERVICE's promise: its `#req-` tag is
|
|
50
|
+
* scoped by the directory to the ids of that service's spec.md and arch.spec.md
|
|
51
|
+
* (`commands/validate/service/usecases/tags.ts`), so it is asked about the
|
|
52
|
+
* service requirements this feature changes there — and only the services the
|
|
53
|
+
* feature's `specs/` touch can hold one. BOTH documents are that scope, so the
|
|
54
|
+
* one a touched service carries no delta for is read as it stands: without it
|
|
55
|
+
* an id the other document also declares would read as gone after the merge,
|
|
56
|
+
* and gate an archive the fleet then grades green. The feature's own
|
|
57
|
+
* `usecases/` are not living and are graded against the new text already
|
|
58
|
+
* (`../grade/feature.ts`).
|
|
59
|
+
*
|
|
60
|
+
* WHAT IT COSTS. Nothing, for a feature that modifies and removes no
|
|
61
|
+
* requirement — which is nearly every feature, and the caller does not call
|
|
62
|
+
* this then. For one that does, a byte scan for the tag's own spelling
|
|
63
|
+
* (`req-<slug>`) over the documents that could declare it, the living document
|
|
64
|
+
* of a touched service's other axis, and a LikeC4 load only for a project one
|
|
65
|
+
* of them is in: a tag name is one token, so a document without its characters
|
|
66
|
+
* cannot carry it. A project that does not parse is skipped, not reported —
|
|
67
|
+
* `validate --all` owns that answer (`usecase.flow-invalid`, `landscape.invalid`),
|
|
68
|
+
* and a finding about one requirement must not become a second report of a
|
|
69
|
+
* broken map.
|
|
70
|
+
*/
|
|
71
|
+
import { existsSync } from "node:fs";
|
|
72
|
+
import { readFile } from "node:fs/promises";
|
|
73
|
+
import { join, relative } from "node:path";
|
|
74
|
+
import { REQ_TAG_PREFIX, resolveCapabilityTags, resolveRequirementTags, tagSlug, } from "../../capabilities/usecase-join.js";
|
|
75
|
+
import { gradableCapabilityIds } from "../../capabilities/findings.js";
|
|
76
|
+
import { architectureDocuments } from "../../c4/project/documents.js";
|
|
77
|
+
import { architectureProjectDocuments } from "../../c4/project/architecture.js";
|
|
78
|
+
import { applyRequirementDelta, replacementsOf } from "../../document/apply.js";
|
|
79
|
+
import { SPEC_AXES } from "../../repo/paths.js";
|
|
80
|
+
import { compareIds } from "../../repo/entries.js";
|
|
81
|
+
import { useCasesIn } from "../fleet.js";
|
|
82
|
+
import { viewFile } from "../place.js";
|
|
83
|
+
import { readServiceFlows } from "../service/flows.js";
|
|
84
|
+
export async function changedPromiseFlowIssues(req) {
|
|
85
|
+
const tables = {
|
|
86
|
+
capability: tableOf(req.capabilities),
|
|
87
|
+
service: tableOf(await withUntouchedAxes(req)),
|
|
88
|
+
};
|
|
89
|
+
const flows = [
|
|
90
|
+
...(await fleetFlows(req, changedIds(tables.capability))),
|
|
91
|
+
...(await serviceFlows(req, changedIds(tables.service))),
|
|
92
|
+
];
|
|
93
|
+
const issues = [];
|
|
94
|
+
for (const flow of flows.sort((a, b) => compareIds(a.file, b.file) || compareIds(a.view.id, b.view.id))) {
|
|
95
|
+
const table = tables[flow.altitude];
|
|
96
|
+
const after = new Map(resolveRequirementTags(flow.view.tags, flow.scope, (id) => table.merged.get(id)).map((c) => [c.tag, c]));
|
|
97
|
+
for (const claim of resolveRequirementTags(flow.view.tags, flow.scope, (id) => table.living.get(id))) {
|
|
98
|
+
if (claim.kind !== "resolved")
|
|
99
|
+
continue;
|
|
100
|
+
const change = changeOf(table, claim);
|
|
101
|
+
if (change === null)
|
|
102
|
+
continue;
|
|
103
|
+
// The merge's verdict first, for either change: a MODIFIED keeps its id,
|
|
104
|
+
// but an id this feature adds beside it can flatten to the same tag, and
|
|
105
|
+
// then the warning's "the tag will still resolve" would be false.
|
|
106
|
+
const later = after.get(claim.tag);
|
|
107
|
+
if (later !== undefined && later.kind !== "resolved")
|
|
108
|
+
issues.push(brokenIssue(flow, claim, { change, later }));
|
|
109
|
+
else if (change === "MODIFIES")
|
|
110
|
+
issues.push(modifiedIssue(flow, claim));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return issues;
|
|
114
|
+
}
|
|
115
|
+
function changeOf(table, claim) {
|
|
116
|
+
if (table.modified.get(claim.capability)?.has(claim.id) === true)
|
|
117
|
+
return "MODIFIES";
|
|
118
|
+
return table.removed.get(claim.capability)?.has(claim.id) === true ? "REMOVES" : null;
|
|
119
|
+
}
|
|
120
|
+
function whose(flow, claim) {
|
|
121
|
+
return flow.altitude === "capability" ? `${claim.capability}#${claim.id}` : `${claim.capability}'s requirement ${claim.id}`;
|
|
122
|
+
}
|
|
123
|
+
function modifiedIssue(flow, claim) {
|
|
124
|
+
return {
|
|
125
|
+
severity: "warn",
|
|
126
|
+
code: "usecase.requirement-modified",
|
|
127
|
+
subject: claim.capability,
|
|
128
|
+
message: `${flow.file}: flow '${flow.view.id}' is tagged #${claim.tag} — it claims ${whose(flow, claim)}, which this feature MODIFIES. ` +
|
|
129
|
+
`The tag will still resolve after the archive and nothing grades what the flow draws against the new ` +
|
|
130
|
+
`wording: read the flow against the replacement, and redraw it in this change if it no longer keeps the promise.`,
|
|
131
|
+
locations: [{ path: flow.file, role: "primary" }],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The tag the merge breaks. Two ways, and each has its own fix: a removal
|
|
136
|
+
* leaves nothing the tag names, and an id this feature adds can flatten to the
|
|
137
|
+
* same tag as the one it claims — the only way a MODIFIED, which keeps its id,
|
|
138
|
+
* can break it at all.
|
|
139
|
+
*/
|
|
140
|
+
function brokenIssue(flow, claim, broken) {
|
|
141
|
+
const { change, later } = broken;
|
|
142
|
+
const [why, fix] = later.kind === "many"
|
|
143
|
+
? [
|
|
144
|
+
`${later.ids.length} requirements will flatten to '${later.slug}' (${later.ids.join(", ")}), so nothing in the tag can say which promise the flow keeps`,
|
|
145
|
+
"rename one of the colliding ids in this change",
|
|
146
|
+
]
|
|
147
|
+
: [
|
|
148
|
+
"nothing it names is left",
|
|
149
|
+
"drop the tag (or point it at the promise that replaces this one) in this change, or MODIFY the requirement instead of removing it",
|
|
150
|
+
];
|
|
151
|
+
return {
|
|
152
|
+
severity: "error",
|
|
153
|
+
code: "usecase.requirement-unresolved",
|
|
154
|
+
// The VIEW, as `validate --all` names it once the archive lands — so the
|
|
155
|
+
// prediction and the outcome are about one thing a reader opens.
|
|
156
|
+
subject: flow.view.id,
|
|
157
|
+
message: `${flow.file}: flow '${flow.view.id}' is tagged #${claim.tag} — it claims ${whose(flow, claim)}, which this feature ${change}. ` +
|
|
158
|
+
`After the archive the tag no longer resolves — ${why} — and \`loam validate --all\` reports this flow with this ` +
|
|
159
|
+
`same error: ${fix}.`,
|
|
160
|
+
locations: [{ path: flow.file, role: "primary" }],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Each document's table rows. The modified and removed ids are named by the id
|
|
165
|
+
* the LIVING document gives them — selected by `replacementsOf`, the merge's own
|
|
166
|
+
* walk, so a MODIFIED or REMOVED written by heading alone still names the id a
|
|
167
|
+
* tag carries — and the after-side is that same merge's result. A document the
|
|
168
|
+
* merge would refuse keeps its living ids on both sides and changes nothing:
|
|
169
|
+
* the delta gate reports it, and nothing here has a true thing to say about a
|
|
170
|
+
* merge that cannot happen.
|
|
171
|
+
*
|
|
172
|
+
* TODAY'S side leaves out a living requirement sitting under a REMOVED heading,
|
|
173
|
+
* as both fleet indexes do (`capabilityRequirementIndex`, `requirementIdsOf`):
|
|
174
|
+
* a tag resolving only through one is already the fleet's error. The fold
|
|
175
|
+
* still runs on the whole living list, because that is the archive's input.
|
|
176
|
+
*/
|
|
177
|
+
function tableOf(docs) {
|
|
178
|
+
const table = { living: new Map(), merged: new Map(), modified: new Map(), removed: new Map() };
|
|
179
|
+
for (const doc of docs) {
|
|
180
|
+
const living = doc.living.filter((r) => r.kind !== "REMOVED");
|
|
181
|
+
let fold;
|
|
182
|
+
try {
|
|
183
|
+
fold = { replaced: replacementsOf([...doc.living], [...doc.reqs]), merged: applyRequirementDelta([...doc.living], [...doc.reqs]) };
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
fold = { replaced: [], merged: living };
|
|
187
|
+
}
|
|
188
|
+
idsInto(table.living, doc.id, living);
|
|
189
|
+
idsInto(table.merged, doc.id, fold.merged);
|
|
190
|
+
for (const r of fold.replaced) {
|
|
191
|
+
if (r.living.id === undefined || (r.kind !== "MODIFIED" && r.kind !== "REMOVED"))
|
|
192
|
+
continue;
|
|
193
|
+
const into = r.kind === "MODIFIED" ? table.modified : table.removed;
|
|
194
|
+
into.set(doc.id, (into.get(doc.id) ?? new Set()).add(r.living.id));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return table;
|
|
198
|
+
}
|
|
199
|
+
/** A document's ids, unioned into its row — created even when empty, which is the `empty` arm's answer rather than `undocumented`'s. */
|
|
200
|
+
function idsInto(rows, id, reqs) {
|
|
201
|
+
const ids = rows.get(id) ?? new Set();
|
|
202
|
+
for (const r of reqs)
|
|
203
|
+
if (r.id !== undefined)
|
|
204
|
+
ids.add(r.id);
|
|
205
|
+
rows.set(id, ids);
|
|
206
|
+
}
|
|
207
|
+
/** The ids each document's delta modifies or removes — what a flow has to mention to be asked about at all. */
|
|
208
|
+
function changedIds(table) {
|
|
209
|
+
const out = new Map();
|
|
210
|
+
for (const rows of [table.modified, table.removed]) {
|
|
211
|
+
for (const [id, ids] of rows)
|
|
212
|
+
out.set(id, new Set([...(out.get(id) ?? []), ...ids]));
|
|
213
|
+
}
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* The service pairs, plus — for each service whose delta modifies or removes
|
|
218
|
+
* something — every document of it the feature carries no delta for, as it
|
|
219
|
+
* stands (`reqs: []`, so it changes nothing and only widens both sides).
|
|
220
|
+
* `requirementIdsOf` (`commands/validate/service/usecases/usecases.ts`) reads
|
|
221
|
+
* both documents for a service-local tag, skipping a requirement under a
|
|
222
|
+
* REMOVED heading; so must this, or a tag the untouched document keeps
|
|
223
|
+
* resolving reads as broken — and one only a REMOVED entry there answers reads
|
|
224
|
+
* as kept, though the archive leaves that document as it is.
|
|
225
|
+
*/
|
|
226
|
+
async function withUntouchedAxes(req) {
|
|
227
|
+
const out = [...req.services];
|
|
228
|
+
const asked = new Set();
|
|
229
|
+
// Sequential, and it costs nothing worth racing: a feature names a handful of
|
|
230
|
+
// services, each read is one memoised document, and most services here
|
|
231
|
+
// already have both axes in the feature or no second document at all.
|
|
232
|
+
for (const pair of req.services) {
|
|
233
|
+
const own = req.services.filter((p) => p.id === pair.id);
|
|
234
|
+
if (asked.has(pair.id) || !own.some((p) => p.reqs.some((r) => r.kind === "MODIFIED" || r.kind === "REMOVED")))
|
|
235
|
+
continue;
|
|
236
|
+
asked.add(pair.id);
|
|
237
|
+
const paths = await pair.paths();
|
|
238
|
+
for (const axis of SPEC_AXES) {
|
|
239
|
+
if (own.some((p) => p.axis === axis.key) || !existsSync(paths[axis.key]))
|
|
240
|
+
continue;
|
|
241
|
+
const living = (await req.readRequirements(paths[axis.key])).filter((r) => r.kind !== "REMOVED");
|
|
242
|
+
out.push({ id: pair.id, reqs: [], living });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return out;
|
|
246
|
+
}
|
|
247
|
+
/** The tag spellings that could claim one of these ids. */
|
|
248
|
+
function needlesFor(changed) {
|
|
249
|
+
return [...new Set([...changed.values()].flatMap((ids) => [...ids].map((id) => `${REQ_TAG_PREFIX}${tagSlug(id)}`)))];
|
|
250
|
+
}
|
|
251
|
+
/** Does any of these documents contain one of the tag spellings at all? Unreadable fails closed, as `../fleet.ts`'s gate does. */
|
|
252
|
+
async function mentions(paths, needles) {
|
|
253
|
+
for (const path of paths) {
|
|
254
|
+
try {
|
|
255
|
+
const text = (await readFile(path)).toString("latin1");
|
|
256
|
+
if (needles.some((needle) => text.includes(needle)))
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
async function fleetFlows(req, changed) {
|
|
266
|
+
// The vocabulary ladder (`core/capabilities/findings.ts`): with nothing
|
|
267
|
+
// declared no `#cap-` tag resolves, so no fleet flow can be said to claim anything.
|
|
268
|
+
const declared = gradableCapabilityIds(req.vocabulary);
|
|
269
|
+
if (changed.size === 0 || declared === null)
|
|
270
|
+
return [];
|
|
271
|
+
if (!(await mentions(await architectureProjectDocuments(req.docsDir), needlesFor(changed))))
|
|
272
|
+
return [];
|
|
273
|
+
const read = useCasesIn(await req.architecture(), req.known);
|
|
274
|
+
if (read.kind !== "read")
|
|
275
|
+
return [];
|
|
276
|
+
return read.views.map((view) => ({
|
|
277
|
+
view,
|
|
278
|
+
file: viewFile(view),
|
|
279
|
+
scope: resolveCapabilityTags(view.tags, declared).flatMap((c) => (c.kind === "resolved" ? [c.id] : [])),
|
|
280
|
+
altitude: "capability",
|
|
281
|
+
}));
|
|
282
|
+
}
|
|
283
|
+
async function serviceFlows(req, changed) {
|
|
284
|
+
const out = [];
|
|
285
|
+
for (const [service, ids] of changed) {
|
|
286
|
+
// Sequential on purpose, for `../fleet.ts`'s gate's reason: nearly every
|
|
287
|
+
// service answers from one readdir and a byte scan, and the rare one that
|
|
288
|
+
// opens a workspace should not be raced by the ones that do not need one.
|
|
289
|
+
const pair = req.services.find((doc) => doc.id === service);
|
|
290
|
+
if (pair === undefined)
|
|
291
|
+
continue;
|
|
292
|
+
const paths = await pair.paths();
|
|
293
|
+
if (!(await mentions(await architectureDocuments(paths.dir), needlesFor(new Map([[service, ids]])))))
|
|
294
|
+
continue;
|
|
295
|
+
const model = await req.serviceModel(paths);
|
|
296
|
+
if (model.mapUnreadable || model.doc.errors.length > 0)
|
|
297
|
+
continue;
|
|
298
|
+
const flows = await readServiceFlows({
|
|
299
|
+
paths,
|
|
300
|
+
model: model.doc,
|
|
301
|
+
known: req.known,
|
|
302
|
+
...(model.shape === "extending" && model.project !== null
|
|
303
|
+
? { extending: { docsDir: req.docsDir, project: model.project } }
|
|
304
|
+
: {}),
|
|
305
|
+
});
|
|
306
|
+
if (flows.kind !== "read")
|
|
307
|
+
continue;
|
|
308
|
+
for (const view of flows.views) {
|
|
309
|
+
const file = relative(req.docsDir, join(paths.dir, view.sourcePath ?? "model.likec4")).split(/[\\/]/).join("/");
|
|
310
|
+
out.push({ view, file, scope: [service], altitude: "service" });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return out;
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=modified.js.map
|