@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,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The base side of `loam diff`: the fleet as the base commit held it, read
|
|
3
|
+
* entirely out of git's object store (`./base-git.ts`) and parsed with the
|
|
4
|
+
* SAME parsers the living files go through — `parseRequirements`,
|
|
5
|
+
* `openapiFromText`, `asyncapiFromText` — so a base document can never read
|
|
6
|
+
* differently from the identical bytes sitting on disk.
|
|
7
|
+
*
|
|
8
|
+
* CLASSIFICATION is a second, simplified spelling of `repo/tree/walk.ts`'s
|
|
9
|
+
* rule, and that is a recorded risk, not an accident: the walk classifies a
|
|
10
|
+
* LIVE filesystem (readdir, symlinks, marker files) and cannot walk a git
|
|
11
|
+
* ref. What keeps the two honest is sharing the artifact-name table
|
|
12
|
+
* (`ARTIFACT_FILES`/`isServiceArtifactName` from `repo/paths.ts`), the
|
|
13
|
+
* marker name (`SUBSYSTEM_MARKER`) and the reserved-interior set
|
|
14
|
+
* (`RESERVED_INTERIOR` from `repo/tree/walk.ts`) instead of respelling them, and restating
|
|
15
|
+
* — exactly — the walk's SERVICE branches: (0) a directory named for a
|
|
16
|
+
* service's own interior (`adrs/`, `usecases/`, `ui/`) is classified nowhere,
|
|
17
|
+
* counts as nothing beneath its parent, and hides everything under it, because
|
|
18
|
+
* the walk never descends into one; (1) a directory holding a service
|
|
19
|
+
* artifact is a service, marker present or not (artifacts win); (2) the leaf
|
|
20
|
+
* rule — neither marker nor artifact and nothing beneath (an empty or
|
|
21
|
+
* not-yet-adopted directory, a lone README.md, a lone `.gitkeep` — which is
|
|
22
|
+
* the whole content of a directory `loam seed` creates) is a service too; (3) nothing
|
|
23
|
+
* inside a PLAIN service is classified again (`examples/openapi.yaml` two
|
|
24
|
+
* levels down is interior, the walk stops there), but a service carrying the
|
|
25
|
+
* marker BESIDE its artifacts is still descended — minus artifact-named
|
|
26
|
+
* children like `adrs/` — so the services stranded beneath it stay
|
|
27
|
+
* enumerated, the walk's marker-misplaced branch. Subsystem and unmarked
|
|
28
|
+
* group directories need no restating: a flat file listing descends through
|
|
29
|
+
* them by construction. What is deliberately NOT restated: the walk's
|
|
30
|
+
* findings (`subsystem.marker-misplaced`, `subsystem.unmarked`,
|
|
31
|
+
* `subsystem.name-collision`) — those are validate's live diagnostics; here
|
|
32
|
+
* a name claimed twice suspends the subject (`ambiguous`) instead. If
|
|
33
|
+
* walk.ts's rule ever changes, this module owes the same change;
|
|
34
|
+
* test/diff.test.ts pins the visible agreement (subsystem move, not-adopted
|
|
35
|
+
* leaf, stranded-under-marker).
|
|
36
|
+
*
|
|
37
|
+
* Deliberate consequence of joining by leaf directory name: a service MOVED
|
|
38
|
+
* between subsystems keeps its id and diffs as UNCHANGED. Subsystem placement
|
|
39
|
+
* is navigation, not identity — SCHEMA's own position, and the reason
|
|
40
|
+
* `subsystem move` never touches a join key.
|
|
41
|
+
*/
|
|
42
|
+
import { isUtf8 } from "node:buffer";
|
|
43
|
+
import { inOrder } from "../kernel/concurrency.js";
|
|
44
|
+
import { rawServiceId } from "../kernel/ids/service.js";
|
|
45
|
+
import { decodeDocument } from "../kernel/document-bytes.js";
|
|
46
|
+
import { parseRequirements } from "../document/parse.js";
|
|
47
|
+
import { openapiFromText } from "../openapi/doc.js";
|
|
48
|
+
import { asyncapiFromText } from "../asyncapi/read.js";
|
|
49
|
+
import { ARTIFACT_FILES, isServiceArtifactName } from "../repo/paths.js";
|
|
50
|
+
import { SUBSYSTEM_MARKER } from "../repo/tree/marker.js";
|
|
51
|
+
import { RESERVED_INTERIOR } from "../repo/tree/walk.js";
|
|
52
|
+
import { listBaseTree, showBaseFile } from "./base-git.js";
|
|
53
|
+
import { bytesDigest, collisions } from "../consumers/state.js";
|
|
54
|
+
/**
|
|
55
|
+
* Classify the base tree's file listing into service directories — the module
|
|
56
|
+
* banner's three restated walk branches, in depth order so every ancestor is
|
|
57
|
+
* decided before anything beneath it.
|
|
58
|
+
*/
|
|
59
|
+
function classifyBaseDirs(paths) {
|
|
60
|
+
const fileChildren = new Map();
|
|
61
|
+
const dirChildren = new Map();
|
|
62
|
+
// Directories nothing VISIBLE lives in, so neither map above names them.
|
|
63
|
+
const bare = new Set();
|
|
64
|
+
for (const path of paths) {
|
|
65
|
+
const all = path.split("/");
|
|
66
|
+
// Dot-named entries are invisible to the live walk — but the walk still
|
|
67
|
+
// SEES the directory holding them, because readdir discovered the
|
|
68
|
+
// directory itself and only its CONTENTS are filtered (walk.ts's
|
|
69
|
+
// `subdirNames` and `visitDir`). So cut the path at its first dot-named
|
|
70
|
+
// segment rather than discarding the whole path: everything above the cut
|
|
71
|
+
// stays a visible directory, the cut segment and everything beneath it
|
|
72
|
+
// stay invisible. Discarding it outright hid every directory whose only
|
|
73
|
+
// file is dot-named — which is exactly what `loam seed` writes into a
|
|
74
|
+
// service directory it creates (`.gitkeep`, and nothing else), so a seeded
|
|
75
|
+
// service was absent from the base and diffed as `diff.service-added`
|
|
76
|
+
// against the unchanged tree that had just been committed.
|
|
77
|
+
const cut = all.findIndex((s) => s.startsWith(".") || s === "");
|
|
78
|
+
const segments = cut === -1 ? all : all.slice(0, cut);
|
|
79
|
+
// Only a whole path ends in a file; a cut one is a pure directory chain.
|
|
80
|
+
const fileAt = cut === -1 ? segments.length - 1 : -1;
|
|
81
|
+
for (let i = 1; i < segments.length; i += 1) {
|
|
82
|
+
const dir = segments.slice(0, i).join("/");
|
|
83
|
+
const child = segments[i];
|
|
84
|
+
const into = i === fileAt ? fileChildren : dirChildren;
|
|
85
|
+
let set = into.get(dir);
|
|
86
|
+
if (set === undefined)
|
|
87
|
+
into.set(dir, (set = new Set()));
|
|
88
|
+
set.add(child);
|
|
89
|
+
}
|
|
90
|
+
if (fileAt === -1 && segments.length > 1)
|
|
91
|
+
bare.add(segments.join("/"));
|
|
92
|
+
}
|
|
93
|
+
const hasMarker = (dir) => fileChildren.get(dir)?.has(SUBSYSTEM_MARKER) === true;
|
|
94
|
+
const hasArtifact = (dir) => [...(fileChildren.get(dir) ?? [])].some((f) => isServiceArtifactName(f, "file")) ||
|
|
95
|
+
[...(dirChildren.get(dir) ?? [])].some((d) => isServiceArtifactName(d, "dir"));
|
|
96
|
+
// The walk's `RESERVED_INTERIOR` rule, restated for a flat listing: a
|
|
97
|
+
// directory named for a service's own interior is never classified, and
|
|
98
|
+
// neither is anything beneath it, because the walk never descends into one.
|
|
99
|
+
// Segment 2 onward, matching where the walk applies it — to a directory's
|
|
100
|
+
// CHILDREN, so a directory literally at `services/usecases/` is still
|
|
101
|
+
// classified there.
|
|
102
|
+
const reserved = (dir) => dir.split("/").slice(2).some((s) => RESERVED_INTERIOR.has(s));
|
|
103
|
+
// …and, for the same reason, one of them is not the subdirectory that keeps
|
|
104
|
+
// its parent off the leaf rule: the walk filters them out of `dirs` before
|
|
105
|
+
// asking whether anything is beneath.
|
|
106
|
+
const classifiableChildren = (dir) => [...(dirChildren.get(dir) ?? [])].some((d) => !RESERVED_INTERIOR.has(d));
|
|
107
|
+
// The walk's leaf rule: neither marker nor artifact and nothing beneath is a
|
|
108
|
+
// service. (A truly EMPTY directory is unrepresentable in a git tree, so at
|
|
109
|
+
// the base this arm means "no visible entry of ours" — files none of which
|
|
110
|
+
// are artifacts, or nothing but dot-named entries, the `loam seed` shape.)
|
|
111
|
+
const isLeafService = (dir) => !hasMarker(dir) && !hasArtifact(dir) && !classifiableChildren(dir);
|
|
112
|
+
const candidates = [...new Set([...fileChildren.keys(), ...dirChildren.keys(), ...bare])]
|
|
113
|
+
.filter((dir) => dir !== "services" && dir.startsWith("services/") && !reserved(dir))
|
|
114
|
+
.filter((dir) => hasArtifact(dir) || isLeafService(dir))
|
|
115
|
+
.sort((a, b) => {
|
|
116
|
+
const depth = a.split("/").length - b.split("/").length;
|
|
117
|
+
return depth !== 0 ? depth : a < b ? -1 : 1;
|
|
118
|
+
});
|
|
119
|
+
const accepted = [];
|
|
120
|
+
const acceptedDirs = new Set();
|
|
121
|
+
// Is this candidate INTERIOR to the nearest service already accepted above
|
|
122
|
+
// it? A plain service swallows everything beneath (the walk stops there); a
|
|
123
|
+
// marker-beside-artifacts service is descended except through its
|
|
124
|
+
// artifact-named children (`adrs/`), so a service stranded under it stays.
|
|
125
|
+
const interior = (segments) => {
|
|
126
|
+
for (let i = segments.length - 1; i >= 2; i -= 1) {
|
|
127
|
+
const ancestor = segments.slice(0, i).join("/");
|
|
128
|
+
if (!acceptedDirs.has(ancestor))
|
|
129
|
+
continue;
|
|
130
|
+
return hasMarker(ancestor) ? isServiceArtifactName(segments[i], "dir") : true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
};
|
|
134
|
+
for (const dir of candidates) {
|
|
135
|
+
const segments = dir.split("/");
|
|
136
|
+
if (interior(segments))
|
|
137
|
+
continue;
|
|
138
|
+
acceptedDirs.add(dir);
|
|
139
|
+
accepted.push({ id: rawServiceId(segments[segments.length - 1]), dir, files: fileChildren.get(dir) ?? new Set() });
|
|
140
|
+
}
|
|
141
|
+
return { dirs: accepted, ambiguous: collisions(accepted) };
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Lift one fetched file into an axis state through its parser. Absence is the
|
|
145
|
+
* listing's answer, a `show` failure is per-subject containment, and only
|
|
146
|
+
* then do the bytes reach a parser. A parser's refusal carries the hash of
|
|
147
|
+
* the bytes it refused (`AxisState`'s `bytes`); a `show` failure has none to
|
|
148
|
+
* hash.
|
|
149
|
+
*/
|
|
150
|
+
function axisFrom(raw, parse) {
|
|
151
|
+
if (raw === null)
|
|
152
|
+
return { kind: "absent" };
|
|
153
|
+
if (raw.read.kind === "failed")
|
|
154
|
+
return { kind: "unreadable", path: raw.rel, error: raw.read.detail };
|
|
155
|
+
const state = parse(raw.rel, raw.read.bytes);
|
|
156
|
+
return state.kind === "unreadable" ? { ...state, bytes: bytesDigest(raw.read.bytes) } : state;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* The same refusal `readOpenapi`/`readAsyncapi` make on the living side for a
|
|
160
|
+
* CONTRACT: non-UTF-8 bytes would be silently rewritten as U+FFFD by
|
|
161
|
+
* `toString`, and a document nobody wrote must not be graded. Contracts only:
|
|
162
|
+
* the spec axis decodes through `decodeDocument` instead (`specState`), because
|
|
163
|
+
* that is what its living side does, and each axis must refuse at the base
|
|
164
|
+
* exactly the bytes its living reader refuses.
|
|
165
|
+
*/
|
|
166
|
+
function decodeBase(path, bytes) {
|
|
167
|
+
if (!isUtf8(bytes))
|
|
168
|
+
return { unreadable: { kind: "unreadable", path, error: "file is not valid UTF-8" } };
|
|
169
|
+
return { text: bytes.toString("utf8") };
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* A spec-axis file decodes through `decodeDocument` — the rule the living side
|
|
173
|
+
* applies to the same file (`FleetContext.readText`) — not through
|
|
174
|
+
* `decodeBase`'s `isUtf8`-only test. The difference is the NUL test: UTF-16LE
|
|
175
|
+
* of ASCII saved WITHOUT a byte-order mark is a valid UTF-8 sequence, so
|
|
176
|
+
* `isUtf8` alone let it through here and it parsed as zero requirements while
|
|
177
|
+
* the working tree refused the identical bytes. The base then read as a
|
|
178
|
+
* readable EMPTY spec: an untouched file diffed as one-sided containment, and
|
|
179
|
+
* a branch that re-saved it as UTF-8 reported every requirement in it as
|
|
180
|
+
* added. `decodeDocument`'s `NotUtf8DocumentError` lands in the catch below
|
|
181
|
+
* and becomes the unreadable arm like any parse failure.
|
|
182
|
+
*/
|
|
183
|
+
function specState(path, bytes) {
|
|
184
|
+
try {
|
|
185
|
+
return { kind: "read", value: parseRequirements(decodeDocument(bytes, path)) };
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
return { kind: "unreadable", path, error: e instanceof Error ? e.message : String(e) };
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function openapiState(path, bytes) {
|
|
192
|
+
const decoded = decodeBase(path, bytes);
|
|
193
|
+
if ("unreadable" in decoded)
|
|
194
|
+
return decoded.unreadable;
|
|
195
|
+
const doc = openapiFromText(decoded.text);
|
|
196
|
+
return doc.unreadable
|
|
197
|
+
? { kind: "unreadable", path, error: doc.error ?? "not a readable OpenAPI document" }
|
|
198
|
+
: { kind: "read", value: doc.ops.filter((op) => !op.remove) };
|
|
199
|
+
}
|
|
200
|
+
function asyncapiState(path, bytes) {
|
|
201
|
+
const decoded = decodeBase(path, bytes);
|
|
202
|
+
if ("unreadable" in decoded)
|
|
203
|
+
return decoded.unreadable;
|
|
204
|
+
const doc = asyncapiFromText(decoded.text);
|
|
205
|
+
return doc.unreadable
|
|
206
|
+
? { kind: "unreadable", path, error: doc.error ?? "not a readable AsyncAPI document" }
|
|
207
|
+
: { kind: "read", value: doc.messages.filter((m) => m.remove !== true) };
|
|
208
|
+
}
|
|
209
|
+
/** One base service's four axes. Sequential INSIDE the service on purpose: the pool below rations children at the service grain, and four spawns per in-flight worker would multiply past the cap it exists to hold. */
|
|
210
|
+
async function readBaseService(base, d) {
|
|
211
|
+
const fetch = async (file) => d.files.has(file) ? { rel: `${d.dir}/${file}`, read: await showBaseFile(base, `${d.dir}/${file}`) } : null;
|
|
212
|
+
return {
|
|
213
|
+
id: d.id,
|
|
214
|
+
dir: d.dir,
|
|
215
|
+
spec: axisFrom(await fetch(ARTIFACT_FILES.spec), specState),
|
|
216
|
+
archSpec: axisFrom(await fetch(ARTIFACT_FILES.archSpec), specState),
|
|
217
|
+
openapi: axisFrom(await fetch(ARTIFACT_FILES.openapi), openapiState),
|
|
218
|
+
asyncapi: axisFrom(await fetch(ARTIFACT_FILES.asyncapi), asyncapiState),
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* The whole base fleet. `failed` only when git cannot LIST the tree — the
|
|
223
|
+
* whole-diff refusal; a single file that cannot be shown or parsed degrades
|
|
224
|
+
* its own subject's axis to `unreadable` and nothing else.
|
|
225
|
+
*/
|
|
226
|
+
export async function readBaseFleet(base) {
|
|
227
|
+
const listing = await listBaseTree(base);
|
|
228
|
+
if (listing.kind === "failed")
|
|
229
|
+
return listing;
|
|
230
|
+
const { dirs, ambiguous } = classifyBaseDirs(listing.paths);
|
|
231
|
+
const sorted = [...dirs].sort((a, b) => (a.id < b.id ? -1 : 1)).filter((d) => !ambiguous.has(d.id));
|
|
232
|
+
// Pooled, ordered reads: bounded children in flight, results by input index,
|
|
233
|
+
// so the same base state always assembles the same fleet.
|
|
234
|
+
const states = await inOrder(sorted, (d) => readBaseService(base, d));
|
|
235
|
+
return { kind: "ok", fleet: { services: new Map(states.map((s) => [s.id, s])), ambiguous } };
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=base-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-state.js","sourceRoot":"","sources":["../../../src/core/diff/base-state.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The base side of `loam diff`: the fleet as the base commit held it, read\n * entirely out of git's object store (`./base-git.ts`) and parsed with the\n * SAME parsers the living files go through — `parseRequirements`,\n * `openapiFromText`, `asyncapiFromText` — so a base document can never read\n * differently from the identical bytes sitting on disk.\n *\n * CLASSIFICATION is a second, simplified spelling of `repo/tree/walk.ts`'s\n * rule, and that is a recorded risk, not an accident: the walk classifies a\n * LIVE filesystem (readdir, symlinks, marker files) and cannot walk a git\n * ref. What keeps the two honest is sharing the artifact-name table\n * (`ARTIFACT_FILES`/`isServiceArtifactName` from `repo/paths.ts`), the\n * marker name (`SUBSYSTEM_MARKER`) and the reserved-interior set\n * (`RESERVED_INTERIOR` from `repo/tree/walk.ts`) instead of respelling them, and restating\n * — exactly — the walk's SERVICE branches: (0) a directory named for a\n * service's own interior (`adrs/`, `usecases/`, `ui/`) is classified nowhere,\n * counts as nothing beneath its parent, and hides everything under it, because\n * the walk never descends into one; (1) a directory holding a service\n * artifact is a service, marker present or not (artifacts win); (2) the leaf\n * rule — neither marker nor artifact and nothing beneath (an empty or\n * not-yet-adopted directory, a lone README.md, a lone `.gitkeep` — which is\n * the whole content of a directory `loam seed` creates) is a service too; (3) nothing\n * inside a PLAIN service is classified again (`examples/openapi.yaml` two\n * levels down is interior, the walk stops there), but a service carrying the\n * marker BESIDE its artifacts is still descended — minus artifact-named\n * children like `adrs/` — so the services stranded beneath it stay\n * enumerated, the walk's marker-misplaced branch. Subsystem and unmarked\n * group directories need no restating: a flat file listing descends through\n * them by construction. What is deliberately NOT restated: the walk's\n * findings (`subsystem.marker-misplaced`, `subsystem.unmarked`,\n * `subsystem.name-collision`) — those are validate's live diagnostics; here\n * a name claimed twice suspends the subject (`ambiguous`) instead. If\n * walk.ts's rule ever changes, this module owes the same change;\n * test/diff.test.ts pins the visible agreement (subsystem move, not-adopted\n * leaf, stranded-under-marker).\n *\n * Deliberate consequence of joining by leaf directory name: a service MOVED\n * between subsystems keeps its id and diffs as UNCHANGED. Subsystem placement\n * is navigation, not identity — SCHEMA's own position, and the reason\n * `subsystem move` never touches a join key.\n */\nimport { isUtf8 } from \"node:buffer\";\nimport { inOrder } from \"../kernel/concurrency.js\";\nimport { rawServiceId, type RawServiceId } from \"../kernel/ids/service.js\";\nimport { decodeDocument } from \"../kernel/document-bytes.js\";\nimport { parseRequirements } from \"../document/parse.js\";\nimport type { Requirement } from \"../document/spec.js\";\nimport { openapiFromText, type Operation } from \"../openapi/doc.js\";\nimport { asyncapiFromText } from \"../asyncapi/read.js\";\nimport type { EventMessage } from \"../asyncapi/model.js\";\nimport { ARTIFACT_FILES, isServiceArtifactName } from \"../repo/paths.js\";\nimport { SUBSYSTEM_MARKER } from \"../repo/tree/marker.js\";\nimport { RESERVED_INTERIOR } from \"../repo/tree/walk.js\";\nimport { listBaseTree, showBaseFile, type ResolvedBase } from \"./base-git.js\";\nimport { bytesDigest, collisions, type AxisState, type ServiceState } from \"../consumers/state.js\";\n\nexport interface BaseFleet {\n /** By service id, insertion-sorted by id — deterministic output depends on it. */\n services: Map<string, ServiceState>;\n /**\n * Ids claimed by MORE than one base directory. The live walk grades this\n * `subsystem.name-collision`; here the id's base state is unanswerable, so\n * the subject is carried with every axis suspended rather than one claimant\n * silently winning the join.\n */\n ambiguous: Map<string, string[]>;\n}\n\nexport type BaseFleetRead =\n | { kind: \"ok\"; fleet: BaseFleet }\n | { kind: \"failed\"; detail: string };\n\n/** A classified base service directory and which artifact files the base tree listed in it. */\ninterface BaseDir {\n id: RawServiceId;\n dir: string;\n files: Set<string>;\n}\n\n/**\n * Classify the base tree's file listing into service directories — the module\n * banner's three restated walk branches, in depth order so every ancestor is\n * decided before anything beneath it.\n */\nfunction classifyBaseDirs(paths: string[]): { dirs: BaseDir[]; ambiguous: Map<string, string[]> } {\n const fileChildren = new Map<string, Set<string>>();\n const dirChildren = new Map<string, Set<string>>();\n // Directories nothing VISIBLE lives in, so neither map above names them.\n const bare = new Set<string>();\n for (const path of paths) {\n const all = path.split(\"/\");\n // Dot-named entries are invisible to the live walk — but the walk still\n // SEES the directory holding them, because readdir discovered the\n // directory itself and only its CONTENTS are filtered (walk.ts's\n // `subdirNames` and `visitDir`). So cut the path at its first dot-named\n // segment rather than discarding the whole path: everything above the cut\n // stays a visible directory, the cut segment and everything beneath it\n // stay invisible. Discarding it outright hid every directory whose only\n // file is dot-named — which is exactly what `loam seed` writes into a\n // service directory it creates (`.gitkeep`, and nothing else), so a seeded\n // service was absent from the base and diffed as `diff.service-added`\n // against the unchanged tree that had just been committed.\n const cut = all.findIndex((s) => s.startsWith(\".\") || s === \"\");\n const segments = cut === -1 ? all : all.slice(0, cut);\n // Only a whole path ends in a file; a cut one is a pure directory chain.\n const fileAt = cut === -1 ? segments.length - 1 : -1;\n for (let i = 1; i < segments.length; i += 1) {\n const dir = segments.slice(0, i).join(\"/\");\n const child = segments[i]!;\n const into = i === fileAt ? fileChildren : dirChildren;\n let set = into.get(dir);\n if (set === undefined) into.set(dir, (set = new Set()));\n set.add(child);\n }\n if (fileAt === -1 && segments.length > 1) bare.add(segments.join(\"/\"));\n }\n const hasMarker = (dir: string): boolean => fileChildren.get(dir)?.has(SUBSYSTEM_MARKER) === true;\n const hasArtifact = (dir: string): boolean =>\n [...(fileChildren.get(dir) ?? [])].some((f) => isServiceArtifactName(f, \"file\")) ||\n [...(dirChildren.get(dir) ?? [])].some((d) => isServiceArtifactName(d, \"dir\"));\n // The walk's `RESERVED_INTERIOR` rule, restated for a flat listing: a\n // directory named for a service's own interior is never classified, and\n // neither is anything beneath it, because the walk never descends into one.\n // Segment 2 onward, matching where the walk applies it — to a directory's\n // CHILDREN, so a directory literally at `services/usecases/` is still\n // classified there.\n const reserved = (dir: string): boolean => dir.split(\"/\").slice(2).some((s) => RESERVED_INTERIOR.has(s));\n // …and, for the same reason, one of them is not the subdirectory that keeps\n // its parent off the leaf rule: the walk filters them out of `dirs` before\n // asking whether anything is beneath.\n const classifiableChildren = (dir: string): boolean =>\n [...(dirChildren.get(dir) ?? [])].some((d) => !RESERVED_INTERIOR.has(d));\n // The walk's leaf rule: neither marker nor artifact and nothing beneath is a\n // service. (A truly EMPTY directory is unrepresentable in a git tree, so at\n // the base this arm means \"no visible entry of ours\" — files none of which\n // are artifacts, or nothing but dot-named entries, the `loam seed` shape.)\n const isLeafService = (dir: string): boolean =>\n !hasMarker(dir) && !hasArtifact(dir) && !classifiableChildren(dir);\n const candidates = [...new Set([...fileChildren.keys(), ...dirChildren.keys(), ...bare])]\n .filter((dir) => dir !== \"services\" && dir.startsWith(\"services/\") && !reserved(dir))\n .filter((dir) => hasArtifact(dir) || isLeafService(dir))\n .sort((a, b) => {\n const depth = a.split(\"/\").length - b.split(\"/\").length;\n return depth !== 0 ? depth : a < b ? -1 : 1;\n });\n const accepted: BaseDir[] = [];\n const acceptedDirs = new Set<string>();\n // Is this candidate INTERIOR to the nearest service already accepted above\n // it? A plain service swallows everything beneath (the walk stops there); a\n // marker-beside-artifacts service is descended except through its\n // artifact-named children (`adrs/`), so a service stranded under it stays.\n const interior = (segments: string[]): boolean => {\n for (let i = segments.length - 1; i >= 2; i -= 1) {\n const ancestor = segments.slice(0, i).join(\"/\");\n if (!acceptedDirs.has(ancestor)) continue;\n return hasMarker(ancestor) ? isServiceArtifactName(segments[i]!, \"dir\") : true;\n }\n return false;\n };\n for (const dir of candidates) {\n const segments = dir.split(\"/\");\n if (interior(segments)) continue;\n acceptedDirs.add(dir);\n accepted.push({ id: rawServiceId(segments[segments.length - 1]!), dir, files: fileChildren.get(dir) ?? new Set() });\n }\n return { dirs: accepted, ambiguous: collisions(accepted) };\n}\n\n/** One shown base file, or `null` for a file the base tree never listed. */\ntype Fetched = { rel: string; read: Awaited<ReturnType<typeof showBaseFile>> } | null;\n\n/**\n * Lift one fetched file into an axis state through its parser. Absence is the\n * listing's answer, a `show` failure is per-subject containment, and only\n * then do the bytes reach a parser. A parser's refusal carries the hash of\n * the bytes it refused (`AxisState`'s `bytes`); a `show` failure has none to\n * hash.\n */\nfunction axisFrom<T>(raw: Fetched, parse: (path: string, bytes: Buffer) => AxisState<T>): AxisState<T> {\n if (raw === null) return { kind: \"absent\" };\n if (raw.read.kind === \"failed\") return { kind: \"unreadable\", path: raw.rel, error: raw.read.detail };\n const state = parse(raw.rel, raw.read.bytes);\n return state.kind === \"unreadable\" ? { ...state, bytes: bytesDigest(raw.read.bytes) } : state;\n}\n\n/**\n * The same refusal `readOpenapi`/`readAsyncapi` make on the living side for a\n * CONTRACT: non-UTF-8 bytes would be silently rewritten as U+FFFD by\n * `toString`, and a document nobody wrote must not be graded. Contracts only:\n * the spec axis decodes through `decodeDocument` instead (`specState`), because\n * that is what its living side does, and each axis must refuse at the base\n * exactly the bytes its living reader refuses.\n */\nfunction decodeBase(path: string, bytes: Buffer): { text: string } | { unreadable: AxisState<never> } {\n if (!isUtf8(bytes)) return { unreadable: { kind: \"unreadable\", path, error: \"file is not valid UTF-8\" } };\n return { text: bytes.toString(\"utf8\") };\n}\n\n/**\n * A spec-axis file decodes through `decodeDocument` — the rule the living side\n * applies to the same file (`FleetContext.readText`) — not through\n * `decodeBase`'s `isUtf8`-only test. The difference is the NUL test: UTF-16LE\n * of ASCII saved WITHOUT a byte-order mark is a valid UTF-8 sequence, so\n * `isUtf8` alone let it through here and it parsed as zero requirements while\n * the working tree refused the identical bytes. The base then read as a\n * readable EMPTY spec: an untouched file diffed as one-sided containment, and\n * a branch that re-saved it as UTF-8 reported every requirement in it as\n * added. `decodeDocument`'s `NotUtf8DocumentError` lands in the catch below\n * and becomes the unreadable arm like any parse failure.\n */\nfunction specState(path: string, bytes: Buffer): AxisState<Requirement[]> {\n try {\n return { kind: \"read\", value: parseRequirements(decodeDocument(bytes, path)) };\n } catch (e) {\n return { kind: \"unreadable\", path, error: e instanceof Error ? e.message : String(e) };\n }\n}\n\nfunction openapiState(path: string, bytes: Buffer): AxisState<Operation[]> {\n const decoded = decodeBase(path, bytes);\n if (\"unreadable\" in decoded) return decoded.unreadable;\n const doc = openapiFromText(decoded.text);\n return doc.unreadable\n ? { kind: \"unreadable\", path, error: doc.error ?? \"not a readable OpenAPI document\" }\n : { kind: \"read\", value: doc.ops.filter((op) => !op.remove) };\n}\n\nfunction asyncapiState(path: string, bytes: Buffer): AxisState<EventMessage[]> {\n const decoded = decodeBase(path, bytes);\n if (\"unreadable\" in decoded) return decoded.unreadable;\n const doc = asyncapiFromText(decoded.text);\n return doc.unreadable\n ? { kind: \"unreadable\", path, error: doc.error ?? \"not a readable AsyncAPI document\" }\n : { kind: \"read\", value: doc.messages.filter((m) => m.remove !== true) };\n}\n\n/** One base service's four axes. Sequential INSIDE the service on purpose: the pool below rations children at the service grain, and four spawns per in-flight worker would multiply past the cap it exists to hold. */\nasync function readBaseService(base: ResolvedBase, d: BaseDir): Promise<ServiceState> {\n const fetch = async (file: string): Promise<Fetched> =>\n d.files.has(file) ? { rel: `${d.dir}/${file}`, read: await showBaseFile(base, `${d.dir}/${file}`) } : null;\n return {\n id: d.id,\n dir: d.dir,\n spec: axisFrom(await fetch(ARTIFACT_FILES.spec), specState),\n archSpec: axisFrom(await fetch(ARTIFACT_FILES.archSpec), specState),\n openapi: axisFrom(await fetch(ARTIFACT_FILES.openapi), openapiState),\n asyncapi: axisFrom(await fetch(ARTIFACT_FILES.asyncapi), asyncapiState),\n };\n}\n\n/**\n * The whole base fleet. `failed` only when git cannot LIST the tree — the\n * whole-diff refusal; a single file that cannot be shown or parsed degrades\n * its own subject's axis to `unreadable` and nothing else.\n */\nexport async function readBaseFleet(base: ResolvedBase): Promise<BaseFleetRead> {\n const listing = await listBaseTree(base);\n if (listing.kind === \"failed\") return listing;\n const { dirs, ambiguous } = classifyBaseDirs(listing.paths);\n const sorted = [...dirs].sort((a, b) => (a.id < b.id ? -1 : 1)).filter((d) => !ambiguous.has(d.id));\n // Pooled, ordered reads: bounded children in flight, results by input index,\n // so the same base state always assembles the same fleet.\n const states = await inOrder(sorted, (d) => readBaseService(base, d));\n return { kind: \"ok\", fleet: { services: new Map(states.map((s) => [s.id, s])), ambiguous } };\n}\n"]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { ownsOperation, REQUIREMENT_AXES } from "../consumers/consumers.js";
|
|
2
|
+
/** The requirements one service contributes to a join — both spec files, a REMOVED one governing nothing. */
|
|
3
|
+
function reqsOf(state) {
|
|
4
|
+
return REQUIREMENT_AXES.flatMap((axis) => {
|
|
5
|
+
const a = state[axis];
|
|
6
|
+
return a.kind === "read" ? a.value.filter((r) => r.kind !== "REMOVED") : [];
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
/** The map key a tuple is joined on between the two states. */
|
|
10
|
+
function tupleKey(t) {
|
|
11
|
+
return `${t.kind}\0${t.consumer}\0${t.provider}\0${t.token}`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Every cross-service join one state holds, keyed for the base/current join.
|
|
15
|
+
* The rules are the consumer index's, read off it rather than restated: both
|
|
16
|
+
* spec files for `Operations:` and `Consumes:` alike (`REQUIREMENT_AXES`), and
|
|
17
|
+
* an `Operations:` line naming an id the consumer's own contract defines is
|
|
18
|
+
* that consumer's own operation, no join onto anybody else's
|
|
19
|
+
* (`ownsOperation`). An unreadable axis simply contributes nothing here — no
|
|
20
|
+
* line from a spec file nobody could read, no ownership from a contract nobody
|
|
21
|
+
* could read — and `tupleVisible` below guards the GRADING, so a join is never
|
|
22
|
+
* called added or removed off a side nobody could read, and `ownershipFlicker`
|
|
23
|
+
* keeps one from being called so off a consumer's own contract that merely
|
|
24
|
+
* stopped or started parsing.
|
|
25
|
+
*/
|
|
26
|
+
export function consumerTuples(states) {
|
|
27
|
+
const providersOf = (pick) => {
|
|
28
|
+
const map = new Map();
|
|
29
|
+
for (const id of [...states.keys()].sort()) {
|
|
30
|
+
for (const token of pick(states.get(id)))
|
|
31
|
+
map.set(token, [...(map.get(token) ?? []), id]);
|
|
32
|
+
}
|
|
33
|
+
return map;
|
|
34
|
+
};
|
|
35
|
+
const opProviders = providersOf((s) => (s.openapi.kind === "read" ? s.openapi.value.map((op) => op.id) : []));
|
|
36
|
+
const msgProviders = providersOf((s) => (s.asyncapi.kind === "read" ? s.asyncapi.value.map((m) => m.name) : []));
|
|
37
|
+
const out = new Map();
|
|
38
|
+
const add = (t) => {
|
|
39
|
+
out.set(tupleKey(t), t);
|
|
40
|
+
};
|
|
41
|
+
for (const consumer of [...states.keys()].sort()) {
|
|
42
|
+
const state = states.get(consumer);
|
|
43
|
+
for (const r of reqsOf(state)) {
|
|
44
|
+
for (const op of r.operations) {
|
|
45
|
+
if (ownsOperation(state, op))
|
|
46
|
+
continue;
|
|
47
|
+
for (const p of opProviders.get(op) ?? [])
|
|
48
|
+
if (p !== consumer)
|
|
49
|
+
add({ kind: "op", consumer, provider: p, token: op });
|
|
50
|
+
}
|
|
51
|
+
for (const name of r.consumes) {
|
|
52
|
+
for (const p of msgProviders.get(name) ?? [])
|
|
53
|
+
if (p !== consumer)
|
|
54
|
+
add({ kind: "message", consumer, provider: p, token: name });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/** May a tuple be graded off this side? Absence answers; unreadable does not; an ambiguous base identity answers nothing. */
|
|
61
|
+
function tupleVisible(states, ambiguous, t) {
|
|
62
|
+
if (ambiguous.has(t.consumer) || ambiguous.has(t.provider))
|
|
63
|
+
return false;
|
|
64
|
+
const readable = (id, axes) => {
|
|
65
|
+
const state = states.get(id);
|
|
66
|
+
return state === undefined || axes.every((axis) => state[axis].kind !== "unreadable");
|
|
67
|
+
};
|
|
68
|
+
// Both spec files on the consumer's side, for either kind: a line in the file
|
|
69
|
+
// nobody could read may be the very one the join came or went by. NOT the
|
|
70
|
+
// consumer's own contract, although an operation join reads it: it is asked
|
|
71
|
+
// only whether the line names the consumer's OWN operation, and an
|
|
72
|
+
// unreadable contract proves no ownership (`ownsOperation`), so the line
|
|
73
|
+
// counts on that side — the index's own rule. A side holding it unread can
|
|
74
|
+
// only have MORE joins, never hide one, and suppressing the join there kept
|
|
75
|
+
// `diff.consumer-added` / `-removed` off a report whose victims named that
|
|
76
|
+
// very consumer (the contract review, finding 4). Those extra joins are a
|
|
77
|
+
// change of their own only when the readable side does not prove the
|
|
78
|
+
// ownership the unread one could not — `ownershipFlicker` below.
|
|
79
|
+
return readable(t.consumer, ["spec", "archSpec"]) && readable(t.provider, [t.kind === "op" ? "openapi" : "asyncapi"]);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Is this operation join held only because the consumer's own contract did not
|
|
83
|
+
* parse on the side that holds it, while on the other side it reads and
|
|
84
|
+
* defines the id? Then the line names the consumer's OWN operation — the
|
|
85
|
+
* readable side says so — and nothing about the join moved but the contract's
|
|
86
|
+
* readability: the line that never changed "went away" when the contract was
|
|
87
|
+
* fixed and "appeared" when it broke, once per provider of a shared id such as
|
|
88
|
+
* `healthCheck` (the verification of finding 4, N1). The unreadable contract
|
|
89
|
+
* is already its own `unreadable[]` entry on the consumer, which carries the
|
|
90
|
+
* run to exit 1; a second, false finding on every provider said nothing true.
|
|
91
|
+
*
|
|
92
|
+
* Only that shape is skipped. A readable side that defines no such id proves
|
|
93
|
+
* no ownership either, so the join is the line's and is graded as before; a
|
|
94
|
+
* message join asks no ownership at all (`ownsOperation` says why).
|
|
95
|
+
*/
|
|
96
|
+
function ownershipFlicker(sides, t) {
|
|
97
|
+
if (t.kind !== "op" || sides.holding.get(t.consumer)?.openapi.kind !== "unreadable")
|
|
98
|
+
return false;
|
|
99
|
+
const other = sides.other.get(t.consumer);
|
|
100
|
+
return other !== undefined && ownsOperation(other, t.token);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The joins that appeared or went away between base and current, sorted for
|
|
104
|
+
* deterministic output (provider, kind, token, consumer). The visibility
|
|
105
|
+
* guard is the containment rule: a join is never called "added" off a base
|
|
106
|
+
* side nobody could read, nor "removed" off an unreadable working file — the
|
|
107
|
+
* suspended axis already carries that fact. The flicker guard is its mirror on
|
|
108
|
+
* the side that HOLDS the join: one held only because the consumer's own
|
|
109
|
+
* contract did not read there, over an id the other side shows it owns, is no
|
|
110
|
+
* change either.
|
|
111
|
+
*/
|
|
112
|
+
export function consumerJoinChanges(input) {
|
|
113
|
+
const baseTuples = consumerTuples(input.base);
|
|
114
|
+
const currentTuples = consumerTuples(input.current);
|
|
115
|
+
const graded = [];
|
|
116
|
+
const added = { holding: input.current, other: input.base };
|
|
117
|
+
const removed = { holding: input.base, other: input.current };
|
|
118
|
+
for (const [key, t] of currentTuples) {
|
|
119
|
+
if (baseTuples.has(key) || ownershipFlicker(added, t))
|
|
120
|
+
continue;
|
|
121
|
+
if (tupleVisible(input.base, input.baseAmbiguous, t))
|
|
122
|
+
graded.push({ t, change: "added" });
|
|
123
|
+
}
|
|
124
|
+
for (const [key, t] of baseTuples) {
|
|
125
|
+
if (currentTuples.has(key) || ownershipFlicker(removed, t))
|
|
126
|
+
continue;
|
|
127
|
+
if (tupleVisible(input.current, input.currentAmbiguous, t))
|
|
128
|
+
graded.push({ t, change: "removed" });
|
|
129
|
+
}
|
|
130
|
+
return graded.sort((a, b) => {
|
|
131
|
+
const ka = `${a.t.provider}\0${a.t.kind}\0${a.t.token}\0${a.t.consumer}\0${a.change}`;
|
|
132
|
+
const kb = `${b.t.provider}\0${b.t.kind}\0${b.t.token}\0${b.t.consumer}\0${b.change}`;
|
|
133
|
+
return ka < kb ? -1 : 1;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=joins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"joins.js","sourceRoot":"","sources":["../../../src/core/diff/joins.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE5E,6GAA6G;AAC7G,SAAS,MAAM,CAAC,KAAmB;IACjC,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9E,CAAC,CAAC,CAAC;AACL,CAAC;AAgBD,+DAA+D;AAC/D,SAAS,QAAQ,CAAC,CAAgB;IAChC,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyC;IACtE,MAAM,WAAW,GAAG,CAAC,IAAmC,EAAyB,EAAE;QACjF,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;QACxC,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9G,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjH,MAAM,GAAG,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC7C,MAAM,GAAG,GAAG,CAAC,CAAgB,EAAQ,EAAE;QACrC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC;IACF,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;QACpC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;gBAC9B,IAAI,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC;oBAAE,SAAS;gBACvC,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;oBAAE,IAAI,CAAC,KAAK,QAAQ;wBAAE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;YACvH,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC9B,KAAK,MAAM,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;oBAAE,IAAI,CAAC,KAAK,QAAQ;wBAAE,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACjI,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6HAA6H;AAC7H,SAAS,YAAY,CAAC,MAAyC,EAAE,SAA8B,EAAE,CAAgB;IAC/G,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACzE,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAE,IAAsD,EAAW,EAAE;QAC/F,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7B,OAAO,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;IACxF,CAAC,CAAC;IACF,8EAA8E;IAC9E,0EAA0E;IAC1E,4EAA4E;IAC5E,mEAAmE;IACnE,yEAAyE;IACzE,2EAA2E;IAC3E,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,qEAAqE;IACrE,iEAAiE;IACjE,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;AACxH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,gBAAgB,CAAC,KAA+F,EAAE,CAAgB;IACzI,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,KAAK,CAAC;IAClG,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,KAAK,KAAK,SAAS,IAAI,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAQD;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAKnC;IACC,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAC5D,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAC9D,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC;YAAE,SAAS;QAChE,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC;QAClC,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC;YAAE,SAAS;QACrE,IAAI,YAAY,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACtF,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QACtF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * The cross-service joins `loam diff` reports appearing or going away between\n * the base ref and the working tree — `diff.consumer-added` /\n * `diff.consumer-removed`.\n *\n * These lived in `./victims.ts` beside the per-removal victim index until that\n * index moved down to `core/consumers/` to become the one consumer answer the\n * coherence gate and the archive planner read too. The joins below stayed: they\n * compare two WHOLE states, which only the diff has, while the index answers\n * about one fleet.\n */\nimport type { Requirement } from \"../document/spec.js\";\nimport type { ServiceState } from \"../consumers/state.js\";\nimport { ownsOperation, REQUIREMENT_AXES } from \"../consumers/consumers.js\";\n\n/** The requirements one service contributes to a join — both spec files, a REMOVED one governing nothing. */\nfunction reqsOf(state: ServiceState): Requirement[] {\n return REQUIREMENT_AXES.flatMap((axis) => {\n const a = state[axis];\n return a.kind === \"read\" ? a.value.filter((r) => r.kind !== \"REMOVED\") : [];\n });\n}\n\n/**\n * One cross-service join: `consumer`'s living requirements name a `token` that\n * `provider`'s contract defines. The same \"who depends on what\" question the\n * consumer index (`core/consumers/consumers.ts`) answers per removal, asked\n * here of a WHOLE state — base or current — so `./semantic.ts` can report\n * joins that appeared or went away.\n */\nexport interface ConsumerTuple {\n kind: \"op\" | \"message\";\n consumer: string;\n provider: string;\n token: string;\n}\n\n/** The map key a tuple is joined on between the two states. */\nfunction tupleKey(t: ConsumerTuple): string {\n return `${t.kind}\\0${t.consumer}\\0${t.provider}\\0${t.token}`;\n}\n\n/**\n * Every cross-service join one state holds, keyed for the base/current join.\n * The rules are the consumer index's, read off it rather than restated: both\n * spec files for `Operations:` and `Consumes:` alike (`REQUIREMENT_AXES`), and\n * an `Operations:` line naming an id the consumer's own contract defines is\n * that consumer's own operation, no join onto anybody else's\n * (`ownsOperation`). An unreadable axis simply contributes nothing here — no\n * line from a spec file nobody could read, no ownership from a contract nobody\n * could read — and `tupleVisible` below guards the GRADING, so a join is never\n * called added or removed off a side nobody could read, and `ownershipFlicker`\n * keeps one from being called so off a consumer's own contract that merely\n * stopped or started parsing.\n */\nexport function consumerTuples(states: ReadonlyMap<string, ServiceState>): Map<string, ConsumerTuple> {\n const providersOf = (pick: (s: ServiceState) => string[]): Map<string, string[]> => {\n const map = new Map<string, string[]>();\n for (const id of [...states.keys()].sort()) {\n for (const token of pick(states.get(id)!)) map.set(token, [...(map.get(token) ?? []), id]);\n }\n return map;\n };\n const opProviders = providersOf((s) => (s.openapi.kind === \"read\" ? s.openapi.value.map((op) => op.id) : []));\n const msgProviders = providersOf((s) => (s.asyncapi.kind === \"read\" ? s.asyncapi.value.map((m) => m.name) : []));\n const out = new Map<string, ConsumerTuple>();\n const add = (t: ConsumerTuple): void => {\n out.set(tupleKey(t), t);\n };\n for (const consumer of [...states.keys()].sort()) {\n const state = states.get(consumer)!;\n for (const r of reqsOf(state)) {\n for (const op of r.operations) {\n if (ownsOperation(state, op)) continue;\n for (const p of opProviders.get(op) ?? []) if (p !== consumer) add({ kind: \"op\", consumer, provider: p, token: op });\n }\n for (const name of r.consumes) {\n for (const p of msgProviders.get(name) ?? []) if (p !== consumer) add({ kind: \"message\", consumer, provider: p, token: name });\n }\n }\n }\n return out;\n}\n\n/** May a tuple be graded off this side? Absence answers; unreadable does not; an ambiguous base identity answers nothing. */\nfunction tupleVisible(states: ReadonlyMap<string, ServiceState>, ambiguous: ReadonlySet<string>, t: ConsumerTuple): boolean {\n if (ambiguous.has(t.consumer) || ambiguous.has(t.provider)) return false;\n const readable = (id: string, axes: (\"spec\" | \"archSpec\" | \"openapi\" | \"asyncapi\")[]): boolean => {\n const state = states.get(id);\n return state === undefined || axes.every((axis) => state[axis].kind !== \"unreadable\");\n };\n // Both spec files on the consumer's side, for either kind: a line in the file\n // nobody could read may be the very one the join came or went by. NOT the\n // consumer's own contract, although an operation join reads it: it is asked\n // only whether the line names the consumer's OWN operation, and an\n // unreadable contract proves no ownership (`ownsOperation`), so the line\n // counts on that side — the index's own rule. A side holding it unread can\n // only have MORE joins, never hide one, and suppressing the join there kept\n // `diff.consumer-added` / `-removed` off a report whose victims named that\n // very consumer (the contract review, finding 4). Those extra joins are a\n // change of their own only when the readable side does not prove the\n // ownership the unread one could not — `ownershipFlicker` below.\n return readable(t.consumer, [\"spec\", \"archSpec\"]) && readable(t.provider, [t.kind === \"op\" ? \"openapi\" : \"asyncapi\"]);\n}\n\n/**\n * Is this operation join held only because the consumer's own contract did not\n * parse on the side that holds it, while on the other side it reads and\n * defines the id? Then the line names the consumer's OWN operation — the\n * readable side says so — and nothing about the join moved but the contract's\n * readability: the line that never changed \"went away\" when the contract was\n * fixed and \"appeared\" when it broke, once per provider of a shared id such as\n * `healthCheck` (the verification of finding 4, N1). The unreadable contract\n * is already its own `unreadable[]` entry on the consumer, which carries the\n * run to exit 1; a second, false finding on every provider said nothing true.\n *\n * Only that shape is skipped. A readable side that defines no such id proves\n * no ownership either, so the join is the line's and is graded as before; a\n * message join asks no ownership at all (`ownsOperation` says why).\n */\nfunction ownershipFlicker(sides: { holding: ReadonlyMap<string, ServiceState>; other: ReadonlyMap<string, ServiceState> }, t: ConsumerTuple): boolean {\n if (t.kind !== \"op\" || sides.holding.get(t.consumer)?.openapi.kind !== \"unreadable\") return false;\n const other = sides.other.get(t.consumer);\n return other !== undefined && ownsOperation(other, t.token);\n}\n\n/** One graded cross-service join change between the two states. */\nexport interface ConsumerChange {\n t: ConsumerTuple;\n change: \"added\" | \"removed\";\n}\n\n/**\n * The joins that appeared or went away between base and current, sorted for\n * deterministic output (provider, kind, token, consumer). The visibility\n * guard is the containment rule: a join is never called \"added\" off a base\n * side nobody could read, nor \"removed\" off an unreadable working file — the\n * suspended axis already carries that fact. The flicker guard is its mirror on\n * the side that HOLDS the join: one held only because the consumer's own\n * contract did not read there, over an id the other side shows it owns, is no\n * change either.\n */\nexport function consumerJoinChanges(input: {\n base: ReadonlyMap<string, ServiceState>;\n baseAmbiguous: ReadonlySet<string>;\n current: ReadonlyMap<string, ServiceState>;\n currentAmbiguous: ReadonlySet<string>;\n}): ConsumerChange[] {\n const baseTuples = consumerTuples(input.base);\n const currentTuples = consumerTuples(input.current);\n const graded: ConsumerChange[] = [];\n const added = { holding: input.current, other: input.base };\n const removed = { holding: input.base, other: input.current };\n for (const [key, t] of currentTuples) {\n if (baseTuples.has(key) || ownershipFlicker(added, t)) continue;\n if (tupleVisible(input.base, input.baseAmbiguous, t)) graded.push({ t, change: \"added\" });\n }\n for (const [key, t] of baseTuples) {\n if (currentTuples.has(key) || ownershipFlicker(removed, t)) continue;\n if (tupleVisible(input.current, input.currentAmbiguous, t)) graded.push({ t, change: \"removed\" });\n }\n return graded.sort((a, b) => {\n const ka = `${a.t.provider}\\0${a.t.kind}\\0${a.t.token}\\0${a.t.consumer}\\0${a.change}`;\n const kb = `${b.t.provider}\\0${b.t.kind}\\0${b.t.token}\\0${b.t.consumer}\\0${b.change}`;\n return ka < kb ? -1 : 1;\n });\n}\n"]}
|