@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 @@
|
|
|
1
|
+
{"version":3,"file":"living.js","sourceRoot":"","sources":["../../../src/commands/rebase/living.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loam rebase --living` — re-pin the LIVING corpus's `Realizes:` entries to the\n * capability requirements they currently name.\n *\n * The other half of `capability.realizes-stale`. That finding says a promise\n * moved under a claim; this is the act that records having re-read it. The two\n * are deliberately separate commands and not one self-healing pass, for the\n * reason the finding's own comment gives: a stale pin has three legitimate\n * outcomes and only one of them is \"the requirement was right as it stands\".\n * loam cannot tell which, so it reports, and a human runs this when they have\n * decided.\n *\n * WHY IT IS NOT PART OF `rebase <FEAT>`. That command pins a FEATURE's deltas\n * against living text — bookkeeping inside a change window, thrown away when\n * the feature archives. This pins the living documents themselves, against the\n * living business tree, with no feature involved at all. Same verb because the\n * act is the same one (record which version I read), different scope because\n * the documents are.\n *\n * IT WRITES NOTHING ELSE. No `Based-On:`, no contract pins, no reserialize —\n * one `Realizes:` line per requirement that has one, through the same line\n * surgery `./edit.ts` performs for every other pin, so a living spec's headings,\n * prose and ordering survive byte for byte.\n */\nimport { existsSync } from \"node:fs\";\nimport { parseRequirements, readRequirementsDocument } from \"../../core/document/parse.js\";\nimport { NotUtf8DocumentError } from \"../../core/kernel/document-bytes.js\";\nimport { splitRealizesPin } from \"../../core/document/spec.js\";\nimport {\n resolveRealizes,\n splitRealizesEntry,\n type CapabilityRequirementIndex,\n} from \"../../core/capabilities/realizes/join.js\";\nimport { capabilityRequirementIndex } from \"../../core/capabilities/findings.js\";\nimport { emitJson, fail } from \"../../core/envelope/json.js\";\nimport { FleetContext } from \"../../core/fleet-context.js\";\nimport type { DocsDir } from \"../../core/kernel/ids/dirs.js\";\nimport { listServices } from \"../../core/repo/repo.js\";\nimport { servicePathsAt, SPEC_AXES } from \"../../core/repo/paths.js\";\nimport { stageWrites } from \"../../core/staging/commit.js\";\nimport { commitStaged } from \"../../core/staging/txn/transaction.js\";\nimport type { PlannedWrite } from \"../../core/staging/writes.js\";\nimport { plural } from \"../policy/format.js\";\nimport { applyEdits, realizesPinEdit, type LineEdit } from \"./edit.js\";\n\n/** What happened to one living `Realizes:` entry. */\nexport interface LivingPinOutcome {\n service: string;\n /** `spec.md` or `arch.spec.md` — which axis carried the line. */\n file: string;\n /** The requirement's `### Requirement:` heading. */\n target: string;\n /** The entry as authored, pin and all. */\n entry: string;\n /**\n * `pinned` — it carried none and now does. `repinned` — the promise moved and\n * this records the re-read. `unchanged` — already correct, no write.\n * `unresolved` — the entry names nothing the tree declares, so there is no\n * version to pin; `capability.realizes-unknown` is that entry's finding and\n * inventing a digest for it would put loam's stamp on a broken join.\n */\n status: \"pinned\" | \"repinned\" | \"unchanged\" | \"unresolved\";\n from: string | null;\n to: string | null;\n}\n\nexport interface LivingAxisPlan {\n outcomes: LivingPinOutcome[];\n /** The rewritten document, or `null` when nothing changed. */\n content: string | null;\n}\n\n/**\n * Plan one living requirements document's pins against the capability index.\n *\n * The index is the caller's, built once for the whole run: it is the same\n * fleet-wide read `validate --all` takes, and rebuilding it per service would\n * re-parse every capability document once per service in the fleet.\n */\nexport async function planLivingRealizes(\n service: string,\n file: string,\n specPath: string,\n index: CapabilityRequirementIndex,\n): Promise<LivingAxisPlan> {\n if (!existsSync(specPath)) return { outcomes: [], content: null };\n // The decoding read, for `planRequirementPins`'s reason one module over: line\n // surgery over bytes loam mis-decoded would write text nobody authored.\n const raw = await readRequirementsDocument(specPath);\n const reqs = parseRequirements(raw);\n\n const outcomes: LivingPinOutcome[] = [];\n const edits: LineEdit[] = [];\n for (const r of reqs) {\n // REMOVED is skipped wherever `Realizes:` is read; a requirement built in\n // memory has no document line to write into, so there is nothing truthful\n // to report about pinning it.\n if (r.kind === \"REMOVED\" || r.line === undefined) continue;\n if (r.realizes.length === 0) continue;\n\n // The resolution and the rewrite must agree entry for entry, so both read\n // the SAME claim list rather than each splitting the strings again.\n const wanted = new Map<string, string>();\n for (const claim of resolveRealizes(r.realizes, index)) {\n const base = { service, file, target: r.name, entry: claim.entry };\n if (claim.kind !== \"resolved\") {\n outcomes.push({ ...base, status: \"unresolved\", from: splitRealizesPin(claim.entry).pin, to: null });\n continue;\n }\n const { pin, current } = claim;\n if (current === null) {\n // Resolved against an index that carries no digest for it — the feature\n // overlay's shape, and not a state a living run reaches. Reported as\n // unresolved rather than silently skipped: a pin loam declined to write\n // must never look like a pin it wrote.\n outcomes.push({ ...base, status: \"unresolved\", from: pin, to: null });\n continue;\n }\n if (pin === current) {\n outcomes.push({ ...base, status: \"unchanged\", from: pin, to: pin });\n continue;\n }\n wanted.set(claim.entry, `${splitRealizesPin(claim.entry).target}@${current}`);\n outcomes.push({\n ...base,\n status: pin === null ? \"pinned\" : \"repinned\",\n from: pin,\n to: current,\n });\n }\n if (wanted.size === 0) continue;\n const edit = realizesPinEdit(r, r.line, (entry) => wanted.get(entry) ?? entry);\n if (edit !== null) edits.push(edit);\n }\n\n return { outcomes, content: edits.length === 0 ? null : applyEdits(raw, edits) };\n}\n\n/** Entries that would change — what the human view counts and `--dry-run` prints. */\nexport function changedPins(outcomes: readonly LivingPinOutcome[]): LivingPinOutcome[] {\n return outcomes.filter((o) => o.status === \"pinned\" || o.status === \"repinned\");\n}\n\n/**\n * The bare target of an entry — exported so a caller can report what an\n * unresolved entry pointed at without re-deriving the separator rule.\n */\nexport function entryTarget(entry: string): string {\n const target = splitRealizesEntry(entry);\n return target === null ? entry : `${target.capability}#${target.requirement}`;\n}\n\n/**\n * The whole `--living` run, under the lock the caller already holds.\n *\n * Order of operations mirrors `rebaseLocked`: read everything, plan everything,\n * then commit once. A fleet's `Realizes:` corpus is one claim about one version\n * of the business tree, so pinning four services against a tree that moved\n * between the second and the third is exactly the split reading the pin exists\n * to make impossible.\n */\nexport async function rebaseLivingLocked(\n docsDir: DocsDir,\n opts: { service?: string; json?: boolean; dryRun?: boolean },\n): Promise<void> {\n const json = opts.json === true;\n const dryRun = opts.dryRun === true;\n const fleet = new FleetContext();\n\n const capabilities = await fleet.capabilities(docsDir);\n const index = await capabilityRequirementIndex(capabilities, (p) => fleet.readRequirements(p));\n if (index.declared === null) {\n // The ladder, one command over from where `../validate` applies it: a fleet\n // with no gradable capability vocabulary has no versions to pin against,\n // and stamping digests from a file loam could not read would be the false\n // claim the whole pin mechanism exists to refuse.\n return fail(\n json,\n \"unknown-target\",\n \"this docs repo declares no readable capability vocabulary, so no `Realizes:` entry has a version to pin — \" +\n \"write `architecture/capabilities.yaml` or a `capabilities/<id>/spec.md` first, or fix the one that does not parse (`loam validate --all`).\",\n );\n }\n\n const all = await listServices(docsDir, fleet);\n const services = opts.service === undefined ? all : all.filter((s) => s.id === opts.service);\n if (opts.service !== undefined && services.length === 0) {\n return fail(\n json,\n \"unknown-target\",\n `no service '${opts.service}' in this docs repo` +\n (all.length === 0 ? \" — it holds none.\" : ` — it holds: ${all.map((s) => s.id).join(\", \")}.`),\n );\n }\n\n const outcomes: LivingPinOutcome[] = [];\n const writes: PlannedWrite[] = [];\n try {\n for (const entry of services) {\n const paths = servicePathsAt(entry.dir);\n for (const axis of SPEC_AXES) {\n const planned = await planLivingRealizes(entry.id, axis.file, paths[axis.key], index);\n outcomes.push(...planned.outcomes);\n if (planned.content !== null) writes.push({ path: paths[axis.key], content: planned.content });\n }\n }\n } catch (err) {\n if (!(err instanceof NotUtf8DocumentError)) throw err;\n return fail(json, \"merge-failed\", `rebase --living failed — nothing was pinned: ${err.message}`);\n }\n\n const changed = changedPins(outcomes);\n if (!dryRun && writes.length > 0) {\n const staged = await stageWrites(writes);\n const committed = await commitStaged(\n { root: docsDir, command: \"rebase\", rerun: \"loam rebase --living\", target: \"living\" },\n staged,\n \"pinned\",\n );\n if (!committed.ok) {\n return fail(json, \"merge-failed\", `rebase --living failed — ${committed.message}`);\n }\n }\n\n if (json) {\n return emitJson({ command: \"rebase\", ok: true, mode: \"living\", dryRun, pinned: changed.length, outcomes });\n }\n const unresolved = outcomes.filter((o) => o.status === \"unresolved\");\n console.log(\n changed.length === 0\n ? `Nothing to pin — every \\`Realizes:\\` entry in ${plural(services.length, \"service\")} already names the version it points at.`\n : `${dryRun ? \"Would pin\" : \"Pinned\"} ${changed.length} entr${changed.length === 1 ? \"y\" : \"ies\"} across ${plural(writes.length, \"document\")}.`,\n );\n for (const o of changed) {\n console.log(` ${o.status === \"pinned\" ? \"+\" : \"~\"} ${o.service}/${o.file}: '${o.target}' → ${entryTarget(o.entry)}@${o.to}`);\n }\n for (const o of unresolved) {\n console.log(` ? ${o.service}/${o.file}: '${o.target}' realizes ${entryTarget(o.entry)}, which nothing declares — not pinned`);\n }\n if (changed.length > 0 && !dryRun) {\n console.log(\n \"\\nA pin says you re-read the promise. Restamping without reading it is the one way to make this a lie with a digest on it.\",\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What each axis is missing a pin for, computed before anything is written.
|
|
3
|
+
*
|
|
4
|
+
* The requirement axis and the contract axis are planned by the same shape and
|
|
5
|
+
* separately on purpose: a requirement is pinned by a `Based-On:` line inserted
|
|
6
|
+
* by surgery, and an operation by an `x-loam-based-on` key the YAML writer
|
|
7
|
+
* emits. Only the first has to preserve the author's sections and prose, which
|
|
8
|
+
* is why it edits lines rather than reserializing.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { readFile } from "node:fs/promises";
|
|
12
|
+
import { decodeDocument } from "../../core/kernel/document-bytes.js";
|
|
13
|
+
import {} from "../../core/kernel/ids/service.js";
|
|
14
|
+
import {} from "../../core/repo/paths.js";
|
|
15
|
+
import { livingCapabilityPaths } from "../../core/repo/authored/paths.js";
|
|
16
|
+
import { locateServicePaths } from "../../core/repo/service-target.js";
|
|
17
|
+
import { parseRequirements, readRequirementsDocument } from "../../core/document/parse.js";
|
|
18
|
+
import { requirementDigest } from "../../core/document/spec.js";
|
|
19
|
+
import { OpenapiMergeError } from "../../core/openapi/merge/error.js";
|
|
20
|
+
import { pinOpenapiOperations } from "../../core/openapi/merge/pin.js";
|
|
21
|
+
import { planOpenapiBaselines } from "../../core/openapi/baseline/plan.js";
|
|
22
|
+
import { AsyncapiMergeError } from "../../core/asyncapi/merge/error.js";
|
|
23
|
+
import { pinAsyncapiSlots } from "../../core/asyncapi/merge/pin.js";
|
|
24
|
+
import { planAsyncapiBaselines } from "../../core/asyncapi/baseline/plan.js";
|
|
25
|
+
import { applyEdits, pinEdit } from "./edit.js";
|
|
26
|
+
/** Pin every MODIFIED/REMOVED requirement in one delta file against one living document. */
|
|
27
|
+
export async function planAxis(repo, service, axis, specPath) {
|
|
28
|
+
const livingPath = (await locateServicePaths(repo.docsDir, service, repo.fleet))[axis.key];
|
|
29
|
+
const planned = await planRequirementPins(specPath, livingPath, axis.file);
|
|
30
|
+
return { outcomes: planned.pins.map((pin) => ({ service, ...pin })), content: planned.content };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The same, for one capability delta against its living document.
|
|
34
|
+
*
|
|
35
|
+
* NOT OPTIONAL, and not symmetry for its own sake: `delta.baseline-missing` is
|
|
36
|
+
* a warning that GATES archive, and its message ends "Run `loam rebase <FEAT>`
|
|
37
|
+
* to pin it". A capability delta graded by that rule while `rebase` skipped the
|
|
38
|
+
* axis would have loam send an author to a command that does not pin the file
|
|
39
|
+
* loam just named — a refusal with no exit, which is the one thing a gating
|
|
40
|
+
* message may never be.
|
|
41
|
+
*
|
|
42
|
+
* The living path resolves through `livingCapabilityPaths` for the reason that
|
|
43
|
+
* function states: the id's nesting is spelled by directories, so an unsplit
|
|
44
|
+
* join reads an empty living document and every pin comes out `unresolved`
|
|
45
|
+
* over a promise the fleet already made.
|
|
46
|
+
*/
|
|
47
|
+
export async function planCapabilityAxis(repo, capability, specPath) {
|
|
48
|
+
const planned = await planRequirementPins(specPath, livingCapabilityPaths(repo.docsDir, capability).spec, "spec.md");
|
|
49
|
+
return { outcomes: planned.pins.map((pin) => ({ capability, ...pin })), content: planned.content };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The pin rule itself: every MODIFIED/REMOVED requirement in one delta document,
|
|
53
|
+
* against one living document. Whose documents they are is the caller's
|
|
54
|
+
* business — this is the part that must not fork, because a second copy is a
|
|
55
|
+
* second answer to "was this delta written against what is there now".
|
|
56
|
+
*/
|
|
57
|
+
async function planRequirementPins(specPath, livingPath, file) {
|
|
58
|
+
// Both sides through the decoding read: the delta because line surgery over a
|
|
59
|
+
// document loam mis-decoded would write bytes nobody authored, the living
|
|
60
|
+
// because it is what every digest below is taken over.
|
|
61
|
+
const raw = await readRequirementsDocument(specPath);
|
|
62
|
+
const reqs = parseRequirements(raw);
|
|
63
|
+
const living = existsSync(livingPath)
|
|
64
|
+
? parseRequirements(await readRequirementsDocument(livingPath))
|
|
65
|
+
: [];
|
|
66
|
+
const pins = [];
|
|
67
|
+
const edits = [];
|
|
68
|
+
for (const r of reqs) {
|
|
69
|
+
if (r.kind !== "MODIFIED" && r.kind !== "REMOVED")
|
|
70
|
+
continue;
|
|
71
|
+
// Every requirement parsed from a document carries its heading line
|
|
72
|
+
// (core/document/parse.ts). One built in memory has no document to write into, and
|
|
73
|
+
// there is nothing truthful to report about pinning it.
|
|
74
|
+
const line = r.line;
|
|
75
|
+
if (line === undefined)
|
|
76
|
+
continue;
|
|
77
|
+
const base = { file, kind: r.kind, target: r.name };
|
|
78
|
+
const selected = selectLiving(living, r);
|
|
79
|
+
if (selected === undefined) {
|
|
80
|
+
pins.push({ ...base, status: "unresolved", from: r.basedOn ?? null, to: null });
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const digest = requirementDigest(selected);
|
|
84
|
+
if (r.basedOn === digest) {
|
|
85
|
+
pins.push({ ...base, status: "unchanged", from: digest, to: digest });
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
pins.push({
|
|
89
|
+
...base,
|
|
90
|
+
status: r.basedOn === undefined ? "pinned" : "repinned",
|
|
91
|
+
from: r.basedOn ?? null,
|
|
92
|
+
to: digest,
|
|
93
|
+
});
|
|
94
|
+
edits.push(pinEdit(r, line, digest));
|
|
95
|
+
}
|
|
96
|
+
return { pins, content: edits.length === 0 ? null : applyEdits(raw, edits) };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Pin every operation in one feature contract against the living contract.
|
|
100
|
+
*
|
|
101
|
+
* The pin is always `operationDigest` of the LIVING operation, never of the
|
|
102
|
+
* delta's own. That single rule produces both merge verdicts on its own: an
|
|
103
|
+
* operation the author only QUOTED is byte-equal to living, so its pin equals
|
|
104
|
+
* its own content and the merge skips it; one the author EDITED differs from
|
|
105
|
+
* its pin, so the merge writes it. Nothing here has to guess at intent — the
|
|
106
|
+
* document already records it, and the pin makes it legible.
|
|
107
|
+
*
|
|
108
|
+
* Slot-keyed (path + method), exactly as the merge upserts. An operationId that
|
|
109
|
+
* moved to another slot is a new slot with nothing living behind it, which is
|
|
110
|
+
* `unresolved` and correct: there is no living version of an operation at a
|
|
111
|
+
* path the contract does not serve yet.
|
|
112
|
+
*/
|
|
113
|
+
export async function planOpenapi(repo, service, openapiPath) {
|
|
114
|
+
const livingPath = (await locateServicePaths(repo.docsDir, service, repo.fleet)).openapi;
|
|
115
|
+
// Decoded, not `readFile(…, "utf8")`, for the requirement axes' reason: a
|
|
116
|
+
// contract read with U+FFFD substituted in defines no operation loam can
|
|
117
|
+
// match, so every pin would come out `unresolved` — "this feature adds them
|
|
118
|
+
// all" — over a living contract that already serves them. Read outside the
|
|
119
|
+
// try below, whose job is the merge's own diagnosis and not this one.
|
|
120
|
+
const living = existsSync(livingPath) ? decodeDocument(await readFile(livingPath), livingPath) : "";
|
|
121
|
+
const delta = decodeDocument(await readFile(openapiPath), openapiPath);
|
|
122
|
+
let plan;
|
|
123
|
+
let baselines;
|
|
124
|
+
try {
|
|
125
|
+
plan = pinOpenapiOperations(delta, living, service);
|
|
126
|
+
// The surface record, planned over the OPERATION pass's output so one run
|
|
127
|
+
// writes one file once. Order is safe: a surface digest never includes an
|
|
128
|
+
// operation pin (`restatedSurfaces` skips the methods entirely), and the
|
|
129
|
+
// root record never enters an operation digest.
|
|
130
|
+
baselines = planOpenapiBaselines(plan.text ?? delta, living);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
// A document loam cannot read is validate's diagnosis to make
|
|
134
|
+
// (`openapi.invalid`), not this command's to guess at — and stamping into a
|
|
135
|
+
// broken parse would write a file nobody asked for.
|
|
136
|
+
if (!(err instanceof OpenapiMergeError))
|
|
137
|
+
throw err;
|
|
138
|
+
return { outcomes: [], content: null };
|
|
139
|
+
}
|
|
140
|
+
return {
|
|
141
|
+
outcomes: [
|
|
142
|
+
...plan.pins.map((pin) => ({
|
|
143
|
+
service,
|
|
144
|
+
file: "openapi.yaml",
|
|
145
|
+
kind: pin.method.toUpperCase(),
|
|
146
|
+
target: pin.operationId.length === 0 ? pin.path : `${pin.path} ('${pin.operationId}')`,
|
|
147
|
+
status: pin.status,
|
|
148
|
+
from: pin.from,
|
|
149
|
+
to: pin.to,
|
|
150
|
+
})),
|
|
151
|
+
...baselines.pins.map((pin) => ({
|
|
152
|
+
service,
|
|
153
|
+
file: "openapi.yaml",
|
|
154
|
+
kind: pin.kind === "component" ? "COMPONENT" : "PATH-ITEM",
|
|
155
|
+
target: pin.target,
|
|
156
|
+
status: pin.status,
|
|
157
|
+
from: pin.from,
|
|
158
|
+
to: pin.to,
|
|
159
|
+
})),
|
|
160
|
+
],
|
|
161
|
+
content: baselines.text ?? plan.text,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Pin every slot AND every component surface in one feature event contract
|
|
166
|
+
* against the living contract — `planOpenapi`'s mirror on the event axis, in
|
|
167
|
+
* both of its halves.
|
|
168
|
+
*
|
|
169
|
+
* The in-value `x-loam-based-on` reaches every SLOT, because a slot value is
|
|
170
|
+
* always a mapping (core/asyncapi/digest.ts owns the slot model; inline
|
|
171
|
+
* channel messages are channel interior and never pinned on their own). It
|
|
172
|
+
* reaches nothing else: a `components/schemas/<name>` value is a JSON Schema,
|
|
173
|
+
* where an in-value loam key would be a schema keyword — so the surfaces are
|
|
174
|
+
* pinned by the same root `x-loam-baselines` record the OpenAPI axis uses, and
|
|
175
|
+
* this function writes both. (This comment used to say the event pin has no
|
|
176
|
+
* root record. It did not, and that is why a `components.schemas`-only delta
|
|
177
|
+
* merged nothing at all.)
|
|
178
|
+
*/
|
|
179
|
+
export async function planAsyncapi(repo, service, asyncapiPath) {
|
|
180
|
+
const livingPath = (await locateServicePaths(repo.docsDir, service, repo.fleet)).asyncapi;
|
|
181
|
+
// Decoded, not `readFile(…, "utf8")`, for planOpenapi's reason: a contract
|
|
182
|
+
// read with U+FFFD substituted in defines no slot loam can match, so every
|
|
183
|
+
// pin would come out `unresolved` over a living contract that already
|
|
184
|
+
// carries them.
|
|
185
|
+
const living = existsSync(livingPath) ? decodeDocument(await readFile(livingPath), livingPath) : "";
|
|
186
|
+
const delta = decodeDocument(await readFile(asyncapiPath), asyncapiPath);
|
|
187
|
+
let plan;
|
|
188
|
+
let baselines;
|
|
189
|
+
try {
|
|
190
|
+
plan = pinAsyncapiSlots(delta, living, service);
|
|
191
|
+
// The surface record, planned over the SLOT pass's output so one run
|
|
192
|
+
// writes one file once. Order is safe, and load-bearing in both
|
|
193
|
+
// directions: a surface digest never includes a slot pin (`asyncapiSurfaces`
|
|
194
|
+
// skips `components.messages` entirely, and no other section is a
|
|
195
|
+
// surface), and the root record never enters a slot digest.
|
|
196
|
+
baselines = planAsyncapiBaselines(plan.text ?? delta, living);
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
// A document loam cannot read is validate's diagnosis to make
|
|
200
|
+
// (`asyncapi.invalid`), not this command's to guess at — and stamping
|
|
201
|
+
// into a broken parse would write a file nobody asked for.
|
|
202
|
+
if (!(err instanceof AsyncapiMergeError))
|
|
203
|
+
throw err;
|
|
204
|
+
return { outcomes: [], content: null };
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
outcomes: [
|
|
208
|
+
...plan.pins.map((pin) => ({
|
|
209
|
+
service,
|
|
210
|
+
file: "asyncapi.yaml",
|
|
211
|
+
kind: pin.section,
|
|
212
|
+
target: pin.key,
|
|
213
|
+
status: pin.status,
|
|
214
|
+
from: pin.from,
|
|
215
|
+
to: pin.to,
|
|
216
|
+
})),
|
|
217
|
+
...baselines.pins.map((pin) => ({
|
|
218
|
+
service,
|
|
219
|
+
file: "asyncapi.yaml",
|
|
220
|
+
kind: "COMPONENT",
|
|
221
|
+
target: pin.target,
|
|
222
|
+
status: pin.status,
|
|
223
|
+
from: pin.from,
|
|
224
|
+
to: pin.to,
|
|
225
|
+
})),
|
|
226
|
+
],
|
|
227
|
+
content: baselines.text ?? plan.text,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The living requirement a delta requirement addresses — the merge's own
|
|
232
|
+
* resolution order (core/document/apply.ts `applyRequirementDelta`), so a pin is taken
|
|
233
|
+
* over exactly the requirement archive would rewrite: the stable ID when the
|
|
234
|
+
* delta carries one, the exact heading otherwise, and the FIRST match either
|
|
235
|
+
* way (duplicates are refused upstream by `delta.living-duplicate-requirement`).
|
|
236
|
+
*/
|
|
237
|
+
export function selectLiving(living, r) {
|
|
238
|
+
if (r.id !== undefined)
|
|
239
|
+
return living.find((candidate) => candidate.id === r.id);
|
|
240
|
+
return living.find((candidate) => candidate.name === r.name);
|
|
241
|
+
}
|
|
242
|
+
/* ------------------------------------------------------------------ */
|
|
243
|
+
/* Line surgery */
|
|
244
|
+
/* ------------------------------------------------------------------ */
|
|
245
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/commands/rebase/plan.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What each axis is missing a pin for, computed before anything is written.\n *\n * The requirement axis and the contract axis are planned by the same shape and\n * separately on purpose: a requirement is pinned by a `Based-On:` line inserted\n * by surgery, and an operation by an `x-loam-based-on` key the YAML writer\n * emits. Only the first has to preserve the author's sections and prose, which\n * is why it edits lines rather than reserializing.\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { decodeDocument } from \"../../core/kernel/document-bytes.js\";\nimport { type PathableService } from \"../../core/kernel/ids/service.js\";\nimport { type SpecAxis } from \"../../core/repo/paths.js\";\nimport { livingCapabilityPaths } from \"../../core/repo/authored/paths.js\";\nimport { locateServicePaths } from \"../../core/repo/service-target.js\";\nimport { parseRequirements, readRequirementsDocument } from \"../../core/document/parse.js\";\nimport { requirementDigest, type Requirement } from \"../../core/document/spec.js\";\nimport { OpenapiMergeError } from \"../../core/openapi/merge/error.js\";\nimport { pinOpenapiOperations, type OpenapiPinPlan } from \"../../core/openapi/merge/pin.js\";\nimport { planOpenapiBaselines, type OpenapiBaselinePlan } from \"../../core/openapi/baseline/plan.js\";\nimport { AsyncapiMergeError } from \"../../core/asyncapi/merge/error.js\";\nimport { pinAsyncapiSlots, type AsyncapiPinPlan } from \"../../core/asyncapi/merge/pin.js\";\nimport { planAsyncapiBaselines } from \"../../core/asyncapi/baseline/plan.js\";\nimport { applyEdits, pinEdit, type LineEdit } from \"./edit.js\";\nimport type { DocsDir } from \"../../core/kernel/ids/dirs.js\";\nimport type { FleetContext } from \"../../core/fleet-context.js\";\n\n/**\n * How a planner reaches the living documents: the repo root plus the\n * command's shared read index. One record on purpose — `rebase` calls these\n * planners in a services × axes loop, and each `locateServicePaths` without\n * a context is a FULL fleet walk (readdir + a frontmatter read per service),\n * so a 20-service feature paid ~80 re-enumerations of a fleet that did not\n * change between them. The context makes that one walk per invocation.\n */\nexport interface RepoRead {\n docsDir: DocsDir;\n fleet?: FleetContext;\n}\n\nexport type PinStatus =\n /** It had none and now has one. */\n | \"pinned\"\n /** It had a pin for an older living version; it now names the current one. */\n | \"repinned\"\n /** It already named the current living version — no write. */\n | \"unchanged\"\n /**\n * It addresses nothing living — a MODIFIED of a requirement another feature\n * in flight still introduces, or an operation this feature is adding. There\n * is no version to be based on, so inventing a pin would be inventing a\n * baseline; `loam validate` already reports the ordering where there is one\n * (`delta.modified-pending`).\n */\n | \"unresolved\"\n /**\n * The operation is written as a YAML alias. One shared value backs every use\n * of an anchor, so stamping \"through\" it would pin every other use too —\n * the same reason the merge refuses to edit aliases in place. Rare, legal,\n * and named rather than silently skipped.\n */\n | \"unwritable\";\n\n/**\n * What happened to ONE pin, minus whose document it was in.\n *\n * Split from `PinOutcome` when the business corpus arrived: a capability delta\n * is pinned by the identical rule against an identical document, but it names\n * no service, and putting a capability id into a published field called\n * `service` would bend the `--json` contract into a lie. Everything a reader\n * acts on lives here; the two wrappers below add only the identity.\n */\nexport interface PinRecord {\n /** The axis's filename — \"spec.md\", \"arch.spec.md\", \"openapi.yaml\" or \"asyncapi.yaml\". */\n file: string;\n /**\n * MODIFIED/REMOVED for a requirement; the upper-case HTTP method for an\n * operation; COMPONENT for a `components/<kind>/<name>`; PATH-ITEM for a\n * path-item non-method key; the AsyncAPI section name (`channels`,\n * `operations`, `components.messages`) for an event slot.\n */\n kind: string;\n /** The requirement heading, `/path ('operationId')`, `<kind>/<name>`, `/path '<key>'`, or the asyncapi slot key. */\n target: string;\n status: PinStatus;\n /** The pin as it was, or null when there was none. */\n from: string | null;\n /** The pin as it now stands, or null when nothing living could be hashed. */\n to: string | null;\n}\n\nexport interface PinOutcome extends PinRecord {\n service: string;\n}\n\n/** The same record on the business corpus, keyed by the promise instead of the service. */\nexport interface CapabilityPinOutcome extends PinRecord {\n capability: string;\n}\n\nexport interface AxisPlan {\n outcomes: PinOutcome[];\n /** The rewritten document, or null when nothing about it changes. */\n content: string | null;\n}\n\nexport interface CapabilityAxisPlan {\n outcomes: CapabilityPinOutcome[];\n content: string | null;\n}\n\n/** Pin every MODIFIED/REMOVED requirement in one delta file against one living document. */\nexport async function planAxis(\n repo: RepoRead,\n service: PathableService,\n axis: SpecAxis,\n specPath: string,\n): Promise<AxisPlan> {\n const livingPath = (await locateServicePaths(repo.docsDir, service, repo.fleet))[axis.key];\n const planned = await planRequirementPins(specPath, livingPath, axis.file);\n return { outcomes: planned.pins.map((pin) => ({ service, ...pin })), content: planned.content };\n}\n\n/**\n * The same, for one capability delta against its living document.\n *\n * NOT OPTIONAL, and not symmetry for its own sake: `delta.baseline-missing` is\n * a warning that GATES archive, and its message ends \"Run `loam rebase <FEAT>`\n * to pin it\". A capability delta graded by that rule while `rebase` skipped the\n * axis would have loam send an author to a command that does not pin the file\n * loam just named — a refusal with no exit, which is the one thing a gating\n * message may never be.\n *\n * The living path resolves through `livingCapabilityPaths` for the reason that\n * function states: the id's nesting is spelled by directories, so an unsplit\n * join reads an empty living document and every pin comes out `unresolved`\n * over a promise the fleet already made.\n */\nexport async function planCapabilityAxis(\n repo: RepoRead,\n capability: string,\n specPath: string,\n): Promise<CapabilityAxisPlan> {\n const planned = await planRequirementPins(specPath, livingCapabilityPaths(repo.docsDir, capability).spec, \"spec.md\");\n return { outcomes: planned.pins.map((pin) => ({ capability, ...pin })), content: planned.content };\n}\n\n/**\n * The pin rule itself: every MODIFIED/REMOVED requirement in one delta document,\n * against one living document. Whose documents they are is the caller's\n * business — this is the part that must not fork, because a second copy is a\n * second answer to \"was this delta written against what is there now\".\n */\nasync function planRequirementPins(\n specPath: string,\n livingPath: string,\n file: string,\n): Promise<{ pins: PinRecord[]; content: string | null }> {\n // Both sides through the decoding read: the delta because line surgery over a\n // document loam mis-decoded would write bytes nobody authored, the living\n // because it is what every digest below is taken over.\n const raw = await readRequirementsDocument(specPath);\n const reqs = parseRequirements(raw);\n const living = existsSync(livingPath)\n ? parseRequirements(await readRequirementsDocument(livingPath))\n : [];\n\n const pins: PinRecord[] = [];\n const edits: LineEdit[] = [];\n for (const r of reqs) {\n if (r.kind !== \"MODIFIED\" && r.kind !== \"REMOVED\") continue;\n // Every requirement parsed from a document carries its heading line\n // (core/document/parse.ts). One built in memory has no document to write into, and\n // there is nothing truthful to report about pinning it.\n const line = r.line;\n if (line === undefined) continue;\n const base = { file, kind: r.kind, target: r.name };\n const selected = selectLiving(living, r);\n if (selected === undefined) {\n pins.push({ ...base, status: \"unresolved\", from: r.basedOn ?? null, to: null });\n continue;\n }\n const digest = requirementDigest(selected);\n if (r.basedOn === digest) {\n pins.push({ ...base, status: \"unchanged\", from: digest, to: digest });\n continue;\n }\n pins.push({\n ...base,\n status: r.basedOn === undefined ? \"pinned\" : \"repinned\",\n from: r.basedOn ?? null,\n to: digest,\n });\n edits.push(pinEdit(r, line, digest));\n }\n\n return { pins, content: edits.length === 0 ? null : applyEdits(raw, edits) };\n}\n\n/**\n * Pin every operation in one feature contract against the living contract.\n *\n * The pin is always `operationDigest` of the LIVING operation, never of the\n * delta's own. That single rule produces both merge verdicts on its own: an\n * operation the author only QUOTED is byte-equal to living, so its pin equals\n * its own content and the merge skips it; one the author EDITED differs from\n * its pin, so the merge writes it. Nothing here has to guess at intent — the\n * document already records it, and the pin makes it legible.\n *\n * Slot-keyed (path + method), exactly as the merge upserts. An operationId that\n * moved to another slot is a new slot with nothing living behind it, which is\n * `unresolved` and correct: there is no living version of an operation at a\n * path the contract does not serve yet.\n */\nexport async function planOpenapi(repo: RepoRead, service: PathableService, openapiPath: string): Promise<AxisPlan> {\n const livingPath = (await locateServicePaths(repo.docsDir, service, repo.fleet)).openapi;\n // Decoded, not `readFile(…, \"utf8\")`, for the requirement axes' reason: a\n // contract read with U+FFFD substituted in defines no operation loam can\n // match, so every pin would come out `unresolved` — \"this feature adds them\n // all\" — over a living contract that already serves them. Read outside the\n // try below, whose job is the merge's own diagnosis and not this one.\n const living = existsSync(livingPath) ? decodeDocument(await readFile(livingPath), livingPath) : \"\";\n const delta = decodeDocument(await readFile(openapiPath), openapiPath);\n let plan: OpenapiPinPlan;\n let baselines: OpenapiBaselinePlan;\n try {\n plan = pinOpenapiOperations(delta, living, service);\n // The surface record, planned over the OPERATION pass's output so one run\n // writes one file once. Order is safe: a surface digest never includes an\n // operation pin (`restatedSurfaces` skips the methods entirely), and the\n // root record never enters an operation digest.\n baselines = planOpenapiBaselines(plan.text ?? delta, living);\n } catch (err) {\n // A document loam cannot read is validate's diagnosis to make\n // (`openapi.invalid`), not this command's to guess at — and stamping into a\n // broken parse would write a file nobody asked for.\n if (!(err instanceof OpenapiMergeError)) throw err;\n return { outcomes: [], content: null };\n }\n return {\n outcomes: [\n ...plan.pins.map((pin) => ({\n service,\n file: \"openapi.yaml\",\n kind: pin.method.toUpperCase(),\n target: pin.operationId.length === 0 ? pin.path : `${pin.path} ('${pin.operationId}')`,\n status: pin.status,\n from: pin.from,\n to: pin.to,\n })),\n ...baselines.pins.map((pin) => ({\n service,\n file: \"openapi.yaml\",\n kind: pin.kind === \"component\" ? \"COMPONENT\" : \"PATH-ITEM\",\n target: pin.target,\n status: pin.status,\n from: pin.from,\n to: pin.to,\n })),\n ],\n content: baselines.text ?? plan.text,\n };\n}\n\n/**\n * Pin every slot AND every component surface in one feature event contract\n * against the living contract — `planOpenapi`'s mirror on the event axis, in\n * both of its halves.\n *\n * The in-value `x-loam-based-on` reaches every SLOT, because a slot value is\n * always a mapping (core/asyncapi/digest.ts owns the slot model; inline\n * channel messages are channel interior and never pinned on their own). It\n * reaches nothing else: a `components/schemas/<name>` value is a JSON Schema,\n * where an in-value loam key would be a schema keyword — so the surfaces are\n * pinned by the same root `x-loam-baselines` record the OpenAPI axis uses, and\n * this function writes both. (This comment used to say the event pin has no\n * root record. It did not, and that is why a `components.schemas`-only delta\n * merged nothing at all.)\n */\nexport async function planAsyncapi(\n repo: RepoRead,\n service: PathableService,\n asyncapiPath: string,\n): Promise<AxisPlan> {\n const livingPath = (await locateServicePaths(repo.docsDir, service, repo.fleet)).asyncapi;\n // Decoded, not `readFile(…, \"utf8\")`, for planOpenapi's reason: a contract\n // read with U+FFFD substituted in defines no slot loam can match, so every\n // pin would come out `unresolved` over a living contract that already\n // carries them.\n const living = existsSync(livingPath) ? decodeDocument(await readFile(livingPath), livingPath) : \"\";\n const delta = decodeDocument(await readFile(asyncapiPath), asyncapiPath);\n let plan: AsyncapiPinPlan;\n let baselines: OpenapiBaselinePlan;\n try {\n plan = pinAsyncapiSlots(delta, living, service);\n // The surface record, planned over the SLOT pass's output so one run\n // writes one file once. Order is safe, and load-bearing in both\n // directions: a surface digest never includes a slot pin (`asyncapiSurfaces`\n // skips `components.messages` entirely, and no other section is a\n // surface), and the root record never enters a slot digest.\n baselines = planAsyncapiBaselines(plan.text ?? delta, living);\n } catch (err) {\n // A document loam cannot read is validate's diagnosis to make\n // (`asyncapi.invalid`), not this command's to guess at — and stamping\n // into a broken parse would write a file nobody asked for.\n if (!(err instanceof AsyncapiMergeError)) throw err;\n return { outcomes: [], content: null };\n }\n return {\n outcomes: [\n ...plan.pins.map((pin) => ({\n service,\n file: \"asyncapi.yaml\",\n kind: pin.section,\n target: pin.key,\n status: pin.status,\n from: pin.from,\n to: pin.to,\n })),\n ...baselines.pins.map((pin) => ({\n service,\n file: \"asyncapi.yaml\",\n kind: \"COMPONENT\",\n target: pin.target,\n status: pin.status,\n from: pin.from,\n to: pin.to,\n })),\n ],\n content: baselines.text ?? plan.text,\n };\n}\n\n/**\n * The living requirement a delta requirement addresses — the merge's own\n * resolution order (core/document/apply.ts `applyRequirementDelta`), so a pin is taken\n * over exactly the requirement archive would rewrite: the stable ID when the\n * delta carries one, the exact heading otherwise, and the FIRST match either\n * way (duplicates are refused upstream by `delta.living-duplicate-requirement`).\n */\nexport function selectLiving(living: Requirement[], r: Requirement): Requirement | undefined {\n if (r.id !== undefined) return living.find((candidate) => candidate.id === r.id);\n return living.find((candidate) => candidate.name === r.name);\n}\n\n/* ------------------------------------------------------------------ */\n/* Line surgery */\n/* ------------------------------------------------------------------ */\n"]}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { NotUtf8DocumentError } from "../../core/kernel/document-bytes.js";
|
|
3
|
+
import { InvalidIdError, assertServiceId } from "../../core/kernel/ids/service.js";
|
|
4
|
+
import { configOrRefuse, emitJson, fail, repoPath } from "../../core/envelope/json.js";
|
|
5
|
+
import { compareIds } from "../../core/repo/entries.js";
|
|
6
|
+
import { featureSpecPaths, SPEC_AXES } from "../../core/repo/paths.js";
|
|
7
|
+
import { missingFeatureMessage, resolveFeature } from "../../core/repo/repo.js";
|
|
8
|
+
import { stageWrites } from "../../core/staging/commit.js";
|
|
9
|
+
import {} from "../../core/staging/interrupted.js";
|
|
10
|
+
import { openCommitWindow } from "../../core/staging/recovery/recover.js";
|
|
11
|
+
import { commitStaged } from "../../core/staging/txn/transaction.js";
|
|
12
|
+
import {} from "../../core/staging/writes.js";
|
|
13
|
+
import { plural, sayRecovered } from "../policy/format.js";
|
|
14
|
+
import { FleetContext } from "../../core/fleet-context.js";
|
|
15
|
+
import { planAsyncapi, planAxis, planCapabilityAxis, planOpenapi, } from "./plan.js";
|
|
16
|
+
import { issueFinding } from "../../core/vocabulary/issue.js";
|
|
17
|
+
import { retiredLookup } from "../../core/coherence/retired/archived.js";
|
|
18
|
+
import { serviceRevivals } from "../../core/coherence/retired/revival/revived.js";
|
|
19
|
+
import { rebaseLivingLocked } from "./living.js";
|
|
20
|
+
/** What happened to one pin. */
|
|
21
|
+
export function registerRebase(program) {
|
|
22
|
+
program
|
|
23
|
+
.command("rebase")
|
|
24
|
+
// Optional ONLY because `--living` names no feature: that mode pins the
|
|
25
|
+
// living corpus itself. Every existing invocation still parses, which is
|
|
26
|
+
// what makes the relaxation additive rather than a contract change.
|
|
27
|
+
.argument("[featureId]", "feature id, e.g. FEAT-101 — omitted with --living")
|
|
28
|
+
.description("Pin a feature's MODIFIED/REMOVED requirements to the living text they are written against")
|
|
29
|
+
.option("--service <id>", "restrict to one service (default: every service the feature touches)")
|
|
30
|
+
.option("--living", "pin the LIVING corpus's `Realizes:` entries to the capability requirements they name, instead of a feature's deltas")
|
|
31
|
+
.option("--dry-run", "print what would be pinned and write nothing — beyond first finishing a predecessor's interrupted commit, exactly as a real run would")
|
|
32
|
+
.option("--json", "emit the machine contract instead of the human view")
|
|
33
|
+
.action(async (featureId, opts) => {
|
|
34
|
+
const json = opts.json === true;
|
|
35
|
+
const config = await configOrRefuse(json);
|
|
36
|
+
if (config === null)
|
|
37
|
+
return;
|
|
38
|
+
// The id grammar on the RAW argument, before it reaches a path join —
|
|
39
|
+
// one grammar for the whole tool (core/kernel/ids/service.ts).
|
|
40
|
+
if (opts.service !== undefined) {
|
|
41
|
+
try {
|
|
42
|
+
assertServiceId(opts.service, "--service");
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (!(err instanceof InvalidIdError))
|
|
46
|
+
throw err;
|
|
47
|
+
return fail(json, "invalid-option", err.message);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// The living specs must not move between the read that computes a pin and
|
|
51
|
+
// the write that records it: a digest taken over a document an archive
|
|
52
|
+
// replaced a millisecond later is precisely the false "I read this" the
|
|
53
|
+
// pin exists to make impossible. One writer per docs repo, refusing
|
|
54
|
+
// rather than queueing, exactly as archive takes it.
|
|
55
|
+
//
|
|
56
|
+
// A journal in the repo means the LAST write never finished — reading
|
|
57
|
+
// living documents to compute pins over a half-commit would digest
|
|
58
|
+
// bytes no run ever produced. Recover (or refuse) first, under the
|
|
59
|
+
// same lock the commit will hold.
|
|
60
|
+
const opened = await openCommitWindow(config.docsDir, 0);
|
|
61
|
+
if (!opened.ok)
|
|
62
|
+
return fail(json, opened.code, opened.message);
|
|
63
|
+
try {
|
|
64
|
+
if (opts.living === true) {
|
|
65
|
+
await rebaseLivingLocked(config.docsDir, opts);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (featureId === undefined) {
|
|
69
|
+
// The argument is optional only for the mode that names no feature.
|
|
70
|
+
// Refusing here rather than making the whole command feature-less
|
|
71
|
+
// keeps one rule: every pin says which documents it read.
|
|
72
|
+
return fail(json, "invalid-option", "loam rebase needs a feature id — e.g. `loam rebase FEAT-101`. To pin the living corpus's `Realizes:` entries instead, run `loam rebase --living`.");
|
|
73
|
+
}
|
|
74
|
+
await rebaseLocked(config.docsDir, featureId, { ...opts, recovered: opened.recovered });
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
await opened.release();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
async function rebaseLocked(docsDir, featureId, opts) {
|
|
82
|
+
const json = opts.json === true;
|
|
83
|
+
const dryRun = opts.dryRun === true;
|
|
84
|
+
const feature = await resolveFeature(docsDir, featureId, "exclude");
|
|
85
|
+
if (!feature) {
|
|
86
|
+
return fail(json, "unknown-target", await missingFeatureMessage(docsDir, featureId));
|
|
87
|
+
}
|
|
88
|
+
const { id } = feature;
|
|
89
|
+
// The enumeration's own id is what travels on when --service names one
|
|
90
|
+
// (`entry.id` rather than the argument — repo/service-target.ts's rule):
|
|
91
|
+
// equal as strings, and only one of them was produced by a readdir.
|
|
92
|
+
const chosen = opts.service === undefined ? undefined : feature.services.find((s) => s === opts.service);
|
|
93
|
+
if (opts.service !== undefined && chosen === undefined) {
|
|
94
|
+
// The refusal names the choices, the way `loam delta`'s does: a typo must
|
|
95
|
+
// never be indistinguishable from a feature with nothing to pin.
|
|
96
|
+
return fail(json, "unknown-target", `${id} carries no requirement delta for '${opts.service}'` +
|
|
97
|
+
(feature.services.length === 0
|
|
98
|
+
? " — it touches no service at all."
|
|
99
|
+
: ` — it touches: ${[...feature.services].sort(compareIds).join(", ")}.`));
|
|
100
|
+
}
|
|
101
|
+
const services = (chosen === undefined ? [...feature.services] : [chosen]).sort(compareIds);
|
|
102
|
+
// One read index for the whole loop below: every planner resolves its
|
|
103
|
+
// living document through `locateServicePaths`, and without a shared
|
|
104
|
+
// context each of those calls is a fresh fleet walk — services × axes of
|
|
105
|
+
// them per run, on a tree that cannot change under the lock this holds.
|
|
106
|
+
const repo = { docsDir, fleet: new FleetContext() };
|
|
107
|
+
const outcomes = [];
|
|
108
|
+
const capabilityOutcomes = [];
|
|
109
|
+
const writes = [];
|
|
110
|
+
const revived = [];
|
|
111
|
+
// The business corpus this feature changes. Skipped entirely under `--service`:
|
|
112
|
+
// that flag means "restrict to one service", and a capability names none — so
|
|
113
|
+
// pinning capability deltas under it would write files the caller narrowed the
|
|
114
|
+
// command to exclude. One `existsSync` when the feature carries no capability
|
|
115
|
+
// delta, which is every feature in a fleet that has not adopted the axis.
|
|
116
|
+
const capabilities = chosen === undefined ? (await repo.fleet.featureCapabilityDeltas(feature.dir)).docs : [];
|
|
117
|
+
try {
|
|
118
|
+
for (const service of services) {
|
|
119
|
+
for (const axis of SPEC_AXES) {
|
|
120
|
+
const specPath = featureSpecPaths(feature.dir, service)[axis.key];
|
|
121
|
+
if (!existsSync(specPath))
|
|
122
|
+
continue;
|
|
123
|
+
const planned = await planAxis(repo, service, axis, specPath);
|
|
124
|
+
outcomes.push(...planned.outcomes);
|
|
125
|
+
if (planned.content !== null)
|
|
126
|
+
writes.push({ path: specPath, content: planned.content });
|
|
127
|
+
}
|
|
128
|
+
// The contract axis. It needs the pin more than the requirement axes do:
|
|
129
|
+
// a requirement delta spells only the requirements it changes, while an
|
|
130
|
+
// openapi delta is a COMPLETE document and spells the whole contract.
|
|
131
|
+
const openapiPath = featureSpecPaths(feature.dir, service).openapi;
|
|
132
|
+
if (existsSync(openapiPath)) {
|
|
133
|
+
const planned = await planOpenapi(repo, service, openapiPath);
|
|
134
|
+
outcomes.push(...planned.outcomes);
|
|
135
|
+
if (planned.content !== null)
|
|
136
|
+
writes.push({ path: openapiPath, content: planned.content });
|
|
137
|
+
}
|
|
138
|
+
// The event axis, for the openapi reason: a feature's asyncapi.yaml is
|
|
139
|
+
// a complete document too, so its quotes need pins or the merge cannot
|
|
140
|
+
// tell them from edits.
|
|
141
|
+
const asyncapiPath = featureSpecPaths(feature.dir, service).asyncapi;
|
|
142
|
+
if (existsSync(asyncapiPath)) {
|
|
143
|
+
const planned = await planAsyncapi(repo, service, asyncapiPath);
|
|
144
|
+
outcomes.push(...planned.outcomes);
|
|
145
|
+
if (planned.content !== null)
|
|
146
|
+
writes.push({ path: asyncapiPath, content: planned.content });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// The business axis, after the services and in the same transaction: a
|
|
150
|
+
// feature that changes a promise and the services keeping it is ONE act,
|
|
151
|
+
// and half of it pinned is the state the journal exists to prevent.
|
|
152
|
+
for (const doc of capabilities) {
|
|
153
|
+
const planned = await planCapabilityAxis(repo, doc.id, doc.spec);
|
|
154
|
+
capabilityOutcomes.push(...planned.outcomes);
|
|
155
|
+
if (planned.content !== null)
|
|
156
|
+
writes.push({ path: doc.spec, content: planned.content });
|
|
157
|
+
}
|
|
158
|
+
// An operation or event slot the living docs do not hold reads `unresolved`
|
|
159
|
+
// above — "this feature is adding it". For one an ARCHIVED feature retired,
|
|
160
|
+
// that is the false sentence that put retired operations back: unpinned, the
|
|
161
|
+
// merge upserts it as an addition. Rebase pins nothing for it, so what it
|
|
162
|
+
// owes is the same finding the gate raises, said here before the archive
|
|
163
|
+
// refuses it, and the decision left to the human. Asked of the documents
|
|
164
|
+
// as this run leaves them (`planned`): a repin over whatever lives at an
|
|
165
|
+
// address now turns a quote the merge skipped into an edit it writes, and
|
|
166
|
+
// a revival that edit makes is this run's to report — the next validate
|
|
167
|
+
// reports it, and a dry run must say what the real one would leave.
|
|
168
|
+
const retired = retiredLookup(docsDir, repo.fleet);
|
|
169
|
+
const planned = new Map(writes.flatMap((w) => (typeof w.content === "string" ? [[w.path, w.content]] : [])));
|
|
170
|
+
for (const service of services) {
|
|
171
|
+
revived.push(...(await serviceRevivals({ docsDir, featureDir: feature.dir, service, retired, context: repo.fleet, planned })));
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
if (!(err instanceof NotUtf8DocumentError))
|
|
176
|
+
throw err;
|
|
177
|
+
// A pin is a claim about text somebody read. Over a document loam could not
|
|
178
|
+
// decode it would be a digest of mojibake with loam's name on it — the
|
|
179
|
+
// precise false claim this command exists to prevent — and the next archive
|
|
180
|
+
// would land a stale delta over living text on the strength of it. So it
|
|
181
|
+
// refuses by name and writes nothing, exactly as `loam archive` refuses a
|
|
182
|
+
// merge it could not read, under archive's code. The refusal is here, in
|
|
183
|
+
// the PLAN, so it lands before stageWrites: no file is touched, and a
|
|
184
|
+
// feature spanning four services does not get two of them pinned.
|
|
185
|
+
return fail(json, "merge-failed", `rebase ${id} failed — nothing was pinned: ${err.message}`);
|
|
186
|
+
}
|
|
187
|
+
if (!dryRun && writes.length > 0) {
|
|
188
|
+
// Staged and committed through the journaled transaction: a feature
|
|
189
|
+
// spanning four services is one act, and neither a full disk between its
|
|
190
|
+
// second and third file NOR a kill between two renames may leave two of
|
|
191
|
+
// them pinned to a reading the other two never saw — the journal makes
|
|
192
|
+
// the second case recoverable where rollback alone could not see it.
|
|
193
|
+
const staged = await stageWrites(writes);
|
|
194
|
+
const committed = await commitStaged({ root: docsDir, command: "rebase", rerun: `loam rebase ${id}`, target: id }, staged, "pinned");
|
|
195
|
+
if (!committed.ok) {
|
|
196
|
+
return fail(json, committed.code, committed.code === "merge-failed" ? `rebase ${id} failed — nothing was pinned: ${committed.message}` : committed.message);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// One line per pin, whichever corpus it came from: what to call the document,
|
|
200
|
+
// and the record itself. The two lists are reported separately in `--json`
|
|
201
|
+
// (the published `pins[]`/`services[]` keys keep meaning exactly what they
|
|
202
|
+
// meant) and together here, because a human rebasing one feature wants one
|
|
203
|
+
// list in one order.
|
|
204
|
+
const lines = [
|
|
205
|
+
...outcomes.map((o) => ({ where: `${o.service}/${o.file}`, pin: o })),
|
|
206
|
+
...capabilityOutcomes.map((o) => ({ where: `capabilities/${o.capability}/${o.file}`, pin: o })),
|
|
207
|
+
];
|
|
208
|
+
const changed = lines.filter((l) => l.pin.status === "pinned" || l.pin.status === "repinned");
|
|
209
|
+
const unresolved = lines.filter((l) => l.pin.status === "unresolved");
|
|
210
|
+
if (json) {
|
|
211
|
+
emitJson({
|
|
212
|
+
command: "rebase",
|
|
213
|
+
feature: id,
|
|
214
|
+
services,
|
|
215
|
+
dryRun,
|
|
216
|
+
pins: outcomes,
|
|
217
|
+
// Additive, and separate from `pins[]` on purpose: `PinOutcome.service`
|
|
218
|
+
// is a published field, and a capability id written into it would say
|
|
219
|
+
// something false to every consumer that already reads it.
|
|
220
|
+
capabilities: capabilities.map((c) => c.id),
|
|
221
|
+
capabilityPins: capabilityOutcomes,
|
|
222
|
+
// Additive: the `openapi.op-revived` / `asyncapi.slot-revived` findings
|
|
223
|
+
// for what this feature spells that an archived feature retired. Their
|
|
224
|
+
// `pins[]` rows still say `unresolved` — true, and published — and this
|
|
225
|
+
// key is what says those rows are not additions.
|
|
226
|
+
revived: revived.map(issueFinding),
|
|
227
|
+
written: dryRun ? [] : writes.map((w) => repoPath(docsDir, w.path)),
|
|
228
|
+
...(opts.recovered === null ? {} : { recovered: opts.recovered }),
|
|
229
|
+
});
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (lines.length === 0) {
|
|
233
|
+
console.log(`${id}: nothing to pin — a baseline only means something for a requirement, an operation, a path-level key, a component or an event slot that already exists in the living docs.`);
|
|
234
|
+
sayRevived(revived);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (opts.recovered !== null)
|
|
238
|
+
console.log(`${sayRecovered(opts.recovered)}\n`);
|
|
239
|
+
console.log(`${id}${dryRun ? " (dry run)" : ""}\n`);
|
|
240
|
+
for (const { where, pin: o } of lines) {
|
|
241
|
+
const what = `${where} ${o.kind} ${o.target}`;
|
|
242
|
+
if (o.status === "unresolved") {
|
|
243
|
+
console.log(` · ${what} — not in the living docs yet, nothing to pin`);
|
|
244
|
+
}
|
|
245
|
+
else if (o.status === "unwritable") {
|
|
246
|
+
console.log(` ! ${what} — a YAML alias (or a key loam cannot address by name); loam will not stamp through it`);
|
|
247
|
+
}
|
|
248
|
+
else if (o.status === "unchanged") {
|
|
249
|
+
console.log(` = ${what} — already ${o.to}`);
|
|
250
|
+
}
|
|
251
|
+
else if (o.status === "pinned") {
|
|
252
|
+
console.log(` + ${what} — pinned ${o.to}`);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
console.log(` ~ ${what} — ${o.from} → ${o.to}`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (changed.length === 0) {
|
|
259
|
+
console.log(`\nNothing to write: every pin already names the living version.`);
|
|
260
|
+
}
|
|
261
|
+
else if (dryRun) {
|
|
262
|
+
console.log(`\n${plural(changed.length, "pin")} would be written. Nothing was written.`);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
console.log(`\n${plural(changed.length, "pin")} written across ${plural(writes.length, "file")}.`);
|
|
266
|
+
// The one sentence that keeps this command honest. A pin is a claim about
|
|
267
|
+
// what its author read, and a `repinned` line means the living text moved
|
|
268
|
+
// under a delta that still says what it said before — restamping does not
|
|
269
|
+
// fold in the change it just stopped reporting.
|
|
270
|
+
const repinned = changed.filter((l) => l.pin.status === "repinned");
|
|
271
|
+
if (repinned.length > 0) {
|
|
272
|
+
console.log(`\n⚠ ${plural(repinned.length, "pin")} moved since this delta was written. A pin records what you read — ` +
|
|
273
|
+
`re-read those living requirements and operations and fold in what you still mean, or the next archive lands your version over theirs with loam's blessing.`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (unresolved.length > 0) {
|
|
277
|
+
console.log(`\n${plural(unresolved.length, "item")} could not be pinned because the living docs do not have them yet — ` +
|
|
278
|
+
`for a requirement, \`loam dependencies ${id}\` says which feature introduces it first; for an operation, this feature is adding it` +
|
|
279
|
+
(revived.length === 0 ? "." : ", unless an archived feature retired it or moved it away — those are listed below, and they are not new."));
|
|
280
|
+
}
|
|
281
|
+
sayRevived(revived);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* The revival findings, in the gate's own words. Printed rather than acted on:
|
|
285
|
+
* deleting a quote and re-adding a retired operation on purpose are both
|
|
286
|
+
* legitimate, and which one this is is the author's call. The sentence once
|
|
287
|
+
* said "nothing was pinned" for them — true of a retired entry, which has no
|
|
288
|
+
* living version, and false of a quote this run repinned over whatever lives
|
|
289
|
+
* at its address now, the very pin that made it a revival.
|
|
290
|
+
*/
|
|
291
|
+
function sayRevived(revived) {
|
|
292
|
+
if (revived.length === 0)
|
|
293
|
+
return;
|
|
294
|
+
const one = revived.length === 1;
|
|
295
|
+
console.log(`\n⚠ ${plural(revived.length, "item")} this feature spells ${one ? "was" : "were"} RETIRED by an archived feature, or moved to another address by one — ` +
|
|
296
|
+
`${one ? "it is" : "they are"} not new, pinned or not, and \`loam archive\` refuses ${one ? "it" : "them"} until you decide:`);
|
|
297
|
+
for (const issue of revived)
|
|
298
|
+
console.log(` ⚠ ${issue.message}`);
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=rebase.js.map
|