@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5992 -82
- package/COMPARISON.md +168 -63
- package/CONTRIBUTING.md +121 -0
- package/MIGRATING-from-OpenSpec.md +238 -55
- package/QUICKSTART.md +302 -0
- package/README.md +653 -144
- package/ROADMAP.md +1035 -0
- package/SCHEMA.md +3916 -263
- package/SECURITY.md +21 -3
- package/WORKFLOW.md +927 -0
- package/dist/cli.js +133 -21
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +204 -0
- package/dist/commands/adopt/adopt.js.map +1 -0
- package/dist/commands/adopt/render.js +309 -0
- package/dist/commands/adopt/render.js.map +1 -0
- package/dist/commands/archive/archive.js +74 -0
- package/dist/commands/archive/archive.js.map +1 -0
- package/dist/commands/archive/closing.js +42 -0
- package/dist/commands/archive/closing.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/consumers.js +56 -0
- package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +193 -0
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
- package/dist/commands/archive/plan/document/head.js +151 -0
- package/dist/commands/archive/plan/document/head.js.map +1 -0
- package/dist/commands/archive/plan/document/links.js +284 -0
- package/dist/commands/archive/plan/document/links.js.map +1 -0
- package/dist/commands/archive/plan/document/run.js +136 -0
- package/dist/commands/archive/plan/document/run.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +319 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +298 -0
- package/dist/commands/archive/plan/landscape.js.map +1 -0
- package/dist/commands/archive/plan/model/extending.js +85 -0
- package/dist/commands/archive/plan/model/extending.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +106 -0
- package/dist/commands/archive/plan/refusal.js.map +1 -0
- package/dist/commands/archive/plan/specs.js +318 -0
- package/dist/commands/archive/plan/specs.js.map +1 -0
- package/dist/commands/archive/plan/state.js +30 -0
- package/dist/commands/archive/plan/state.js.map +1 -0
- package/dist/commands/archive/run.js +355 -0
- package/dist/commands/archive/run.js.map +1 -0
- package/dist/commands/archive/shipped.js +49 -0
- package/dist/commands/archive/shipped.js.map +1 -0
- package/dist/commands/context/context.js +166 -0
- package/dist/commands/context/context.js.map +1 -0
- package/dist/commands/context/print.js +305 -0
- package/dist/commands/context/print.js.map +1 -0
- package/dist/commands/delta/delta.js +367 -0
- package/dist/commands/delta/delta.js.map +1 -0
- package/dist/commands/delta/print.js +221 -0
- package/dist/commands/delta/print.js.map +1 -0
- package/dist/commands/dependencies.js +6 -8
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +86 -0
- package/dist/commands/diff/diff.js.map +1 -0
- package/dist/commands/diff/print.js +38 -0
- package/dist/commands/diff/print.js.map +1 -0
- package/dist/commands/doctor.js +65 -5
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +227 -0
- package/dist/commands/explain/explain.js.map +1 -0
- package/dist/commands/explore.js +39 -28
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +152 -0
- package/dist/commands/gate/gate.js.map +1 -0
- package/dist/commands/gate/print.js +66 -0
- package/dist/commands/gate/print.js.map +1 -0
- package/dist/commands/gherkin/commit.js +105 -0
- package/dist/commands/gherkin/commit.js.map +1 -0
- package/dist/commands/gherkin/gherkin.js +262 -0
- package/dist/commands/gherkin/gherkin.js.map +1 -0
- package/dist/commands/gherkin/reconcile.js +146 -0
- package/dist/commands/gherkin/reconcile.js.map +1 -0
- package/dist/commands/gherkin/render.js +77 -0
- package/dist/commands/gherkin/render.js.map +1 -0
- package/dist/commands/init/example.js +204 -0
- package/dist/commands/init/example.js.map +1 -0
- package/dist/commands/init/first-hour.js +72 -0
- package/dist/commands/init/first-hour.js.map +1 -0
- package/dist/commands/{init.js → init/init.js} +142 -71
- package/dist/commands/init/init.js.map +1 -0
- package/dist/commands/init/mcp.js +131 -0
- package/dist/commands/init/mcp.js.map +1 -0
- package/dist/commands/init/options.js +78 -0
- package/dist/commands/init/options.js.map +1 -0
- package/dist/commands/instructions.js +72 -14
- package/dist/commands/instructions.js.map +1 -1
- package/dist/commands/list/campaign/campaign.js +63 -0
- package/dist/commands/list/campaign/campaign.js.map +1 -0
- package/dist/commands/list/campaign/owners.js +65 -0
- package/dist/commands/list/campaign/owners.js.map +1 -0
- package/dist/commands/list/json.js +155 -0
- package/dist/commands/list/json.js.map +1 -0
- package/dist/commands/list/list.js +358 -0
- package/dist/commands/list/list.js.map +1 -0
- package/dist/commands/list/print.js +344 -0
- package/dist/commands/list/print.js.map +1 -0
- package/dist/commands/list/review.js +120 -0
- package/dist/commands/list/review.js.map +1 -0
- package/dist/commands/list/suites/suites.js +140 -0
- package/dist/commands/list/suites/suites.js.map +1 -0
- package/dist/commands/list/views.js +108 -0
- package/dist/commands/list/views.js.map +1 -0
- package/dist/commands/mcp/dispatch.js +238 -0
- package/dist/commands/mcp/dispatch.js.map +1 -0
- package/dist/commands/mcp/mcp.js +75 -0
- package/dist/commands/mcp/mcp.js.map +1 -0
- package/dist/commands/mcp/serve.js +55 -0
- package/dist/commands/mcp/serve.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/active.js +175 -0
- package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
- package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/living.js +62 -0
- package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
- package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/target.js +219 -0
- package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/error.js +18 -0
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
- package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/read.js +49 -0
- package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
- package/dist/commands/migrate-openspec/print.js +89 -0
- package/dist/commands/migrate-openspec/print.js.map +1 -0
- package/dist/commands/new/capability-template.js +118 -0
- package/dist/commands/new/capability-template.js.map +1 -0
- package/dist/commands/new/commit.js +62 -0
- package/dist/commands/new/commit.js.map +1 -0
- package/dist/commands/new/modifies.js +206 -0
- package/dist/commands/new/modifies.js.map +1 -0
- package/dist/commands/new/new.js +328 -0
- package/dist/commands/new/new.js.map +1 -0
- package/dist/commands/new/templates.js +279 -0
- package/dist/commands/new/templates.js.map +1 -0
- package/dist/commands/open.js +199 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/policy/format.js +152 -0
- package/dist/commands/policy/format.js.map +1 -0
- package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
- package/dist/commands/policy/gate.js.map +1 -0
- package/dist/commands/rebase/edit.js +106 -0
- package/dist/commands/rebase/edit.js.map +1 -0
- package/dist/commands/rebase/living.js +185 -0
- package/dist/commands/rebase/living.js.map +1 -0
- package/dist/commands/rebase/plan.js +245 -0
- package/dist/commands/rebase/plan.js.map +1 -0
- package/dist/commands/rebase/rebase.js +300 -0
- package/dist/commands/rebase/rebase.js.map +1 -0
- package/dist/commands/seed/commit.js +221 -0
- package/dist/commands/seed/commit.js.map +1 -0
- package/dist/commands/seed/plan.js +278 -0
- package/dist/commands/seed/plan.js.map +1 -0
- package/dist/commands/seed/seed.js +174 -0
- package/dist/commands/seed/seed.js.map +1 -0
- package/dist/commands/show/feature.js +182 -0
- package/dist/commands/show/feature.js.map +1 -0
- package/dist/commands/show/introduced.js +157 -0
- package/dist/commands/show/introduced.js.map +1 -0
- package/dist/commands/show/marks.js +53 -0
- package/dist/commands/show/marks.js.map +1 -0
- package/dist/commands/show/service.js +239 -0
- package/dist/commands/show/service.js.map +1 -0
- package/dist/commands/show/show.js +87 -0
- package/dist/commands/show/show.js.map +1 -0
- package/dist/commands/status/fleet-next.js +90 -0
- package/dist/commands/status/fleet-next.js.map +1 -0
- package/dist/commands/status/json.js +47 -0
- package/dist/commands/status/json.js.map +1 -0
- package/dist/commands/status/print.js +209 -0
- package/dist/commands/status/print.js.map +1 -0
- package/dist/commands/status/status.js +115 -0
- package/dist/commands/status/status.js.map +1 -0
- package/dist/commands/steps/steps.js +269 -0
- package/dist/commands/steps/steps.js.map +1 -0
- package/dist/commands/subsystem/edit.js +192 -0
- package/dist/commands/subsystem/edit.js.map +1 -0
- package/dist/commands/subsystem/move.js +325 -0
- package/dist/commands/subsystem/move.js.map +1 -0
- package/dist/commands/subsystem/query.js +113 -0
- package/dist/commands/subsystem/query.js.map +1 -0
- package/dist/commands/subsystem/subsystem.js +98 -0
- package/dist/commands/subsystem/subsystem.js.map +1 -0
- package/dist/commands/subsystem/sync.js +318 -0
- package/dist/commands/subsystem/sync.js.map +1 -0
- package/dist/commands/subsystem/txn/exclude.js +132 -0
- package/dist/commands/subsystem/txn/exclude.js.map +1 -0
- package/dist/commands/subsystem/txn/links.js +128 -0
- package/dist/commands/subsystem/txn/links.js.map +1 -0
- package/dist/commands/subsystem/txn/report.js +174 -0
- package/dist/commands/subsystem/txn/report.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +196 -0
- package/dist/commands/subsystem/txn/txn.js.map +1 -0
- package/dist/commands/subsystem/txn/views.js +249 -0
- package/dist/commands/subsystem/txn/views.js.map +1 -0
- package/dist/commands/tasks/actions.js +107 -0
- package/dist/commands/tasks/actions.js.map +1 -0
- package/dist/commands/tasks/render.js +253 -0
- package/dist/commands/tasks/render.js.map +1 -0
- package/dist/commands/tasks/tasks.js +119 -0
- package/dist/commands/tasks/tasks.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +176 -0
- package/dist/commands/unarchive/manifest.js.map +1 -0
- package/dist/commands/unarchive/restore.js +254 -0
- package/dist/commands/unarchive/restore.js.map +1 -0
- package/dist/commands/unarchive/unarchive.js +59 -0
- package/dist/commands/unarchive/unarchive.js.map +1 -0
- package/dist/commands/validate/arch-coverage.js +245 -0
- package/dist/commands/validate/arch-coverage.js.map +1 -0
- package/dist/commands/validate/checks/fleet-shape.js +204 -0
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
- package/dist/commands/validate/checks/health-deps.js +58 -0
- package/dist/commands/validate/checks/health-deps.js.map +1 -0
- package/dist/commands/validate/checks/introduced.js +102 -0
- package/dist/commands/validate/checks/introduced.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +264 -0
- package/dist/commands/validate/checks/requirements.js.map +1 -0
- package/dist/commands/validate/checks/sources.js +85 -0
- package/dist/commands/validate/checks/sources.js.map +1 -0
- package/dist/commands/validate/coverage/covers-after.js +105 -0
- package/dist/commands/validate/coverage/covers-after.js.map +1 -0
- package/dist/commands/validate/feature.js +222 -0
- package/dist/commands/validate/feature.js.map +1 -0
- package/dist/commands/validate/fleet/census.js +93 -0
- package/dist/commands/validate/fleet/census.js.map +1 -0
- package/dist/commands/validate/fleet/kind-tags.js +39 -0
- package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
- package/dist/commands/validate/fleet/landscape.js +371 -0
- package/dist/commands/validate/fleet/landscape.js.map +1 -0
- package/dist/commands/validate/fleet/load.js +118 -0
- package/dist/commands/validate/fleet/load.js.map +1 -0
- package/dist/commands/validate/fleet/map/attest.js +98 -0
- package/dist/commands/validate/fleet/map/attest.js.map +1 -0
- package/dist/commands/validate/fleet/map/bindings.js +107 -0
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
- package/dist/commands/validate/fleet/map/consumers.js +244 -0
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
- package/dist/commands/validate/fleet/map/isolation.js +116 -0
- package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
- package/dist/commands/validate/fleet/map/usecases.js +54 -0
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +266 -0
- package/dist/commands/validate/fleet/obligations.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/print.js +71 -0
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/place.js +13 -0
- package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
- package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +75 -0
- package/dist/commands/validate/fleet/views/ids.js.map +1 -0
- package/dist/commands/validate/fleet/views/projects.js +278 -0
- package/dist/commands/validate/fleet/views/projects.js.map +1 -0
- package/dist/commands/validate/fleet/views/root-documents.js +83 -0
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +52 -0
- package/dist/commands/validate/fleet/views/stale.js.map +1 -0
- package/dist/commands/validate/links/corpus.js +89 -0
- package/dist/commands/validate/links/corpus.js.map +1 -0
- package/dist/commands/validate/links/glossary.js +75 -0
- package/dist/commands/validate/links/glossary.js.map +1 -0
- package/dist/commands/validate/render/repeats.js +63 -0
- package/dist/commands/validate/render/repeats.js.map +1 -0
- package/dist/commands/validate/render/rollups.js +115 -0
- package/dist/commands/validate/render/rollups.js.map +1 -0
- package/dist/commands/validate/render/text.js +199 -0
- package/dist/commands/validate/render/text.js.map +1 -0
- package/dist/commands/validate/report.js +145 -0
- package/dist/commands/validate/report.js.map +1 -0
- package/dist/commands/validate/scope.js +113 -0
- package/dist/commands/validate/scope.js.map +1 -0
- package/dist/commands/validate/service/api.js +252 -0
- package/dist/commands/validate/service/api.js.map +1 -0
- package/dist/commands/validate/service/contracts/generated.js +134 -0
- package/dist/commands/validate/service/contracts/generated.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +241 -0
- package/dist/commands/validate/service/events/events.js.map +1 -0
- package/dist/commands/validate/service/events/message-producers.js +77 -0
- package/dist/commands/validate/service/events/message-producers.js.map +1 -0
- package/dist/commands/validate/service/evidence-pins.js +177 -0
- package/dist/commands/validate/service/evidence-pins.js.map +1 -0
- package/dist/commands/validate/service/model/diverged.js +226 -0
- package/dist/commands/validate/service/model/diverged.js.map +1 -0
- package/dist/commands/validate/service/model/grade.js +163 -0
- package/dist/commands/validate/service/model/grade.js.map +1 -0
- package/dist/commands/validate/service/service.js +310 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +279 -0
- package/dist/commands/validate/service/specs.js.map +1 -0
- package/dist/commands/validate/service/spine.js +148 -0
- package/dist/commands/validate/service/spine.js.map +1 -0
- package/dist/commands/validate/service/usecases/tags.js +113 -0
- package/dist/commands/validate/service/usecases/tags.js.map +1 -0
- package/dist/commands/validate/service/usecases/usecases.js +209 -0
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/validate.js +363 -0
- package/dist/commands/validate/validate.js.map +1 -0
- package/dist/commands/verify/cross/diff.js +178 -0
- package/dist/commands/verify/cross/diff.js.map +1 -0
- package/dist/commands/verify/evidence/contract.js +32 -0
- package/dist/commands/verify/evidence/contract.js.map +1 -0
- package/dist/commands/verify/evidence/pins.js +52 -0
- package/dist/commands/verify/evidence/pins.js.map +1 -0
- package/dist/commands/verify/evidence/read.js +81 -0
- package/dist/commands/verify/evidence/read.js.map +1 -0
- package/dist/commands/verify/frozen.js +263 -0
- package/dist/commands/verify/frozen.js.map +1 -0
- package/dist/commands/verify/record.js +278 -0
- package/dist/commands/verify/record.js.map +1 -0
- package/dist/commands/verify/report.js +206 -0
- package/dist/commands/verify/report.js.map +1 -0
- package/dist/commands/verify/results.js +328 -0
- package/dist/commands/verify/results.js.map +1 -0
- package/dist/commands/verify/verify.js +220 -0
- package/dist/commands/verify/verify.js.map +1 -0
- package/dist/commands/vouch/contract.js +11 -0
- package/dist/commands/vouch/contract.js.map +1 -0
- package/dist/commands/vouch/pack/contract.js +2 -0
- package/dist/commands/vouch/pack/contract.js.map +1 -0
- package/dist/commands/vouch/pack/pack.js +266 -0
- package/dist/commands/vouch/pack/pack.js.map +1 -0
- package/dist/commands/vouch/pack/print.js +266 -0
- package/dist/commands/vouch/pack/print.js.map +1 -0
- package/dist/commands/vouch/pack/sections.js +141 -0
- package/dist/commands/vouch/pack/sections.js.map +1 -0
- package/dist/commands/vouch/prompt/confirm.js +46 -0
- package/dist/commands/vouch/prompt/confirm.js.map +1 -0
- package/dist/commands/vouch/report.js +101 -0
- package/dist/commands/vouch/report.js.map +1 -0
- package/dist/commands/vouch/run.js +230 -0
- package/dist/commands/vouch/run.js.map +1 -0
- package/dist/commands/vouch/sample/plan.js +111 -0
- package/dist/commands/vouch/sample/plan.js.map +1 -0
- package/dist/commands/vouch/sample/print.js +109 -0
- package/dist/commands/vouch/sample/print.js.map +1 -0
- package/dist/commands/vouch/vet/verify.js +155 -0
- package/dist/commands/vouch/vet/verify.js.map +1 -0
- package/dist/commands/vouch/vouch.js +169 -0
- package/dist/commands/vouch/vouch.js.map +1 -0
- package/dist/core/agent/agents-md/command-map.js +299 -0
- package/dist/core/agent/agents-md/command-map.js.map +1 -0
- package/dist/core/agent/agents-md/map/explain.js +46 -0
- package/dist/core/agent/agents-md/map/explain.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
- package/dist/core/agent/agents-md/map/mcp.js +44 -0
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
- package/dist/core/agent/agents-md/map/status.js +78 -0
- package/dist/core/agent/agents-md/map/status.js.map +1 -0
- package/dist/core/agent/agents-md/map/subsystem.js +104 -0
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
- package/dist/core/agent/agents-md/map/usecases.js +138 -0
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
- package/dist/core/agent/agents-md/refusals.js +273 -0
- package/dist/core/agent/agents-md/refusals.js.map +1 -0
- package/dist/core/agent/agents-md.js +203 -0
- package/dist/core/agent/agents-md.js.map +1 -0
- package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
- package/dist/core/agent/agents-stamp.js.map +1 -0
- package/dist/core/agent/contract.js +2 -0
- package/dist/core/agent/contract.js.map +1 -0
- package/dist/core/agent/protocol.js +193 -0
- package/dist/core/agent/protocol.js.map +1 -0
- package/dist/core/agent/scaffold.js +254 -0
- package/dist/core/agent/scaffold.js.map +1 -0
- package/dist/core/agent/support/report.js +144 -0
- package/dist/core/agent/support/report.js.map +1 -0
- package/dist/core/agent/tools/dialects.js +151 -0
- package/dist/core/agent/tools/dialects.js.map +1 -0
- package/dist/core/agent/tools/registry.js +193 -0
- package/dist/core/agent/tools/registry.js.map +1 -0
- package/dist/core/agent/workflows/adopt.js +280 -0
- package/dist/core/agent/workflows/adopt.js.map +1 -0
- package/dist/core/agent/workflows/check.js +373 -0
- package/dist/core/agent/workflows/check.js.map +1 -0
- package/dist/core/agent/workflows/closing.js +323 -0
- package/dist/core/agent/workflows/closing.js.map +1 -0
- package/dist/core/agent/workflows/feature.js +220 -0
- package/dist/core/agent/workflows/feature.js.map +1 -0
- package/dist/core/agent/workflows/implement.js +188 -0
- package/dist/core/agent/workflows/implement.js.map +1 -0
- package/dist/core/agent/workflows/reference/authoring.js +311 -0
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
- package/dist/core/agent/workflows/reference/codes.js +67 -0
- package/dist/core/agent/workflows/reference/codes.js.map +1 -0
- package/dist/core/agent/workflows/reference/done-check.js +210 -0
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +19 -0
- package/dist/core/agent/workflows/reference/reference.js.map +1 -0
- package/dist/core/agent/workflows/reference/spine.js +338 -0
- package/dist/core/agent/workflows/reference/spine.js.map +1 -0
- package/dist/core/asyncapi/baseline/plan.js +43 -0
- package/dist/core/asyncapi/baseline/plan.js.map +1 -0
- package/dist/core/asyncapi/baseline/surfaces.js +54 -0
- package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
- package/dist/core/asyncapi/depth.js +164 -0
- package/dist/core/asyncapi/depth.js.map +1 -0
- package/dist/core/asyncapi/digest.js +146 -0
- package/dist/core/asyncapi/digest.js.map +1 -0
- package/dist/core/asyncapi/merge/components.js +92 -0
- package/dist/core/asyncapi/merge/components.js.map +1 -0
- package/dist/core/asyncapi/merge/error.js +38 -0
- package/dist/core/asyncapi/merge/error.js.map +1 -0
- package/dist/core/asyncapi/merge/markers.js +290 -0
- package/dist/core/asyncapi/merge/markers.js.map +1 -0
- package/dist/core/asyncapi/merge/merge.js +195 -0
- package/dist/core/asyncapi/merge/merge.js.map +1 -0
- package/dist/core/asyncapi/merge/pin.js +83 -0
- package/dist/core/asyncapi/merge/pin.js.map +1 -0
- package/dist/core/asyncapi/model.js +11 -0
- package/dist/core/asyncapi/model.js.map +1 -0
- package/dist/core/asyncapi/producers.js +50 -0
- package/dist/core/asyncapi/producers.js.map +1 -0
- package/dist/core/asyncapi/read.js +263 -0
- package/dist/core/asyncapi/read.js.map +1 -0
- package/dist/core/brief/brief.js +285 -0
- package/dist/core/brief/brief.js.map +1 -0
- package/dist/core/brief/checks.js +385 -0
- package/dist/core/brief/checks.js.map +1 -0
- package/dist/core/brief/landscape.js +273 -0
- package/dist/core/brief/landscape.js.map +1 -0
- package/dist/core/brief/map/extend.js +84 -0
- package/dist/core/brief/map/extend.js.map +1 -0
- package/dist/core/brief/map/owed.js +266 -0
- package/dist/core/brief/map/owed.js.map +1 -0
- package/dist/core/brief/targets.js +304 -0
- package/dist/core/brief/targets.js.map +1 -0
- package/dist/core/brief/unchecked.js +58 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +190 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/direction/direction.js +114 -0
- package/dist/core/c4/direction/direction.js.map +1 -0
- package/dist/core/c4/likec4.js +243 -0
- package/dist/core/c4/likec4.js.map +1 -0
- package/dist/core/c4/locate/unlocated.js +150 -0
- package/dist/core/c4/locate/unlocated.js.map +1 -0
- package/dist/core/c4/parsed/deployment.js +160 -0
- package/dist/core/c4/parsed/deployment.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js +132 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
- package/dist/core/c4/parsed/specification.js +78 -0
- package/dist/core/c4/parsed/specification.js.map +1 -0
- package/dist/core/c4/parsed/values.js +110 -0
- package/dist/core/c4/parsed/values.js.map +1 -0
- package/dist/core/c4/parsed/view-ids.js +113 -0
- package/dist/core/c4/parsed/view-ids.js.map +1 -0
- package/dist/core/c4/prefetch/fleet.js +134 -0
- package/dist/core/c4/prefetch/fleet.js.map +1 -0
- package/dist/core/c4/project/architecture.js +161 -0
- package/dist/core/c4/project/architecture.js.map +1 -0
- package/dist/core/c4/project/batch.js +140 -0
- package/dist/core/c4/project/batch.js.map +1 -0
- package/dist/core/c4/project/documents.js +89 -0
- package/dist/core/c4/project/documents.js.map +1 -0
- package/dist/core/c4/project/load.js +219 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/project/staged.js +277 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/attested.js +0 -0
- package/dist/core/c4/resolve/attested.js.map +1 -0
- package/dist/core/c4/resolve/external.js +51 -0
- package/dist/core/c4/resolve/external.js.map +1 -0
- package/dist/core/c4/resolve/service.js +174 -0
- package/dist/core/c4/resolve/service.js.map +1 -0
- package/dist/core/c4/resolve/steps.js +290 -0
- package/dist/core/c4/resolve/steps.js.map +1 -0
- package/dist/core/c4/resolve/systems.js +154 -0
- package/dist/core/c4/resolve/systems.js.map +1 -0
- package/dist/core/c4/root-project/exclude.js +352 -0
- package/dist/core/c4/root-project/exclude.js.map +1 -0
- package/dist/core/c4/seed/fleet-file.js +201 -0
- package/dist/core/c4/seed/fleet-file.js.map +1 -0
- package/dist/core/c4/seed/items.js +91 -0
- package/dist/core/c4/seed/items.js.map +1 -0
- package/dist/core/c4/seed/stamp.js +48 -0
- package/dist/core/c4/seed/stamp.js.map +1 -0
- package/dist/core/c4/seed/template.js +173 -0
- package/dist/core/c4/seed/template.js.map +1 -0
- package/dist/core/c4/service-model/created/models.js +96 -0
- package/dist/core/c4/service-model/created/models.js.map +1 -0
- package/dist/core/c4/service-model/documents.js +47 -0
- package/dist/core/c4/service-model/documents.js.map +1 -0
- package/dist/core/c4/service-model/fleet/extending.js +82 -0
- package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
- package/dist/core/c4/service-model/load.js +165 -0
- package/dist/core/c4/service-model/load.js.map +1 -0
- package/dist/core/c4/service-model/renderer.js +128 -0
- package/dist/core/c4/service-model/renderer.js.map +1 -0
- package/dist/core/c4/service-model/shape.js +106 -0
- package/dist/core/c4/service-model/shape.js.map +1 -0
- package/dist/core/c4/service-model/slice.js +188 -0
- package/dist/core/c4/service-model/slice.js.map +1 -0
- package/dist/core/c4/source-mask.js +369 -0
- package/dist/core/c4/source-mask.js.map +1 -0
- package/dist/core/c4/source-scan.js +308 -0
- package/dist/core/c4/source-scan.js.map +1 -0
- package/dist/core/c4/splice/authored-source.js +167 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -0
- package/dist/core/c4/splice/contract.js +30 -0
- package/dist/core/c4/splice/contract.js.map +1 -0
- package/dist/core/c4/splice/delta-blocks.js +126 -0
- package/dist/core/c4/splice/delta-blocks.js.map +1 -0
- package/dist/core/c4/splice/identity/declared.js +87 -0
- package/dist/core/c4/splice/identity/declared.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +73 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -0
- package/dist/core/c4/splice/identity/existing.js +80 -0
- package/dist/core/c4/splice/identity/existing.js.map +1 -0
- package/dist/core/c4/splice/identity/interior.js +80 -0
- package/dist/core/c4/splice/identity/interior.js.map +1 -0
- package/dist/core/c4/splice/identity/owner.js +50 -0
- package/dist/core/c4/splice/identity/owner.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +337 -0
- package/dist/core/c4/splice/landscape-merge.js.map +1 -0
- package/dist/core/c4/splice/model/merge.js +151 -0
- package/dist/core/c4/splice/model/merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +298 -0
- package/dist/core/c4/splice/placement.js.map +1 -0
- package/dist/core/c4/splice/text/spot.js +131 -0
- package/dist/core/c4/splice/text/spot.js.map +1 -0
- package/dist/core/c4/workspace.js +166 -0
- package/dist/core/c4/workspace.js.map +1 -0
- package/dist/core/capabilities/authoring/notes.js +141 -0
- package/dist/core/capabilities/authoring/notes.js.map +1 -0
- package/dist/core/capabilities/capabilities.js +124 -0
- package/dist/core/capabilities/capabilities.js.map +1 -0
- package/dist/core/capabilities/delta/doc.js +47 -0
- package/dist/core/capabilities/delta/doc.js.map +1 -0
- package/dist/core/capabilities/delta/overlay.js +129 -0
- package/dist/core/capabilities/delta/overlay.js.map +1 -0
- package/dist/core/capabilities/delta/summary.js +57 -0
- package/dist/core/capabilities/delta/summary.js.map +1 -0
- package/dist/core/capabilities/delta/tree.js +43 -0
- package/dist/core/capabilities/delta/tree.js.map +1 -0
- package/dist/core/capabilities/delta/uncovered.js +222 -0
- package/dist/core/capabilities/delta/uncovered.js.map +1 -0
- package/dist/core/capabilities/findings.js +338 -0
- package/dist/core/capabilities/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/findings.js +174 -0
- package/dist/core/capabilities/realizes/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/join.js +123 -0
- package/dist/core/capabilities/realizes/join.js.map +1 -0
- package/dist/core/capabilities/rollup.js +205 -0
- package/dist/core/capabilities/rollup.js.map +1 -0
- package/dist/core/capabilities/tree.js +104 -0
- package/dist/core/capabilities/tree.js.map +1 -0
- package/dist/core/capabilities/usecase-join.js +267 -0
- package/dist/core/capabilities/usecase-join.js.map +1 -0
- package/dist/core/coherence/authoring/scaffold.js +185 -0
- package/dist/core/coherence/authoring/scaffold.js.map +1 -0
- package/dist/core/coherence/authoring/sentinels.js +75 -0
- package/dist/core/coherence/authoring/sentinels.js.map +1 -0
- package/dist/core/coherence/calls/called.js +52 -0
- package/dist/core/coherence/calls/called.js.map +1 -0
- package/dist/core/coherence/coherence.js +332 -0
- package/dist/core/coherence/coherence.js.map +1 -0
- package/dist/core/coherence/consumed/operations.js +70 -0
- package/dist/core/coherence/consumed/operations.js.map +1 -0
- package/dist/core/coherence/consumed/refusal.js +38 -0
- package/dist/core/coherence/consumed/refusal.js.map +1 -0
- package/dist/core/coherence/covers/health.js +85 -0
- package/dist/core/coherence/covers/health.js.map +1 -0
- package/dist/core/coherence/declared.js +295 -0
- package/dist/core/coherence/declared.js.map +1 -0
- package/dist/core/coherence/events/declared.js +191 -0
- package/dist/core/coherence/events/declared.js.map +1 -0
- package/dist/core/coherence/events/events.js +335 -0
- package/dist/core/coherence/events/events.js.map +1 -0
- package/dist/core/coherence/events/grades.js +189 -0
- package/dist/core/coherence/events/grades.js.map +1 -0
- package/dist/core/coherence/events/lookups.js +63 -0
- package/dist/core/coherence/events/lookups.js.map +1 -0
- package/dist/core/coherence/events/produced.js +100 -0
- package/dist/core/coherence/events/produced.js.map +1 -0
- package/dist/core/coherence/living.js +198 -0
- package/dist/core/coherence/living.js.map +1 -0
- package/dist/core/coherence/lookups.js +95 -0
- package/dist/core/coherence/lookups.js.map +1 -0
- package/dist/core/coherence/pending.js +39 -0
- package/dist/core/coherence/pending.js.map +1 -0
- package/dist/core/coherence/retired/archived.js +285 -0
- package/dist/core/coherence/retired/archived.js.map +1 -0
- package/dist/core/coherence/retired/event-pair.js +62 -0
- package/dist/core/coherence/retired/event-pair.js.map +1 -0
- package/dist/core/coherence/retired/merged.js +79 -0
- package/dist/core/coherence/retired/merged.js.map +1 -0
- package/dist/core/coherence/retired/retirement.js +49 -0
- package/dist/core/coherence/retired/retirement.js.map +1 -0
- package/dist/core/coherence/retired/revival/arrivals.js +131 -0
- package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
- package/dist/core/coherence/retired/revival/revived.js +297 -0
- package/dist/core/coherence/retired/revival/revived.js.map +1 -0
- package/dist/core/conflict-markers.js +60 -0
- package/dist/core/conflict-markers.js.map +1 -0
- package/dist/core/consumers/after.js +113 -0
- package/dist/core/consumers/after.js.map +1 -0
- package/dist/core/consumers/consumers.js +296 -0
- package/dist/core/consumers/consumers.js.map +1 -0
- package/dist/core/consumers/current.js +211 -0
- package/dist/core/consumers/current.js.map +1 -0
- package/dist/core/consumers/scan.js +46 -0
- package/dist/core/consumers/scan.js.map +1 -0
- package/dist/core/consumers/state.js +27 -0
- package/dist/core/consumers/state.js.map +1 -0
- package/dist/core/delta/claims.js +73 -0
- package/dist/core/delta/claims.js.map +1 -0
- package/dist/core/delta/delta.js +341 -0
- package/dist/core/delta/delta.js.map +1 -0
- package/dist/core/delta/document.js +177 -0
- package/dist/core/delta/document.js.map +1 -0
- package/dist/core/delta/scope.js +48 -0
- package/dist/core/delta/scope.js.map +1 -0
- package/dist/core/delta/select.js +237 -0
- package/dist/core/delta/select.js.map +1 -0
- package/dist/core/dependencies/dependencies.js +141 -0
- package/dist/core/dependencies/dependencies.js.map +1 -0
- package/dist/core/dependencies/facts.js +165 -0
- package/dist/core/dependencies/facts.js.map +1 -0
- package/dist/core/dependencies/fanin.js +88 -0
- package/dist/core/dependencies/fanin.js.map +1 -0
- package/dist/core/dependencies/graph.js +106 -0
- package/dist/core/dependencies/graph.js.map +1 -0
- package/dist/core/deployment/delta.js +191 -0
- package/dist/core/deployment/delta.js.map +1 -0
- package/dist/core/deployment/objects.js +145 -0
- package/dist/core/deployment/objects.js.map +1 -0
- package/dist/core/diff/base-git.js +230 -0
- package/dist/core/diff/base-git.js.map +1 -0
- package/dist/core/diff/base-state.js +237 -0
- package/dist/core/diff/base-state.js.map +1 -0
- package/dist/core/diff/joins.js +136 -0
- package/dist/core/diff/joins.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +204 -0
- package/dist/core/diff/scope/changed-paths.js.map +1 -0
- package/dist/core/diff/scope/edges.js +82 -0
- package/dist/core/diff/scope/edges.js.map +1 -0
- package/dist/core/diff/semantic.js +312 -0
- package/dist/core/diff/semantic.js.map +1 -0
- package/dist/core/docs.js +37 -85
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +238 -0
- package/dist/core/doctor/agents.js.map +1 -0
- package/dist/core/doctor/config.js +139 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/doctor.js +355 -0
- package/dist/core/doctor/doctor.js.map +1 -0
- package/dist/core/doctor/report.js +13 -0
- package/dist/core/doctor/report.js.map +1 -0
- package/dist/core/doctor/reports/scan.js +242 -0
- package/dist/core/doctor/reports/scan.js.map +1 -0
- package/dist/core/doctor/residue.js +110 -0
- package/dist/core/doctor/residue.js.map +1 -0
- package/dist/core/document/apply.js +224 -0
- package/dist/core/document/apply.js.map +1 -0
- package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
- package/dist/core/document/frontmatter.js.map +1 -0
- package/dist/core/document/grammar/directives.js +143 -0
- package/dist/core/document/grammar/directives.js.map +1 -0
- package/dist/core/document/parse.js +286 -0
- package/dist/core/document/parse.js.map +1 -0
- package/dist/core/document/scenarios.js +238 -0
- package/dist/core/document/scenarios.js.map +1 -0
- package/dist/core/document/spec.js +234 -0
- package/dist/core/document/spec.js.map +1 -0
- package/dist/core/{config.js → envelope/config.js} +89 -18
- package/dist/core/envelope/config.js.map +1 -0
- package/dist/core/envelope/json.js +209 -0
- package/dist/core/envelope/json.js.map +1 -0
- package/dist/core/{version.js → envelope/version.js} +3 -3
- package/dist/core/envelope/version.js.map +1 -0
- package/dist/core/explain/families.js +180 -0
- package/dist/core/explain/families.js.map +1 -0
- package/dist/core/explain/fix-tables.js +178 -0
- package/dist/core/explain/fix-tables.js.map +1 -0
- package/dist/core/explain/lookup.js +194 -0
- package/dist/core/explain/lookup.js.map +1 -0
- package/dist/core/explain/refusals.js +49 -0
- package/dist/core/explain/refusals.js.map +1 -0
- package/dist/core/explain/terms/documents.js +227 -0
- package/dist/core/explain/terms/documents.js.map +1 -0
- package/dist/core/explain/terms/done-check.js +144 -0
- package/dist/core/explain/terms/done-check.js.map +1 -0
- package/dist/core/explain/terms/entry.js +14 -0
- package/dist/core/explain/terms/entry.js.map +1 -0
- package/dist/core/explain/terms/stages.js +71 -0
- package/dist/core/explain/terms/stages.js.map +1 -0
- package/dist/core/explain/terms/tasks.js +97 -0
- package/dist/core/explain/terms/tasks.js.map +1 -0
- package/dist/core/explain/terms.js +103 -0
- package/dist/core/explain/terms.js.map +1 -0
- package/dist/core/explore/describe.js +105 -0
- package/dist/core/explore/describe.js.map +1 -0
- package/dist/core/explore/explore.js +204 -0
- package/dist/core/explore/explore.js.map +1 -0
- package/dist/core/fleet-context.js +174 -146
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +208 -0
- package/dist/core/gate/checks.js.map +1 -0
- package/dist/core/gate/partners.js +246 -0
- package/dist/core/gate/partners.js.map +1 -0
- package/dist/core/gate/report.js +47 -0
- package/dist/core/gate/report.js.map +1 -0
- package/dist/core/gate/verification.js +176 -0
- package/dist/core/gate/verification.js.map +1 -0
- package/dist/core/gherkin/digest.js +60 -0
- package/dist/core/gherkin/digest.js.map +1 -0
- package/dist/core/gherkin/emit.js +177 -0
- package/dist/core/gherkin/emit.js.map +1 -0
- package/dist/core/gherkin/read.js +76 -0
- package/dist/core/gherkin/read.js.map +1 -0
- package/dist/core/gherkin/stale.js +210 -0
- package/dist/core/gherkin/stale.js.map +1 -0
- package/dist/core/gherkin/stamp.js +77 -0
- package/dist/core/gherkin/stamp.js.map +1 -0
- package/dist/core/gherkin/steps/catalogue.js +154 -0
- package/dist/core/gherkin/steps/catalogue.js.map +1 -0
- package/dist/core/gherkin/steps/inventory.js +98 -0
- package/dist/core/gherkin/steps/inventory.js.map +1 -0
- package/dist/core/gherkin/steps/phrase.js +72 -0
- package/dist/core/gherkin/steps/phrase.js.map +1 -0
- package/dist/core/glossary/delta.js +109 -0
- package/dist/core/glossary/delta.js.map +1 -0
- package/dist/core/glossary/tree.js +73 -0
- package/dist/core/glossary/tree.js.map +1 -0
- package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
- package/dist/core/kernel/concurrency.js.map +1 -0
- package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
- package/dist/core/kernel/document-bytes.js.map +1 -0
- package/dist/core/kernel/fences.js +42 -0
- package/dist/core/kernel/fences.js.map +1 -0
- package/dist/core/kernel/ids/capability.js +72 -0
- package/dist/core/kernel/ids/capability.js.map +1 -0
- package/dist/core/kernel/ids/dirs.js +33 -0
- package/dist/core/kernel/ids/dirs.js.map +1 -0
- package/dist/core/kernel/ids/feature.js +75 -0
- package/dist/core/kernel/ids/feature.js.map +1 -0
- package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
- package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
- package/dist/core/kernel/ids/service.js +156 -0
- package/dist/core/kernel/ids/service.js.map +1 -0
- package/dist/core/kernel/ids/subsystem.js +63 -0
- package/dist/core/kernel/ids/subsystem.js.map +1 -0
- package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
- package/dist/core/kernel/path-safety.js.map +1 -0
- package/dist/core/{records.js → kernel/records.js} +11 -0
- package/dist/core/kernel/records.js.map +1 -0
- package/dist/core/links/backlinks.js +66 -0
- package/dist/core/links/backlinks.js.map +1 -0
- package/dist/core/links/case.js +74 -0
- package/dist/core/links/case.js.map +1 -0
- package/dist/core/links/corpus.js +118 -0
- package/dist/core/links/corpus.js.map +1 -0
- package/dist/core/links/findings.js +110 -0
- package/dist/core/links/findings.js.map +1 -0
- package/dist/core/links/parse.js +265 -0
- package/dist/core/links/parse.js.map +1 -0
- package/dist/core/mcp/argv.js +212 -0
- package/dist/core/mcp/argv.js.map +1 -0
- package/dist/core/mcp/author-tools.js +73 -0
- package/dist/core/mcp/author-tools.js.map +1 -0
- package/dist/core/mcp/framing.js +46 -0
- package/dist/core/mcp/framing.js.map +1 -0
- package/dist/core/mcp/protocol.js +280 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/tools.js +324 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/obligations/obligations.js +106 -0
- package/dist/core/obligations/obligations.js.map +1 -0
- package/dist/core/openapi/baseline/gate.js +207 -0
- package/dist/core/openapi/baseline/gate.js.map +1 -0
- package/dist/core/openapi/baseline/plan.js +142 -0
- package/dist/core/openapi/baseline/plan.js.map +1 -0
- package/dist/core/openapi/baseline/record.js +174 -0
- package/dist/core/openapi/baseline/record.js.map +1 -0
- package/dist/core/openapi/contract-text.js +33 -0
- package/dist/core/openapi/contract-text.js.map +1 -0
- package/dist/core/openapi/contract-tree.js +301 -0
- package/dist/core/openapi/contract-tree.js.map +1 -0
- package/dist/core/openapi/depth.js +136 -0
- package/dist/core/openapi/depth.js.map +1 -0
- package/dist/core/openapi/digest.js +239 -0
- package/dist/core/openapi/digest.js.map +1 -0
- package/dist/core/{openapi.js → openapi/doc.js} +54 -108
- package/dist/core/openapi/doc.js.map +1 -0
- package/dist/core/openapi/merge/components.js +199 -0
- package/dist/core/openapi/merge/components.js.map +1 -0
- package/dist/core/openapi/merge/error.js +16 -0
- package/dist/core/openapi/merge/error.js.map +1 -0
- package/dist/core/openapi/merge/markers.js +204 -0
- package/dist/core/openapi/merge/markers.js.map +1 -0
- package/dist/core/openapi/merge/merge.js +232 -0
- package/dist/core/openapi/merge/merge.js.map +1 -0
- package/dist/core/openapi/merge/pin.js +110 -0
- package/dist/core/openapi/merge/pin.js.map +1 -0
- package/dist/core/openspec/decide/capabilities.js +244 -0
- package/dist/core/openspec/decide/capabilities.js.map +1 -0
- package/dist/core/openspec/decide/dispositions.js +63 -0
- package/dist/core/openspec/decide/dispositions.js.map +1 -0
- package/dist/core/openspec/decide/renames.js +179 -0
- package/dist/core/openspec/decide/renames.js.map +1 -0
- package/dist/core/openspec/decide/verdict.js +84 -0
- package/dist/core/openspec/decide/verdict.js.map +1 -0
- package/dist/core/openspec/inventory.js +220 -0
- package/dist/core/openspec/inventory.js.map +1 -0
- package/dist/core/openspec/model/mapping.js +78 -0
- package/dist/core/openspec/model/mapping.js.map +1 -0
- package/dist/core/openspec/model/model.js +70 -0
- package/dist/core/openspec/model/model.js.map +1 -0
- package/dist/core/openspec/scan/changes.js +241 -0
- package/dist/core/openspec/scan/changes.js.map +1 -0
- package/dist/core/openspec/scan/config.js +191 -0
- package/dist/core/openspec/scan/config.js.map +1 -0
- package/dist/core/openspec/scan/shape.js +304 -0
- package/dist/core/openspec/scan/shape.js.map +1 -0
- package/dist/core/openspec/scan/walk.js +116 -0
- package/dist/core/openspec/scan/walk.js.map +1 -0
- package/dist/core/openspec/scan/workspace.js +71 -0
- package/dist/core/openspec/scan/workspace.js.map +1 -0
- package/dist/core/owners/codeowners.js +141 -0
- package/dist/core/owners/codeowners.js.map +1 -0
- package/dist/core/pack/features.js +120 -0
- package/dist/core/pack/features.js.map +1 -0
- package/dist/core/pack/joins.js +112 -0
- package/dist/core/pack/joins.js.map +1 -0
- package/dist/core/pack/living.js +157 -0
- package/dist/core/pack/living.js.map +1 -0
- package/dist/core/pack/pack.js +120 -0
- package/dist/core/pack/pack.js.map +1 -0
- package/dist/core/permissions/permissions.js +87 -0
- package/dist/core/permissions/permissions.js.map +1 -0
- package/dist/core/projection/api.js +84 -0
- package/dist/core/projection/api.js.map +1 -0
- package/dist/core/projection/arch-slice.js +63 -0
- package/dist/core/projection/arch-slice.js.map +1 -0
- package/dist/core/projection/events.js +34 -0
- package/dist/core/projection/events.js.map +1 -0
- package/dist/core/projection/introduced.js +14 -0
- package/dist/core/projection/introduced.js.map +1 -0
- package/dist/core/provenance/findings.js +244 -0
- package/dist/core/provenance/findings.js.map +1 -0
- package/dist/core/provenance/git.js +201 -0
- package/dist/core/provenance/git.js.map +1 -0
- package/dist/core/provenance/gitq/moves.js +139 -0
- package/dist/core/provenance/gitq/moves.js.map +1 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
- package/dist/core/provenance/sample/scope.js +238 -0
- package/dist/core/provenance/sample/scope.js.map +1 -0
- package/dist/core/provenance/sample/sections.js +61 -0
- package/dist/core/provenance/sample/sections.js.map +1 -0
- package/dist/core/provenance/sources.js +280 -0
- package/dist/core/provenance/sources.js.map +1 -0
- package/dist/core/provenance/stamp.js +220 -0
- package/dist/core/provenance/stamp.js.map +1 -0
- package/dist/core/provenance/walk.js +157 -0
- package/dist/core/provenance/walk.js.map +1 -0
- package/dist/core/repo/authored/paths.js +210 -0
- package/dist/core/repo/authored/paths.js.map +1 -0
- package/dist/core/repo/entries.js +126 -0
- package/dist/core/repo/entries.js.map +1 -0
- package/dist/core/repo/paths.js +322 -0
- package/dist/core/repo/paths.js.map +1 -0
- package/dist/core/repo/repo.js +308 -0
- package/dist/core/repo/repo.js.map +1 -0
- package/dist/core/repo/service-target.js +153 -0
- package/dist/core/repo/service-target.js.map +1 -0
- package/dist/core/repo/state.js +58 -0
- package/dist/core/repo/state.js.map +1 -0
- package/dist/core/repo/tree/find.js +61 -0
- package/dist/core/repo/tree/find.js.map +1 -0
- package/dist/core/repo/tree/fs.js +90 -0
- package/dist/core/repo/tree/fs.js.map +1 -0
- package/dist/core/repo/tree/marker.js +61 -0
- package/dist/core/repo/tree/marker.js.map +1 -0
- package/dist/core/repo/tree/render/body.js +258 -0
- package/dist/core/repo/tree/render/body.js.map +1 -0
- package/dist/core/repo/tree/render/projects.js +182 -0
- package/dist/core/repo/tree/render/projects.js.map +1 -0
- package/dist/core/repo/tree/render/service/header.js +125 -0
- package/dist/core/repo/tree/render/service/header.js.map +1 -0
- package/dist/core/repo/tree/render/service/peers.js +28 -0
- package/dist/core/repo/tree/render/service/peers.js.map +1 -0
- package/dist/core/repo/tree/render/service/view-id.js +67 -0
- package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
- package/dist/core/repo/tree/render/service/views.js +78 -0
- package/dist/core/repo/tree/render/service/views.js.map +1 -0
- package/dist/core/repo/tree/render/stale.js +42 -0
- package/dist/core/repo/tree/render/stale.js.map +1 -0
- package/dist/core/repo/tree/render/text.js +84 -0
- package/dist/core/repo/tree/render/text.js.map +1 -0
- package/dist/core/repo/tree/render/views.js +293 -0
- package/dist/core/repo/tree/render/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +255 -0
- package/dist/core/repo/tree/walk.js.map +1 -0
- package/dist/core/results.js +146 -14
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +239 -0
- package/dist/core/scaffold/landscape.js.map +1 -0
- package/dist/core/scaffold/legacy.js +271 -0
- package/dist/core/scaffold/legacy.js.map +1 -0
- package/dist/core/scaffold/readme.js +84 -0
- package/dist/core/scaffold/readme.js.map +1 -0
- package/dist/core/staging/commit.js +252 -0
- package/dist/core/staging/commit.js.map +1 -0
- package/dist/core/staging/interrupted.js +96 -0
- package/dist/core/staging/interrupted.js.map +1 -0
- package/dist/core/staging/lock.js +268 -0
- package/dist/core/staging/lock.js.map +1 -0
- package/dist/core/staging/recovery/finding.js +35 -0
- package/dist/core/staging/recovery/finding.js.map +1 -0
- package/dist/core/staging/recovery/intent.js +95 -0
- package/dist/core/staging/recovery/intent.js.map +1 -0
- package/dist/core/staging/recovery/recover.js +204 -0
- package/dist/core/staging/recovery/recover.js.map +1 -0
- package/dist/core/staging/recovery/residue.js +62 -0
- package/dist/core/staging/recovery/residue.js.map +1 -0
- package/dist/core/staging/snapshot/manifest.js +188 -0
- package/dist/core/staging/snapshot/manifest.js.map +1 -0
- package/dist/core/staging/snapshot/snapshot.js +196 -0
- package/dist/core/staging/snapshot/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +181 -0
- package/dist/core/staging/txn/forward.js.map +1 -0
- package/dist/core/staging/txn/journal.js +139 -0
- package/dist/core/staging/txn/journal.js.map +1 -0
- package/dist/core/staging/txn/transaction.js +75 -0
- package/dist/core/staging/txn/transaction.js.map +1 -0
- package/dist/core/staging/writes.js +113 -0
- package/dist/core/staging/writes.js.map +1 -0
- package/dist/core/status/actions/execution.js +60 -0
- package/dist/core/status/actions/execution.js.map +1 -0
- package/dist/core/status/contracts.js +126 -0
- package/dist/core/status/contracts.js.map +1 -0
- package/dist/core/status/feature/artifacts.js +196 -0
- package/dist/core/status/feature/artifacts.js.map +1 -0
- package/dist/core/status/feature/feature.js +214 -0
- package/dist/core/status/feature/feature.js.map +1 -0
- package/dist/core/status/feature/next.js +163 -0
- package/dist/core/status/feature/next.js.map +1 -0
- package/dist/core/status/feature/state.js +21 -0
- package/dist/core/status/feature/state.js.map +1 -0
- package/dist/core/status/feature/words.js +96 -0
- package/dist/core/status/feature/words.js.map +1 -0
- package/dist/core/status/fleet/fleet.js +216 -0
- package/dist/core/status/fleet/fleet.js.map +1 -0
- package/dist/core/status/fleet/next.js +302 -0
- package/dist/core/status/fleet/next.js.map +1 -0
- package/dist/core/status/interrupted.js +97 -0
- package/dist/core/status/interrupted.js.map +1 -0
- package/dist/core/status/report.js +31 -0
- package/dist/core/status/report.js.map +1 -0
- package/dist/core/status/scan.js +41 -0
- package/dist/core/status/scan.js.map +1 -0
- package/dist/core/status/verification.js +216 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/tasks/packet.js +199 -0
- package/dist/core/tasks/packet.js.map +1 -0
- package/dist/core/tasks/record.js +43 -0
- package/dist/core/tasks/record.js.map +1 -0
- package/dist/core/tasks/sources.js +181 -0
- package/dist/core/tasks/sources.js.map +1 -0
- package/dist/core/tasks/stamps.js +76 -0
- package/dist/core/tasks/stamps.js.map +1 -0
- package/dist/core/tasks/unit.js +0 -0
- package/dist/core/tasks/unit.js.map +1 -0
- package/dist/core/usecases/capability.js +166 -0
- package/dist/core/usecases/capability.js.map +1 -0
- package/dist/core/usecases/delta/claims.js +140 -0
- package/dist/core/usecases/delta/claims.js.map +1 -0
- package/dist/core/usecases/delta/flows.js +101 -0
- package/dist/core/usecases/delta/flows.js.map +1 -0
- package/dist/core/usecases/delta/modified.js +315 -0
- package/dist/core/usecases/delta/modified.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +76 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -0
- package/dist/core/usecases/fleet.js +296 -0
- package/dist/core/usecases/fleet.js.map +1 -0
- package/dist/core/usecases/grade/capability-tag.js +93 -0
- package/dist/core/usecases/grade/capability-tag.js.map +1 -0
- package/dist/core/usecases/grade/feature.js +88 -0
- package/dist/core/usecases/grade/feature.js.map +1 -0
- package/dist/core/usecases/grade/requirement-tag.js +94 -0
- package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
- package/dist/core/usecases/grade/steps.js +266 -0
- package/dist/core/usecases/grade/steps.js.map +1 -0
- package/dist/core/usecases/grade/usecases.js +112 -0
- package/dist/core/usecases/grade/usecases.js.map +1 -0
- package/dist/core/usecases/operations.js +123 -0
- package/dist/core/usecases/operations.js.map +1 -0
- package/dist/core/usecases/place.js +44 -0
- package/dist/core/usecases/place.js.map +1 -0
- package/dist/core/usecases/service/exclude.js +119 -0
- package/dist/core/usecases/service/exclude.js.map +1 -0
- package/dist/core/usecases/service/flows.js +164 -0
- package/dist/core/usecases/service/flows.js.map +1 -0
- package/dist/core/usecases/suites/participants.js +83 -0
- package/dist/core/usecases/suites/participants.js.map +1 -0
- package/dist/core/usecases/suites/suites.js +45 -0
- package/dist/core/usecases/suites/suites.js.map +1 -0
- package/dist/core/usecases/touch.js +101 -0
- package/dist/core/usecases/touch.js.map +1 -0
- package/dist/core/verify/answers.js +180 -0
- package/dist/core/verify/answers.js.map +1 -0
- package/dist/core/verify/build.js +170 -0
- package/dist/core/verify/build.js.map +1 -0
- package/dist/core/verify/checklist.js +259 -0
- package/dist/core/verify/checklist.js.map +1 -0
- package/dist/core/verify/claims/identity.js +61 -0
- package/dist/core/verify/claims/identity.js.map +1 -0
- package/dist/core/verify/cross/diff.js +97 -0
- package/dist/core/verify/cross/diff.js.map +1 -0
- package/dist/core/verify/evidence/contract.js +169 -0
- package/dist/core/verify/evidence/contract.js.map +1 -0
- package/dist/core/verify/location.js +67 -0
- package/dist/core/verify/location.js.map +1 -0
- package/dist/core/verify/pins/lint.js +158 -0
- package/dist/core/verify/pins/lint.js.map +1 -0
- package/dist/core/verify/pins/pin.js +95 -0
- package/dist/core/verify/pins/pin.js.map +1 -0
- package/dist/core/verify/read/file.js +224 -0
- package/dist/core/verify/read/file.js.map +1 -0
- package/dist/core/verify/read/shape.js +169 -0
- package/dist/core/verify/read/shape.js.map +1 -0
- package/dist/core/verify/read/union.js +105 -0
- package/dist/core/verify/read/union.js.map +1 -0
- package/dist/core/verify/record.js +165 -0
- package/dist/core/verify/record.js.map +1 -0
- package/dist/core/verify/store/commit.js +99 -0
- package/dist/core/verify/store/commit.js.map +1 -0
- package/dist/core/verify/store/render.js +61 -0
- package/dist/core/verify/store/render.js.map +1 -0
- package/dist/core/vocabulary/health.js +91 -0
- package/dist/core/vocabulary/health.js.map +1 -0
- package/dist/core/vocabulary/issue.js +59 -0
- package/dist/core/vocabulary/issue.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +216 -0
- package/dist/core/vocabulary/maturity.js.map +1 -0
- package/dist/core/vocabulary/report.js +90 -0
- package/dist/core/vocabulary/report.js.map +1 -0
- package/dist/core/vocabulary/steps.js +266 -0
- package/dist/core/vocabulary/steps.js.map +1 -0
- package/dist/core/workspace/discover.js +239 -0
- package/dist/core/workspace/discover.js.map +1 -0
- package/dist/core/workspace/render.js +52 -0
- package/dist/core/workspace/render.js.map +1 -0
- package/examples/README.md +232 -0
- package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
- package/examples/docs/architecture/capabilities.yaml +31 -0
- package/examples/docs/architecture/landscape.likec4 +336 -0
- package/examples/docs/architecture/obligations.yaml +23 -0
- package/examples/docs/architecture/permissions.yaml +50 -0
- package/examples/docs/architecture/services.likec4 +70 -0
- package/examples/docs/architecture/subsystems.likec4 +18 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
- package/examples/docs/capabilities/checkout/spec.md +55 -0
- package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
- package/examples/docs/capabilities/order-notifications/spec.md +43 -0
- package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
- package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
- package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
- package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
- package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
- package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
- package/examples/docs/glossary/order.md +15 -0
- package/examples/docs/glossary/payments/authorization.md +14 -0
- package/examples/docs/likec4.config.json +8 -0
- package/examples/docs/loam.json +3 -0
- package/examples/docs/services/checkout-web/model.likec4 +92 -0
- package/examples/docs/services/checkout-web/spec.md +91 -0
- package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
- package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
- package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
- package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
- package/examples/docs/services/order-service/arch.spec.md +134 -0
- package/examples/docs/services/order-service/asyncapi.yaml +109 -0
- package/examples/docs/services/order-service/health.yaml +57 -0
- package/examples/docs/services/order-service/model.likec4 +126 -0
- package/examples/docs/services/order-service/openapi.yaml +257 -0
- package/examples/docs/services/order-service/runbook.md +62 -0
- package/examples/docs/services/order-service/spec.md +134 -0
- package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
- package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
- package/examples/docs/services/payment-service/arch.spec.md +76 -0
- package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
- package/examples/docs/services/payment-service/health.yaml +39 -0
- package/examples/docs/services/payment-service/model.likec4 +68 -0
- package/examples/docs/services/payment-service/openapi.yaml +151 -0
- package/examples/docs/services/payment-service/runbook.md +37 -0
- package/examples/docs/services/payment-service/spec.md +88 -0
- package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
- package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
- package/examples/docs/services/platform/identity-service/health.yaml +70 -0
- package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
- package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
- package/examples/docs/services/platform/identity-service/runbook.md +95 -0
- package/examples/docs/services/platform/identity-service/spec.md +119 -0
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
- package/examples/docs/services/platform/notification-service/health.yaml +40 -0
- package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
- package/examples/docs/services/platform/notification-service/runbook.md +48 -0
- package/examples/docs/services/platform/notification-service/spec.md +112 -0
- package/examples/docs/services/platform/subsystem.yaml +2 -0
- package/examples/fleet.yaml +57 -0
- package/package.json +19 -6
- package/dist/commands/adopt.js +0 -240
- package/dist/commands/adopt.js.map +0 -1
- package/dist/commands/archive.js +0 -1313
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/delta.js +0 -388
- package/dist/commands/delta.js.map +0 -1
- package/dist/commands/docs-repo-gate.js.map +0 -1
- package/dist/commands/format.js +0 -17
- package/dist/commands/format.js.map +0 -1
- package/dist/commands/gherkin.js +0 -309
- package/dist/commands/gherkin.js.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list.js +0 -295
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/migrate-openspec.js +0 -950
- package/dist/commands/migrate-openspec.js.map +0 -1
- package/dist/commands/new.js +0 -413
- package/dist/commands/new.js.map +0 -1
- package/dist/commands/rebase.js +0 -356
- package/dist/commands/rebase.js.map +0 -1
- package/dist/commands/show.js +0 -320
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/unarchive.js +0 -317
- package/dist/commands/unarchive.js.map +0 -1
- package/dist/commands/validate.js +0 -1773
- package/dist/commands/validate.js.map +0 -1
- package/dist/commands/verify.js +0 -775
- package/dist/commands/verify.js.map +0 -1
- package/dist/commands/vouch.js +0 -421
- package/dist/commands/vouch.js.map +0 -1
- package/dist/core/agent.js +0 -2173
- package/dist/core/agent.js.map +0 -1
- package/dist/core/agents-stamp.js.map +0 -1
- package/dist/core/arch.js +0 -130
- package/dist/core/arch.js.map +0 -1
- package/dist/core/asyncapi.js +0 -253
- package/dist/core/asyncapi.js.map +0 -1
- package/dist/core/brief.js +0 -755
- package/dist/core/brief.js.map +0 -1
- package/dist/core/coherence.js +0 -577
- package/dist/core/coherence.js.map +0 -1
- package/dist/core/concurrency.js.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/delta.js +0 -476
- package/dist/core/delta.js.map +0 -1
- package/dist/core/dependencies.js +0 -356
- package/dist/core/dependencies.js.map +0 -1
- package/dist/core/doctor.js +0 -596
- package/dist/core/doctor.js.map +0 -1
- package/dist/core/document-bytes.js.map +0 -1
- package/dist/core/explore.js +0 -225
- package/dist/core/explore.js.map +0 -1
- package/dist/core/frontmatter.js.map +0 -1
- package/dist/core/gherkin.js +0 -463
- package/dist/core/gherkin.js.map +0 -1
- package/dist/core/health.js +0 -67
- package/dist/core/health.js.map +0 -1
- package/dist/core/ids.js +0 -122
- package/dist/core/ids.js.map +0 -1
- package/dist/core/issue.js +0 -9
- package/dist/core/issue.js.map +0 -1
- package/dist/core/json.js +0 -74
- package/dist/core/json.js.map +0 -1
- package/dist/core/likec4.js +0 -489
- package/dist/core/likec4.js.map +0 -1
- package/dist/core/maturity.js +0 -66
- package/dist/core/maturity.js.map +0 -1
- package/dist/core/openapi-merge.js +0 -552
- package/dist/core/openapi-merge.js.map +0 -1
- package/dist/core/openapi.js.map +0 -1
- package/dist/core/openspec-inventory.js +0 -1440
- package/dist/core/openspec-inventory.js.map +0 -1
- package/dist/core/path-safety.js.map +0 -1
- package/dist/core/provenance.js +0 -787
- package/dist/core/provenance.js.map +0 -1
- package/dist/core/records.js.map +0 -1
- package/dist/core/repo.js +0 -438
- package/dist/core/repo.js.map +0 -1
- package/dist/core/report.js +0 -47
- package/dist/core/report.js.map +0 -1
- package/dist/core/spec.js +0 -505
- package/dist/core/spec.js.map +0 -1
- package/dist/core/staging.js +0 -890
- package/dist/core/staging.js.map +0 -1
- package/dist/core/status.js +0 -1132
- package/dist/core/status.js.map +0 -1
- package/dist/core/steps.js +0 -72
- package/dist/core/steps.js.map +0 -1
- package/dist/core/verify.js +0 -807
- package/dist/core/verify.js.map +0 -1
- package/dist/core/version.js.map +0 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `glossary.unlinked` — a defined term that no document outside the glossary
|
|
3
|
+
* cites.
|
|
4
|
+
*
|
|
5
|
+
* The mirror of `permissions.unenforced` and `capability.unrealized`, and it
|
|
6
|
+
* earns its place for their reason: a vocabulary is worth what cites it. A term
|
|
7
|
+
* nobody links to is either a word the fleet never adopted or a definition left
|
|
8
|
+
* behind by a rename — both are drift, and neither is visible from inside the
|
|
9
|
+
* file. WARN, because the honest answer is often "not written up yet", and
|
|
10
|
+
* because a glossary must be safe to start: a fleet that defines twenty terms
|
|
11
|
+
* on a Monday and cites four of them is adopting the axis, not failing it.
|
|
12
|
+
*
|
|
13
|
+
* A TERM CITED ONLY BY OTHER TERMS IS STILL UNLINKED, and this is the judgement
|
|
14
|
+
* that keeps the warning worth anything. A glossary is a network of definitions,
|
|
15
|
+
* so `order-line` linking to `order` is normal and correct — and it proves
|
|
16
|
+
* nothing about whether the FLEET uses either word. The same reasoning
|
|
17
|
+
* `capability.requirement-inert-join` applies one axis over: a join written
|
|
18
|
+
* inside the tree is not evidence about the world outside it. The intra-glossary
|
|
19
|
+
* citations are listed in `details` rather than hidden, because they are the
|
|
20
|
+
* first thing a reader will otherwise go looking for.
|
|
21
|
+
*
|
|
22
|
+
* ONE FINDING FOR THE WHOLE GLOSSARY when nothing cites anything, and one per
|
|
23
|
+
* term otherwise. A fleet that has just created `glossary/` and written its
|
|
24
|
+
* first eight definitions would otherwise get eight identical warnings saying
|
|
25
|
+
* the same thing about the same afternoon's work.
|
|
26
|
+
*/
|
|
27
|
+
import { backlinkIndex } from "../../../core/links/backlinks.js";
|
|
28
|
+
import { readGlossary } from "../../../core/glossary/tree.js";
|
|
29
|
+
import { glossaryDir } from "../../../core/repo/authored/paths.js";
|
|
30
|
+
import { repoPath } from "../../../core/envelope/json.js";
|
|
31
|
+
import { FleetContext } from "../../../core/fleet-context.js";
|
|
32
|
+
import {} from "../../../core/vocabulary/report.js";
|
|
33
|
+
export async function glossaryFindings(docsDir, fleet) {
|
|
34
|
+
const root = glossaryDir(docsDir);
|
|
35
|
+
const glossary = await readGlossary(root);
|
|
36
|
+
// The directory's existence is the axis's opt-in, exactly as
|
|
37
|
+
// `architecture/capabilities.yaml` and `capabilities/` are the business
|
|
38
|
+
// axis's. A fleet without one pays a single `existsSync` and hears nothing —
|
|
39
|
+
// and the whole fleet-wide link walk below is never built.
|
|
40
|
+
if (!glossary.present || glossary.terms.length === 0)
|
|
41
|
+
return [];
|
|
42
|
+
const index = await backlinkIndex(docsDir, fleet);
|
|
43
|
+
const inGlossary = (source) => source.startsWith(`${repoPath(docsDir, root)}/`);
|
|
44
|
+
const unlinked = glossary.terms
|
|
45
|
+
.map((term) => ({ term, cited: index.linkersOf(term.path) }))
|
|
46
|
+
.map(({ term, cited }) => ({ term, outside: cited.filter((s) => !inGlossary(s)), within: cited.filter(inGlossary) }))
|
|
47
|
+
.filter(({ outside }) => outside.length === 0);
|
|
48
|
+
if (unlinked.length === 0)
|
|
49
|
+
return [];
|
|
50
|
+
// The whole vocabulary uncited is one fact about one afternoon, not N facts.
|
|
51
|
+
if (unlinked.length === glossary.terms.length && glossary.terms.length > 1) {
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
severity: "warn",
|
|
55
|
+
code: "glossary.unlinked",
|
|
56
|
+
message: `glossary: none of the ${glossary.terms.length} defined term(s) is linked from any document outside glossary/. ` +
|
|
57
|
+
"A term becomes checkable when a requirement, capability or intent cites it — " +
|
|
58
|
+
"`[Order](../../glossary/order.md)` — and until then the definitions are a document nothing joins to.",
|
|
59
|
+
details: unlinked.map(({ term }) => term.id),
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
return unlinked.map(({ term, within }) => ({
|
|
64
|
+
severity: "warn",
|
|
65
|
+
code: "glossary.unlinked",
|
|
66
|
+
subject: term.id,
|
|
67
|
+
message: `glossary/${term.id}.md is linked from no document outside glossary/` +
|
|
68
|
+
(within.length === 0
|
|
69
|
+
? " — either a word the fleet has not adopted, or a definition left behind by a rename."
|
|
70
|
+
: ", only from other terms — which says the glossary is consistent, not that the fleet uses the word.") +
|
|
71
|
+
` Cite it as \`[${term.id}](<relative>/glossary/${term.id}.md)\` from the requirement or capability that uses it, or delete the definition.`,
|
|
72
|
+
...(within.length === 0 ? {} : { details: within }),
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=glossary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../../../src/commands/validate/links/glossary.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `glossary.unlinked` — a defined term that no document outside the glossary\n * cites.\n *\n * The mirror of `permissions.unenforced` and `capability.unrealized`, and it\n * earns its place for their reason: a vocabulary is worth what cites it. A term\n * nobody links to is either a word the fleet never adopted or a definition left\n * behind by a rename — both are drift, and neither is visible from inside the\n * file. WARN, because the honest answer is often \"not written up yet\", and\n * because a glossary must be safe to start: a fleet that defines twenty terms\n * on a Monday and cites four of them is adopting the axis, not failing it.\n *\n * A TERM CITED ONLY BY OTHER TERMS IS STILL UNLINKED, and this is the judgement\n * that keeps the warning worth anything. A glossary is a network of definitions,\n * so `order-line` linking to `order` is normal and correct — and it proves\n * nothing about whether the FLEET uses either word. The same reasoning\n * `capability.requirement-inert-join` applies one axis over: a join written\n * inside the tree is not evidence about the world outside it. The intra-glossary\n * citations are listed in `details` rather than hidden, because they are the\n * first thing a reader will otherwise go looking for.\n *\n * ONE FINDING FOR THE WHOLE GLOSSARY when nothing cites anything, and one per\n * term otherwise. A fleet that has just created `glossary/` and written its\n * first eight definitions would otherwise get eight identical warnings saying\n * the same thing about the same afternoon's work.\n */\nimport { backlinkIndex } from \"../../../core/links/backlinks.js\";\nimport { readGlossary } from \"../../../core/glossary/tree.js\";\nimport { glossaryDir } from \"../../../core/repo/authored/paths.js\";\nimport { repoPath } from \"../../../core/envelope/json.js\";\nimport { FleetContext } from \"../../../core/fleet-context.js\";\nimport { type Finding } from \"../../../core/vocabulary/report.js\";\nimport type { DocsDir } from \"../../../core/kernel/ids/dirs.js\";\n\nexport async function glossaryFindings(docsDir: DocsDir, fleet: FleetContext): Promise<Finding[]> {\n const root = glossaryDir(docsDir);\n const glossary = await readGlossary(root);\n // The directory's existence is the axis's opt-in, exactly as\n // `architecture/capabilities.yaml` and `capabilities/` are the business\n // axis's. A fleet without one pays a single `existsSync` and hears nothing —\n // and the whole fleet-wide link walk below is never built.\n if (!glossary.present || glossary.terms.length === 0) return [];\n\n const index = await backlinkIndex(docsDir, fleet);\n const inGlossary = (source: string): boolean => source.startsWith(`${repoPath(docsDir, root)}/`);\n const unlinked = glossary.terms\n .map((term) => ({ term, cited: index.linkersOf(term.path) }))\n .map(({ term, cited }) => ({ term, outside: cited.filter((s) => !inGlossary(s)), within: cited.filter(inGlossary) }))\n .filter(({ outside }) => outside.length === 0);\n if (unlinked.length === 0) return [];\n\n // The whole vocabulary uncited is one fact about one afternoon, not N facts.\n if (unlinked.length === glossary.terms.length && glossary.terms.length > 1) {\n return [\n {\n severity: \"warn\",\n code: \"glossary.unlinked\",\n message:\n `glossary: none of the ${glossary.terms.length} defined term(s) is linked from any document outside glossary/. ` +\n \"A term becomes checkable when a requirement, capability or intent cites it — \" +\n \"`[Order](../../glossary/order.md)` — and until then the definitions are a document nothing joins to.\",\n details: unlinked.map(({ term }) => term.id),\n },\n ];\n }\n return unlinked.map(({ term, within }) => ({\n severity: \"warn\" as const,\n code: \"glossary.unlinked\",\n subject: term.id,\n message:\n `glossary/${term.id}.md is linked from no document outside glossary/` +\n (within.length === 0\n ? \" — either a word the fleet has not adopted, or a definition left behind by a rename.\"\n : \", only from other terms — which says the glossary is consistent, not that the fleet uses the word.\") +\n ` Cite it as \\`[${term.id}](<relative>/glossary/${term.id}.md)\\` from the requirement or capability that uses it, or delete the definition.`,\n ...(within.length === 0 ? {} : { details: within }),\n }));\n}\n"]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { plural } from "../../policy/format.js";
|
|
2
|
+
import { cappedNames } from "./rollups.js";
|
|
3
|
+
/**
|
|
4
|
+
* More than three services: three can be a coincidence of one team's
|
|
5
|
+
* services, and three lines are still read one by one. Past that the lines
|
|
6
|
+
* stop being read and start being scrolled.
|
|
7
|
+
*/
|
|
8
|
+
const REPEAT_THRESHOLD = 3;
|
|
9
|
+
/**
|
|
10
|
+
* The groups over `services`, considering only the findings `shown` would
|
|
11
|
+
* print. The predicate is the listing's own, so a finding another lever
|
|
12
|
+
* already took out of the listing (`--errors-only`, an axis banner, a lead) is
|
|
13
|
+
* neither counted here nor printed twice.
|
|
14
|
+
*/
|
|
15
|
+
export function repeatedFindings(services, shown) {
|
|
16
|
+
// Per key, the foldable finding of each service that raises the key exactly
|
|
17
|
+
// once — a Map iterates in insertion order, so the names keep the report's.
|
|
18
|
+
const byKey = new Map();
|
|
19
|
+
for (const t of services) {
|
|
20
|
+
for (const f of t.findings) {
|
|
21
|
+
if (f.severity === "ok" || !shown(f))
|
|
22
|
+
continue;
|
|
23
|
+
const key = `${f.severity} ${f.code}`;
|
|
24
|
+
const perService = byKey.get(key) ?? new Map();
|
|
25
|
+
// A second finding from the same service, or one carrying details, makes
|
|
26
|
+
// that service's entry unfoldable (null): its lines print as themselves.
|
|
27
|
+
const foldable = !perService.has(t.id) && (f.details ?? []).length === 0;
|
|
28
|
+
perService.set(t.id, foldable ? f : null);
|
|
29
|
+
byKey.set(key, perService);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const groups = [];
|
|
33
|
+
const collapsed = new Set();
|
|
34
|
+
for (const perService of byKey.values()) {
|
|
35
|
+
const folded = [...perService].filter((entry) => entry[1] !== null);
|
|
36
|
+
const [first] = folded;
|
|
37
|
+
if (first === undefined || folded.length <= REPEAT_THRESHOLD)
|
|
38
|
+
continue;
|
|
39
|
+
groups.push({ example: first[1], findings: folded.length, services: folded.map(([id]) => id) });
|
|
40
|
+
for (const [, f] of folded)
|
|
41
|
+
collapsed.add(f);
|
|
42
|
+
}
|
|
43
|
+
// A stable sort, so the report order survives inside each severity.
|
|
44
|
+
groups.sort((a, b) => severityRank(a.example) - severityRank(b.example));
|
|
45
|
+
return { groups, collapsed };
|
|
46
|
+
}
|
|
47
|
+
function severityRank(f) {
|
|
48
|
+
return f.severity === "error" ? 0 : 1;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Each group as its example — through `lineOf`, the listing's own line, so it
|
|
52
|
+
* keeps the severity marker and the `(code)` suffix exactly as any finding
|
|
53
|
+
* does — and one indented line saying how far it repeats. No member carries
|
|
54
|
+
* details (those are never folded), so nothing is left out of either line.
|
|
55
|
+
*/
|
|
56
|
+
export function printRepeats(groups, lineOf) {
|
|
57
|
+
for (const g of groups) {
|
|
58
|
+
console.log(lineOf(g.example));
|
|
59
|
+
console.log(` same code ×${g.findings} on ${plural(g.services.length, "service")}: ` +
|
|
60
|
+
`${cappedNames(g.services)} — every finding is in --json`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=repeats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repeats.js","sourceRoot":"","sources":["../../../../src/commands/validate/render/repeats.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Repeat grouping: on a fleet run, a warning or error that MORE THAN\n * `REPEAT_THRESHOLD` services raise prints once, as itself, followed by one\n * counted line naming the services — instead of once per service.\n *\n * A fleet mid-adoption raises the same finding on most of its services: forty\n * services with no `sources:` print forty near-identical warnings, and the one\n * warning that is actually different sits somewhere among them. The reader of\n * a CI log needs the pattern once and the exceptions individually; the per-\n * service copies are what the `--json` payload and a single-service run are\n * for, and both still carry every one.\n *\n * It is the same kind of lever as `--errors-only` and axis grouping\n * (`./text.ts`), and holds the same discipline: the report, the footer's\n * counts, `--json` and `--strict` are computed from the UNFILTERED findings,\n * and nothing is dropped — every finding a group stands for is counted on its\n * line and its service named there (capped, the remainder counted). Each\n * boundary below is chosen so a group cannot hide something a reader needs:\n *\n * - SERVICE targets only. A feature's block is that feature's work list, and\n * the landscape's findings are each about a different place on the map, so\n * neither is \"the same finding again\".\n * - Warnings and errors only. An `ok` line confirms a per-service fact (how\n * many elements, how many requirements), and `--errors-only` already exists\n * for a reader who wants confirmations gone.\n * - Keyed on severity AND code. `service.no-openapi` is an error or a warning\n * depending on what already points into the missing file; one key would file\n * an error under a ⚠.\n * - The threshold counts distinct SERVICES, not findings, and only a service\n * raising the finding exactly ONCE is folded. One service raising\n * `covers.unknown` five times is five broken lines in one document, and each\n * of them has to print — that is not a fleet-wide pattern, it is a worklist —\n * so its five lines stay in its own listing even when four other services\n * raise the code once each and are folded.\n * - A finding that carries `details` is never folded. Details are evidence\n * about one service (which links dangle into the missing file, which ids do\n * not resolve), and a counted line could only drop them.\n */\nimport type { Finding, TargetReport } from \"../../../core/vocabulary/report.js\";\nimport { plural } from \"../../policy/format.js\";\nimport { cappedNames } from \"./rollups.js\";\n\n/**\n * More than three services: three can be a coincidence of one team's\n * services, and three lines are still read one by one. Past that the lines\n * stop being read and start being scrolled.\n */\nconst REPEAT_THRESHOLD = 3;\n\nexport interface RepeatGroup {\n /** The group's first finding in report order — printed in full, as itself. */\n readonly example: Finding;\n /** How many findings the group stands for, the example included. */\n readonly findings: number;\n /** The distinct services raising it, in report order. */\n readonly services: readonly string[];\n}\n\nexport interface Repeats {\n /** Errors first, then warnings; within each, the order the report raised them in. */\n readonly groups: readonly RepeatGroup[];\n /** Every finding a group stands for — exactly what the per-service listing skips. */\n readonly collapsed: ReadonlySet<Finding>;\n}\n\n/**\n * The groups over `services`, considering only the findings `shown` would\n * print. The predicate is the listing's own, so a finding another lever\n * already took out of the listing (`--errors-only`, an axis banner, a lead) is\n * neither counted here nor printed twice.\n */\nexport function repeatedFindings(\n services: readonly TargetReport[],\n shown: (f: Finding) => boolean,\n): Repeats {\n // Per key, the foldable finding of each service that raises the key exactly\n // once — a Map iterates in insertion order, so the names keep the report's.\n const byKey = new Map<string, Map<string, Finding | null>>();\n for (const t of services) {\n for (const f of t.findings) {\n if (f.severity === \"ok\" || !shown(f)) continue;\n const key = `${f.severity} ${f.code}`;\n const perService = byKey.get(key) ?? new Map<string, Finding | null>();\n // A second finding from the same service, or one carrying details, makes\n // that service's entry unfoldable (null): its lines print as themselves.\n const foldable = !perService.has(t.id) && (f.details ?? []).length === 0;\n perService.set(t.id, foldable ? f : null);\n byKey.set(key, perService);\n }\n }\n const groups: RepeatGroup[] = [];\n const collapsed = new Set<Finding>();\n for (const perService of byKey.values()) {\n const folded = [...perService].filter((entry): entry is [string, Finding] => entry[1] !== null);\n const [first] = folded;\n if (first === undefined || folded.length <= REPEAT_THRESHOLD) continue;\n groups.push({ example: first[1], findings: folded.length, services: folded.map(([id]) => id) });\n for (const [, f] of folded) collapsed.add(f);\n }\n // A stable sort, so the report order survives inside each severity.\n groups.sort((a, b) => severityRank(a.example) - severityRank(b.example));\n return { groups, collapsed };\n}\n\nfunction severityRank(f: Finding): number {\n return f.severity === \"error\" ? 0 : 1;\n}\n\n/**\n * Each group as its example — through `lineOf`, the listing's own line, so it\n * keeps the severity marker and the `(code)` suffix exactly as any finding\n * does — and one indented line saying how far it repeats. No member carries\n * details (those are never folded), so nothing is left out of either line.\n */\nexport function printRepeats(groups: readonly RepeatGroup[], lineOf: (f: Finding) => string): void {\n for (const g of groups) {\n console.log(lineOf(g.example));\n console.log(\n ` same code ×${g.findings} on ${plural(g.services.length, \"service\")}: ` +\n `${cappedNames(g.services)} — every finding is in --json`,\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The lines of a fleet report that describe the WHOLE run rather than one
|
|
3
|
+
* finding: the summary that opens and closes it, the index of its errors, the
|
|
4
|
+
* unverifiable-sources line and the not-started axis banners.
|
|
5
|
+
*
|
|
6
|
+
* Every one of them is tallied off the UNFILTERED findings — the same walk the
|
|
7
|
+
* `--json` summary counts — and none of them is a finding, which is why they
|
|
8
|
+
* all print under `--errors-only` and why no rendering lever (axis grouping,
|
|
9
|
+
* repeat grouping) can move a number in any of them.
|
|
10
|
+
*/
|
|
11
|
+
import { SEVERITY_MARK } from "../../../core/vocabulary/report.js";
|
|
12
|
+
import { plural } from "../../policy/format.js";
|
|
13
|
+
import { ADOPTION_AXES } from "../fleet/scorecard/adoption.js";
|
|
14
|
+
/**
|
|
15
|
+
* How many names a counted line spells before the rest become `+N more`.
|
|
16
|
+
*
|
|
17
|
+
* A counted line exists to keep a hundred-service fleet's report readable, and
|
|
18
|
+
* a line that names all hundred is the same wall of text moved sideways. Five
|
|
19
|
+
* is enough to recognise a pattern — "it is every platform service" — and the
|
|
20
|
+
* count beside the list says how much was left out, so nothing reads complete
|
|
21
|
+
* when it is not. `--json` always carries every one.
|
|
22
|
+
*/
|
|
23
|
+
const NAME_LIMIT = 5;
|
|
24
|
+
/** `a, b, c, d, e +3 more` — the one spelling of a capped name list. */
|
|
25
|
+
export function cappedNames(names) {
|
|
26
|
+
const shown = names.slice(0, NAME_LIMIT).join(", ");
|
|
27
|
+
return names.length > NAME_LIMIT ? `${shown} +${names.length - NAME_LIMIT} more` : shown;
|
|
28
|
+
}
|
|
29
|
+
/** The counts line, printed above a fleet report and again as its footer. */
|
|
30
|
+
export function summaryLine(s) {
|
|
31
|
+
return (`${plural(s.services, "service")}, ${plural(s.features, "feature")} — ` +
|
|
32
|
+
`${plural(s.errors, "error")}, ${plural(s.warnings, "warning")}`);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Every error the run raised, one line per code, BEFORE the long listing.
|
|
36
|
+
*
|
|
37
|
+
* A fleet run that fails prints its errors wherever their targets happen to
|
|
38
|
+
* sit, and on a large fleet that is hundreds of lines in: a reader who opens
|
|
39
|
+
* the log at the top saw confirmations and warnings first and had to scroll to
|
|
40
|
+
* learn that, and why, the run was red. The index answers that in a few lines
|
|
41
|
+
* — which codes, how many, on what — and does NOT repeat the findings: each
|
|
42
|
+
* prints further down, under its own target or counted on a repeat group.
|
|
43
|
+
*
|
|
44
|
+
* Each error is named by WHERE it prints and, when narrower, what it is
|
|
45
|
+
* about: `FEAT-112 (order-service)` for a feature's per-service check, bare
|
|
46
|
+
* `payment-service` for a service's own. The subject alone sent a reader to
|
|
47
|
+
* the service section for an error printed under a feature; the target alone
|
|
48
|
+
* hid which service a feature or landscape finding is about. Most frequent
|
|
49
|
+
* first; ties keep the order the report raised them in, because a stable sort
|
|
50
|
+
* over the target walk is deterministic across runs and machines. The ×counts
|
|
51
|
+
* sum to the summary's error count by construction — both walk every error.
|
|
52
|
+
*/
|
|
53
|
+
export function printErrorIndex(targets) {
|
|
54
|
+
const byCode = new Map();
|
|
55
|
+
for (const t of targets) {
|
|
56
|
+
for (const f of t.findings) {
|
|
57
|
+
if (f.severity !== "error")
|
|
58
|
+
continue;
|
|
59
|
+
const entry = byCode.get(f.code) ?? { count: 0, places: new Set() };
|
|
60
|
+
entry.count += 1;
|
|
61
|
+
const where = f.subject === undefined || f.subject === t.id ? t.id : `${t.id} (${f.subject})`;
|
|
62
|
+
entry.places.add(where);
|
|
63
|
+
byCode.set(f.code, entry);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (byCode.size === 0)
|
|
67
|
+
return;
|
|
68
|
+
console.log("errors by code:");
|
|
69
|
+
const rows = [...byCode].sort(([, a], [, b]) => b.count - a.count);
|
|
70
|
+
for (const [raised, entry] of rows) {
|
|
71
|
+
console.log(` ${SEVERITY_MARK.error} ${raised} ×${entry.count}: ${cappedNames([...entry.places])}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The `--all` footer: the summary, the unverifiable-sources line and the axis
|
|
76
|
+
* banners. Printed last because CI logs are read from the tail.
|
|
77
|
+
*/
|
|
78
|
+
export function printFooter(targets, footer) {
|
|
79
|
+
const { unverifiable, card, grouped, isGrouped } = footer;
|
|
80
|
+
console.log(`\n${summaryLine(footer.summary)}`);
|
|
81
|
+
// One line for the whole fleet, never one per service: honest about the blind
|
|
82
|
+
// spot without drowning the report in a hundred copies of it.
|
|
83
|
+
if (unverifiable > 0) {
|
|
84
|
+
const whose = unverifiable === 1 ? "1 service's" : `${unverifiable} services'`;
|
|
85
|
+
console.log(`⚠ sources.unverifiable-from-here: ${whose} sources can only be checked from their own repos`);
|
|
86
|
+
}
|
|
87
|
+
// The axis banners — one per not-started axis that actually grouped a
|
|
88
|
+
// warning, in the axes' fixed order, each naming its dropped codes with
|
|
89
|
+
// counts. Tallied off the UNFILTERED findings (the same walk the footer
|
|
90
|
+
// counts), and printed under --errors-only too: like the footer and the
|
|
91
|
+
// unverifiable line this is a rollup, not a finding.
|
|
92
|
+
if (card !== null && grouped.size > 0) {
|
|
93
|
+
const tally = new Map();
|
|
94
|
+
for (const t of targets) {
|
|
95
|
+
for (const f of t.findings) {
|
|
96
|
+
if (isGrouped(f))
|
|
97
|
+
tally.set(f.code, (tally.get(f.code) ?? 0) + 1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (const axis of ADOPTION_AXES) {
|
|
101
|
+
// Insertion order of `grouped` is the table's order, so the pairs render
|
|
102
|
+
// deterministically across runs and machines.
|
|
103
|
+
const pairs = [...grouped]
|
|
104
|
+
.filter(([code, a]) => a === axis && (tally.get(code) ?? 0) > 0)
|
|
105
|
+
.map(([code]) => [code, tally.get(code) ?? 0]);
|
|
106
|
+
if (pairs.length === 0)
|
|
107
|
+
continue;
|
|
108
|
+
const total = pairs.reduce((n, [, k]) => n + k, 0);
|
|
109
|
+
console.log(`⚠ ${axis} axis not started fleet-wide (0 of ${plural(card.services, "service")}), ` +
|
|
110
|
+
`expected during staged adoption — ${total} warning(s) grouped: ` +
|
|
111
|
+
`${pairs.map(([code, k]) => `${code}×${k}`).join(", ")}; every finding is unchanged in --json`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=rollups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollups.js","sourceRoot":"","sources":["../../../../src/commands/validate/render/rollups.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The lines of a fleet report that describe the WHOLE run rather than one\n * finding: the summary that opens and closes it, the index of its errors, the\n * unverifiable-sources line and the not-started axis banners.\n *\n * Every one of them is tallied off the UNFILTERED findings — the same walk the\n * `--json` summary counts — and none of them is a finding, which is why they\n * all print under `--errors-only` and why no rendering lever (axis grouping,\n * repeat grouping) can move a number in any of them.\n */\nimport { SEVERITY_MARK, type Finding, type TargetReport } from \"../../../core/vocabulary/report.js\";\nimport { plural } from \"../../policy/format.js\";\nimport { ADOPTION_AXES, type Adoption, type AdoptionAxis } from \"../fleet/scorecard/adoption.js\";\nimport type { ValidateSummary } from \"../report.js\";\n\n/**\n * How many names a counted line spells before the rest become `+N more`.\n *\n * A counted line exists to keep a hundred-service fleet's report readable, and\n * a line that names all hundred is the same wall of text moved sideways. Five\n * is enough to recognise a pattern — \"it is every platform service\" — and the\n * count beside the list says how much was left out, so nothing reads complete\n * when it is not. `--json` always carries every one.\n */\nconst NAME_LIMIT = 5;\n\n/** `a, b, c, d, e +3 more` — the one spelling of a capped name list. */\nexport function cappedNames(names: readonly string[]): string {\n const shown = names.slice(0, NAME_LIMIT).join(\", \");\n return names.length > NAME_LIMIT ? `${shown} +${names.length - NAME_LIMIT} more` : shown;\n}\n\n/** The counts line, printed above a fleet report and again as its footer. */\nexport function summaryLine(s: ValidateSummary): string {\n return (\n `${plural(s.services, \"service\")}, ${plural(s.features, \"feature\")} — ` +\n `${plural(s.errors, \"error\")}, ${plural(s.warnings, \"warning\")}`\n );\n}\n\n/**\n * Every error the run raised, one line per code, BEFORE the long listing.\n *\n * A fleet run that fails prints its errors wherever their targets happen to\n * sit, and on a large fleet that is hundreds of lines in: a reader who opens\n * the log at the top saw confirmations and warnings first and had to scroll to\n * learn that, and why, the run was red. The index answers that in a few lines\n * — which codes, how many, on what — and does NOT repeat the findings: each\n * prints further down, under its own target or counted on a repeat group.\n *\n * Each error is named by WHERE it prints and, when narrower, what it is\n * about: `FEAT-112 (order-service)` for a feature's per-service check, bare\n * `payment-service` for a service's own. The subject alone sent a reader to\n * the service section for an error printed under a feature; the target alone\n * hid which service a feature or landscape finding is about. Most frequent\n * first; ties keep the order the report raised them in, because a stable sort\n * over the target walk is deterministic across runs and machines. The ×counts\n * sum to the summary's error count by construction — both walk every error.\n */\nexport function printErrorIndex(targets: readonly TargetReport[]): void {\n const byCode = new Map<string, { count: number; places: Set<string> }>();\n for (const t of targets) {\n for (const f of t.findings) {\n if (f.severity !== \"error\") continue;\n const entry = byCode.get(f.code) ?? { count: 0, places: new Set<string>() };\n entry.count += 1;\n const where = f.subject === undefined || f.subject === t.id ? t.id : `${t.id} (${f.subject})`;\n entry.places.add(where);\n byCode.set(f.code, entry);\n }\n }\n if (byCode.size === 0) return;\n console.log(\"errors by code:\");\n const rows = [...byCode].sort(([, a], [, b]) => b.count - a.count);\n for (const [raised, entry] of rows) {\n console.log(` ${SEVERITY_MARK.error} ${raised} ×${entry.count}: ${cappedNames([...entry.places])}`);\n }\n}\n\n/** What the footer needs beyond the targets themselves. */\nexport interface Footer {\n summary: ValidateSummary;\n /** The fleet's unverifiable-sources subject count. */\n unverifiable: number;\n /** The scorecard facts that licensed axis grouping, or null when nothing was grouped. */\n card: { readonly adoption: Adoption; readonly services: number } | null;\n /** The warn codes axis grouping folded, by axis — empty when `card` is null. */\n grouped: ReadonlyMap<string, AdoptionAxis>;\n /**\n * The predicate the listing dropped findings by. Handed in rather than\n * re-derived from `grouped`, so the banner counts exactly the findings the\n * listing left out — two spellings of one rule are two rules.\n */\n isGrouped: (f: Finding) => boolean;\n}\n\n/**\n * The `--all` footer: the summary, the unverifiable-sources line and the axis\n * banners. Printed last because CI logs are read from the tail.\n */\nexport function printFooter(targets: readonly TargetReport[], footer: Footer): void {\n const { unverifiable, card, grouped, isGrouped } = footer;\n console.log(`\\n${summaryLine(footer.summary)}`);\n // One line for the whole fleet, never one per service: honest about the blind\n // spot without drowning the report in a hundred copies of it.\n if (unverifiable > 0) {\n const whose = unverifiable === 1 ? \"1 service's\" : `${unverifiable} services'`;\n console.log(\n `⚠ sources.unverifiable-from-here: ${whose} sources can only be checked from their own repos`,\n );\n }\n // The axis banners — one per not-started axis that actually grouped a\n // warning, in the axes' fixed order, each naming its dropped codes with\n // counts. Tallied off the UNFILTERED findings (the same walk the footer\n // counts), and printed under --errors-only too: like the footer and the\n // unverifiable line this is a rollup, not a finding.\n if (card !== null && grouped.size > 0) {\n const tally = new Map<string, number>();\n for (const t of targets) {\n for (const f of t.findings) {\n if (isGrouped(f)) tally.set(f.code, (tally.get(f.code) ?? 0) + 1);\n }\n }\n for (const axis of ADOPTION_AXES) {\n // Insertion order of `grouped` is the table's order, so the pairs render\n // deterministically across runs and machines.\n const pairs = [...grouped]\n .filter(([code, a]) => a === axis && (tally.get(code) ?? 0) > 0)\n .map(([code]) => [code, tally.get(code) ?? 0] as const);\n if (pairs.length === 0) continue;\n const total = pairs.reduce((n, [, k]) => n + k, 0);\n console.log(\n `⚠ ${axis} axis not started fleet-wide (0 of ${plural(card.services, \"service\")}), ` +\n `expected during staged adoption — ${total} warning(s) grouped: ` +\n `${pairs.map(([code, k]) => `${code}×${k}`).join(\", \")}; every finding is unchanged in --json`,\n );\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `loam validate`'s human view: how a graded report prints.
|
|
3
|
+
*
|
|
4
|
+
* Its own package since the fleet report grew an ORDER — lead findings, the
|
|
5
|
+
* counts and the error index, every feature, the fleet, the footer — and two
|
|
6
|
+
* levers that fold lines (axis banners, repeat groups). None of that changes a
|
|
7
|
+
* finding, a count or an exit code: `--json` and `--strict` read the targets
|
|
8
|
+
* this module is handed, never what it chose to print.
|
|
9
|
+
*
|
|
10
|
+
* The rollup is not recounted here. `RenderOptions.summary` IS the run's
|
|
11
|
+
* `summary()` (`../report.ts`), the same object `--json` carries, handed in by
|
|
12
|
+
* validate.ts — a renderer with its own count is how a footer starts printing
|
|
13
|
+
* a number its own findings contradict.
|
|
14
|
+
*/
|
|
15
|
+
import { listCodes } from "../../../core/explain/lookup.js";
|
|
16
|
+
import { NOT_CHECKED_MARK, SEVERITY_MARK, subjectsWith, } from "../../../core/vocabulary/report.js";
|
|
17
|
+
import { EXPLAIN_FOOTER } from "../../policy/format.js";
|
|
18
|
+
import { groupedWarnCodes } from "../fleet/scorecard/adoption.js";
|
|
19
|
+
import { printRepeats, repeatedFindings } from "./repeats.js";
|
|
20
|
+
import { printErrorIndex, printFooter, summaryLine } from "./rollups.js";
|
|
21
|
+
/**
|
|
22
|
+
* `--errors-only` is a RENDERING lever, the way `--strict` is an exit-code
|
|
23
|
+
* lever: neither changes the report, and the `--json` payload is unaffected by
|
|
24
|
+
* both. On a fleet of a hundred services the clean run prints several hundred
|
|
25
|
+
* `ok` confirmations, and the two warnings that matter are somewhere inside it;
|
|
26
|
+
* anyone reading a CI log wants the exceptions, and anyone auditing wants all
|
|
27
|
+
* of it. Both are available, from the same run, and neither is the default.
|
|
28
|
+
*
|
|
29
|
+
* Axis grouping is the same kind of lever, one notch further: warnings whose
|
|
30
|
+
* SOLE cause is a fleet-wide not-started axis (the mechanical, fail-closed
|
|
31
|
+
* rule in fleet/scorecard/adoption.ts — warn severity, listed code, axis at
|
|
32
|
+
* zero) are dropped from the per-target listing and re-stated as one banner
|
|
33
|
+
* per axis after the footer. The report, the footer's counts, `--json` and
|
|
34
|
+
* `--strict` are all computed from the UNFILTERED findings, so nothing a
|
|
35
|
+
* machine or an exit code reads moves by a single bit. Repeat grouping
|
|
36
|
+
* (`./repeats.ts`) is the third, under the same rule.
|
|
37
|
+
*/
|
|
38
|
+
export function renderText(targets, opts) {
|
|
39
|
+
const { all, errorsOnly } = opts;
|
|
40
|
+
// When the fleet-wide "not started" claim is measurable at all — each guard
|
|
41
|
+
// fails closed to ungrouped rendering. `!all` is structural, not just the
|
|
42
|
+
// call site's promise: the banners print after the footer that only `--all`
|
|
43
|
+
// reaches, so grouping outside `--all` would DROP warnings instead of
|
|
44
|
+
// moving them — the one thing this lever must never do. `services === 0`
|
|
45
|
+
// is the vacuous fleet: with no services every axis is 0 "fleet-wide", and
|
|
46
|
+
// a banner over "0 of 0 services" would hide the fleet-level warnings of a
|
|
47
|
+
// repo that merely has no fleet yet. And an unreadable service proves
|
|
48
|
+
// nothing about what it started: its all-false participation (contracts.ts)
|
|
49
|
+
// could MANUFACTURE the very N=0 that licenses suppression — beside an
|
|
50
|
+
// error saying that service could not be checked — so one
|
|
51
|
+
// `service.unreadable` subject disables grouping for the whole run.
|
|
52
|
+
const card = !all ||
|
|
53
|
+
opts.scorecard === null ||
|
|
54
|
+
opts.scorecard.services === 0 ||
|
|
55
|
+
subjectsWith(targets, "service.unreadable") > 0
|
|
56
|
+
? null
|
|
57
|
+
: opts.scorecard;
|
|
58
|
+
const grouped = card === null ? new Map() : groupedWarnCodes(card.adoption);
|
|
59
|
+
const isGrouped = (f) => f.severity === "warn" && grouped.has(f.code);
|
|
60
|
+
// The explain pointer follows any report that printed work — a non-ok
|
|
61
|
+
// finding, listed or folded under an axis banner. Gated on the UNFILTERED
|
|
62
|
+
// findings like every other rollup, so `--errors-only` and grouping cannot
|
|
63
|
+
// print codes the pointer then fails to follow. It is computed HERE rather
|
|
64
|
+
// than beside the two places it prints because the code column below asks
|
|
65
|
+
// the same question and must not walk the findings a second time to answer
|
|
66
|
+
// it differently.
|
|
67
|
+
const pointer = targets.some((t) => t.findings.some((f) => f.severity !== "ok"));
|
|
68
|
+
// The lookup key on the line itself.
|
|
69
|
+
//
|
|
70
|
+
// Until now a text report printed messages and no codes, so the footer under
|
|
71
|
+
// it could only say codes were somewhere else — in `--json`, which a reader
|
|
72
|
+
// would have to re-run the whole command to see. The code is what `loam
|
|
73
|
+
// explain` takes, what a CI branch tests and what a bug report quotes, and
|
|
74
|
+
// withholding it from the one surface a person actually reads made the
|
|
75
|
+
// footer's own offer unreachable.
|
|
76
|
+
//
|
|
77
|
+
// Only where a code is genuinely answerable, and that guard is not
|
|
78
|
+
// decoration: a handful of emitted finding codes still have no fix-table row
|
|
79
|
+
// (test/explain.test.ts names them), and printing one beside a footer
|
|
80
|
+
// promising an explanation would send the reader to a refusal. The set is
|
|
81
|
+
// built ONCE per render, and only when something non-ok will be printed:
|
|
82
|
+
// `explainSubject` walks the shipped workflow bodies per code (the cost
|
|
83
|
+
// `fixesFor` measured from the other side, where a handful of lookups is the
|
|
84
|
+
// cheaper shape), while `listCodes()` walks them once for the whole
|
|
85
|
+
// vocabulary — and a fleet report has far more finding lines than the fleet
|
|
86
|
+
// has distinct codes. Measured: 2.7 ms for all 273 codes, once per report.
|
|
87
|
+
const explainable = pointer ? new Set(listCodes().map((listing) => listing.code)) : new Set();
|
|
88
|
+
const listed = (f) => !isGrouped(f) && (!errorsOnly || f.severity !== "ok");
|
|
89
|
+
if (!all) {
|
|
90
|
+
for (const t of targets)
|
|
91
|
+
printTarget(t, listed, explainable);
|
|
92
|
+
// Without the --all footer there would be nothing at all to print for a
|
|
93
|
+
// clean single target under --errors-only — and silence is the one output
|
|
94
|
+
// that must never mean "checked, fine".
|
|
95
|
+
if (errorsOnly && targets.every((t) => t.findings.every((f) => f.severity === "ok"))) {
|
|
96
|
+
console.log(`${targets.map((t) => t.id).join(", ")}: no errors or warnings`);
|
|
97
|
+
}
|
|
98
|
+
if (pointer)
|
|
99
|
+
console.log(`\n${EXPLAIN_FOOTER}`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
printFleet(targets, { listed, explainable, summary: opts.summary });
|
|
103
|
+
printFooter(targets, { summary: opts.summary, unverifiable: opts.unverifiable, card, grouped, isGrouped });
|
|
104
|
+
if (pointer)
|
|
105
|
+
console.log(`\n${EXPLAIN_FOOTER}`);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The `--all` listing, in the order a reader needs it rather than the order
|
|
109
|
+
* the targets were graded in.
|
|
110
|
+
*
|
|
111
|
+
* Graded order put every service first and the features last, so on a real
|
|
112
|
+
* fleet the feature blocks — the work somebody is doing right now — and any
|
|
113
|
+
* error that made the run red sat under hundreds of per-service lines. Now:
|
|
114
|
+
* the findings that say nothing below can be trusted (`TextHint.lead`); the
|
|
115
|
+
* counts; the error index; each feature's block; then the fleet — the
|
|
116
|
+
* landscape, the groups repeat grouping folded, every service. The footer
|
|
117
|
+
* still closes it, because CI logs are read from the tail. A finding prints at
|
|
118
|
+
* most once: in full under its target, or — when repeat grouping folded it —
|
|
119
|
+
* counted on its group's line, the group's first member printed in full.
|
|
120
|
+
*/
|
|
121
|
+
function printFleet(targets, view) {
|
|
122
|
+
const { listed, explainable } = view;
|
|
123
|
+
const lead = (f) => f.text?.lead === true;
|
|
124
|
+
const body = (f) => listed(f) && !lead(f);
|
|
125
|
+
const services = targets.filter((t) => t.kind === "service");
|
|
126
|
+
const repeats = repeatedFindings(services, body);
|
|
127
|
+
const block = (f) => body(f) && !repeats.collapsed.has(f);
|
|
128
|
+
const features = targets.filter((t) => t.kind === "feature");
|
|
129
|
+
const featuresPrint = features.some((t) => t.findings.some(block));
|
|
130
|
+
const fleetPrints = repeats.groups.length > 0 || targets.some((t) => t.kind !== "feature" && t.findings.some(block));
|
|
131
|
+
// The head prints only above something: on a run whose listing is empty (a
|
|
132
|
+
// clean fleet under --errors-only) the footer below is the whole report,
|
|
133
|
+
// and the same counts twice in a row would say nothing new.
|
|
134
|
+
if (targets.some((t) => t.findings.some(listed))) {
|
|
135
|
+
const leads = targets.flatMap((t) => t.findings.filter((f) => lead(f) && listed(f)));
|
|
136
|
+
for (const f of leads)
|
|
137
|
+
printFinding(f, explainable);
|
|
138
|
+
console.log(summaryLine(view.summary));
|
|
139
|
+
printErrorIndex(targets);
|
|
140
|
+
if (featuresPrint || fleetPrints)
|
|
141
|
+
console.log("");
|
|
142
|
+
}
|
|
143
|
+
for (const t of features)
|
|
144
|
+
printTarget(t, block, explainable);
|
|
145
|
+
// One blank line between the features and the fleet, so the last feature's
|
|
146
|
+
// indented coherence line is not read as the landscape's first.
|
|
147
|
+
if (featuresPrint && fleetPrints)
|
|
148
|
+
console.log("");
|
|
149
|
+
for (const t of targets)
|
|
150
|
+
if (t.kind === "landscape")
|
|
151
|
+
printTarget(t, block, explainable);
|
|
152
|
+
printRepeats(repeats.groups, (f) => findingLine(f, explainable));
|
|
153
|
+
for (const t of services)
|
|
154
|
+
printTarget(t, block, explainable);
|
|
155
|
+
}
|
|
156
|
+
/** One target's block: the findings `show` admits, under the target's own header. */
|
|
157
|
+
function printTarget(t, show, explainable) {
|
|
158
|
+
const shown = t.findings.filter(show);
|
|
159
|
+
if (shown.length === 0)
|
|
160
|
+
return;
|
|
161
|
+
// A feature announces itself; a service's findings already carry its name.
|
|
162
|
+
if (t.kind === "feature")
|
|
163
|
+
console.log(t.id);
|
|
164
|
+
let header;
|
|
165
|
+
for (const f of shown) {
|
|
166
|
+
const hint = f.text ?? {};
|
|
167
|
+
if (hint.header && hint.header !== header) {
|
|
168
|
+
header = hint.header;
|
|
169
|
+
console.log(` ${header}`);
|
|
170
|
+
}
|
|
171
|
+
printFinding(f, explainable);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** A finding's line and its evidence. */
|
|
175
|
+
function printFinding(f, explainable) {
|
|
176
|
+
// The whole report goes to stdout, in the order it prints. Splitting errors
|
|
177
|
+
// onto stderr meant a piped stdout silently lost them from the middle of
|
|
178
|
+
// the report and 2>&1 could reorder it; the exit code carries failure,
|
|
179
|
+
// and stderr stays reserved for refusals (the fail() path).
|
|
180
|
+
console.log(findingLine(f, explainable));
|
|
181
|
+
for (const d of f.details ?? [])
|
|
182
|
+
console.log(` ${f.text?.detailPrefix ?? ""}${d}`);
|
|
183
|
+
}
|
|
184
|
+
/** The one spelling of a finding's line — the listing's and a repeat group's example's. */
|
|
185
|
+
function findingLine(f, explainable) {
|
|
186
|
+
const hint = f.text ?? {};
|
|
187
|
+
// The not-checked glyph replaces ✓ only. A hint can never print a ⚠ or a ✗
|
|
188
|
+
// as anything but itself: a check that did not run is an `ok` fact, and a
|
|
189
|
+
// stray hint on a real finding must not make it look like one.
|
|
190
|
+
const glyph = hint.marker === "not-checked" && f.severity === "ok" ? NOT_CHECKED_MARK : SEVERITY_MARK[f.severity];
|
|
191
|
+
const marker = hint.marker === false ? "" : `${glyph} `;
|
|
192
|
+
// `ok` confirmations stay clean, deliberately. A clean fleet run is
|
|
193
|
+
// several hundred ✓ lines and two warnings, and a code appended to every
|
|
194
|
+
// one of them would cost exactly the signal the exceptions carry — there
|
|
195
|
+
// is nothing to look up about a check that passed.
|
|
196
|
+
const code = f.severity !== "ok" && explainable.has(f.code) ? ` (${f.code})` : "";
|
|
197
|
+
return `${" ".repeat(hint.indent ?? 0)}${marker}${f.message}${code}`;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../../src/commands/validate/render/text.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loam validate`'s human view: how a graded report prints.\n *\n * Its own package since the fleet report grew an ORDER — lead findings, the\n * counts and the error index, every feature, the fleet, the footer — and two\n * levers that fold lines (axis banners, repeat groups). None of that changes a\n * finding, a count or an exit code: `--json` and `--strict` read the targets\n * this module is handed, never what it chose to print.\n *\n * The rollup is not recounted here. `RenderOptions.summary` IS the run's\n * `summary()` (`../report.ts`), the same object `--json` carries, handed in by\n * validate.ts — a renderer with its own count is how a footer starts printing\n * a number its own findings contradict.\n */\nimport { listCodes } from \"../../../core/explain/lookup.js\";\nimport {\n NOT_CHECKED_MARK,\n SEVERITY_MARK,\n subjectsWith,\n type Finding,\n type TargetReport,\n} from \"../../../core/vocabulary/report.js\";\nimport { EXPLAIN_FOOTER } from \"../../policy/format.js\";\nimport { groupedWarnCodes, type Adoption, type AdoptionAxis } from \"../fleet/scorecard/adoption.js\";\nimport type { ValidateSummary } from \"../report.js\";\nimport { printRepeats, repeatedFindings } from \"./repeats.js\";\nimport { printErrorIndex, printFooter, summaryLine } from \"./rollups.js\";\n\n/** What `renderText` needs of the run beyond the graded targets themselves. */\nexport interface RenderOptions {\n all: boolean;\n errorsOnly: boolean;\n /** The run's `summary()` — the very object the `--json` payload carries. */\n summary: ValidateSummary;\n /** The fleet's unverifiable-sources subject count, for the one-line rollup. */\n unverifiable: number;\n /**\n * The run's scorecard facts the renderer reads — ONE field, not a nullable\n * adoption beside a defaulted denominator, so \"adoption without its real\n * denominator\" is not constructible. Null on every single-target run and on\n * an `--all` run whose card failed closed, and null renders exactly as\n * before grouping existed: fail-open to today's behaviour, every warning\n * printed individually.\n */\n scorecard: { readonly adoption: Adoption; readonly services: number } | null;\n}\n\n/**\n * `--errors-only` is a RENDERING lever, the way `--strict` is an exit-code\n * lever: neither changes the report, and the `--json` payload is unaffected by\n * both. On a fleet of a hundred services the clean run prints several hundred\n * `ok` confirmations, and the two warnings that matter are somewhere inside it;\n * anyone reading a CI log wants the exceptions, and anyone auditing wants all\n * of it. Both are available, from the same run, and neither is the default.\n *\n * Axis grouping is the same kind of lever, one notch further: warnings whose\n * SOLE cause is a fleet-wide not-started axis (the mechanical, fail-closed\n * rule in fleet/scorecard/adoption.ts — warn severity, listed code, axis at\n * zero) are dropped from the per-target listing and re-stated as one banner\n * per axis after the footer. The report, the footer's counts, `--json` and\n * `--strict` are all computed from the UNFILTERED findings, so nothing a\n * machine or an exit code reads moves by a single bit. Repeat grouping\n * (`./repeats.ts`) is the third, under the same rule.\n */\nexport function renderText(targets: TargetReport[], opts: RenderOptions): void {\n const { all, errorsOnly } = opts;\n // When the fleet-wide \"not started\" claim is measurable at all — each guard\n // fails closed to ungrouped rendering. `!all` is structural, not just the\n // call site's promise: the banners print after the footer that only `--all`\n // reaches, so grouping outside `--all` would DROP warnings instead of\n // moving them — the one thing this lever must never do. `services === 0`\n // is the vacuous fleet: with no services every axis is 0 \"fleet-wide\", and\n // a banner over \"0 of 0 services\" would hide the fleet-level warnings of a\n // repo that merely has no fleet yet. And an unreadable service proves\n // nothing about what it started: its all-false participation (contracts.ts)\n // could MANUFACTURE the very N=0 that licenses suppression — beside an\n // error saying that service could not be checked — so one\n // `service.unreadable` subject disables grouping for the whole run.\n const card =\n !all ||\n opts.scorecard === null ||\n opts.scorecard.services === 0 ||\n subjectsWith(targets, \"service.unreadable\") > 0\n ? null\n : opts.scorecard;\n const grouped = card === null ? new Map<string, AdoptionAxis>() : groupedWarnCodes(card.adoption);\n const isGrouped = (f: Finding): boolean => f.severity === \"warn\" && grouped.has(f.code);\n\n // The explain pointer follows any report that printed work — a non-ok\n // finding, listed or folded under an axis banner. Gated on the UNFILTERED\n // findings like every other rollup, so `--errors-only` and grouping cannot\n // print codes the pointer then fails to follow. It is computed HERE rather\n // than beside the two places it prints because the code column below asks\n // the same question and must not walk the findings a second time to answer\n // it differently.\n const pointer = targets.some((t) => t.findings.some((f) => f.severity !== \"ok\"));\n // The lookup key on the line itself.\n //\n // Until now a text report printed messages and no codes, so the footer under\n // it could only say codes were somewhere else — in `--json`, which a reader\n // would have to re-run the whole command to see. The code is what `loam\n // explain` takes, what a CI branch tests and what a bug report quotes, and\n // withholding it from the one surface a person actually reads made the\n // footer's own offer unreachable.\n //\n // Only where a code is genuinely answerable, and that guard is not\n // decoration: a handful of emitted finding codes still have no fix-table row\n // (test/explain.test.ts names them), and printing one beside a footer\n // promising an explanation would send the reader to a refusal. The set is\n // built ONCE per render, and only when something non-ok will be printed:\n // `explainSubject` walks the shipped workflow bodies per code (the cost\n // `fixesFor` measured from the other side, where a handful of lookups is the\n // cheaper shape), while `listCodes()` walks them once for the whole\n // vocabulary — and a fleet report has far more finding lines than the fleet\n // has distinct codes. Measured: 2.7 ms for all 273 codes, once per report.\n const explainable = pointer ? new Set(listCodes().map((listing) => listing.code)) : new Set<string>();\n const listed = (f: Finding): boolean => !isGrouped(f) && (!errorsOnly || f.severity !== \"ok\");\n\n if (!all) {\n for (const t of targets) printTarget(t, listed, explainable);\n // Without the --all footer there would be nothing at all to print for a\n // clean single target under --errors-only — and silence is the one output\n // that must never mean \"checked, fine\".\n if (errorsOnly && targets.every((t) => t.findings.every((f) => f.severity === \"ok\"))) {\n console.log(`${targets.map((t) => t.id).join(\", \")}: no errors or warnings`);\n }\n if (pointer) console.log(`\\n${EXPLAIN_FOOTER}`);\n return;\n }\n printFleet(targets, { listed, explainable, summary: opts.summary });\n printFooter(targets, { summary: opts.summary, unverifiable: opts.unverifiable, card, grouped, isGrouped });\n if (pointer) console.log(`\\n${EXPLAIN_FOOTER}`);\n}\n\n/** What the fleet layout reads of the render already decided above. */\ninterface FleetView {\n /** Whether a finding prints at all — the `--errors-only` and axis-banner levers already applied. */\n listed: (f: Finding) => boolean;\n explainable: ReadonlySet<string>;\n summary: ValidateSummary;\n}\n\n/**\n * The `--all` listing, in the order a reader needs it rather than the order\n * the targets were graded in.\n *\n * Graded order put every service first and the features last, so on a real\n * fleet the feature blocks — the work somebody is doing right now — and any\n * error that made the run red sat under hundreds of per-service lines. Now:\n * the findings that say nothing below can be trusted (`TextHint.lead`); the\n * counts; the error index; each feature's block; then the fleet — the\n * landscape, the groups repeat grouping folded, every service. The footer\n * still closes it, because CI logs are read from the tail. A finding prints at\n * most once: in full under its target, or — when repeat grouping folded it —\n * counted on its group's line, the group's first member printed in full.\n */\nfunction printFleet(targets: readonly TargetReport[], view: FleetView): void {\n const { listed, explainable } = view;\n const lead = (f: Finding): boolean => f.text?.lead === true;\n const body = (f: Finding): boolean => listed(f) && !lead(f);\n const services = targets.filter((t) => t.kind === \"service\");\n const repeats = repeatedFindings(services, body);\n const block = (f: Finding): boolean => body(f) && !repeats.collapsed.has(f);\n const features = targets.filter((t) => t.kind === \"feature\");\n const featuresPrint = features.some((t) => t.findings.some(block));\n const fleetPrints = repeats.groups.length > 0 || targets.some((t) => t.kind !== \"feature\" && t.findings.some(block));\n\n // The head prints only above something: on a run whose listing is empty (a\n // clean fleet under --errors-only) the footer below is the whole report,\n // and the same counts twice in a row would say nothing new.\n if (targets.some((t) => t.findings.some(listed))) {\n const leads = targets.flatMap((t) => t.findings.filter((f) => lead(f) && listed(f)));\n for (const f of leads) printFinding(f, explainable);\n console.log(summaryLine(view.summary));\n printErrorIndex(targets);\n if (featuresPrint || fleetPrints) console.log(\"\");\n }\n for (const t of features) printTarget(t, block, explainable);\n // One blank line between the features and the fleet, so the last feature's\n // indented coherence line is not read as the landscape's first.\n if (featuresPrint && fleetPrints) console.log(\"\");\n for (const t of targets) if (t.kind === \"landscape\") printTarget(t, block, explainable);\n printRepeats(repeats.groups, (f) => findingLine(f, explainable));\n for (const t of services) printTarget(t, block, explainable);\n}\n\n/** One target's block: the findings `show` admits, under the target's own header. */\nfunction printTarget(t: TargetReport, show: (f: Finding) => boolean, explainable: ReadonlySet<string>): void {\n const shown = t.findings.filter(show);\n if (shown.length === 0) return;\n // A feature announces itself; a service's findings already carry its name.\n if (t.kind === \"feature\") console.log(t.id);\n let header: string | undefined;\n for (const f of shown) {\n const hint = f.text ?? {};\n if (hint.header && hint.header !== header) {\n header = hint.header;\n console.log(` ${header}`);\n }\n printFinding(f, explainable);\n }\n}\n\n/** A finding's line and its evidence. */\nfunction printFinding(f: Finding, explainable: ReadonlySet<string>): void {\n // The whole report goes to stdout, in the order it prints. Splitting errors\n // onto stderr meant a piped stdout silently lost them from the middle of\n // the report and 2>&1 could reorder it; the exit code carries failure,\n // and stderr stays reserved for refusals (the fail() path).\n console.log(findingLine(f, explainable));\n for (const d of f.details ?? []) console.log(` ${f.text?.detailPrefix ?? \"\"}${d}`);\n}\n\n/** The one spelling of a finding's line — the listing's and a repeat group's example's. */\nfunction findingLine(f: Finding, explainable: ReadonlySet<string>): string {\n const hint = f.text ?? {};\n // The not-checked glyph replaces ✓ only. A hint can never print a ⚠ or a ✗\n // as anything but itself: a check that did not run is an `ok` fact, and a\n // stray hint on a real finding must not make it look like one.\n const glyph = hint.marker === \"not-checked\" && f.severity === \"ok\" ? NOT_CHECKED_MARK : SEVERITY_MARK[f.severity];\n const marker = hint.marker === false ? \"\" : `${glyph} `;\n // `ok` confirmations stay clean, deliberately. A clean fleet run is\n // several hundred ✓ lines and two warnings, and a code appended to every\n // one of them would cost exactly the signal the exceptions carry — there\n // is nothing to look up about a check that passed.\n const code = f.severity !== \"ok\" && explainable.has(f.code) ? ` (${f.code})` : \"\";\n return `${\" \".repeat(hint.indent ?? 0)}${marker}${f.message}${code}`;\n}\n"]}
|