@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.1
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 +2548 -86
- package/COMPARISON.md +80 -63
- package/CONTRIBUTING.md +84 -0
- package/MIGRATING-from-OpenSpec.md +213 -54
- package/QUICKSTART.md +125 -0
- package/README.md +450 -150
- package/ROADMAP.md +494 -0
- package/SCHEMA.md +2355 -256
- package/SECURITY.md +21 -3
- package/WORKFLOW.md +701 -0
- package/dist/cli.js +113 -19
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +209 -0
- package/dist/commands/adopt/adopt.js.map +1 -0
- package/dist/commands/adopt/render.js +268 -0
- package/dist/commands/adopt/render.js.map +1 -0
- package/dist/commands/archive/archive.js +77 -0
- package/dist/commands/archive/archive.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +159 -0
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +317 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +161 -0
- package/dist/commands/archive/plan/landscape.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +111 -0
- package/dist/commands/archive/plan/refusal.js.map +1 -0
- package/dist/commands/archive/plan/specs.js +237 -0
- package/dist/commands/archive/plan/specs.js.map +1 -0
- package/dist/commands/archive/plan/state.js +27 -0
- package/dist/commands/archive/plan/state.js.map +1 -0
- package/dist/commands/archive/run.js +251 -0
- package/dist/commands/archive/run.js.map +1 -0
- package/dist/commands/context/context.js +99 -0
- package/dist/commands/context/context.js.map +1 -0
- package/dist/commands/context/print.js +283 -0
- package/dist/commands/context/print.js.map +1 -0
- package/dist/commands/delta/delta.js +279 -0
- package/dist/commands/delta/delta.js.map +1 -0
- package/dist/commands/delta/print.js +205 -0
- package/dist/commands/delta/print.js.map +1 -0
- package/dist/commands/dependencies.js +9 -7
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +93 -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 +5 -4
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +151 -0
- package/dist/commands/explain/explain.js.map +1 -0
- package/dist/commands/explore.js +29 -24
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +115 -0
- package/dist/commands/gate/gate.js.map +1 -0
- package/dist/commands/gate/print.js +54 -0
- package/dist/commands/gate/print.js.map +1 -0
- package/dist/commands/gherkin/commit.js +146 -0
- package/dist/commands/gherkin/commit.js.map +1 -0
- package/dist/commands/gherkin/gherkin.js +246 -0
- package/dist/commands/gherkin/gherkin.js.map +1 -0
- package/dist/commands/gherkin/reconcile.js +149 -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 +28 -0
- package/dist/commands/init/first-hour.js.map +1 -0
- package/dist/commands/{init.js → init/init.js} +146 -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 +65 -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 +157 -0
- package/dist/commands/list/json.js.map +1 -0
- package/dist/commands/list/list.js +343 -0
- package/dist/commands/list/list.js.map +1 -0
- package/dist/commands/list/print.js +301 -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/views.js +105 -0
- package/dist/commands/list/views.js.map +1 -0
- package/dist/commands/mcp/dispatch.js +183 -0
- package/dist/commands/mcp/dispatch.js.map +1 -0
- package/dist/commands/mcp/mcp.js +34 -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 +170 -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 +142 -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 +91 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/error.js +19 -0
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/paths.js +43 -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/commit.js +76 -0
- package/dist/commands/new/commit.js.map +1 -0
- package/dist/commands/new/new.js +283 -0
- package/dist/commands/new/new.js.map +1 -0
- package/dist/commands/new/templates.js +355 -0
- package/dist/commands/new/templates.js.map +1 -0
- package/dist/commands/open.js +203 -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} +11 -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 +275 -0
- package/dist/commands/rebase/rebase.js.map +1 -0
- package/dist/commands/seed/commit.js +192 -0
- package/dist/commands/seed/commit.js.map +1 -0
- package/dist/commands/seed/plan.js +133 -0
- package/dist/commands/seed/plan.js.map +1 -0
- package/dist/commands/seed/seed.js +172 -0
- package/dist/commands/seed/seed.js.map +1 -0
- package/dist/commands/show/feature.js +178 -0
- package/dist/commands/show/feature.js.map +1 -0
- package/dist/commands/show/marks.js +24 -0
- package/dist/commands/show/marks.js.map +1 -0
- package/dist/commands/{show.js → show/service.js} +63 -152
- package/dist/commands/show/service.js.map +1 -0
- package/dist/commands/show/show.js +77 -0
- package/dist/commands/show/show.js.map +1 -0
- package/dist/commands/status/json.js +45 -0
- package/dist/commands/status/json.js.map +1 -0
- package/dist/commands/status/print.js +157 -0
- package/dist/commands/status/print.js.map +1 -0
- package/dist/commands/status/status.js +119 -0
- package/dist/commands/status/status.js.map +1 -0
- package/dist/commands/steps/steps.js +189 -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 +265 -0
- package/dist/commands/subsystem/move.js.map +1 -0
- package/dist/commands/subsystem/query.js +115 -0
- package/dist/commands/subsystem/query.js.map +1 -0
- package/dist/commands/subsystem/subsystem.js +101 -0
- package/dist/commands/subsystem/subsystem.js.map +1 -0
- package/dist/commands/subsystem/sync.js +103 -0
- package/dist/commands/subsystem/sync.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +94 -0
- package/dist/commands/subsystem/txn/txn.js.map +1 -0
- package/dist/commands/subsystem/txn/views.js +70 -0
- package/dist/commands/subsystem/txn/views.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +160 -0
- package/dist/commands/unarchive/manifest.js.map +1 -0
- package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
- package/dist/commands/unarchive/restore.js.map +1 -0
- package/dist/commands/unarchive/unarchive.js +67 -0
- package/dist/commands/unarchive/unarchive.js.map +1 -0
- package/dist/commands/validate/arch-coverage.js +194 -0
- package/dist/commands/validate/arch-coverage.js.map +1 -0
- package/dist/commands/validate/checks/fleet-shape.js +296 -0
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
- package/dist/commands/validate/checks/health-deps.js +55 -0
- package/dist/commands/validate/checks/health-deps.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +254 -0
- package/dist/commands/validate/checks/requirements.js.map +1 -0
- package/dist/commands/validate/checks/sources.js +76 -0
- package/dist/commands/validate/checks/sources.js.map +1 -0
- package/dist/commands/validate/checks/vocabulary.js +31 -0
- package/dist/commands/validate/checks/vocabulary.js.map +1 -0
- package/dist/commands/validate/feature.js +216 -0
- package/dist/commands/validate/feature.js.map +1 -0
- package/dist/commands/validate/fleet/census.js +69 -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 +353 -0
- package/dist/commands/validate/fleet/landscape.js.map +1 -0
- package/dist/commands/validate/fleet/load.js +52 -0
- package/dist/commands/validate/fleet/load.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +236 -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 +63 -0
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
- package/dist/commands/validate/fleet/usecases/capability-tag.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/usecases/requirement-tag.js +95 -0
- package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/steps.js +197 -0
- package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
- package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +40 -0
- package/dist/commands/validate/fleet/views/ids.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +59 -0
- package/dist/commands/validate/fleet/views/stale.js.map +1 -0
- package/dist/commands/validate/links/corpus.js +92 -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/report.js +269 -0
- package/dist/commands/validate/report.js.map +1 -0
- package/dist/commands/validate/service/api.js +338 -0
- package/dist/commands/validate/service/api.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +219 -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 +131 -0
- package/dist/commands/validate/service/evidence-pins.js.map +1 -0
- package/dist/commands/validate/service/service.js +250 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +219 -0
- package/dist/commands/validate/service/specs.js.map +1 -0
- package/dist/commands/validate/service/spine.js +113 -0
- package/dist/commands/validate/service/spine.js.map +1 -0
- package/dist/commands/validate/validate.js +338 -0
- package/dist/commands/validate/validate.js.map +1 -0
- package/dist/commands/verify/cross/diff.js +182 -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 +72 -0
- package/dist/commands/verify/evidence/read.js.map +1 -0
- package/dist/commands/verify/frozen.js +241 -0
- package/dist/commands/verify/frozen.js.map +1 -0
- package/dist/commands/verify/record.js +226 -0
- package/dist/commands/verify/record.js.map +1 -0
- package/dist/commands/verify/report.js +223 -0
- package/dist/commands/verify/report.js.map +1 -0
- package/dist/commands/verify/results.js +246 -0
- package/dist/commands/verify/results.js.map +1 -0
- package/dist/commands/verify/verify.js +217 -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 +271 -0
- package/dist/commands/vouch/pack/print.js.map +1 -0
- package/dist/commands/vouch/pack/sections.js +142 -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 +285 -0
- package/dist/commands/vouch/run.js.map +1 -0
- package/dist/commands/vouch/sample/plan.js +125 -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 +123 -0
- package/dist/commands/vouch/vet/verify.js.map +1 -0
- package/dist/commands/vouch/vouch.js +176 -0
- package/dist/commands/vouch/vouch.js.map +1 -0
- package/dist/core/agent/agents-md/artifacts.js +220 -0
- package/dist/core/agent/agents-md/artifacts.js.map +1 -0
- package/dist/core/agent/agents-md/command-map.js +324 -0
- package/dist/core/agent/agents-md/command-map.js.map +1 -0
- package/dist/core/agent/agents-md/cycle.js +165 -0
- package/dist/core/agent/agents-md/cycle.js.map +1 -0
- package/dist/core/agent/agents-md/map/explain.js +34 -0
- package/dist/core/agent/agents-md/map/explain.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
- package/dist/core/agent/agents-md/map/mcp.js +41 -0
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
- package/dist/core/agent/agents-md/map/status.js +62 -0
- package/dist/core/agent/agents-md/map/status.js.map +1 -0
- package/dist/core/agent/agents-md/map/subsystem.js +32 -0
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
- package/dist/core/agent/agents-md/map/usecases.js +60 -0
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
- package/dist/core/agent/agents-md/refusals.js +246 -0
- package/dist/core/agent/agents-md/refusals.js.map +1 -0
- package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
- package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
- package/dist/core/agent/agents-md/spine.js +40 -0
- package/dist/core/agent/agents-md/spine.js.map +1 -0
- package/dist/core/agent/agents-md.js +170 -0
- package/dist/core/agent/agents-md.js.map +1 -0
- package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +50 -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 +259 -0
- package/dist/core/agent/scaffold.js.map +1 -0
- package/dist/core/agent/support/report.js +103 -0
- package/dist/core/agent/support/report.js.map +1 -0
- package/dist/core/agent/tools/dialects.js +150 -0
- package/dist/core/agent/tools/dialects.js.map +1 -0
- package/dist/core/agent/tools/registry.js +228 -0
- package/dist/core/agent/tools/registry.js.map +1 -0
- package/dist/core/agent/workflows/adopt.js +133 -0
- package/dist/core/agent/workflows/adopt.js.map +1 -0
- package/dist/core/agent/workflows/check.js +334 -0
- package/dist/core/agent/workflows/check.js.map +1 -0
- package/dist/core/agent/workflows/closing.js +262 -0
- package/dist/core/agent/workflows/closing.js.map +1 -0
- package/dist/core/agent/workflows/feature.js +105 -0
- package/dist/core/agent/workflows/feature.js.map +1 -0
- package/dist/core/agent/workflows/implement.js +105 -0
- package/dist/core/agent/workflows/implement.js.map +1 -0
- package/dist/core/agent/workflows/reference/authoring.js +209 -0
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
- package/dist/core/agent/workflows/reference/codes.js +65 -0
- package/dist/core/agent/workflows/reference/codes.js.map +1 -0
- package/dist/core/agent/workflows/reference/done-check.js +188 -0
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +16 -0
- package/dist/core/agent/workflows/reference/reference.js.map +1 -0
- package/dist/core/agent/workflows/reference/spine.js +297 -0
- package/dist/core/agent/workflows/reference/spine.js.map +1 -0
- package/dist/core/asyncapi/baseline/plan.js +110 -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 +141 -0
- package/dist/core/asyncapi/digest.js.map +1 -0
- package/dist/core/asyncapi/merge/components.js +91 -0
- package/dist/core/asyncapi/merge/components.js.map +1 -0
- package/dist/core/asyncapi/merge/error.js +33 -0
- package/dist/core/asyncapi/merge/error.js.map +1 -0
- package/dist/core/asyncapi/merge/markers.js +308 -0
- package/dist/core/asyncapi/merge/markers.js.map +1 -0
- package/dist/core/asyncapi/merge/merge.js +215 -0
- package/dist/core/asyncapi/merge/merge.js.map +1 -0
- package/dist/core/asyncapi/merge/pin.js +107 -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.js → asyncapi/read.js} +95 -109
- package/dist/core/asyncapi/read.js.map +1 -0
- package/dist/core/brief/brief.js +225 -0
- package/dist/core/brief/brief.js.map +1 -0
- package/dist/core/brief/checks.js +250 -0
- package/dist/core/brief/checks.js.map +1 -0
- package/dist/core/brief/landscape.js +194 -0
- package/dist/core/brief/landscape.js.map +1 -0
- package/dist/core/brief/targets.js +226 -0
- package/dist/core/brief/targets.js.map +1 -0
- package/dist/core/brief/unchecked.js +47 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +282 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/likec4.js +88 -0
- package/dist/core/c4/likec4.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 +57 -0
- package/dist/core/c4/parsed/values.js.map +1 -0
- package/dist/core/c4/parsed/view-ids.js +75 -0
- package/dist/core/c4/parsed/view-ids.js.map +1 -0
- package/dist/core/c4/project/architecture.js +45 -0
- package/dist/core/c4/project/architecture.js.map +1 -0
- package/dist/core/c4/project/documents.js +58 -0
- package/dist/core/c4/project/documents.js.map +1 -0
- package/dist/core/c4/project/load.js +183 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/resolve/service.js +113 -0
- package/dist/core/c4/resolve/service.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 +109 -0
- package/dist/core/c4/seed/template.js.map +1 -0
- package/dist/core/c4/source-mask.js +82 -0
- package/dist/core/c4/source-mask.js.map +1 -0
- package/dist/core/c4/source-scan.js +227 -0
- package/dist/core/c4/source-scan.js.map +1 -0
- package/dist/core/c4/splice/authored-source.js +101 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -0
- package/dist/core/c4/splice/contract.js +10 -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/edges.js +36 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +269 -0
- package/dist/core/c4/splice/landscape-merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +194 -0
- package/dist/core/c4/splice/placement.js.map +1 -0
- package/dist/core/c4/workspace.js +172 -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 +50 -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 +342 -0
- package/dist/core/capabilities/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/findings.js +181 -0
- package/dist/core/capabilities/realizes/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/join.js +143 -0
- package/dist/core/capabilities/realizes/join.js.map +1 -0
- package/dist/core/capabilities/rollup.js +199 -0
- package/dist/core/capabilities/rollup.js.map +1 -0
- package/dist/core/capabilities/tree.js +126 -0
- package/dist/core/capabilities/tree.js.map +1 -0
- package/dist/core/capabilities/usecase-join.js +277 -0
- package/dist/core/capabilities/usecase-join.js.map +1 -0
- package/dist/core/coherence/authoring/scaffold.js +177 -0
- package/dist/core/coherence/authoring/scaffold.js.map +1 -0
- package/dist/core/coherence/authoring/sentinels.js +74 -0
- package/dist/core/coherence/authoring/sentinels.js.map +1 -0
- package/dist/core/coherence/coherence.js +251 -0
- package/dist/core/coherence/coherence.js.map +1 -0
- package/dist/core/coherence/declared.js +269 -0
- package/dist/core/coherence/declared.js.map +1 -0
- package/dist/core/coherence/events/declared.js +206 -0
- package/dist/core/coherence/events/declared.js.map +1 -0
- package/dist/core/coherence/events/events.js +204 -0
- package/dist/core/coherence/events/events.js.map +1 -0
- package/dist/core/coherence/events/grades.js +166 -0
- package/dist/core/coherence/events/grades.js.map +1 -0
- package/dist/core/coherence/events/lookups.js +122 -0
- package/dist/core/coherence/events/lookups.js.map +1 -0
- package/dist/core/coherence/events/merged.js +40 -0
- package/dist/core/coherence/events/merged.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 +155 -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/conflict-markers.js +60 -0
- package/dist/core/conflict-markers.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 +296 -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/diff/base-git.js +148 -0
- package/dist/core/diff/base-git.js.map +1 -0
- package/dist/core/diff/base-state.js +209 -0
- package/dist/core/diff/base-state.js.map +1 -0
- package/dist/core/diff/current-state.js +96 -0
- package/dist/core/diff/current-state.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +188 -0
- package/dist/core/diff/scope/changed-paths.js.map +1 -0
- package/dist/core/diff/semantic.js +243 -0
- package/dist/core/diff/semantic.js.map +1 -0
- package/dist/core/diff/victims.js +247 -0
- package/dist/core/diff/victims.js.map +1 -0
- package/dist/core/docs.js +7 -64
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +222 -0
- package/dist/core/doctor/agents.js.map +1 -0
- package/dist/core/doctor/config.js +135 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/doctor.js +275 -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/residue.js +110 -0
- package/dist/core/doctor/residue.js.map +1 -0
- package/dist/core/document/apply.js +77 -0
- package/dist/core/document/apply.js.map +1 -0
- package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -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 +263 -0
- package/dist/core/document/parse.js.map +1 -0
- package/dist/core/document/scenarios.js +221 -0
- package/dist/core/document/scenarios.js.map +1 -0
- package/dist/core/document/spec.js +241 -0
- package/dist/core/document/spec.js.map +1 -0
- package/dist/core/{config.js → envelope/config.js} +79 -18
- package/dist/core/envelope/config.js.map +1 -0
- package/dist/core/envelope/json.js +175 -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 +175 -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 +181 -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.js +144 -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.js → explore/explore.js} +50 -101
- package/dist/core/explore/explore.js.map +1 -0
- package/dist/core/fleet-context.js +120 -78
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +201 -0
- package/dist/core/gate/checks.js.map +1 -0
- package/dist/core/gate/partners.js +205 -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 +113 -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 +234 -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 +106 -0
- package/dist/core/glossary/delta.js.map +1 -0
- package/dist/core/glossary/tree.js +86 -0
- package/dist/core/glossary/tree.js.map +1 -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/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} +18 -4
- package/dist/core/kernel/path-safety.js.map +1 -0
- package/dist/core/kernel/records.js.map +1 -0
- package/dist/core/links/backlinks.js +68 -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 +104 -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 +236 -0
- package/dist/core/links/parse.js.map +1 -0
- package/dist/core/mcp/argv.js +111 -0
- package/dist/core/mcp/argv.js.map +1 -0
- package/dist/core/mcp/author-tools.js +72 -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 +314 -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 +166 -0
- package/dist/core/openapi/baseline/gate.js.map +1 -0
- package/dist/core/openapi/baseline/plan.js +112 -0
- package/dist/core/openapi/baseline/plan.js.map +1 -0
- package/dist/core/openapi/baseline/record.js +175 -0
- package/dist/core/openapi/baseline/record.js.map +1 -0
- package/dist/core/openapi/depth.js +122 -0
- package/dist/core/openapi/depth.js.map +1 -0
- package/dist/core/openapi/digest.js +189 -0
- package/dist/core/openapi/digest.js.map +1 -0
- package/dist/core/{openapi.js → openapi/doc.js} +44 -106
- package/dist/core/openapi/doc.js.map +1 -0
- package/dist/core/openapi/merge/components.js +234 -0
- package/dist/core/openapi/merge/components.js.map +1 -0
- package/dist/core/openapi/merge/error.js +26 -0
- package/dist/core/openapi/merge/error.js.map +1 -0
- package/dist/core/openapi/merge/markers.js +208 -0
- package/dist/core/openapi/merge/markers.js.map +1 -0
- package/dist/core/openapi/merge/merge.js +256 -0
- package/dist/core/openapi/merge/merge.js.map +1 -0
- package/dist/core/openapi/merge/pin.js +128 -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 +221 -0
- package/dist/core/openspec/inventory.js.map +1 -0
- package/dist/core/openspec/model/mapping.js +76 -0
- package/dist/core/openspec/model/mapping.js.map +1 -0
- package/dist/core/openspec/model/model.js +65 -0
- package/dist/core/openspec/model/model.js.map +1 -0
- package/dist/core/openspec/scan/changes.js +235 -0
- package/dist/core/openspec/scan/changes.js.map +1 -0
- package/dist/core/openspec/scan/config.js +200 -0
- package/dist/core/openspec/scan/config.js.map +1 -0
- package/dist/core/openspec/scan/shape.js +260 -0
- package/dist/core/openspec/scan/shape.js.map +1 -0
- package/dist/core/openspec/scan/walk.js +133 -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 +118 -0
- package/dist/core/pack/living.js.map +1 -0
- package/dist/core/pack/pack.js +76 -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/provenance/findings.js +208 -0
- package/dist/core/provenance/findings.js.map +1 -0
- package/dist/core/provenance/git.js +225 -0
- package/dist/core/provenance/git.js.map +1 -0
- package/dist/core/provenance/gitq/moves.js +182 -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 +263 -0
- package/dist/core/provenance/sources.js.map +1 -0
- package/dist/core/provenance/stamp.js +232 -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 +192 -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 +236 -0
- package/dist/core/repo/paths.js.map +1 -0
- package/dist/core/repo/repo.js +248 -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 +52 -0
- package/dist/core/repo/tree/find.js.map +1 -0
- package/dist/core/repo/tree/fs.js +64 -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/views.js +172 -0
- package/dist/core/repo/tree/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +234 -0
- package/dist/core/repo/tree/walk.js.map +1 -0
- package/dist/core/results.js +99 -2
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +131 -0
- package/dist/core/scaffold/landscape.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 +241 -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 +206 -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 +98 -0
- package/dist/core/staging/recovery/intent.js.map +1 -0
- package/dist/core/staging/recovery/recover.js +126 -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.js +202 -0
- package/dist/core/staging/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +171 -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 +49 -0
- package/dist/core/status/actions/execution.js.map +1 -0
- package/dist/core/status/contracts.js +102 -0
- package/dist/core/status/contracts.js.map +1 -0
- package/dist/core/status/feature/artifacts.js +171 -0
- package/dist/core/status/feature/artifacts.js.map +1 -0
- package/dist/core/status/feature/feature.js +207 -0
- package/dist/core/status/feature/feature.js.map +1 -0
- package/dist/core/status/feature/next.js +150 -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/fleet/fleet.js +187 -0
- package/dist/core/status/fleet/fleet.js.map +1 -0
- package/dist/core/status/fleet/next.js +207 -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 +201 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/usecases/capability.js +169 -0
- package/dist/core/usecases/capability.js.map +1 -0
- package/dist/core/usecases/delta/claims.js +116 -0
- package/dist/core/usecases/delta/claims.js.map +1 -0
- package/dist/core/usecases/delta/flows.js +103 -0
- package/dist/core/usecases/delta/flows.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +235 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -0
- package/dist/core/usecases/fleet.js +137 -0
- package/dist/core/usecases/fleet.js.map +1 -0
- package/dist/core/usecases/operations.js +111 -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/touch.js +101 -0
- package/dist/core/usecases/touch.js.map +1 -0
- package/dist/core/verify/answers.js +173 -0
- package/dist/core/verify/answers.js.map +1 -0
- package/dist/core/verify/build.js +150 -0
- package/dist/core/verify/build.js.map +1 -0
- package/dist/core/verify/checklist.js +201 -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/file.js +257 -0
- package/dist/core/verify/file.js.map +1 -0
- package/dist/core/verify/pins/lint.js +157 -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/record.js +142 -0
- package/dist/core/verify/record.js.map +1 -0
- package/dist/core/verify/store/commit.js +89 -0
- package/dist/core/verify/store/commit.js.map +1 -0
- package/dist/core/verify/store/render.js +57 -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 +55 -0
- package/dist/core/vocabulary/issue.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +145 -0
- package/dist/core/vocabulary/maturity.js.map +1 -0
- package/dist/core/{report.js → vocabulary/report.js} +30 -2
- 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 +189 -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 +280 -0
- package/examples/docs/architecture/obligations.yaml +23 -0
- package/examples/docs/architecture/permissions.yaml +50 -0
- package/examples/docs/architecture/subsystems.likec4 +11 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +65 -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 +129 -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 +28 -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 +70 -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 +9 -0
- package/examples/docs/loam.json +3 -0
- package/examples/docs/services/checkout-web/model.likec4 +109 -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 +127 -0
- package/examples/docs/services/order-service/asyncapi.yaml +108 -0
- package/examples/docs/services/order-service/health.yaml +57 -0
- package/examples/docs/services/order-service/model.likec4 +138 -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 +73 -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 +67 -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 +117 -0
- package/examples/docs/services/platform/identity-service/health.yaml +70 -0
- package/examples/docs/services/platform/identity-service/model.likec4 +83 -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 +199 -0
- package/examples/docs/services/platform/notification-service/health.yaml +35 -0
- package/examples/docs/services/platform/notification-service/model.likec4 +118 -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.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- 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.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.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.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
- /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
- /package/dist/core/{records.js → kernel/records.js} +0 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { loadConfig } from "../../core/envelope/config.js";
|
|
2
|
+
import { emitJson, fail, repoPath, reportNoConfig } from "../../core/envelope/json.js";
|
|
3
|
+
import { maturityRollup } from "../../core/vocabulary/maturity.js";
|
|
4
|
+
import { FleetContext } from "../../core/fleet-context.js";
|
|
5
|
+
import { DocsRepoUnavailableError } from "../../core/repo/state.js";
|
|
6
|
+
import { capabilityRollup } from "../../core/capabilities/rollup.js";
|
|
7
|
+
import { invalidVocabularyFinding } from "../../core/capabilities/findings.js";
|
|
8
|
+
import { promisesKeptByFlows } from "../../core/usecases/capability.js";
|
|
9
|
+
import { fleetAdrCount, listFeatures, listFleetTree, listServices } from "../../core/repo/repo.js";
|
|
10
|
+
import { readGlossary } from "../../core/glossary/tree.js";
|
|
11
|
+
import { backlinkIndex } from "../../core/links/backlinks.js";
|
|
12
|
+
import { glossaryDir } from "../../core/repo/authored/paths.js";
|
|
13
|
+
import { docsRepoReady, reportDocsRepoError, reportRepositoryUnavailable } from "../policy/gate.js";
|
|
14
|
+
import { featureVerification, serviceViews } from "./views.js";
|
|
15
|
+
import { capabilityJson, featureJson, glossaryJson, ownersJson, serviceRows, subsystemsJson } from "./json.js";
|
|
16
|
+
import { printCapabilities, printFeatures, printGlossary, printOwners, printServices, printWorklist, } from "./print.js";
|
|
17
|
+
import { fanInByService, reviewLandscape, reviewOrder } from "./review.js";
|
|
18
|
+
import { resolveSubsystemSlice } from "./campaign/campaign.js";
|
|
19
|
+
import { ownersJoin } from "./campaign/owners.js";
|
|
20
|
+
const SECTIONS = ["services", "features", "capabilities", "glossary"];
|
|
21
|
+
/**
|
|
22
|
+
* What a bare `loam list` shows. `capabilities` is explicit-only, NEVER part
|
|
23
|
+
* of this default: the no-argument output and its `--json` payload are a
|
|
24
|
+
* frozen contract, byte-identical whether or not a fleet declares capabilities.
|
|
25
|
+
*/
|
|
26
|
+
const DEFAULT_SECTIONS = ["services", "features"];
|
|
27
|
+
export function registerList(program) {
|
|
28
|
+
program
|
|
29
|
+
.command("list")
|
|
30
|
+
.argument("[section]", "services | features | capabilities | glossary (default: services + features)")
|
|
31
|
+
.description("List the services and features in the docs repo")
|
|
32
|
+
.option("--json", "emit the machine contract instead of the human view")
|
|
33
|
+
.option("--archived", "include archived features")
|
|
34
|
+
.option("--needs-work", "services only: the adoption worklist — every service below `vouched`, with what it is missing")
|
|
35
|
+
.option("--review-order", "with --needs-work: order the worklist by blast radius — services the most other services depend on first")
|
|
36
|
+
.option("--subsystem <name>", "services only: limit the listing to services filed under this subsystem, at any depth ('unfiled' selects the ones filed under none, while nothing in the tree claims that name)")
|
|
37
|
+
.option("--owners <path>", "services only: group the listing by owning team from this CODEOWNERS file, resolved from the current directory (directory-pattern rules only; unsupported rules are listed as skipped, never guessed)")
|
|
38
|
+
.action(async (section, opts) => {
|
|
39
|
+
const json = opts.json === true;
|
|
40
|
+
// The campaign flags grade services, so — exactly like --needs-work —
|
|
41
|
+
// they narrow a bare `loam list` to the services section instead of
|
|
42
|
+
// printing a features table the filter silently does not apply to.
|
|
43
|
+
const campaign = opts.subsystem !== undefined || opts.owners !== undefined;
|
|
44
|
+
const wanted = opts.needsWork || campaign
|
|
45
|
+
? DEFAULT_SECTIONS.filter((s) => s === "services")
|
|
46
|
+
: section
|
|
47
|
+
? SECTIONS.filter((s) => s === section)
|
|
48
|
+
: DEFAULT_SECTIONS;
|
|
49
|
+
if (section && !SECTIONS.includes(section)) {
|
|
50
|
+
// `invalid-option`, same as show's bad --type: one mistake class, one code.
|
|
51
|
+
fail(json, "invalid-option", `Unknown section '${section}'. Expected: ${SECTIONS.join(" | ")}.`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (opts.needsWork && section === "features") {
|
|
55
|
+
fail(json, "invalid-option", "--needs-work is the service adoption worklist; drop the 'features' section.");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (campaign && section !== undefined && section !== "services") {
|
|
59
|
+
fail(json, "invalid-option", `--subsystem and --owners grade the services section; drop the '${section}' section.`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// The flag ORDERS the worklist, so it requires the worklist explicitly:
|
|
63
|
+
// silently implying --needs-work would make one flag change which rows
|
|
64
|
+
// exist, not only their order.
|
|
65
|
+
if (opts.reviewOrder && !opts.needsWork) {
|
|
66
|
+
fail(json, "invalid-option", "--review-order sorts the adoption worklist; add --needs-work.");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const loaded = await loadConfig();
|
|
70
|
+
if (loaded.kind !== "loaded") {
|
|
71
|
+
reportNoConfig(json, loaded);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const config = loaded.config;
|
|
75
|
+
const { docsDir } = config;
|
|
76
|
+
// A docsDir that is not a docs repo is refused, never rendered as an empty
|
|
77
|
+
// fleet — the whole point of the gate (see docs-repo-gate.ts).
|
|
78
|
+
// `list features` alone does not need services/, so it asks for less;
|
|
79
|
+
// the capability rollup walks every service's spec files, so it asks for them.
|
|
80
|
+
const needsServices = wanted.includes("services") || wanted.includes("capabilities") || wanted.includes("glossary");
|
|
81
|
+
if (!docsRepoReady(json, docsDir, needsServices ? "services" : "docs"))
|
|
82
|
+
return;
|
|
83
|
+
try {
|
|
84
|
+
// One context, one walk: the tree memo answers both the service
|
|
85
|
+
// entries and the subsystem/unfiled counts beside them.
|
|
86
|
+
const fleet = new FleetContext();
|
|
87
|
+
const tree = wanted.includes("services") ? await listFleetTree(docsDir, fleet) : undefined;
|
|
88
|
+
const services = wanted.includes("services") ? await listServices(docsDir, fleet) : undefined;
|
|
89
|
+
// --review-order parses the landscape ONCE for both of its consumers —
|
|
90
|
+
// serviceViews' `called` set (handed in as `preloaded`) and the fan-in
|
|
91
|
+
// joins below. Without the flag, `undefined` keeps serviceViews' own
|
|
92
|
+
// load-if-exists behaviour and the run byte-identical to today's.
|
|
93
|
+
const land = opts.reviewOrder === true && services !== undefined
|
|
94
|
+
? await reviewLandscape(docsDir, fleet)
|
|
95
|
+
: undefined;
|
|
96
|
+
const views = services ? await serviceViews(docsDir, services, config.service, land) : undefined;
|
|
97
|
+
// The slice is resolved AFTER the full-fleet views, and rows are
|
|
98
|
+
// filtered rather than re-derived: fan-in, apiExpected and the missing
|
|
99
|
+
// lists are fleet facts, and a slice-first derivation would recompute
|
|
100
|
+
// them against a fleet with the callers outside the slice erased. The
|
|
101
|
+
// composition is pinned as filter-first-then-rank — ranks stay
|
|
102
|
+
// contiguous within the filtered set (test/list-campaign.test.ts).
|
|
103
|
+
// `tree !== undefined` is a type NARROWING, not a branch: a campaign
|
|
104
|
+
// flag forces the services section, so the tree always exists here.
|
|
105
|
+
const slice = opts.subsystem !== undefined && tree !== undefined
|
|
106
|
+
? resolveSubsystemSlice(tree, opts.subsystem, json)
|
|
107
|
+
: undefined;
|
|
108
|
+
if (slice === null)
|
|
109
|
+
return;
|
|
110
|
+
// Membership is by DIRECTORY: leaf ids can collide across a broken
|
|
111
|
+
// tree (`subsystem.name-collision`), and the directory is the row's
|
|
112
|
+
// actual identity — campaign.ts's SubsystemSlice says why.
|
|
113
|
+
const shown = slice === undefined ? views : views?.filter((v) => slice.members.has(v.entry.dir));
|
|
114
|
+
// The fleet's own decision records. Read unconditionally — it is one
|
|
115
|
+
// existsSync over `architecture/adrs/` and it belongs to the docs repo
|
|
116
|
+
// rather than to any section, so `loam list features --json` reports it
|
|
117
|
+
// as truthfully as `loam list services --json` does. Nothing grades it:
|
|
118
|
+
// an absent directory is 0 and 0 is a fine, permanent answer.
|
|
119
|
+
const fleetAdrs = await fleetAdrCount(docsDir);
|
|
120
|
+
const features = wanted.includes("features")
|
|
121
|
+
? await listFeatures(docsDir, { includeArchived: opts.archived }, fleet)
|
|
122
|
+
: undefined;
|
|
123
|
+
const verification = features
|
|
124
|
+
? await Promise.all(features.map((f) => featureVerification(docsDir, f)))
|
|
125
|
+
: undefined;
|
|
126
|
+
// The capability section: the vocabulary's own verdict decides the shape.
|
|
127
|
+
// An INVALID file refuses with `repository-unavailable` — an
|
|
128
|
+
// empty-looking success over a broken file is the silent hole this
|
|
129
|
+
// command already refuses elsewhere — while an ABSENT one is an honest
|
|
130
|
+
// empty answer, because the file is the axis's opt-in. The message is
|
|
131
|
+
// `capability.invalid`'s own sentence, not the fs-error helper's: the
|
|
132
|
+
// file WAS read, it just is not a vocabulary, and one diagnosis should
|
|
133
|
+
// have one spelling wherever it surfaces.
|
|
134
|
+
const capabilityVocab = wanted.includes("capabilities")
|
|
135
|
+
? await fleet.capabilities(docsDir)
|
|
136
|
+
: undefined;
|
|
137
|
+
const brokenVocab = capabilityVocab === undefined ? null : invalidVocabularyFinding(capabilityVocab);
|
|
138
|
+
if (brokenVocab !== null) {
|
|
139
|
+
fail(json, "repository-unavailable", brokenVocab.message);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
// The SECOND corpus behind a capability's promises: the `#cap-`/`#req-`
|
|
143
|
+
// tagged flows. Read only under `loam list capabilities`, and
|
|
144
|
+
// `promisesKeptByFlows` carries `readUseCases`' byte gate, so a fleet
|
|
145
|
+
// whose architecture/ never mentions the reserved tag prefix pays a
|
|
146
|
+
// readdir here rather than a LikeC4 workspace.
|
|
147
|
+
//
|
|
148
|
+
// AN UNREADABLE architecture/ DEGRADES, it does not refuse — the
|
|
149
|
+
// opposite of the invalid vocabulary above, and the difference is which
|
|
150
|
+
// corpus broke. `architecture/capabilities.yaml` is what the ROWS are
|
|
151
|
+
// built from: unreadable, there is no listing to print, so refusing is
|
|
152
|
+
// the only honest answer. The flows are a second corpus over rows that
|
|
153
|
+
// are already true, and refusing the whole listing because a use-case
|
|
154
|
+
// document has a syntax error would take `loam list capabilities` away
|
|
155
|
+
// during exactly the minutes somebody is fixing that document, while
|
|
156
|
+
// `validate` already reports it as `landscape.invalid`. So the join is
|
|
157
|
+
// withheld instead — every `keptBy` absent rather than `[]` — and the
|
|
158
|
+
// reason is stated, which is `core/pack/joins.ts`' holes idiom: carry
|
|
159
|
+
// what is true, name what could not be looked at, never let the two read
|
|
160
|
+
// the same.
|
|
161
|
+
const entries = capabilityVocab === undefined ? undefined : await listServices(docsDir, fleet);
|
|
162
|
+
const promises = capabilityVocab === undefined || entries === undefined
|
|
163
|
+
? undefined
|
|
164
|
+
: await promisesKeptByFlows({
|
|
165
|
+
docsDir,
|
|
166
|
+
vocab: capabilityVocab,
|
|
167
|
+
known: new Set(entries.map((e) => e.id)),
|
|
168
|
+
read: (p) => fleet.readRequirements(p),
|
|
169
|
+
});
|
|
170
|
+
const capabilities = capabilityVocab === undefined || entries === undefined
|
|
171
|
+
? undefined
|
|
172
|
+
: await capabilityRollup({
|
|
173
|
+
services: entries,
|
|
174
|
+
vocab: capabilityVocab,
|
|
175
|
+
read: (p) => fleet.readRequirements(p),
|
|
176
|
+
...(promises?.kind === "read" ? { keptByFlows: promises.kept } : {}),
|
|
177
|
+
});
|
|
178
|
+
// The glossary section: the tree, and who cites each term. The
|
|
179
|
+
// citation index is the expensive half — it reads every authored
|
|
180
|
+
// document in the repository — so it is built only when the section is
|
|
181
|
+
// asked for, and not at all when `glossary/` does not exist. The
|
|
182
|
+
// directory's existence is the axis's opt-in, exactly as it is for
|
|
183
|
+
// `capabilities/`, so a fleet without one prints an empty section
|
|
184
|
+
// rather than paying for a fleet-wide walk to say so.
|
|
185
|
+
const glossary = wanted.includes("glossary") ? await readGlossary(glossaryDir(docsDir)) : undefined;
|
|
186
|
+
const citations = glossary !== undefined && glossary.terms.length > 0 ? await backlinkIndex(docsDir, fleet) : undefined;
|
|
187
|
+
const terms = glossary?.terms.map((term) => ({
|
|
188
|
+
term,
|
|
189
|
+
linkedBy: citations === undefined ? [] : citations.linkersOf(term.path),
|
|
190
|
+
}));
|
|
191
|
+
const worklist = (shown ?? []).filter((v) => v.maturity !== "vouched");
|
|
192
|
+
// The ranked review queue, derived never stored: fan-in is computed
|
|
193
|
+
// FLEET-WIDE (the joins need every service's slice anyway — and a
|
|
194
|
+
// --subsystem filter must never change a service's count, only which
|
|
195
|
+
// rows appear) while ranks are assigned over the WORKLIST only — a
|
|
196
|
+
// vouched service needs no review, and ranking it would put gaps in
|
|
197
|
+
// the queue. The worklist is already sliced, so under --subsystem the
|
|
198
|
+
// ranks are contiguous within the filtered set.
|
|
199
|
+
let ranked;
|
|
200
|
+
if (opts.reviewOrder === true && services !== undefined) {
|
|
201
|
+
const fanIn = await fanInByService(services, fleet, land ?? null);
|
|
202
|
+
ranked = { queue: reviewOrder(worklist, fanIn), fanIn };
|
|
203
|
+
}
|
|
204
|
+
// THE row set of this listing, spelled once: the owners join, the
|
|
205
|
+
// `services[]` payload and the text view must all be about the same
|
|
206
|
+
// rows — `owners.teams[]` is only "that team's campaign worklist"
|
|
207
|
+
// while it was computed over the rows `services[]` lists — and three
|
|
208
|
+
// copies of this expression is how they would drift apart.
|
|
209
|
+
const rows = shown === undefined ? undefined : (ranked?.queue ?? (opts.needsWork ? worklist : shown));
|
|
210
|
+
let owned;
|
|
211
|
+
if (opts.owners !== undefined && rows !== undefined) {
|
|
212
|
+
const join = await ownersJoin({
|
|
213
|
+
path: opts.owners,
|
|
214
|
+
rows: rows.map((v) => ({ id: v.entry.id, repoDir: repoPath(docsDir, v.entry.dir) })),
|
|
215
|
+
json,
|
|
216
|
+
});
|
|
217
|
+
if (join === null)
|
|
218
|
+
return;
|
|
219
|
+
owned = join;
|
|
220
|
+
}
|
|
221
|
+
if (json) {
|
|
222
|
+
emitJson({
|
|
223
|
+
command: "list",
|
|
224
|
+
docsDir,
|
|
225
|
+
// Additive, unconditional and flat, mirroring the per-service
|
|
226
|
+
// `adrs` key one row down rather than inventing a second shape for
|
|
227
|
+
// the same number. Not nested under the services section: the fleet
|
|
228
|
+
// has decision records whether or not this run listed services.
|
|
229
|
+
fleetAdrs,
|
|
230
|
+
...(rows && shown
|
|
231
|
+
? {
|
|
232
|
+
services: serviceRows(docsDir, ranked ?? rows),
|
|
233
|
+
// Under --subsystem the dial is the SLICE's — the filter's
|
|
234
|
+
// whole answer — while unfiltered runs keep the full fleet's
|
|
235
|
+
// rollup, byte-identical to before the flag existed.
|
|
236
|
+
maturity: maturityRollup(shown),
|
|
237
|
+
// The tree beside the table — additive keys, wave 3 of the
|
|
238
|
+
// subsystem item: the groups, and how many services sit
|
|
239
|
+
// unfiled (a permanent, normal state, so a count, never a
|
|
240
|
+
// finding). Under --subsystem the rows narrow to the named
|
|
241
|
+
// group and its descendants; memberCount stays transitive
|
|
242
|
+
// because the full tree's services back the modified copy.
|
|
243
|
+
subsystems: subsystemsJson(docsDir, slice === undefined ? tree : { ...tree, subsystems: slice.subsystems }),
|
|
244
|
+
// `unfiledServices` is a fleet-root fact: under a filter it
|
|
245
|
+
// is omitted rather than reported as 0, which would lie.
|
|
246
|
+
...(slice === undefined
|
|
247
|
+
? { unfiledServices: tree.services.filter((s) => s.subsystem.length === 0).length }
|
|
248
|
+
: {}),
|
|
249
|
+
}
|
|
250
|
+
: {}),
|
|
251
|
+
...(owned !== undefined ? { owners: ownersJson(owned) } : {}),
|
|
252
|
+
...(features
|
|
253
|
+
? { features: features.map((f, i) => featureJson(docsDir, f, verification[i] ?? null)) }
|
|
254
|
+
: {}),
|
|
255
|
+
...(capabilities ? { capabilities: capabilities.map(capabilityJson) } : {}),
|
|
256
|
+
...(terms ? { glossary: terms.map((t) => glossaryJson(t.term, t.linkedBy, docsDir)) } : {}),
|
|
257
|
+
// What the citation walk could not read, beside the rows it
|
|
258
|
+
// decorates — `useCases` below is the same shape for the same
|
|
259
|
+
// reason. An empty `linkedBy` means loam read every authored
|
|
260
|
+
// document and none cites the term; this key is how a reader tells
|
|
261
|
+
// that from "one of them would not decode".
|
|
262
|
+
...(citations ? { links: { unreadable: citations.unreadable } } : {}),
|
|
263
|
+
// The use-case corpus's own health, beside the rows it decorates —
|
|
264
|
+
// `status --json` and `delta --json` already spell this key this
|
|
265
|
+
// way. It is what makes an absent `keptBy` legible: `unreadable:
|
|
266
|
+
// false` with no `keptBy` on a row means the document declares that
|
|
267
|
+
// promise and no flow keeps it, while `unreadable: true` means
|
|
268
|
+
// nobody could look. Emitted only with the capabilities section, so
|
|
269
|
+
// bare `loam list --json` is untouched.
|
|
270
|
+
...(promises === undefined
|
|
271
|
+
? {}
|
|
272
|
+
: {
|
|
273
|
+
useCases: {
|
|
274
|
+
unreadable: promises.kind === "unreadable",
|
|
275
|
+
...(promises.kind === "unreadable" && promises.errors[0] !== undefined
|
|
276
|
+
? { error: promises.errors[0] }
|
|
277
|
+
: {}),
|
|
278
|
+
},
|
|
279
|
+
}),
|
|
280
|
+
});
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (slice !== undefined && shown !== undefined) {
|
|
284
|
+
console.log(`filtered to ${slice.label}: ${shown.length} of ${views.length} service(s)`);
|
|
285
|
+
}
|
|
286
|
+
if (owned !== undefined && rows !== undefined && shown !== undefined) {
|
|
287
|
+
if (opts.needsWork && rows.length === 0) {
|
|
288
|
+
// printWorklist's own affordance, kept under the grouping flag:
|
|
289
|
+
// empty owner groups would answer "who owns the work" without
|
|
290
|
+
// saying there is none.
|
|
291
|
+
console.log(`nothing to do — all ${shown.length} service(s) are vouched`);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const kind = opts.needsWork
|
|
295
|
+
? `${rows.length} of ${shown.length} service(s) need work`
|
|
296
|
+
: `services (${rows.length})`;
|
|
297
|
+
const ordered = ranked === undefined ? "" : " — review order (fan-in: services depending on each)";
|
|
298
|
+
console.log(`${kind} — by owner (${owned.path})${ordered}`);
|
|
299
|
+
printOwners(owned, new Map(rows.map((v) => [repoPath(docsDir, v.entry.dir), v])), ranked?.fanIn);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
if (opts.needsWork) {
|
|
303
|
+
printWorklist(ranked === undefined ? worklist : ranked.queue, shown.length, ranked?.fanIn);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
// Under --subsystem the tree dial (subsystem and unfiled counts) is a
|
|
307
|
+
// fleet-root fact the filtered table must not claim, so no tree. The
|
|
308
|
+
// fleet's ADR count is not derived from the rows at all and stays.
|
|
309
|
+
if (shown)
|
|
310
|
+
printServices(shown, { tree: slice === undefined ? tree : undefined, adrs: fleetAdrs });
|
|
311
|
+
if (views && features)
|
|
312
|
+
console.log("");
|
|
313
|
+
if (features)
|
|
314
|
+
printFeatures(features, verification);
|
|
315
|
+
if (capabilities) {
|
|
316
|
+
if (capabilityVocab.present)
|
|
317
|
+
printCapabilities(capabilities, promises);
|
|
318
|
+
else
|
|
319
|
+
console.log("no architecture/capabilities.yaml — the fleet declares no capabilities");
|
|
320
|
+
}
|
|
321
|
+
if (terms && glossary) {
|
|
322
|
+
if (glossary.present) {
|
|
323
|
+
printGlossary(terms.map((t) => ({ id: t.term.id, linkedBy: t.linkedBy })), citations?.unreadable ?? []);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
console.log("no glossary/ — the fleet defines no domain terms");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
if (err instanceof DocsRepoUnavailableError) {
|
|
332
|
+
reportDocsRepoError(json, err);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
// One unreadable file used to escape as a stack trace (`internal` in
|
|
336
|
+
// --json), naming nothing. The enumeration is all-or-nothing — it reads
|
|
337
|
+
// every service's frontmatter to build one table — so the honest answer
|
|
338
|
+
// is a refusal that says WHICH path could not be read.
|
|
339
|
+
reportRepositoryUnavailable(json, err, "the listing would be missing a service", docsDir);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/list/list.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"../../core/envelope/config.js\";\nimport { emitJson, fail, repoPath, reportNoConfig } from \"../../core/envelope/json.js\";\nimport { maturityRollup } from \"../../core/vocabulary/maturity.js\";\nimport { FleetContext } from \"../../core/fleet-context.js\";\nimport { DocsRepoUnavailableError } from \"../../core/repo/state.js\";\nimport { capabilityRollup, type CapabilityRow } from \"../../core/capabilities/rollup.js\";\nimport { invalidVocabularyFinding } from \"../../core/capabilities/findings.js\";\nimport { promisesKeptByFlows } from \"../../core/usecases/capability.js\";\nimport { fleetAdrCount, listFeatures, listFleetTree, listServices } from \"../../core/repo/repo.js\";\nimport { readGlossary } from \"../../core/glossary/tree.js\";\nimport { backlinkIndex } from \"../../core/links/backlinks.js\";\nimport { glossaryDir } from \"../../core/repo/authored/paths.js\";\nimport { docsRepoReady, reportDocsRepoError, reportRepositoryUnavailable } from \"../policy/gate.js\";\nimport { featureVerification, serviceViews, type ServiceView } from \"./views.js\";\nimport { capabilityJson, featureJson, glossaryJson, ownersJson, serviceRows, subsystemsJson } from \"./json.js\";\nimport {\n printCapabilities,\n printFeatures,\n printGlossary,\n printOwners,\n printServices,\n printWorklist,\n} from \"./print.js\";\nimport { fanInByService, reviewLandscape, reviewOrder } from \"./review.js\";\nimport { resolveSubsystemSlice } from \"./campaign/campaign.js\";\nimport { ownersJoin, type OwnersJoin } from \"./campaign/owners.js\";\n\ntype Section = \"services\" | \"features\" | \"capabilities\" | \"glossary\";\nconst SECTIONS: Section[] = [\"services\", \"features\", \"capabilities\", \"glossary\"];\n/**\n * What a bare `loam list` shows. `capabilities` is explicit-only, NEVER part\n * of this default: the no-argument output and its `--json` payload are a\n * frozen contract, byte-identical whether or not a fleet declares capabilities.\n */\nconst DEFAULT_SECTIONS: Section[] = [\"services\", \"features\"];\n\ninterface ListOptions {\n json?: boolean;\n archived?: boolean;\n needsWork?: boolean;\n reviewOrder?: boolean;\n subsystem?: string;\n owners?: string;\n}\n\nexport function registerList(program: Command): void {\n program\n .command(\"list\")\n .argument(\"[section]\", \"services | features | capabilities | glossary (default: services + features)\")\n .description(\"List the services and features in the docs repo\")\n .option(\"--json\", \"emit the machine contract instead of the human view\")\n .option(\"--archived\", \"include archived features\")\n .option(\n \"--needs-work\",\n \"services only: the adoption worklist — every service below `vouched`, with what it is missing\",\n )\n .option(\n \"--review-order\",\n \"with --needs-work: order the worklist by blast radius — services the most other services depend on first\",\n )\n .option(\n \"--subsystem <name>\",\n \"services only: limit the listing to services filed under this subsystem, at any depth ('unfiled' selects the ones filed under none, while nothing in the tree claims that name)\",\n )\n .option(\n \"--owners <path>\",\n \"services only: group the listing by owning team from this CODEOWNERS file, resolved from the current directory (directory-pattern rules only; unsupported rules are listed as skipped, never guessed)\",\n )\n .action(async (section: string | undefined, opts: ListOptions) => {\n const json = opts.json === true;\n // The campaign flags grade services, so — exactly like --needs-work —\n // they narrow a bare `loam list` to the services section instead of\n // printing a features table the filter silently does not apply to.\n const campaign = opts.subsystem !== undefined || opts.owners !== undefined;\n const wanted =\n opts.needsWork || campaign\n ? DEFAULT_SECTIONS.filter((s) => s === \"services\")\n : section\n ? SECTIONS.filter((s) => s === section)\n : DEFAULT_SECTIONS;\n if (section && !SECTIONS.includes(section as Section)) {\n // `invalid-option`, same as show's bad --type: one mistake class, one code.\n fail(json, \"invalid-option\", `Unknown section '${section}'. Expected: ${SECTIONS.join(\" | \")}.`);\n return;\n }\n if (opts.needsWork && section === \"features\") {\n fail(json, \"invalid-option\", \"--needs-work is the service adoption worklist; drop the 'features' section.\");\n return;\n }\n if (campaign && section !== undefined && section !== \"services\") {\n fail(json, \"invalid-option\", `--subsystem and --owners grade the services section; drop the '${section}' section.`);\n return;\n }\n // The flag ORDERS the worklist, so it requires the worklist explicitly:\n // silently implying --needs-work would make one flag change which rows\n // exist, not only their order.\n if (opts.reviewOrder && !opts.needsWork) {\n fail(json, \"invalid-option\", \"--review-order sorts the adoption worklist; add --needs-work.\");\n return;\n }\n\n const loaded = await loadConfig();\n if (loaded.kind !== \"loaded\") {\n reportNoConfig(json, loaded);\n return;\n }\n const config = loaded.config;\n const { docsDir } = config;\n // A docsDir that is not a docs repo is refused, never rendered as an empty\n // fleet — the whole point of the gate (see docs-repo-gate.ts).\n // `list features` alone does not need services/, so it asks for less;\n // the capability rollup walks every service's spec files, so it asks for them.\n const needsServices =\n wanted.includes(\"services\") || wanted.includes(\"capabilities\") || wanted.includes(\"glossary\");\n if (!docsRepoReady(json, docsDir, needsServices ? \"services\" : \"docs\")) return;\n\n try {\n // One context, one walk: the tree memo answers both the service\n // entries and the subsystem/unfiled counts beside them.\n const fleet = new FleetContext();\n const tree = wanted.includes(\"services\") ? await listFleetTree(docsDir, fleet) : undefined;\n const services = wanted.includes(\"services\") ? await listServices(docsDir, fleet) : undefined;\n // --review-order parses the landscape ONCE for both of its consumers —\n // serviceViews' `called` set (handed in as `preloaded`) and the fan-in\n // joins below. Without the flag, `undefined` keeps serviceViews' own\n // load-if-exists behaviour and the run byte-identical to today's.\n const land =\n opts.reviewOrder === true && services !== undefined\n ? await reviewLandscape(docsDir, fleet)\n : undefined;\n const views = services ? await serviceViews(docsDir, services, config.service, land) : undefined;\n // The slice is resolved AFTER the full-fleet views, and rows are\n // filtered rather than re-derived: fan-in, apiExpected and the missing\n // lists are fleet facts, and a slice-first derivation would recompute\n // them against a fleet with the callers outside the slice erased. The\n // composition is pinned as filter-first-then-rank — ranks stay\n // contiguous within the filtered set (test/list-campaign.test.ts).\n // `tree !== undefined` is a type NARROWING, not a branch: a campaign\n // flag forces the services section, so the tree always exists here.\n const slice =\n opts.subsystem !== undefined && tree !== undefined\n ? resolveSubsystemSlice(tree, opts.subsystem, json)\n : undefined;\n if (slice === null) return;\n // Membership is by DIRECTORY: leaf ids can collide across a broken\n // tree (`subsystem.name-collision`), and the directory is the row's\n // actual identity — campaign.ts's SubsystemSlice says why.\n const shown = slice === undefined ? views : views?.filter((v) => slice.members.has(v.entry.dir));\n // The fleet's own decision records. Read unconditionally — it is one\n // existsSync over `architecture/adrs/` and it belongs to the docs repo\n // rather than to any section, so `loam list features --json` reports it\n // as truthfully as `loam list services --json` does. Nothing grades it:\n // an absent directory is 0 and 0 is a fine, permanent answer.\n const fleetAdrs = await fleetAdrCount(docsDir);\n const features = wanted.includes(\"features\")\n ? await listFeatures(docsDir, { includeArchived: opts.archived }, fleet)\n : undefined;\n const verification = features\n ? await Promise.all(features.map((f) => featureVerification(docsDir, f)))\n : undefined;\n\n // The capability section: the vocabulary's own verdict decides the shape.\n // An INVALID file refuses with `repository-unavailable` — an\n // empty-looking success over a broken file is the silent hole this\n // command already refuses elsewhere — while an ABSENT one is an honest\n // empty answer, because the file is the axis's opt-in. The message is\n // `capability.invalid`'s own sentence, not the fs-error helper's: the\n // file WAS read, it just is not a vocabulary, and one diagnosis should\n // have one spelling wherever it surfaces.\n const capabilityVocab = wanted.includes(\"capabilities\")\n ? await fleet.capabilities(docsDir)\n : undefined;\n const brokenVocab = capabilityVocab === undefined ? null : invalidVocabularyFinding(capabilityVocab);\n if (brokenVocab !== null) {\n fail(json, \"repository-unavailable\", brokenVocab.message);\n return;\n }\n // The SECOND corpus behind a capability's promises: the `#cap-`/`#req-`\n // tagged flows. Read only under `loam list capabilities`, and\n // `promisesKeptByFlows` carries `readUseCases`' byte gate, so a fleet\n // whose architecture/ never mentions the reserved tag prefix pays a\n // readdir here rather than a LikeC4 workspace.\n //\n // AN UNREADABLE architecture/ DEGRADES, it does not refuse — the\n // opposite of the invalid vocabulary above, and the difference is which\n // corpus broke. `architecture/capabilities.yaml` is what the ROWS are\n // built from: unreadable, there is no listing to print, so refusing is\n // the only honest answer. The flows are a second corpus over rows that\n // are already true, and refusing the whole listing because a use-case\n // document has a syntax error would take `loam list capabilities` away\n // during exactly the minutes somebody is fixing that document, while\n // `validate` already reports it as `landscape.invalid`. So the join is\n // withheld instead — every `keptBy` absent rather than `[]` — and the\n // reason is stated, which is `core/pack/joins.ts`' holes idiom: carry\n // what is true, name what could not be looked at, never let the two read\n // the same.\n const entries = capabilityVocab === undefined ? undefined : await listServices(docsDir, fleet);\n const promises =\n capabilityVocab === undefined || entries === undefined\n ? undefined\n : await promisesKeptByFlows({\n docsDir,\n vocab: capabilityVocab,\n known: new Set(entries.map((e) => e.id)),\n read: (p) => fleet.readRequirements(p),\n });\n const capabilities: CapabilityRow[] | undefined =\n capabilityVocab === undefined || entries === undefined\n ? undefined\n : await capabilityRollup({\n services: entries,\n vocab: capabilityVocab,\n read: (p) => fleet.readRequirements(p),\n ...(promises?.kind === \"read\" ? { keptByFlows: promises.kept } : {}),\n });\n\n // The glossary section: the tree, and who cites each term. The\n // citation index is the expensive half — it reads every authored\n // document in the repository — so it is built only when the section is\n // asked for, and not at all when `glossary/` does not exist. The\n // directory's existence is the axis's opt-in, exactly as it is for\n // `capabilities/`, so a fleet without one prints an empty section\n // rather than paying for a fleet-wide walk to say so.\n const glossary = wanted.includes(\"glossary\") ? await readGlossary(glossaryDir(docsDir)) : undefined;\n const citations =\n glossary !== undefined && glossary.terms.length > 0 ? await backlinkIndex(docsDir, fleet) : undefined;\n const terms = glossary?.terms.map((term) => ({\n term,\n linkedBy: citations === undefined ? [] : citations.linkersOf(term.path),\n }));\n\n const worklist = (shown ?? []).filter((v) => v.maturity !== \"vouched\");\n // The ranked review queue, derived never stored: fan-in is computed\n // FLEET-WIDE (the joins need every service's slice anyway — and a\n // --subsystem filter must never change a service's count, only which\n // rows appear) while ranks are assigned over the WORKLIST only — a\n // vouched service needs no review, and ranking it would put gaps in\n // the queue. The worklist is already sliced, so under --subsystem the\n // ranks are contiguous within the filtered set.\n let ranked: { queue: ServiceView[]; fanIn: ReadonlyMap<string, number> } | undefined;\n if (opts.reviewOrder === true && services !== undefined) {\n const fanIn = await fanInByService(services, fleet, land ?? null);\n ranked = { queue: reviewOrder(worklist, fanIn), fanIn };\n }\n\n // THE row set of this listing, spelled once: the owners join, the\n // `services[]` payload and the text view must all be about the same\n // rows — `owners.teams[]` is only \"that team's campaign worklist\"\n // while it was computed over the rows `services[]` lists — and three\n // copies of this expression is how they would drift apart.\n const rows = shown === undefined ? undefined : (ranked?.queue ?? (opts.needsWork ? worklist : shown));\n\n let owned: OwnersJoin | undefined;\n if (opts.owners !== undefined && rows !== undefined) {\n const join = await ownersJoin({\n path: opts.owners,\n rows: rows.map((v) => ({ id: v.entry.id, repoDir: repoPath(docsDir, v.entry.dir) })),\n json,\n });\n if (join === null) return;\n owned = join;\n }\n\n if (json) {\n emitJson({\n command: \"list\",\n docsDir,\n // Additive, unconditional and flat, mirroring the per-service\n // `adrs` key one row down rather than inventing a second shape for\n // the same number. Not nested under the services section: the fleet\n // has decision records whether or not this run listed services.\n fleetAdrs,\n ...(rows && shown\n ? {\n services: serviceRows(docsDir, ranked ?? rows),\n // Under --subsystem the dial is the SLICE's — the filter's\n // whole answer — while unfiltered runs keep the full fleet's\n // rollup, byte-identical to before the flag existed.\n maturity: maturityRollup(shown),\n // The tree beside the table — additive keys, wave 3 of the\n // subsystem item: the groups, and how many services sit\n // unfiled (a permanent, normal state, so a count, never a\n // finding). Under --subsystem the rows narrow to the named\n // group and its descendants; memberCount stays transitive\n // because the full tree's services back the modified copy.\n subsystems: subsystemsJson(\n docsDir,\n slice === undefined ? tree! : { ...tree!, subsystems: slice.subsystems },\n ),\n // `unfiledServices` is a fleet-root fact: under a filter it\n // is omitted rather than reported as 0, which would lie.\n ...(slice === undefined\n ? { unfiledServices: tree!.services.filter((s) => s.subsystem.length === 0).length }\n : {}),\n }\n : {}),\n ...(owned !== undefined ? { owners: ownersJson(owned) } : {}),\n ...(features\n ? { features: features.map((f, i) => featureJson(docsDir, f, verification![i] ?? null)) }\n : {}),\n ...(capabilities ? { capabilities: capabilities.map(capabilityJson) } : {}),\n ...(terms ? { glossary: terms.map((t) => glossaryJson(t.term, t.linkedBy, docsDir)) } : {}),\n // What the citation walk could not read, beside the rows it\n // decorates — `useCases` below is the same shape for the same\n // reason. An empty `linkedBy` means loam read every authored\n // document and none cites the term; this key is how a reader tells\n // that from \"one of them would not decode\".\n ...(citations ? { links: { unreadable: citations.unreadable } } : {}),\n // The use-case corpus's own health, beside the rows it decorates —\n // `status --json` and `delta --json` already spell this key this\n // way. It is what makes an absent `keptBy` legible: `unreadable:\n // false` with no `keptBy` on a row means the document declares that\n // promise and no flow keeps it, while `unreadable: true` means\n // nobody could look. Emitted only with the capabilities section, so\n // bare `loam list --json` is untouched.\n ...(promises === undefined\n ? {}\n : {\n useCases: {\n unreadable: promises.kind === \"unreadable\",\n ...(promises.kind === \"unreadable\" && promises.errors[0] !== undefined\n ? { error: promises.errors[0] }\n : {}),\n },\n }),\n });\n return;\n }\n\n if (slice !== undefined && shown !== undefined) {\n console.log(`filtered to ${slice.label}: ${shown.length} of ${views!.length} service(s)`);\n }\n if (owned !== undefined && rows !== undefined && shown !== undefined) {\n if (opts.needsWork && rows.length === 0) {\n // printWorklist's own affordance, kept under the grouping flag:\n // empty owner groups would answer \"who owns the work\" without\n // saying there is none.\n console.log(`nothing to do — all ${shown.length} service(s) are vouched`);\n return;\n }\n const kind = opts.needsWork\n ? `${rows.length} of ${shown.length} service(s) need work`\n : `services (${rows.length})`;\n const ordered =\n ranked === undefined ? \"\" : \" — review order (fan-in: services depending on each)\";\n console.log(`${kind} — by owner (${owned.path})${ordered}`);\n printOwners(owned, new Map(rows.map((v) => [repoPath(docsDir, v.entry.dir), v])), ranked?.fanIn);\n return;\n }\n if (opts.needsWork) {\n printWorklist(ranked === undefined ? worklist : ranked.queue, shown!.length, ranked?.fanIn);\n return;\n }\n // Under --subsystem the tree dial (subsystem and unfiled counts) is a\n // fleet-root fact the filtered table must not claim, so no tree. The\n // fleet's ADR count is not derived from the rows at all and stays.\n if (shown) printServices(shown, { tree: slice === undefined ? tree : undefined, adrs: fleetAdrs });\n if (views && features) console.log(\"\");\n if (features) printFeatures(features, verification!);\n if (capabilities) {\n if (capabilityVocab!.present) printCapabilities(capabilities, promises!);\n else console.log(\"no architecture/capabilities.yaml — the fleet declares no capabilities\");\n }\n if (terms && glossary) {\n if (glossary.present) {\n printGlossary(\n terms.map((t) => ({ id: t.term.id, linkedBy: t.linkedBy })),\n citations?.unreadable ?? [],\n );\n } else {\n console.log(\"no glossary/ — the fleet defines no domain terms\");\n }\n }\n } catch (err) {\n if (err instanceof DocsRepoUnavailableError) {\n reportDocsRepoError(json, err);\n return;\n }\n // One unreadable file used to escape as a stack trace (`internal` in\n // --json), naming nothing. The enumeration is all-or-nothing — it reads\n // every service's frontmatter to build one table — so the honest answer\n // is a refusal that says WHICH path could not be read.\n reportRepositoryUnavailable(json, err, \"the listing would be missing a service\", docsDir);\n }\n });\n}\n\n"]}
|