@ybotok/loam 0.1.0-beta.2 → 0.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2570 -61
- package/COMPARISON.md +80 -63
- package/CONTRIBUTING.md +84 -0
- package/MIGRATING-from-OpenSpec.md +213 -54
- package/QUICKSTART.md +125 -0
- package/README.md +450 -150
- package/ROADMAP.md +494 -0
- package/SCHEMA.md +2362 -245
- package/SECURITY.md +21 -3
- package/WORKFLOW.md +701 -0
- package/dist/cli.js +113 -19
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +209 -0
- package/dist/commands/adopt/adopt.js.map +1 -0
- package/dist/commands/adopt/render.js +268 -0
- package/dist/commands/adopt/render.js.map +1 -0
- package/dist/commands/archive/archive.js +77 -0
- package/dist/commands/archive/archive.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +159 -0
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +317 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +161 -0
- package/dist/commands/archive/plan/landscape.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +111 -0
- package/dist/commands/archive/plan/refusal.js.map +1 -0
- package/dist/commands/archive/plan/specs.js +237 -0
- package/dist/commands/archive/plan/specs.js.map +1 -0
- package/dist/commands/archive/plan/state.js +27 -0
- package/dist/commands/archive/plan/state.js.map +1 -0
- package/dist/commands/archive/run.js +251 -0
- package/dist/commands/archive/run.js.map +1 -0
- package/dist/commands/context/context.js +99 -0
- package/dist/commands/context/context.js.map +1 -0
- package/dist/commands/context/print.js +283 -0
- package/dist/commands/context/print.js.map +1 -0
- package/dist/commands/delta/delta.js +279 -0
- package/dist/commands/delta/delta.js.map +1 -0
- package/dist/commands/delta/print.js +205 -0
- package/dist/commands/delta/print.js.map +1 -0
- package/dist/commands/dependencies.js +9 -7
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +93 -0
- package/dist/commands/diff/diff.js.map +1 -0
- package/dist/commands/diff/print.js +38 -0
- package/dist/commands/diff/print.js.map +1 -0
- package/dist/commands/doctor.js +5 -4
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +151 -0
- package/dist/commands/explain/explain.js.map +1 -0
- package/dist/commands/explore.js +29 -24
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +115 -0
- package/dist/commands/gate/gate.js.map +1 -0
- package/dist/commands/gate/print.js +54 -0
- package/dist/commands/gate/print.js.map +1 -0
- package/dist/commands/gherkin/commit.js +146 -0
- package/dist/commands/gherkin/commit.js.map +1 -0
- package/dist/commands/gherkin/gherkin.js +246 -0
- package/dist/commands/gherkin/gherkin.js.map +1 -0
- package/dist/commands/gherkin/reconcile.js +149 -0
- package/dist/commands/gherkin/reconcile.js.map +1 -0
- package/dist/commands/gherkin/render.js +77 -0
- package/dist/commands/gherkin/render.js.map +1 -0
- package/dist/commands/init/example.js +204 -0
- package/dist/commands/init/example.js.map +1 -0
- package/dist/commands/init/first-hour.js +28 -0
- package/dist/commands/init/first-hour.js.map +1 -0
- package/dist/commands/{init.js → init/init.js} +146 -71
- package/dist/commands/init/init.js.map +1 -0
- package/dist/commands/init/mcp.js +131 -0
- package/dist/commands/init/mcp.js.map +1 -0
- package/dist/commands/init/options.js +78 -0
- package/dist/commands/init/options.js.map +1 -0
- package/dist/commands/instructions.js +82 -14
- package/dist/commands/instructions.js.map +1 -1
- package/dist/commands/list/campaign/campaign.js +65 -0
- package/dist/commands/list/campaign/campaign.js.map +1 -0
- package/dist/commands/list/campaign/owners.js +65 -0
- package/dist/commands/list/campaign/owners.js.map +1 -0
- package/dist/commands/list/json.js +157 -0
- package/dist/commands/list/json.js.map +1 -0
- package/dist/commands/list/list.js +343 -0
- package/dist/commands/list/list.js.map +1 -0
- package/dist/commands/list/print.js +301 -0
- package/dist/commands/list/print.js.map +1 -0
- package/dist/commands/list/review.js +120 -0
- package/dist/commands/list/review.js.map +1 -0
- package/dist/commands/list/views.js +105 -0
- package/dist/commands/list/views.js.map +1 -0
- package/dist/commands/mcp/dispatch.js +183 -0
- package/dist/commands/mcp/dispatch.js.map +1 -0
- package/dist/commands/mcp/mcp.js +34 -0
- package/dist/commands/mcp/mcp.js.map +1 -0
- package/dist/commands/mcp/serve.js +55 -0
- package/dist/commands/mcp/serve.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/active.js +170 -0
- package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
- package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/living.js +62 -0
- package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/stage.js +142 -0
- package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/target.js +219 -0
- package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js +91 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/error.js +19 -0
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/paths.js +43 -0
- package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/read.js +49 -0
- package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
- package/dist/commands/migrate-openspec/print.js +89 -0
- package/dist/commands/migrate-openspec/print.js.map +1 -0
- package/dist/commands/new/commit.js +76 -0
- package/dist/commands/new/commit.js.map +1 -0
- package/dist/commands/new/new.js +283 -0
- package/dist/commands/new/new.js.map +1 -0
- package/dist/commands/new/templates.js +355 -0
- package/dist/commands/new/templates.js.map +1 -0
- package/dist/commands/open.js +203 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/policy/format.js +152 -0
- package/dist/commands/policy/format.js.map +1 -0
- package/dist/commands/{docs-repo-gate.js → policy/gate.js} +11 -11
- package/dist/commands/policy/gate.js.map +1 -0
- package/dist/commands/rebase/edit.js +106 -0
- package/dist/commands/rebase/edit.js.map +1 -0
- package/dist/commands/rebase/living.js +185 -0
- package/dist/commands/rebase/living.js.map +1 -0
- package/dist/commands/rebase/plan.js +245 -0
- package/dist/commands/rebase/plan.js.map +1 -0
- package/dist/commands/rebase/rebase.js +275 -0
- package/dist/commands/rebase/rebase.js.map +1 -0
- package/dist/commands/seed/commit.js +192 -0
- package/dist/commands/seed/commit.js.map +1 -0
- package/dist/commands/seed/plan.js +133 -0
- package/dist/commands/seed/plan.js.map +1 -0
- package/dist/commands/seed/seed.js +172 -0
- package/dist/commands/seed/seed.js.map +1 -0
- package/dist/commands/show/feature.js +178 -0
- package/dist/commands/show/feature.js.map +1 -0
- package/dist/commands/show/marks.js +24 -0
- package/dist/commands/show/marks.js.map +1 -0
- package/dist/commands/{show.js → show/service.js} +63 -152
- package/dist/commands/show/service.js.map +1 -0
- package/dist/commands/show/show.js +77 -0
- package/dist/commands/show/show.js.map +1 -0
- package/dist/commands/status/json.js +45 -0
- package/dist/commands/status/json.js.map +1 -0
- package/dist/commands/status/print.js +157 -0
- package/dist/commands/status/print.js.map +1 -0
- package/dist/commands/status/status.js +119 -0
- package/dist/commands/status/status.js.map +1 -0
- package/dist/commands/steps/steps.js +189 -0
- package/dist/commands/steps/steps.js.map +1 -0
- package/dist/commands/subsystem/edit.js +192 -0
- package/dist/commands/subsystem/edit.js.map +1 -0
- package/dist/commands/subsystem/move.js +265 -0
- package/dist/commands/subsystem/move.js.map +1 -0
- package/dist/commands/subsystem/query.js +115 -0
- package/dist/commands/subsystem/query.js.map +1 -0
- package/dist/commands/subsystem/subsystem.js +101 -0
- package/dist/commands/subsystem/subsystem.js.map +1 -0
- package/dist/commands/subsystem/sync.js +103 -0
- package/dist/commands/subsystem/sync.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +94 -0
- package/dist/commands/subsystem/txn/txn.js.map +1 -0
- package/dist/commands/subsystem/txn/views.js +70 -0
- package/dist/commands/subsystem/txn/views.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +160 -0
- package/dist/commands/unarchive/manifest.js.map +1 -0
- package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
- package/dist/commands/unarchive/restore.js.map +1 -0
- package/dist/commands/unarchive/unarchive.js +67 -0
- package/dist/commands/unarchive/unarchive.js.map +1 -0
- package/dist/commands/validate/arch-coverage.js +194 -0
- package/dist/commands/validate/arch-coverage.js.map +1 -0
- package/dist/commands/validate/checks/fleet-shape.js +296 -0
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
- package/dist/commands/validate/checks/health-deps.js +55 -0
- package/dist/commands/validate/checks/health-deps.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +254 -0
- package/dist/commands/validate/checks/requirements.js.map +1 -0
- package/dist/commands/validate/checks/sources.js +76 -0
- package/dist/commands/validate/checks/sources.js.map +1 -0
- package/dist/commands/validate/checks/vocabulary.js +31 -0
- package/dist/commands/validate/checks/vocabulary.js.map +1 -0
- package/dist/commands/validate/feature.js +216 -0
- package/dist/commands/validate/feature.js.map +1 -0
- package/dist/commands/validate/fleet/census.js +69 -0
- package/dist/commands/validate/fleet/census.js.map +1 -0
- package/dist/commands/validate/fleet/kind-tags.js +39 -0
- package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
- package/dist/commands/validate/fleet/landscape.js +353 -0
- package/dist/commands/validate/fleet/landscape.js.map +1 -0
- package/dist/commands/validate/fleet/load.js +52 -0
- package/dist/commands/validate/fleet/load.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +236 -0
- package/dist/commands/validate/fleet/obligations.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/print.js +63 -0
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
- package/dist/commands/validate/fleet/usecases/capability-tag.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/place.js +13 -0
- package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/requirement-tag.js +95 -0
- package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/steps.js +197 -0
- package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
- package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +40 -0
- package/dist/commands/validate/fleet/views/ids.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +59 -0
- package/dist/commands/validate/fleet/views/stale.js.map +1 -0
- package/dist/commands/validate/links/corpus.js +92 -0
- package/dist/commands/validate/links/corpus.js.map +1 -0
- package/dist/commands/validate/links/glossary.js +75 -0
- package/dist/commands/validate/links/glossary.js.map +1 -0
- package/dist/commands/validate/report.js +269 -0
- package/dist/commands/validate/report.js.map +1 -0
- package/dist/commands/validate/service/api.js +338 -0
- package/dist/commands/validate/service/api.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +219 -0
- package/dist/commands/validate/service/events/events.js.map +1 -0
- package/dist/commands/validate/service/events/message-producers.js +77 -0
- package/dist/commands/validate/service/events/message-producers.js.map +1 -0
- package/dist/commands/validate/service/evidence-pins.js +131 -0
- package/dist/commands/validate/service/evidence-pins.js.map +1 -0
- package/dist/commands/validate/service/service.js +250 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +219 -0
- package/dist/commands/validate/service/specs.js.map +1 -0
- package/dist/commands/validate/service/spine.js +113 -0
- package/dist/commands/validate/service/spine.js.map +1 -0
- package/dist/commands/validate/validate.js +338 -0
- package/dist/commands/validate/validate.js.map +1 -0
- package/dist/commands/verify/cross/diff.js +182 -0
- package/dist/commands/verify/cross/diff.js.map +1 -0
- package/dist/commands/verify/evidence/contract.js +32 -0
- package/dist/commands/verify/evidence/contract.js.map +1 -0
- package/dist/commands/verify/evidence/pins.js +52 -0
- package/dist/commands/verify/evidence/pins.js.map +1 -0
- package/dist/commands/verify/evidence/read.js +72 -0
- package/dist/commands/verify/evidence/read.js.map +1 -0
- package/dist/commands/verify/frozen.js +241 -0
- package/dist/commands/verify/frozen.js.map +1 -0
- package/dist/commands/verify/record.js +226 -0
- package/dist/commands/verify/record.js.map +1 -0
- package/dist/commands/verify/report.js +223 -0
- package/dist/commands/verify/report.js.map +1 -0
- package/dist/commands/verify/results.js +246 -0
- package/dist/commands/verify/results.js.map +1 -0
- package/dist/commands/verify/verify.js +217 -0
- package/dist/commands/verify/verify.js.map +1 -0
- package/dist/commands/vouch/contract.js +11 -0
- package/dist/commands/vouch/contract.js.map +1 -0
- package/dist/commands/vouch/pack/contract.js +2 -0
- package/dist/commands/vouch/pack/contract.js.map +1 -0
- package/dist/commands/vouch/pack/pack.js +266 -0
- package/dist/commands/vouch/pack/pack.js.map +1 -0
- package/dist/commands/vouch/pack/print.js +271 -0
- package/dist/commands/vouch/pack/print.js.map +1 -0
- package/dist/commands/vouch/pack/sections.js +142 -0
- package/dist/commands/vouch/pack/sections.js.map +1 -0
- package/dist/commands/vouch/prompt/confirm.js +46 -0
- package/dist/commands/vouch/prompt/confirm.js.map +1 -0
- package/dist/commands/vouch/report.js +101 -0
- package/dist/commands/vouch/report.js.map +1 -0
- package/dist/commands/vouch/run.js +285 -0
- package/dist/commands/vouch/run.js.map +1 -0
- package/dist/commands/vouch/sample/plan.js +125 -0
- package/dist/commands/vouch/sample/plan.js.map +1 -0
- package/dist/commands/vouch/sample/print.js +109 -0
- package/dist/commands/vouch/sample/print.js.map +1 -0
- package/dist/commands/vouch/vet/verify.js +123 -0
- package/dist/commands/vouch/vet/verify.js.map +1 -0
- package/dist/commands/vouch/vouch.js +176 -0
- package/dist/commands/vouch/vouch.js.map +1 -0
- package/dist/core/agent/agents-md/artifacts.js +220 -0
- package/dist/core/agent/agents-md/artifacts.js.map +1 -0
- package/dist/core/agent/agents-md/command-map.js +324 -0
- package/dist/core/agent/agents-md/command-map.js.map +1 -0
- package/dist/core/agent/agents-md/cycle.js +165 -0
- package/dist/core/agent/agents-md/cycle.js.map +1 -0
- package/dist/core/agent/agents-md/map/explain.js +34 -0
- package/dist/core/agent/agents-md/map/explain.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
- package/dist/core/agent/agents-md/map/mcp.js +41 -0
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
- package/dist/core/agent/agents-md/map/status.js +62 -0
- package/dist/core/agent/agents-md/map/status.js.map +1 -0
- package/dist/core/agent/agents-md/map/subsystem.js +32 -0
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
- package/dist/core/agent/agents-md/map/usecases.js +60 -0
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
- package/dist/core/agent/agents-md/refusals.js +246 -0
- package/dist/core/agent/agents-md/refusals.js.map +1 -0
- package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
- package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
- package/dist/core/agent/agents-md/spine.js +40 -0
- package/dist/core/agent/agents-md/spine.js.map +1 -0
- package/dist/core/agent/agents-md.js +170 -0
- package/dist/core/agent/agents-md.js.map +1 -0
- package/dist/core/agent/agents-stamp.js +155 -0
- package/dist/core/agent/agents-stamp.js.map +1 -0
- package/dist/core/agent/contract.js +2 -0
- package/dist/core/agent/contract.js.map +1 -0
- package/dist/core/agent/protocol.js +193 -0
- package/dist/core/agent/protocol.js.map +1 -0
- package/dist/core/agent/scaffold.js +259 -0
- package/dist/core/agent/scaffold.js.map +1 -0
- package/dist/core/agent/support/report.js +103 -0
- package/dist/core/agent/support/report.js.map +1 -0
- package/dist/core/agent/tools/dialects.js +150 -0
- package/dist/core/agent/tools/dialects.js.map +1 -0
- package/dist/core/agent/tools/registry.js +228 -0
- package/dist/core/agent/tools/registry.js.map +1 -0
- package/dist/core/agent/workflows/adopt.js +133 -0
- package/dist/core/agent/workflows/adopt.js.map +1 -0
- package/dist/core/agent/workflows/check.js +334 -0
- package/dist/core/agent/workflows/check.js.map +1 -0
- package/dist/core/agent/workflows/closing.js +262 -0
- package/dist/core/agent/workflows/closing.js.map +1 -0
- package/dist/core/agent/workflows/feature.js +105 -0
- package/dist/core/agent/workflows/feature.js.map +1 -0
- package/dist/core/agent/workflows/implement.js +105 -0
- package/dist/core/agent/workflows/implement.js.map +1 -0
- package/dist/core/agent/workflows/reference/authoring.js +209 -0
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
- package/dist/core/agent/workflows/reference/codes.js +65 -0
- package/dist/core/agent/workflows/reference/codes.js.map +1 -0
- package/dist/core/agent/workflows/reference/done-check.js +188 -0
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +16 -0
- package/dist/core/agent/workflows/reference/reference.js.map +1 -0
- package/dist/core/agent/workflows/reference/spine.js +297 -0
- package/dist/core/agent/workflows/reference/spine.js.map +1 -0
- package/dist/core/asyncapi/baseline/plan.js +110 -0
- package/dist/core/asyncapi/baseline/plan.js.map +1 -0
- package/dist/core/asyncapi/baseline/surfaces.js +54 -0
- package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
- package/dist/core/asyncapi/depth.js +164 -0
- package/dist/core/asyncapi/depth.js.map +1 -0
- package/dist/core/asyncapi/digest.js +141 -0
- package/dist/core/asyncapi/digest.js.map +1 -0
- package/dist/core/asyncapi/merge/components.js +91 -0
- package/dist/core/asyncapi/merge/components.js.map +1 -0
- package/dist/core/asyncapi/merge/error.js +33 -0
- package/dist/core/asyncapi/merge/error.js.map +1 -0
- package/dist/core/asyncapi/merge/markers.js +308 -0
- package/dist/core/asyncapi/merge/markers.js.map +1 -0
- package/dist/core/asyncapi/merge/merge.js +215 -0
- package/dist/core/asyncapi/merge/merge.js.map +1 -0
- package/dist/core/asyncapi/merge/pin.js +107 -0
- package/dist/core/asyncapi/merge/pin.js.map +1 -0
- package/dist/core/asyncapi/model.js +11 -0
- package/dist/core/asyncapi/model.js.map +1 -0
- package/dist/core/asyncapi/producers.js +50 -0
- package/dist/core/asyncapi/producers.js.map +1 -0
- package/dist/core/asyncapi/read.js +239 -0
- package/dist/core/asyncapi/read.js.map +1 -0
- package/dist/core/brief/brief.js +225 -0
- package/dist/core/brief/brief.js.map +1 -0
- package/dist/core/brief/checks.js +250 -0
- package/dist/core/brief/checks.js.map +1 -0
- package/dist/core/brief/landscape.js +194 -0
- package/dist/core/brief/landscape.js.map +1 -0
- package/dist/core/brief/targets.js +226 -0
- package/dist/core/brief/targets.js.map +1 -0
- package/dist/core/brief/unchecked.js +47 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +282 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/likec4.js +88 -0
- package/dist/core/c4/likec4.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js +132 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
- package/dist/core/c4/parsed/specification.js +78 -0
- package/dist/core/c4/parsed/specification.js.map +1 -0
- package/dist/core/c4/parsed/values.js +57 -0
- package/dist/core/c4/parsed/values.js.map +1 -0
- package/dist/core/c4/parsed/view-ids.js +75 -0
- package/dist/core/c4/parsed/view-ids.js.map +1 -0
- package/dist/core/c4/project/architecture.js +45 -0
- package/dist/core/c4/project/architecture.js.map +1 -0
- package/dist/core/c4/project/documents.js +58 -0
- package/dist/core/c4/project/documents.js.map +1 -0
- package/dist/core/c4/project/load.js +183 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/resolve/service.js +113 -0
- package/dist/core/c4/resolve/service.js.map +1 -0
- package/dist/core/c4/seed/fleet-file.js +201 -0
- package/dist/core/c4/seed/fleet-file.js.map +1 -0
- package/dist/core/c4/seed/items.js +91 -0
- package/dist/core/c4/seed/items.js.map +1 -0
- package/dist/core/c4/seed/stamp.js +48 -0
- package/dist/core/c4/seed/stamp.js.map +1 -0
- package/dist/core/c4/seed/template.js +109 -0
- package/dist/core/c4/seed/template.js.map +1 -0
- package/dist/core/c4/source-mask.js +82 -0
- package/dist/core/c4/source-mask.js.map +1 -0
- package/dist/core/c4/source-scan.js +227 -0
- package/dist/core/c4/source-scan.js.map +1 -0
- package/dist/core/c4/splice/authored-source.js +101 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -0
- package/dist/core/c4/splice/contract.js +10 -0
- package/dist/core/c4/splice/contract.js.map +1 -0
- package/dist/core/c4/splice/delta-blocks.js +126 -0
- package/dist/core/c4/splice/delta-blocks.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +36 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +269 -0
- package/dist/core/c4/splice/landscape-merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +194 -0
- package/dist/core/c4/splice/placement.js.map +1 -0
- package/dist/core/c4/workspace.js +172 -0
- package/dist/core/c4/workspace.js.map +1 -0
- package/dist/core/capabilities/authoring/notes.js +141 -0
- package/dist/core/capabilities/authoring/notes.js.map +1 -0
- package/dist/core/capabilities/capabilities.js +124 -0
- package/dist/core/capabilities/capabilities.js.map +1 -0
- package/dist/core/capabilities/delta/doc.js +50 -0
- package/dist/core/capabilities/delta/doc.js.map +1 -0
- package/dist/core/capabilities/delta/overlay.js +129 -0
- package/dist/core/capabilities/delta/overlay.js.map +1 -0
- package/dist/core/capabilities/delta/summary.js +57 -0
- package/dist/core/capabilities/delta/summary.js.map +1 -0
- package/dist/core/capabilities/delta/tree.js +43 -0
- package/dist/core/capabilities/delta/tree.js.map +1 -0
- package/dist/core/capabilities/delta/uncovered.js +222 -0
- package/dist/core/capabilities/delta/uncovered.js.map +1 -0
- package/dist/core/capabilities/findings.js +342 -0
- package/dist/core/capabilities/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/findings.js +181 -0
- package/dist/core/capabilities/realizes/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/join.js +143 -0
- package/dist/core/capabilities/realizes/join.js.map +1 -0
- package/dist/core/capabilities/rollup.js +199 -0
- package/dist/core/capabilities/rollup.js.map +1 -0
- package/dist/core/capabilities/tree.js +126 -0
- package/dist/core/capabilities/tree.js.map +1 -0
- package/dist/core/capabilities/usecase-join.js +277 -0
- package/dist/core/capabilities/usecase-join.js.map +1 -0
- package/dist/core/coherence/authoring/scaffold.js +177 -0
- package/dist/core/coherence/authoring/scaffold.js.map +1 -0
- package/dist/core/coherence/authoring/sentinels.js +74 -0
- package/dist/core/coherence/authoring/sentinels.js.map +1 -0
- package/dist/core/coherence/coherence.js +251 -0
- package/dist/core/coherence/coherence.js.map +1 -0
- package/dist/core/coherence/declared.js +269 -0
- package/dist/core/coherence/declared.js.map +1 -0
- package/dist/core/coherence/events/declared.js +206 -0
- package/dist/core/coherence/events/declared.js.map +1 -0
- package/dist/core/coherence/events/events.js +204 -0
- package/dist/core/coherence/events/events.js.map +1 -0
- package/dist/core/coherence/events/grades.js +166 -0
- package/dist/core/coherence/events/grades.js.map +1 -0
- package/dist/core/coherence/events/lookups.js +122 -0
- package/dist/core/coherence/events/lookups.js.map +1 -0
- package/dist/core/coherence/events/merged.js +40 -0
- package/dist/core/coherence/events/merged.js.map +1 -0
- package/dist/core/coherence/living.js +198 -0
- package/dist/core/coherence/living.js.map +1 -0
- package/dist/core/coherence/lookups.js +155 -0
- package/dist/core/coherence/lookups.js.map +1 -0
- package/dist/core/coherence/pending.js +39 -0
- package/dist/core/coherence/pending.js.map +1 -0
- package/dist/core/conflict-markers.js +60 -0
- package/dist/core/conflict-markers.js.map +1 -0
- package/dist/core/delta/claims.js +73 -0
- package/dist/core/delta/claims.js.map +1 -0
- package/dist/core/delta/delta.js +296 -0
- package/dist/core/delta/delta.js.map +1 -0
- package/dist/core/delta/document.js +177 -0
- package/dist/core/delta/document.js.map +1 -0
- package/dist/core/delta/scope.js +48 -0
- package/dist/core/delta/scope.js.map +1 -0
- package/dist/core/delta/select.js +237 -0
- package/dist/core/delta/select.js.map +1 -0
- package/dist/core/dependencies/dependencies.js +141 -0
- package/dist/core/dependencies/dependencies.js.map +1 -0
- package/dist/core/dependencies/facts.js +165 -0
- package/dist/core/dependencies/facts.js.map +1 -0
- package/dist/core/dependencies/fanin.js +88 -0
- package/dist/core/dependencies/fanin.js.map +1 -0
- package/dist/core/dependencies/graph.js +106 -0
- package/dist/core/dependencies/graph.js.map +1 -0
- package/dist/core/diff/base-git.js +148 -0
- package/dist/core/diff/base-git.js.map +1 -0
- package/dist/core/diff/base-state.js +209 -0
- package/dist/core/diff/base-state.js.map +1 -0
- package/dist/core/diff/current-state.js +96 -0
- package/dist/core/diff/current-state.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +188 -0
- package/dist/core/diff/scope/changed-paths.js.map +1 -0
- package/dist/core/diff/semantic.js +243 -0
- package/dist/core/diff/semantic.js.map +1 -0
- package/dist/core/diff/victims.js +247 -0
- package/dist/core/diff/victims.js.map +1 -0
- package/dist/core/docs.js +59 -55
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +222 -0
- package/dist/core/doctor/agents.js.map +1 -0
- package/dist/core/doctor/config.js +135 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/doctor.js +275 -0
- package/dist/core/doctor/doctor.js.map +1 -0
- package/dist/core/doctor/report.js +13 -0
- package/dist/core/doctor/report.js.map +1 -0
- package/dist/core/doctor/residue.js +110 -0
- package/dist/core/doctor/residue.js.map +1 -0
- package/dist/core/document/apply.js +77 -0
- package/dist/core/document/apply.js.map +1 -0
- package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -2
- package/dist/core/document/frontmatter.js.map +1 -0
- package/dist/core/document/grammar/directives.js +143 -0
- package/dist/core/document/grammar/directives.js.map +1 -0
- package/dist/core/document/parse.js +263 -0
- package/dist/core/document/parse.js.map +1 -0
- package/dist/core/document/scenarios.js +221 -0
- package/dist/core/document/scenarios.js.map +1 -0
- package/dist/core/document/spec.js +241 -0
- package/dist/core/document/spec.js.map +1 -0
- package/dist/core/{config.js → envelope/config.js} +79 -18
- package/dist/core/envelope/config.js.map +1 -0
- package/dist/core/envelope/json.js +175 -0
- package/dist/core/envelope/json.js.map +1 -0
- package/dist/core/{version.js → envelope/version.js} +3 -3
- package/dist/core/envelope/version.js.map +1 -0
- package/dist/core/explain/families.js +175 -0
- package/dist/core/explain/families.js.map +1 -0
- package/dist/core/explain/fix-tables.js +178 -0
- package/dist/core/explain/fix-tables.js.map +1 -0
- package/dist/core/explain/lookup.js +181 -0
- package/dist/core/explain/lookup.js.map +1 -0
- package/dist/core/explain/refusals.js +49 -0
- package/dist/core/explain/refusals.js.map +1 -0
- package/dist/core/explain/terms.js +144 -0
- package/dist/core/explain/terms.js.map +1 -0
- package/dist/core/explore/describe.js +105 -0
- package/dist/core/explore/describe.js.map +1 -0
- package/dist/core/{explore.js → explore/explore.js} +50 -101
- package/dist/core/explore/explore.js.map +1 -0
- package/dist/core/fleet-context.js +132 -77
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +201 -0
- package/dist/core/gate/checks.js.map +1 -0
- package/dist/core/gate/partners.js +205 -0
- package/dist/core/gate/partners.js.map +1 -0
- package/dist/core/gate/report.js +47 -0
- package/dist/core/gate/report.js.map +1 -0
- package/dist/core/gate/verification.js +113 -0
- package/dist/core/gate/verification.js.map +1 -0
- package/dist/core/gherkin/digest.js +60 -0
- package/dist/core/gherkin/digest.js.map +1 -0
- package/dist/core/gherkin/emit.js +177 -0
- package/dist/core/gherkin/emit.js.map +1 -0
- package/dist/core/gherkin/read.js +76 -0
- package/dist/core/gherkin/read.js.map +1 -0
- package/dist/core/gherkin/stale.js +234 -0
- package/dist/core/gherkin/stale.js.map +1 -0
- package/dist/core/gherkin/stamp.js +77 -0
- package/dist/core/gherkin/stamp.js.map +1 -0
- package/dist/core/gherkin/steps/catalogue.js +154 -0
- package/dist/core/gherkin/steps/catalogue.js.map +1 -0
- package/dist/core/gherkin/steps/inventory.js +98 -0
- package/dist/core/gherkin/steps/inventory.js.map +1 -0
- package/dist/core/gherkin/steps/phrase.js +72 -0
- package/dist/core/gherkin/steps/phrase.js.map +1 -0
- package/dist/core/glossary/delta.js +106 -0
- package/dist/core/glossary/delta.js.map +1 -0
- package/dist/core/glossary/tree.js +86 -0
- package/dist/core/glossary/tree.js.map +1 -0
- package/dist/core/kernel/concurrency.js.map +1 -0
- package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
- package/dist/core/kernel/document-bytes.js.map +1 -0
- package/dist/core/kernel/fences.js +42 -0
- package/dist/core/kernel/fences.js.map +1 -0
- package/dist/core/kernel/ids/capability.js +72 -0
- package/dist/core/kernel/ids/capability.js.map +1 -0
- package/dist/core/kernel/ids/dirs.js +33 -0
- package/dist/core/kernel/ids/dirs.js.map +1 -0
- package/dist/core/kernel/ids/feature.js +75 -0
- package/dist/core/kernel/ids/feature.js.map +1 -0
- package/dist/core/kernel/ids/service.js +156 -0
- package/dist/core/kernel/ids/service.js.map +1 -0
- package/dist/core/kernel/ids/subsystem.js +63 -0
- package/dist/core/kernel/ids/subsystem.js.map +1 -0
- package/dist/core/{path-safety.js → kernel/path-safety.js} +18 -4
- package/dist/core/kernel/path-safety.js.map +1 -0
- package/dist/core/kernel/records.js.map +1 -0
- package/dist/core/links/backlinks.js +68 -0
- package/dist/core/links/backlinks.js.map +1 -0
- package/dist/core/links/case.js +74 -0
- package/dist/core/links/case.js.map +1 -0
- package/dist/core/links/corpus.js +104 -0
- package/dist/core/links/corpus.js.map +1 -0
- package/dist/core/links/findings.js +110 -0
- package/dist/core/links/findings.js.map +1 -0
- package/dist/core/links/parse.js +236 -0
- package/dist/core/links/parse.js.map +1 -0
- package/dist/core/mcp/argv.js +111 -0
- package/dist/core/mcp/argv.js.map +1 -0
- package/dist/core/mcp/author-tools.js +72 -0
- package/dist/core/mcp/author-tools.js.map +1 -0
- package/dist/core/mcp/framing.js +46 -0
- package/dist/core/mcp/framing.js.map +1 -0
- package/dist/core/mcp/protocol.js +280 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/tools.js +314 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/obligations/obligations.js +106 -0
- package/dist/core/obligations/obligations.js.map +1 -0
- package/dist/core/openapi/baseline/gate.js +166 -0
- package/dist/core/openapi/baseline/gate.js.map +1 -0
- package/dist/core/openapi/baseline/plan.js +112 -0
- package/dist/core/openapi/baseline/plan.js.map +1 -0
- package/dist/core/openapi/baseline/record.js +175 -0
- package/dist/core/openapi/baseline/record.js.map +1 -0
- package/dist/core/openapi/depth.js +122 -0
- package/dist/core/openapi/depth.js.map +1 -0
- package/dist/core/openapi/digest.js +189 -0
- package/dist/core/openapi/digest.js.map +1 -0
- package/dist/core/{openapi.js → openapi/doc.js} +44 -106
- package/dist/core/openapi/doc.js.map +1 -0
- package/dist/core/openapi/merge/components.js +234 -0
- package/dist/core/openapi/merge/components.js.map +1 -0
- package/dist/core/openapi/merge/error.js +26 -0
- package/dist/core/openapi/merge/error.js.map +1 -0
- package/dist/core/openapi/merge/markers.js +208 -0
- package/dist/core/openapi/merge/markers.js.map +1 -0
- package/dist/core/openapi/merge/merge.js +256 -0
- package/dist/core/openapi/merge/merge.js.map +1 -0
- package/dist/core/openapi/merge/pin.js +128 -0
- package/dist/core/openapi/merge/pin.js.map +1 -0
- package/dist/core/openspec/decide/capabilities.js +244 -0
- package/dist/core/openspec/decide/capabilities.js.map +1 -0
- package/dist/core/openspec/decide/dispositions.js +63 -0
- package/dist/core/openspec/decide/dispositions.js.map +1 -0
- package/dist/core/openspec/decide/renames.js +179 -0
- package/dist/core/openspec/decide/renames.js.map +1 -0
- package/dist/core/openspec/decide/verdict.js +84 -0
- package/dist/core/openspec/decide/verdict.js.map +1 -0
- package/dist/core/openspec/inventory.js +221 -0
- package/dist/core/openspec/inventory.js.map +1 -0
- package/dist/core/openspec/model/mapping.js +76 -0
- package/dist/core/openspec/model/mapping.js.map +1 -0
- package/dist/core/openspec/model/model.js +65 -0
- package/dist/core/openspec/model/model.js.map +1 -0
- package/dist/core/openspec/scan/changes.js +235 -0
- package/dist/core/openspec/scan/changes.js.map +1 -0
- package/dist/core/openspec/scan/config.js +200 -0
- package/dist/core/openspec/scan/config.js.map +1 -0
- package/dist/core/openspec/scan/shape.js +260 -0
- package/dist/core/openspec/scan/shape.js.map +1 -0
- package/dist/core/openspec/scan/walk.js +133 -0
- package/dist/core/openspec/scan/walk.js.map +1 -0
- package/dist/core/openspec/scan/workspace.js +71 -0
- package/dist/core/openspec/scan/workspace.js.map +1 -0
- package/dist/core/owners/codeowners.js +141 -0
- package/dist/core/owners/codeowners.js.map +1 -0
- package/dist/core/pack/features.js +120 -0
- package/dist/core/pack/features.js.map +1 -0
- package/dist/core/pack/joins.js +112 -0
- package/dist/core/pack/joins.js.map +1 -0
- package/dist/core/pack/living.js +118 -0
- package/dist/core/pack/living.js.map +1 -0
- package/dist/core/pack/pack.js +76 -0
- package/dist/core/pack/pack.js.map +1 -0
- package/dist/core/permissions/permissions.js +87 -0
- package/dist/core/permissions/permissions.js.map +1 -0
- package/dist/core/projection/api.js +84 -0
- package/dist/core/projection/api.js.map +1 -0
- package/dist/core/projection/arch-slice.js +63 -0
- package/dist/core/projection/arch-slice.js.map +1 -0
- package/dist/core/projection/events.js +34 -0
- package/dist/core/projection/events.js.map +1 -0
- package/dist/core/provenance/findings.js +208 -0
- package/dist/core/provenance/findings.js.map +1 -0
- package/dist/core/provenance/git.js +225 -0
- package/dist/core/provenance/git.js.map +1 -0
- package/dist/core/provenance/gitq/moves.js +182 -0
- package/dist/core/provenance/gitq/moves.js.map +1 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
- package/dist/core/provenance/sample/scope.js +238 -0
- package/dist/core/provenance/sample/scope.js.map +1 -0
- package/dist/core/provenance/sample/sections.js +61 -0
- package/dist/core/provenance/sample/sections.js.map +1 -0
- package/dist/core/provenance/sources.js +263 -0
- package/dist/core/provenance/sources.js.map +1 -0
- package/dist/core/provenance/stamp.js +232 -0
- package/dist/core/provenance/stamp.js.map +1 -0
- package/dist/core/provenance/walk.js +157 -0
- package/dist/core/provenance/walk.js.map +1 -0
- package/dist/core/repo/authored/paths.js +192 -0
- package/dist/core/repo/authored/paths.js.map +1 -0
- package/dist/core/repo/entries.js +126 -0
- package/dist/core/repo/entries.js.map +1 -0
- package/dist/core/repo/paths.js +236 -0
- package/dist/core/repo/paths.js.map +1 -0
- package/dist/core/repo/repo.js +248 -0
- package/dist/core/repo/repo.js.map +1 -0
- package/dist/core/repo/service-target.js +153 -0
- package/dist/core/repo/service-target.js.map +1 -0
- package/dist/core/repo/state.js +58 -0
- package/dist/core/repo/state.js.map +1 -0
- package/dist/core/repo/tree/find.js +52 -0
- package/dist/core/repo/tree/find.js.map +1 -0
- package/dist/core/repo/tree/fs.js +64 -0
- package/dist/core/repo/tree/fs.js.map +1 -0
- package/dist/core/repo/tree/marker.js +61 -0
- package/dist/core/repo/tree/marker.js.map +1 -0
- package/dist/core/repo/tree/views.js +172 -0
- package/dist/core/repo/tree/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +234 -0
- package/dist/core/repo/tree/walk.js.map +1 -0
- package/dist/core/results.js +99 -2
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +131 -0
- package/dist/core/scaffold/landscape.js.map +1 -0
- package/dist/core/scaffold/readme.js +84 -0
- package/dist/core/scaffold/readme.js.map +1 -0
- package/dist/core/staging/commit.js +241 -0
- package/dist/core/staging/commit.js.map +1 -0
- package/dist/core/staging/interrupted.js +96 -0
- package/dist/core/staging/interrupted.js.map +1 -0
- package/dist/core/staging/lock.js +206 -0
- package/dist/core/staging/lock.js.map +1 -0
- package/dist/core/staging/recovery/finding.js +35 -0
- package/dist/core/staging/recovery/finding.js.map +1 -0
- package/dist/core/staging/recovery/intent.js +98 -0
- package/dist/core/staging/recovery/intent.js.map +1 -0
- package/dist/core/staging/recovery/recover.js +126 -0
- package/dist/core/staging/recovery/recover.js.map +1 -0
- package/dist/core/staging/recovery/residue.js +62 -0
- package/dist/core/staging/recovery/residue.js.map +1 -0
- package/dist/core/staging/snapshot.js +202 -0
- package/dist/core/staging/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +171 -0
- package/dist/core/staging/txn/forward.js.map +1 -0
- package/dist/core/staging/txn/journal.js +139 -0
- package/dist/core/staging/txn/journal.js.map +1 -0
- package/dist/core/staging/txn/transaction.js +75 -0
- package/dist/core/staging/txn/transaction.js.map +1 -0
- package/dist/core/staging/writes.js +113 -0
- package/dist/core/staging/writes.js.map +1 -0
- package/dist/core/status/actions/execution.js +49 -0
- package/dist/core/status/actions/execution.js.map +1 -0
- package/dist/core/status/contracts.js +102 -0
- package/dist/core/status/contracts.js.map +1 -0
- package/dist/core/status/feature/artifacts.js +171 -0
- package/dist/core/status/feature/artifacts.js.map +1 -0
- package/dist/core/status/feature/feature.js +207 -0
- package/dist/core/status/feature/feature.js.map +1 -0
- package/dist/core/status/feature/next.js +150 -0
- package/dist/core/status/feature/next.js.map +1 -0
- package/dist/core/status/feature/state.js +21 -0
- package/dist/core/status/feature/state.js.map +1 -0
- package/dist/core/status/fleet/fleet.js +187 -0
- package/dist/core/status/fleet/fleet.js.map +1 -0
- package/dist/core/status/fleet/next.js +207 -0
- package/dist/core/status/fleet/next.js.map +1 -0
- package/dist/core/status/interrupted.js +97 -0
- package/dist/core/status/interrupted.js.map +1 -0
- package/dist/core/status/report.js +31 -0
- package/dist/core/status/report.js.map +1 -0
- package/dist/core/status/scan.js +41 -0
- package/dist/core/status/scan.js.map +1 -0
- package/dist/core/status/verification.js +201 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/usecases/capability.js +169 -0
- package/dist/core/usecases/capability.js.map +1 -0
- package/dist/core/usecases/delta/claims.js +116 -0
- package/dist/core/usecases/delta/claims.js.map +1 -0
- package/dist/core/usecases/delta/flows.js +103 -0
- package/dist/core/usecases/delta/flows.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +235 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -0
- package/dist/core/usecases/fleet.js +137 -0
- package/dist/core/usecases/fleet.js.map +1 -0
- package/dist/core/usecases/operations.js +111 -0
- package/dist/core/usecases/operations.js.map +1 -0
- package/dist/core/usecases/place.js +44 -0
- package/dist/core/usecases/place.js.map +1 -0
- package/dist/core/usecases/touch.js +101 -0
- package/dist/core/usecases/touch.js.map +1 -0
- package/dist/core/verify/answers.js +173 -0
- package/dist/core/verify/answers.js.map +1 -0
- package/dist/core/verify/build.js +150 -0
- package/dist/core/verify/build.js.map +1 -0
- package/dist/core/verify/checklist.js +201 -0
- package/dist/core/verify/checklist.js.map +1 -0
- package/dist/core/verify/claims/identity.js +61 -0
- package/dist/core/verify/claims/identity.js.map +1 -0
- package/dist/core/verify/cross/diff.js +97 -0
- package/dist/core/verify/cross/diff.js.map +1 -0
- package/dist/core/verify/evidence/contract.js +169 -0
- package/dist/core/verify/evidence/contract.js.map +1 -0
- package/dist/core/verify/file.js +257 -0
- package/dist/core/verify/file.js.map +1 -0
- package/dist/core/verify/pins/lint.js +157 -0
- package/dist/core/verify/pins/lint.js.map +1 -0
- package/dist/core/verify/pins/pin.js +95 -0
- package/dist/core/verify/pins/pin.js.map +1 -0
- package/dist/core/verify/record.js +142 -0
- package/dist/core/verify/record.js.map +1 -0
- package/dist/core/verify/store/commit.js +89 -0
- package/dist/core/verify/store/commit.js.map +1 -0
- package/dist/core/verify/store/render.js +57 -0
- package/dist/core/verify/store/render.js.map +1 -0
- package/dist/core/vocabulary/health.js +91 -0
- package/dist/core/vocabulary/health.js.map +1 -0
- package/dist/core/vocabulary/issue.js +55 -0
- package/dist/core/vocabulary/issue.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +145 -0
- package/dist/core/vocabulary/maturity.js.map +1 -0
- package/dist/core/{report.js → vocabulary/report.js} +30 -2
- package/dist/core/vocabulary/report.js.map +1 -0
- package/dist/core/vocabulary/steps.js +266 -0
- package/dist/core/vocabulary/steps.js.map +1 -0
- package/dist/core/workspace/discover.js +239 -0
- package/dist/core/workspace/discover.js.map +1 -0
- package/dist/core/workspace/render.js +52 -0
- package/dist/core/workspace/render.js.map +1 -0
- package/examples/README.md +189 -0
- package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
- package/examples/docs/architecture/capabilities.yaml +31 -0
- package/examples/docs/architecture/landscape.likec4 +280 -0
- package/examples/docs/architecture/obligations.yaml +23 -0
- package/examples/docs/architecture/permissions.yaml +50 -0
- package/examples/docs/architecture/subsystems.likec4 +11 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +65 -0
- package/examples/docs/capabilities/checkout/spec.md +55 -0
- package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
- package/examples/docs/capabilities/order-notifications/spec.md +43 -0
- package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
- package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
- package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +129 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +28 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
- package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
- package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +70 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
- package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
- package/examples/docs/glossary/order.md +15 -0
- package/examples/docs/glossary/payments/authorization.md +14 -0
- package/examples/docs/likec4.config.json +9 -0
- package/examples/docs/loam.json +3 -0
- package/examples/docs/services/checkout-web/model.likec4 +109 -0
- package/examples/docs/services/checkout-web/spec.md +91 -0
- package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
- package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
- package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
- package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
- package/examples/docs/services/order-service/arch.spec.md +127 -0
- package/examples/docs/services/order-service/asyncapi.yaml +108 -0
- package/examples/docs/services/order-service/health.yaml +57 -0
- package/examples/docs/services/order-service/model.likec4 +138 -0
- package/examples/docs/services/order-service/openapi.yaml +257 -0
- package/examples/docs/services/order-service/runbook.md +62 -0
- package/examples/docs/services/order-service/spec.md +134 -0
- package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
- package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
- package/examples/docs/services/payment-service/arch.spec.md +73 -0
- package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
- package/examples/docs/services/payment-service/health.yaml +39 -0
- package/examples/docs/services/payment-service/model.likec4 +67 -0
- package/examples/docs/services/payment-service/openapi.yaml +151 -0
- package/examples/docs/services/payment-service/runbook.md +37 -0
- package/examples/docs/services/payment-service/spec.md +88 -0
- package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
- package/examples/docs/services/platform/identity-service/arch.spec.md +117 -0
- package/examples/docs/services/platform/identity-service/health.yaml +70 -0
- package/examples/docs/services/platform/identity-service/model.likec4 +83 -0
- package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
- package/examples/docs/services/platform/identity-service/runbook.md +95 -0
- package/examples/docs/services/platform/identity-service/spec.md +119 -0
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +199 -0
- package/examples/docs/services/platform/notification-service/health.yaml +35 -0
- package/examples/docs/services/platform/notification-service/model.likec4 +118 -0
- package/examples/docs/services/platform/notification-service/runbook.md +48 -0
- package/examples/docs/services/platform/notification-service/spec.md +112 -0
- package/examples/docs/services/platform/subsystem.yaml +2 -0
- package/examples/fleet.yaml +57 -0
- package/package.json +19 -6
- package/dist/commands/adopt.js +0 -240
- package/dist/commands/adopt.js.map +0 -1
- package/dist/commands/archive.js +0 -1313
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/delta.js +0 -388
- package/dist/commands/delta.js.map +0 -1
- package/dist/commands/docs-repo-gate.js.map +0 -1
- package/dist/commands/format.js +0 -17
- package/dist/commands/format.js.map +0 -1
- package/dist/commands/gherkin.js +0 -309
- package/dist/commands/gherkin.js.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list.js +0 -291
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/migrate-openspec.js +0 -950
- package/dist/commands/migrate-openspec.js.map +0 -1
- package/dist/commands/new.js +0 -413
- package/dist/commands/new.js.map +0 -1
- package/dist/commands/rebase.js +0 -356
- package/dist/commands/rebase.js.map +0 -1
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/status.js +0 -254
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/unarchive.js.map +0 -1
- package/dist/commands/validate.js +0 -1591
- 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 -343
- package/dist/commands/vouch.js.map +0 -1
- package/dist/core/agent.js +0 -2065
- package/dist/core/agent.js.map +0 -1
- package/dist/core/agents-stamp.js +0 -68
- 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/brief.js +0 -733
- 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 -559
- package/dist/core/doctor.js.map +0 -1
- package/dist/core/document-bytes.js.map +0 -1
- package/dist/core/explore.js.map +0 -1
- package/dist/core/frontmatter.js.map +0 -1
- package/dist/core/gherkin.js +0 -463
- package/dist/core/gherkin.js.map +0 -1
- package/dist/core/health.js +0 -67
- package/dist/core/health.js.map +0 -1
- package/dist/core/ids.js +0 -122
- package/dist/core/ids.js.map +0 -1
- package/dist/core/issue.js +0 -9
- package/dist/core/issue.js.map +0 -1
- package/dist/core/json.js +0 -74
- package/dist/core/json.js.map +0 -1
- package/dist/core/likec4.js +0 -479
- 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 -720
- package/dist/core/provenance.js.map +0 -1
- package/dist/core/records.js.map +0 -1
- package/dist/core/repo.js +0 -436
- package/dist/core/repo.js.map +0 -1
- package/dist/core/report.js.map +0 -1
- package/dist/core/spec.js +0 -481
- 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 -1104
- package/dist/core/status.js.map +0 -1
- package/dist/core/steps.js +0 -72
- package/dist/core/steps.js.map +0 -1
- package/dist/core/verify.js +0 -807
- package/dist/core/verify.js.map +0 -1
- package/dist/core/version.js.map +0 -1
- /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
- /package/dist/core/{records.js → kernel/records.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facts.js","sourceRoot":"","sources":["../../../src/core/dependencies/facts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What one feature ADDS and what it NEEDS, read out of its own delta.\n *\n * The whole graph is built from these five lists and nothing else, which is why\n * they are computed once per feature and indexed rather than re-derived per\n * edge: a feature is a node here only because some other feature's requirement\n * or operation resolves into it, and answering that per pair would be a fleet\n * walk per pair.\n *\n * `reqKeys` returns BOTH spellings of a requirement's identity — the stable\n * `Requirement-ID` and the exact heading — because a legacy requirement has only\n * the second, and an edge that existed under one spelling and not the other\n * would make the graph depend on when the corpus was migrated.\n */\nimport { existsSync } from \"node:fs\";\nimport type { PathableService } from \"../kernel/ids/service.js\";\nimport { FleetContext } from \"../fleet-context.js\";\nimport { serviceResolver } from \"../c4/resolve/service.js\";\nimport { operations } from \"../openapi/doc.js\";\nimport { type FeatureEntry } from \"../repo/entries.js\";\nimport { SPEC_AXES, featurePaths, featureSpecPaths, type SpecAxis } from \"../repo/paths.js\";\nimport { locateServicePaths } from \"../repo/service-target.js\";\nimport { enumeratedServiceIds, enumeratedServiceIndex } from \"../repo/service-target.js\";\nimport type { Requirement } from \"../document/spec.js\";\nimport type { DocsDir } from \"../kernel/ids/dirs.js\";\n\nexport type DependencyReason =\n | {\n kind: \"requirement\";\n service: string;\n axis: SpecAxis[\"file\"];\n identity: string;\n }\n | { kind: \"operation\"; service: string; operationId: string };\n\nexport interface DependencyEdge {\n /** The feature that consumes/modifies something. */\n from: string;\n /** The feature that introduces it and therefore has to land first. */\n to: string;\n reasons: DependencyReason[];\n}\n\nexport interface FeatureConflict {\n kind: \"requirement\" | \"operation\";\n /**\n * How the owners collide.\n *\n * `added` — two features ADD the same identity (or define the same\n * operationId): whichever archives second replaces the first outright.\n *\n * `changed` — two features MODIFY or REMOVE the same living requirement.\n * That collision was invisible until now, and it is the more common one on a\n * fleet: nobody adds \"Cancel an order\" twice, but two teams editing its text\n * in the same week is a Tuesday. A MODIFIED requirement carries its FULL new\n * text, so the second archive does not merge the first one's wording — it\n * overwrites it, silently and completely.\n */\n change: \"added\" | \"changed\";\n service: string;\n axis?: SpecAxis[\"file\"];\n identity: string;\n features: string[];\n}\n\nexport interface DependencyNode {\n id: string;\n dirName: string;\n services: string[];\n dependsOn: string[];\n}\n\nexport interface DependencyGraph {\n nodes: DependencyNode[];\n edges: DependencyEdge[];\n conflicts: FeatureConflict[];\n /** Dependencies precede their consumers; cyclic members remain deterministic. */\n order: string[];\n /** Strongly connected components with more than one node (or a self-loop). */\n cycles: string[][];\n}\n\nexport interface FeatureFacts {\n feature: FeatureEntry;\n addedRequirements: Array<{\n service: string;\n axis: SpecAxis[\"file\"];\n requirement: Requirement;\n }>;\n changedRequirements: Array<{\n service: string;\n axis: SpecAxis[\"file\"];\n requirement: Requirement;\n }>;\n introducedOperations: Array<{ service: string; operationId: string }>;\n requiredOperations: Array<{ service: string; operationId: string }>;\n}\n\nexport function reqKeys(requirement: Pick<Requirement, \"id\" | \"name\">): string[] {\n return [\n ...(requirement.id === undefined ? [] : [`id:${requirement.id}`]),\n `name:${requirement.name}`,\n ];\n}\n\n/**\n * WHERE a collision happens, kept as fields rather than as a string.\n *\n * An index needs one scalar per entry to hash on, so the fields get NUL-joined\n * into a key — but the conflict records want those fields back, and splitting\n * the key apart again means asserting the pieces back into their types. That\n * assertion is a claim about data loam does not own: a service directory or a\n * requirement name containing a NUL would hand `axis` a fragment of an identity\n * with nothing to notice. Carrying the structured value beside the owner set\n * means the key is only ever a key, and the record is read, not reconstructed.\n */\nexport interface ReqAt {\n service: string;\n axis: SpecAxis[\"file\"];\n identity: string;\n}\n\nexport interface OpAt {\n service: string;\n operationId: string;\n}\n\nexport interface Owners<T> {\n readonly at: T;\n readonly features: Set<string>;\n}\n\nexport function reqIndexKey(at: ReqAt): string {\n return `${at.service}\\0${at.axis}\\0${at.identity}`;\n}\n\nexport function opIndexKey(at: OpAt): string {\n return `${at.service}\\0${at.operationId}`;\n}\n\nexport function addOwner<T>(index: Map<string, Owners<T>>, key: string, at: T, feature: string): void {\n const owners = index.get(key) ?? { at, features: new Set<string>() };\n owners.features.add(feature);\n index.set(key, owners);\n}\n\nexport async function readFacts(\n docsDir: DocsDir,\n feature: FeatureEntry,\n context: FleetContext,\n): Promise<FeatureFacts> {\n const addedRequirements: FeatureFacts[\"addedRequirements\"] = [];\n const changedRequirements: FeatureFacts[\"changedRequirements\"] = [];\n const introducedOperations: FeatureFacts[\"introducedOperations\"] = [];\n const requiredOperations: FeatureFacts[\"requiredOperations\"] = [];\n\n /**\n * The operationIds a service ALREADY has, per service.\n *\n * This is the whole difference between a dependency graph and a rumour mill.\n * A feature's `openapi.yaml` is a COMPLETE document, not a patch — authors\n * restate the living API around the slot they are changing — so every feature\n * that so much as mentions `authorizePayment` used to be recorded as\n * INTRODUCING it, and every other feature governing it as REQUIRING it. Two\n * features quoting the same living operation therefore depended on each other\n * in both directions: an invented cycle, an invented conflict, and an ordering\n * for work that had none. `loam validate`'s coherence pass already subtracts\n * the living contract this way (core/coherence/coherence.ts); this is the\n * same subtraction, so the two cannot disagree about what \"new\" means.\n *\n * Cached per service inside the call and, through the FleetContext, across\n * features: a fleet-wide graph asks about the same ten services N times.\n */\n const livingByService = new Map<string, Set<string>>();\n const living = async (service: PathableService): Promise<Set<string>> => {\n let ids = livingByService.get(service);\n if (ids === undefined) {\n ids = new Set(\n (await operations((await locateServicePaths(docsDir, service, context)).openapi, context))\n .filter((op) => !op.remove)\n .map((op) => op.id),\n );\n livingByService.set(service, ids);\n }\n return ids;\n };\n\n for (const service of feature.services) {\n const paths = featureSpecPaths(feature.dir, service);\n const livingIds = await living(service);\n for (const axis of SPEC_AXES) {\n const path = paths[axis.key];\n if (!existsSync(path)) continue;\n const requirements = await context.readRequirements(path);\n for (const requirement of requirements) {\n const fact = { service, axis: axis.file, requirement };\n if (requirement.kind === \"ADDED\") addedRequirements.push(fact);\n if (requirement.kind === \"MODIFIED\" || requirement.kind === \"REMOVED\") {\n changedRequirements.push(fact);\n }\n for (const operationId of requirement.operations) {\n // Governing an operation the service already provides is not a\n // dependency on anybody: the contract it needs is already merged.\n if (livingIds.has(operationId)) continue;\n requiredOperations.push({ service, operationId });\n }\n }\n }\n\n if (existsSync(paths.openapi)) {\n const featureOperations = await operations(paths.openapi, context);\n for (const operation of featureOperations) {\n if (livingIds.has(operation.id)) continue;\n if (operation.remove) requiredOperations.push({ service, operationId: operation.id });\n else introducedOperations.push({ service, operationId: operation.id });\n }\n }\n }\n\n // The C4 delta is the FOURTH place a feature names an operation, and it was\n // the one the graph could not see: an edge carrying `metadata { op 'x' }` is\n // a call this feature builds on `x`, which is exactly the \"must land first\"\n // relation this module exists to compute. Validate already says so — it\n // reports `c4-api.op-pending` when the op is defined by another feature in\n // flight — so the graph disagreeing with the validator about the same pair of\n // features was the graph being wrong, not quiet.\n //\n // Endpoints resolve through `serviceResolver` — the element's\n // `metadata { service }` binding, title as fallback — the same join every\n // other check uses, so renaming a box in a diagram cannot silently unhook it\n // here either.\n const deltaPath = featurePaths(feature.dir).delta;\n if (existsSync(deltaPath)) {\n const doc = await context.loadLikeC4(deltaPath);\n // A delta that does not parse proves nothing about who depends on whom.\n // `loam validate` owns that diagnosis (`delta.invalid`); inventing edges out\n // of a half-read document would be worse than the silence.\n if (doc.errors.length === 0) {\n // One resolver for the whole delta: `serviceOf` rebuilds its id map on\n // every call, and this loop asks once per edge. The enumerated fleet —\n // `services/` plus this feature's own `specs/` directories, the same\n // union `enumeratedTarget` probes below — rides into the resolver so a\n // delta that models CONTAINERS keeps its edges attached: without it, an\n // edge into `payment.api` resolves to a service called \"api\" that has\n // never existed, the op lookup misses the living contract, and the graph\n // invents a dependency (or orders two features that share nothing). An\n // unenumerable services/ falls back to the feature's own names — every\n // living probe would have found nothing there anyway.\n const fleetIds = await enumeratedServiceIds(docsDir, context);\n const svcOf = serviceResolver(doc.elements, new Set([...fleetIds, ...feature.services]));\n // The resolver answers with document text and `living` builds a path, so\n // the name crosses through the enumeration — coherence.ts grades its\n // edges through the same bridge. A name no enumeration vouches for has\n // no living contract anywhere: the op is required, exactly what the\n // probe answered for an absent service.\n const enumeratedTarget = enumeratedServiceIndex(docsDir, feature.services, context);\n for (const rel of doc.relationships) {\n if (rel.op === undefined) continue;\n const service = svcOf(rel.target);\n const pathable = await enumeratedTarget(service);\n if (pathable !== undefined && (await living(pathable)).has(rel.op)) continue;\n requiredOperations.push({ service, operationId: rel.op });\n }\n }\n }\n\n return {\n feature,\n addedRequirements,\n changedRequirements,\n introducedOperations,\n requiredOperations,\n };\n}\n"]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fleet fan-in: for each service, how many DISTINCT other known services
|
|
3
|
+
* depend on it — the blast radius behind `loam list --needs-work
|
|
4
|
+
* --review-order`. Reviewing the most-depended-on service first is the one
|
|
5
|
+
* ordering a campaign lead cannot derive by eye from the worklist.
|
|
6
|
+
*
|
|
7
|
+
* Pure derivation, derived-never-stored, in the package that already owns
|
|
8
|
+
* who-depends-on-whom: `core/dependencies/` derives the feature ordering from
|
|
9
|
+
* artifact identities, and this module derives the service-level analog. The
|
|
10
|
+
* command layer (commands/list/review.ts) gathers the inputs from reads the
|
|
11
|
+
* repository already pays for and hands them in as data, so the module itself
|
|
12
|
+
* imports nothing — no IO, no parser import, never prints. The edge slice is
|
|
13
|
+
* structural for the same reason `core/vocabulary/maturity.ts`'s EdgeSource
|
|
14
|
+
* is: `core/c4/likec4.ts`'s `Rel` satisfies it without an import edge into
|
|
15
|
+
* the parser.
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Distinct known consumers per service, as a count for every id in
|
|
19
|
+
* `req.services` (0 when nothing depends on it — a proven zero, since only
|
|
20
|
+
* positive evidence ever increments it).
|
|
21
|
+
*
|
|
22
|
+
* Three joins, unioned by DISTINCT consumer so overlapping evidence for one
|
|
23
|
+
* caller counts once:
|
|
24
|
+
* 1. a drawn edge WITHOUT `consumes` into a service — its source is a
|
|
25
|
+
* caller, whether or not the edge carries an `op` (an op edge and a plain
|
|
26
|
+
* edge are one claim of dependence each);
|
|
27
|
+
* 2. a drawn edge carrying `consumes` — the rule of
|
|
28
|
+
* commands/validate/service/events/events.ts: `consumes` binds the edge's
|
|
29
|
+
* TARGET as the consumer and its SOURCE as the producer, so an edge drawn
|
|
30
|
+
* producer→consumer is fan-in on the SOURCE. Such an edge contributes
|
|
31
|
+
* join 2 ONLY: on the event spine THE ARROW FOLLOWS THE MESSAGE (the
|
|
32
|
+
* scaffolded landscape's own doctrine, examples/docs' landscape spells
|
|
33
|
+
* it), so the arrow of a delivery edge is not a call into its target —
|
|
34
|
+
* reading it as one would rank a pure event sink above a real dependency
|
|
35
|
+
* and hand a bound broker service one phantom dependant per consumer;
|
|
36
|
+
* 3. the landscape-independent requirement join — a service consumes a
|
|
37
|
+
* message some other service declares `action: send` for.
|
|
38
|
+
* Self-dependence proves nothing, and an endpoint outside the known-service
|
|
39
|
+
* set (an actor, an `#external` system, an unresolved id) is not a fleet
|
|
40
|
+
* caller — review order ranks work the FLEET depends on.
|
|
41
|
+
*/
|
|
42
|
+
export function fleetFanIn(req) {
|
|
43
|
+
const known = new Set(req.services);
|
|
44
|
+
const consumers = new Map();
|
|
45
|
+
const depend = (producer, consumer) => {
|
|
46
|
+
if (producer === consumer)
|
|
47
|
+
return;
|
|
48
|
+
if (!known.has(producer) || !known.has(consumer))
|
|
49
|
+
return;
|
|
50
|
+
const set = consumers.get(producer) ?? new Set();
|
|
51
|
+
set.add(consumer);
|
|
52
|
+
consumers.set(producer, set);
|
|
53
|
+
};
|
|
54
|
+
if (req.landscape.parses) {
|
|
55
|
+
const { relationships, svcOf } = req.landscape;
|
|
56
|
+
for (const r of relationships) {
|
|
57
|
+
const source = svcOf(r.source);
|
|
58
|
+
const target = svcOf(r.target);
|
|
59
|
+
// The variants of the join comment above: a delivery edge (consumes)
|
|
60
|
+
// claims producer→consumer, never a call into its target.
|
|
61
|
+
if (r.consumes === undefined)
|
|
62
|
+
depend(target, source);
|
|
63
|
+
else
|
|
64
|
+
depend(source, target);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Join 3. Producer index first: message name → every service declaring it
|
|
68
|
+
// sent. A message more than one service declares lands its subscribers on
|
|
69
|
+
// every declarer — the derivation never guesses which declaration wins.
|
|
70
|
+
const producers = new Map();
|
|
71
|
+
for (const [id, slice] of req.contracts) {
|
|
72
|
+
if (!known.has(id))
|
|
73
|
+
continue;
|
|
74
|
+
for (const message of slice.sent) {
|
|
75
|
+
producers.set(message, [...(producers.get(message) ?? []), id]);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const [id, slice] of req.contracts) {
|
|
79
|
+
if (!known.has(id))
|
|
80
|
+
continue;
|
|
81
|
+
for (const message of slice.consumed) {
|
|
82
|
+
for (const producer of producers.get(message) ?? [])
|
|
83
|
+
depend(producer, id);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return new Map(req.services.map((id) => [id, consumers.get(id)?.size ?? 0]));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=fanin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fanin.js","sourceRoot":"","sources":["../../../src/core/dependencies/fanin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AA2CH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,UAAU,CAAC,GAAiB;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAC;IACjD,MAAM,MAAM,GAAG,CAAC,QAAgB,EAAE,QAAgB,EAAQ,EAAE;QAC1D,IAAI,QAAQ,KAAK,QAAQ;YAAE,OAAO;QAClC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO;QACzD,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;QACzD,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClB,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,SAAS,CAAC;QAC/C,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/B,qEAAqE;YACrE,0DAA0D;YAC1D,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;gBAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;;gBAChD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC9C,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAS;QAC7B,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACjC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IACD,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAS;QAC7B,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACrC,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE;gBAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC","sourcesContent":["/**\n * Fleet fan-in: for each service, how many DISTINCT other known services\n * depend on it — the blast radius behind `loam list --needs-work\n * --review-order`. Reviewing the most-depended-on service first is the one\n * ordering a campaign lead cannot derive by eye from the worklist.\n *\n * Pure derivation, derived-never-stored, in the package that already owns\n * who-depends-on-whom: `core/dependencies/` derives the feature ordering from\n * artifact identities, and this module derives the service-level analog. The\n * command layer (commands/list/review.ts) gathers the inputs from reads the\n * repository already pays for and hands them in as data, so the module itself\n * imports nothing — no IO, no parser import, never prints. The edge slice is\n * structural for the same reason `core/vocabulary/maturity.ts`'s EdgeSource\n * is: `core/c4/likec4.ts`'s `Rel` satisfies it without an import edge into\n * the parser.\n */\n\n/** The slice of a drawn relationship the joins read. */\nexport interface FanInEdge {\n source: string;\n target: string;\n /** AsyncAPI message this edge CONSUMES — binds the TARGET as the consumer. */\n consumes?: string;\n}\n\n/** One service's contract slice: what it declares it sends, and what its living requirements consume. */\nexport interface FanInContracts {\n /** Message names this service's asyncapi.yaml reaches from an `action: send` operation. */\n sent: readonly string[];\n /** Message names the service's living (non-REMOVED) spec/arch requirements carry on `Consumes:` lines. */\n consumed: readonly string[];\n}\n\n/**\n * The fleet map's contribution, as a variant rather than optional fields: a\n * landscape either parses — and then it has relationships and a resolver — or\n * it proves nothing, and there is no half-state in which `parses: false`\n * arrives carrying edges anyway. Positive evidence only, the rule\n * `landscapeEvidence` (core/vocabulary/maturity.ts) spells for the same map:\n * an absent or unparseable landscape contributes NOTHING to the edge joins,\n * while the requirement join below still counts.\n */\nexport type FanInLandscape =\n | {\n parses: true;\n relationships: readonly FanInEdge[];\n /** The shared container-aware resolver (`core/c4/resolve/service.ts` serviceResolver), widened to plain strings. */\n svcOf: (id: string) => string;\n }\n | { parses: false };\n\nexport interface FanInRequest {\n /** Every known service id — the universe both ends of every join are filtered to. */\n services: readonly string[];\n landscape: FanInLandscape;\n contracts: ReadonlyMap<string, FanInContracts>;\n}\n\n/**\n * Distinct known consumers per service, as a count for every id in\n * `req.services` (0 when nothing depends on it — a proven zero, since only\n * positive evidence ever increments it).\n *\n * Three joins, unioned by DISTINCT consumer so overlapping evidence for one\n * caller counts once:\n * 1. a drawn edge WITHOUT `consumes` into a service — its source is a\n * caller, whether or not the edge carries an `op` (an op edge and a plain\n * edge are one claim of dependence each);\n * 2. a drawn edge carrying `consumes` — the rule of\n * commands/validate/service/events/events.ts: `consumes` binds the edge's\n * TARGET as the consumer and its SOURCE as the producer, so an edge drawn\n * producer→consumer is fan-in on the SOURCE. Such an edge contributes\n * join 2 ONLY: on the event spine THE ARROW FOLLOWS THE MESSAGE (the\n * scaffolded landscape's own doctrine, examples/docs' landscape spells\n * it), so the arrow of a delivery edge is not a call into its target —\n * reading it as one would rank a pure event sink above a real dependency\n * and hand a bound broker service one phantom dependant per consumer;\n * 3. the landscape-independent requirement join — a service consumes a\n * message some other service declares `action: send` for.\n * Self-dependence proves nothing, and an endpoint outside the known-service\n * set (an actor, an `#external` system, an unresolved id) is not a fleet\n * caller — review order ranks work the FLEET depends on.\n */\nexport function fleetFanIn(req: FanInRequest): Map<string, number> {\n const known = new Set(req.services);\n const consumers = new Map<string, Set<string>>();\n const depend = (producer: string, consumer: string): void => {\n if (producer === consumer) return;\n if (!known.has(producer) || !known.has(consumer)) return;\n const set = consumers.get(producer) ?? new Set<string>();\n set.add(consumer);\n consumers.set(producer, set);\n };\n\n if (req.landscape.parses) {\n const { relationships, svcOf } = req.landscape;\n for (const r of relationships) {\n const source = svcOf(r.source);\n const target = svcOf(r.target);\n // The variants of the join comment above: a delivery edge (consumes)\n // claims producer→consumer, never a call into its target.\n if (r.consumes === undefined) depend(target, source);\n else depend(source, target);\n }\n }\n\n // Join 3. Producer index first: message name → every service declaring it\n // sent. A message more than one service declares lands its subscribers on\n // every declarer — the derivation never guesses which declaration wins.\n const producers = new Map<string, string[]>();\n for (const [id, slice] of req.contracts) {\n if (!known.has(id)) continue;\n for (const message of slice.sent) {\n producers.set(message, [...(producers.get(message) ?? []), id]);\n }\n }\n for (const [id, slice] of req.contracts) {\n if (!known.has(id)) continue;\n for (const message of slice.consumed) {\n for (const producer of producers.get(message) ?? []) depend(producer, id);\n }\n }\n\n return new Map(req.services.map((id) => [id, consumers.get(id)?.size ?? 0]));\n}\n"]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The graph arithmetic: which edges exist, which of them form a cycle, and what
|
|
3
|
+
* order the features can be archived in.
|
|
4
|
+
*
|
|
5
|
+
* Kept apart from `./facts.ts` because it knows nothing about requirements or
|
|
6
|
+
* operations — it takes ids and edges. That is what makes the cycle detection
|
|
7
|
+
* and the ordering testable against a graph nobody had to build a fleet for,
|
|
8
|
+
* and it is why `compareIds` sorts every adjacency list: the answer has to be
|
|
9
|
+
* the same on two machines that enumerated the docs tree in different orders.
|
|
10
|
+
*/
|
|
11
|
+
import { compareIds } from "../repo/entries.js";
|
|
12
|
+
import {} from "./facts.js";
|
|
13
|
+
export function compareReasons(a, b) {
|
|
14
|
+
const ak = a.kind === "requirement"
|
|
15
|
+
? `${a.kind}\0${a.service}\0${a.axis}\0${a.identity}`
|
|
16
|
+
: `${a.kind}\0${a.service}\0${a.operationId}`;
|
|
17
|
+
const bk = b.kind === "requirement"
|
|
18
|
+
? `${b.kind}\0${b.service}\0${b.axis}\0${b.identity}`
|
|
19
|
+
: `${b.kind}\0${b.service}\0${b.operationId}`;
|
|
20
|
+
return compareIds(ak, bk);
|
|
21
|
+
}
|
|
22
|
+
export function edgeKey(from, to) {
|
|
23
|
+
return `${from}\0${to}`;
|
|
24
|
+
}
|
|
25
|
+
export function appendReason(edges, from, to, reason) {
|
|
26
|
+
if (from === to)
|
|
27
|
+
return;
|
|
28
|
+
const key = edgeKey(from, to);
|
|
29
|
+
const edge = edges.get(key) ?? { from, to, reasons: [] };
|
|
30
|
+
const encoded = JSON.stringify(reason);
|
|
31
|
+
if (!edge.reasons.some((item) => JSON.stringify(item) === encoded))
|
|
32
|
+
edge.reasons.push(reason);
|
|
33
|
+
edges.set(key, edge);
|
|
34
|
+
}
|
|
35
|
+
export function stronglyConnected(ids, edges) {
|
|
36
|
+
const adjacency = new Map(ids.map((id) => [id, []]));
|
|
37
|
+
for (const edge of edges)
|
|
38
|
+
adjacency.get(edge.from)?.push(edge.to);
|
|
39
|
+
for (const targets of adjacency.values())
|
|
40
|
+
targets.sort(compareIds);
|
|
41
|
+
let nextIndex = 0;
|
|
42
|
+
const indices = new Map();
|
|
43
|
+
const low = new Map();
|
|
44
|
+
const stack = [];
|
|
45
|
+
const onStack = new Set();
|
|
46
|
+
const components = [];
|
|
47
|
+
const visit = (id) => {
|
|
48
|
+
indices.set(id, nextIndex);
|
|
49
|
+
low.set(id, nextIndex);
|
|
50
|
+
nextIndex += 1;
|
|
51
|
+
stack.push(id);
|
|
52
|
+
onStack.add(id);
|
|
53
|
+
for (const target of adjacency.get(id) ?? []) {
|
|
54
|
+
if (!indices.has(target)) {
|
|
55
|
+
visit(target);
|
|
56
|
+
low.set(id, Math.min(low.get(id), low.get(target)));
|
|
57
|
+
}
|
|
58
|
+
else if (onStack.has(target)) {
|
|
59
|
+
low.set(id, Math.min(low.get(id), indices.get(target)));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (low.get(id) !== indices.get(id))
|
|
63
|
+
return;
|
|
64
|
+
const component = [];
|
|
65
|
+
while (stack.length > 0) {
|
|
66
|
+
const member = stack.pop();
|
|
67
|
+
onStack.delete(member);
|
|
68
|
+
component.push(member);
|
|
69
|
+
if (member === id)
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
component.sort(compareIds);
|
|
73
|
+
const selfLoop = component.length === 1
|
|
74
|
+
&& (adjacency.get(component[0]) ?? []).includes(component[0]);
|
|
75
|
+
if (component.length > 1 || selfLoop)
|
|
76
|
+
components.push(component);
|
|
77
|
+
};
|
|
78
|
+
for (const id of [...ids].sort(compareIds))
|
|
79
|
+
if (!indices.has(id))
|
|
80
|
+
visit(id);
|
|
81
|
+
return components.sort((a, b) => compareIds(a[0], b[0]));
|
|
82
|
+
}
|
|
83
|
+
export function dependencyFirstOrder(ids, edges) {
|
|
84
|
+
const deps = new Map(ids.map((id) => [id, []]));
|
|
85
|
+
for (const edge of edges)
|
|
86
|
+
deps.get(edge.from)?.push(edge.to);
|
|
87
|
+
for (const values of deps.values())
|
|
88
|
+
values.sort(compareIds);
|
|
89
|
+
const visited = new Set();
|
|
90
|
+
const visiting = new Set();
|
|
91
|
+
const order = [];
|
|
92
|
+
const visit = (id) => {
|
|
93
|
+
if (visited.has(id) || visiting.has(id))
|
|
94
|
+
return;
|
|
95
|
+
visiting.add(id);
|
|
96
|
+
for (const dependency of deps.get(id) ?? [])
|
|
97
|
+
visit(dependency);
|
|
98
|
+
visiting.delete(id);
|
|
99
|
+
visited.add(id);
|
|
100
|
+
order.push(id);
|
|
101
|
+
};
|
|
102
|
+
for (const id of [...ids].sort(compareIds))
|
|
103
|
+
visit(id);
|
|
104
|
+
return order;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/core/dependencies/graph.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The graph arithmetic: which edges exist, which of them form a cycle, and what\n * order the features can be archived in.\n *\n * Kept apart from `./facts.ts` because it knows nothing about requirements or\n * operations — it takes ids and edges. That is what makes the cycle detection\n * and the ordering testable against a graph nobody had to build a fleet for,\n * and it is why `compareIds` sorts every adjacency list: the answer has to be\n * the same on two machines that enumerated the docs tree in different orders.\n */\nimport { compareIds } from \"../repo/entries.js\";\nimport { type DependencyEdge, type DependencyReason } from \"./facts.js\";\n\nexport function compareReasons(a: DependencyReason, b: DependencyReason): number {\n const ak = a.kind === \"requirement\"\n ? `${a.kind}\\0${a.service}\\0${a.axis}\\0${a.identity}`\n : `${a.kind}\\0${a.service}\\0${a.operationId}`;\n const bk = b.kind === \"requirement\"\n ? `${b.kind}\\0${b.service}\\0${b.axis}\\0${b.identity}`\n : `${b.kind}\\0${b.service}\\0${b.operationId}`;\n return compareIds(ak, bk);\n}\n\nexport function edgeKey(from: string, to: string): string {\n return `${from}\\0${to}`;\n}\n\nexport function appendReason(\n edges: Map<string, DependencyEdge>,\n from: string,\n to: string,\n reason: DependencyReason,\n): void {\n if (from === to) return;\n const key = edgeKey(from, to);\n const edge = edges.get(key) ?? { from, to, reasons: [] };\n const encoded = JSON.stringify(reason);\n if (!edge.reasons.some((item) => JSON.stringify(item) === encoded)) edge.reasons.push(reason);\n edges.set(key, edge);\n}\n\nexport function stronglyConnected(ids: string[], edges: DependencyEdge[]): string[][] {\n const adjacency = new Map(ids.map((id) => [id, [] as string[]]));\n for (const edge of edges) adjacency.get(edge.from)?.push(edge.to);\n for (const targets of adjacency.values()) targets.sort(compareIds);\n\n let nextIndex = 0;\n const indices = new Map<string, number>();\n const low = new Map<string, number>();\n const stack: string[] = [];\n const onStack = new Set<string>();\n const components: string[][] = [];\n\n const visit = (id: string): void => {\n indices.set(id, nextIndex);\n low.set(id, nextIndex);\n nextIndex += 1;\n stack.push(id);\n onStack.add(id);\n\n for (const target of adjacency.get(id) ?? []) {\n if (!indices.has(target)) {\n visit(target);\n low.set(id, Math.min(low.get(id)!, low.get(target)!));\n } else if (onStack.has(target)) {\n low.set(id, Math.min(low.get(id)!, indices.get(target)!));\n }\n }\n if (low.get(id) !== indices.get(id)) return;\n const component: string[] = [];\n while (stack.length > 0) {\n const member = stack.pop()!;\n onStack.delete(member);\n component.push(member);\n if (member === id) break;\n }\n component.sort(compareIds);\n const selfLoop = component.length === 1\n && (adjacency.get(component[0]!) ?? []).includes(component[0]!);\n if (component.length > 1 || selfLoop) components.push(component);\n };\n\n for (const id of [...ids].sort(compareIds)) if (!indices.has(id)) visit(id);\n return components.sort((a, b) => compareIds(a[0]!, b[0]!));\n}\n\nexport function dependencyFirstOrder(ids: string[], edges: DependencyEdge[]): string[] {\n const deps = new Map(ids.map((id) => [id, [] as string[]]));\n for (const edge of edges) deps.get(edge.from)?.push(edge.to);\n for (const values of deps.values()) values.sort(compareIds);\n const visited = new Set<string>();\n const visiting = new Set<string>();\n const order: string[] = [];\n const visit = (id: string): void => {\n if (visited.has(id) || visiting.has(id)) return;\n visiting.add(id);\n for (const dependency of deps.get(id) ?? []) visit(dependency);\n visiting.delete(id);\n visited.add(id);\n order.push(id);\n };\n for (const id of [...ids].sort(compareIds)) visit(id);\n return order;\n}\n"]}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git-at-a-ref reader for the DOCS repo — the base side of `loam diff`.
|
|
3
|
+
*
|
|
4
|
+
* Three questions, all read-only: does this docs directory sit in a git
|
|
5
|
+
* repository and where (`resolveBase`), what did `services/` hold at the base
|
|
6
|
+
* commit (`listBaseTree`), and what were one file's bytes there
|
|
7
|
+
* (`showBaseFile`). No checkout, no temp writes — the base state is read
|
|
8
|
+
* straight out of the object store with `rev-parse`/`ls-tree`/`show`.
|
|
9
|
+
*
|
|
10
|
+
* The doctrine here is deliberately NOT provenance's. `../provenance/git.ts`
|
|
11
|
+
* answers every git decline with "git will not say" — null, no finding —
|
|
12
|
+
* because provenance has no denominator without git and nothing to report.
|
|
13
|
+
* Diff is the opposite case: without the base there is no honest diff at all,
|
|
14
|
+
* and a silently empty base would report the whole fleet as ADDED — the exact
|
|
15
|
+
* "green over zero services" failure `docsRepoReady` exists to prevent, one
|
|
16
|
+
* step later. So every decline travels as a typed outcome the command REFUSES
|
|
17
|
+
* on, carrying git's own words (bounded) so the refusal can say why.
|
|
18
|
+
*
|
|
19
|
+
* What is shared with provenance is the mechanics: the one timeout and the
|
|
20
|
+
* capped stdout reader, so rule 20 (every child spawn bounded) holds by
|
|
21
|
+
* construction.
|
|
22
|
+
*/
|
|
23
|
+
import { spawn } from "node:child_process";
|
|
24
|
+
import { collectStderr, declineDetail, GIT_TIMEOUT_MS, gitSaid, gitText } from "../provenance/git.js";
|
|
25
|
+
/**
|
|
26
|
+
* How many bytes one base file may be — the same generosity as
|
|
27
|
+
* `../provenance/git.ts`'s stdout cap, restated here because that constant is
|
|
28
|
+
* private to its module and this one collects BYTES, not text (a base
|
|
29
|
+
* contract's UTF-8-ness is a fact to grade, and `setEncoding("utf8")` would
|
|
30
|
+
* substitute U+FFFD before anyone could check). Past the cap the child is
|
|
31
|
+
* killed and the file reads as unreadable for its subject, never truncated.
|
|
32
|
+
*
|
|
33
|
+
* The question-asking mechanics — `gitText`, `GitAnswer`, `gitSaid`,
|
|
34
|
+
* `declineDetail`, `collectStderr` — are the shared set exported beside
|
|
35
|
+
* `collectStdout`: `../provenance/gitq/vouched-ancestor.ts` asks with the
|
|
36
|
+
* same shapes and the opposite consequence (it degrades to "full read" where
|
|
37
|
+
* this module's callers REFUSE), and the helpers stay verdict-free so the two
|
|
38
|
+
* doctrines cannot bleed into each other through a shared line.
|
|
39
|
+
*/
|
|
40
|
+
const MAX_BASE_FILE_BYTES = 64 * 1024 * 1024;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the base: is `docsDir` inside a git work tree, where does it sit in
|
|
43
|
+
* that repository, and which commit does `ref` name?
|
|
44
|
+
*
|
|
45
|
+
* `--show-prefix` is asked FIRST and is not decoration: a docs repo checked
|
|
46
|
+
* out as a subdirectory of a larger repository (a monorepo's `docs/`) answers
|
|
47
|
+
* every later `ls-tree`/`show` only under that prefix. Dropping it makes every
|
|
48
|
+
* path miss, and a diff whose base paths all miss reports the whole fleet as
|
|
49
|
+
* added — silently, in exactly the repositories big enough to care.
|
|
50
|
+
*/
|
|
51
|
+
export async function resolveBase(docsDir, ref) {
|
|
52
|
+
const where = await gitText(docsDir, ["rev-parse", "--show-prefix"]);
|
|
53
|
+
if (where.spawnError !== undefined || where.code !== 0) {
|
|
54
|
+
return { kind: "no-git", detail: declineDetail(where) };
|
|
55
|
+
}
|
|
56
|
+
// A ref spelled like an option would be parsed as one by git, not resolved
|
|
57
|
+
// as a revision — refuse it before it reaches an argv. Same reason the MCP
|
|
58
|
+
// argv boundary refuses '-'-prefixed strings.
|
|
59
|
+
const spelled = ref.trim();
|
|
60
|
+
if (spelled === "" || spelled.startsWith("-")) {
|
|
61
|
+
return { kind: "no-ref", detail: "a ref must be a revision name, not empty and not option-shaped." };
|
|
62
|
+
}
|
|
63
|
+
// `^{commit}` peels an annotated tag to the commit it tags, and refuses a
|
|
64
|
+
// ref that names any other object kind — a tree or blob sha is not a base
|
|
65
|
+
// state to diff against.
|
|
66
|
+
const verified = await gitText(docsDir, ["rev-parse", "--verify", `${spelled}^{commit}`]);
|
|
67
|
+
const commit = verified.out.trim();
|
|
68
|
+
if (verified.code !== 0 || !/^[0-9a-f]{40}$/.test(commit)) {
|
|
69
|
+
const said = gitSaid(verified);
|
|
70
|
+
return { kind: "no-ref", detail: said === "" ? "" : `git said: ${said}` };
|
|
71
|
+
}
|
|
72
|
+
return { kind: "ok", commit, prefix: where.out.trim() };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Every file path under `services/` at the base commit, DOCS-RELATIVE
|
|
76
|
+
* (`services/...`, prefix already stripped). `--full-tree` anchors both the
|
|
77
|
+
* pathspec and the output at the repository root regardless of cwd, so the
|
|
78
|
+
* one prefix from `resolveBase` is the whole story; `-z` because git quotes
|
|
79
|
+
* non-ASCII paths in line output. An empty answer is git ANSWERING — the base
|
|
80
|
+
* commit simply has no `services/` — and only a non-zero exit is a failure.
|
|
81
|
+
*/
|
|
82
|
+
export async function listBaseTree(base) {
|
|
83
|
+
const answer = await gitText(base.docsDir, [
|
|
84
|
+
"ls-tree", "-r", "-z", "--name-only", "--full-tree", base.commit, "--", `${base.prefix}services`,
|
|
85
|
+
]);
|
|
86
|
+
if (answer.spawnError !== undefined || answer.code !== 0 || answer.overflowed) {
|
|
87
|
+
return {
|
|
88
|
+
kind: "failed",
|
|
89
|
+
detail: answer.overflowed
|
|
90
|
+
? "the base tree listing exceeded the output cap."
|
|
91
|
+
: declineDetail(answer),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
kind: "ok",
|
|
96
|
+
paths: answer.out
|
|
97
|
+
.split("\0")
|
|
98
|
+
.filter((p) => p.startsWith(base.prefix) && p !== "")
|
|
99
|
+
.map((p) => p.slice(base.prefix.length)),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* One base file's bytes, by docs-relative path. Callers only ask for paths
|
|
104
|
+
* `listBaseTree` returned, so there is no "absent" arm: a decline here is
|
|
105
|
+
* abnormal and travels as `failed` for per-subject containment — that one
|
|
106
|
+
* subject degrades with the detail, never the whole diff.
|
|
107
|
+
*/
|
|
108
|
+
export async function showBaseFile(base, rel) {
|
|
109
|
+
return new Promise((done) => {
|
|
110
|
+
const child = spawn("git", ["show", `${base.commit}:${base.prefix}${rel}`], {
|
|
111
|
+
cwd: base.docsDir,
|
|
112
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
113
|
+
timeout: GIT_TIMEOUT_MS,
|
|
114
|
+
});
|
|
115
|
+
// Bytes, not text: `collectStdout` decodes as UTF-8, and a base contract
|
|
116
|
+
// whose bytes are NOT UTF-8 must arrive intact so base-state can grade it
|
|
117
|
+
// unreadable instead of parsing a document nobody wrote.
|
|
118
|
+
const chunks = [];
|
|
119
|
+
let held = 0;
|
|
120
|
+
let overflowed = false;
|
|
121
|
+
child.stdout.on("data", (chunk) => {
|
|
122
|
+
if (overflowed)
|
|
123
|
+
return;
|
|
124
|
+
if (held + chunk.length > MAX_BASE_FILE_BYTES) {
|
|
125
|
+
overflowed = true;
|
|
126
|
+
child.kill();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
chunks.push(chunk);
|
|
130
|
+
held += chunk.length;
|
|
131
|
+
});
|
|
132
|
+
const err = collectStderr(child);
|
|
133
|
+
child.on("error", (e) => done({ kind: "failed", detail: `git could not be started: ${e.message}.` }));
|
|
134
|
+
child.on("close", (code) => {
|
|
135
|
+
if (code !== 0 || overflowed) {
|
|
136
|
+
done({
|
|
137
|
+
kind: "failed",
|
|
138
|
+
detail: overflowed
|
|
139
|
+
? "the file exceeds the base-read byte cap."
|
|
140
|
+
: declineDetail({ code, out: "", err: err(), overflowed }),
|
|
141
|
+
});
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
done({ kind: "ok", bytes: Buffer.concat(chunks) });
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=base-git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-git.js","sourceRoot":"","sources":["../../../src/core/diff/base-git.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Git-at-a-ref reader for the DOCS repo — the base side of `loam diff`.\n *\n * Three questions, all read-only: does this docs directory sit in a git\n * repository and where (`resolveBase`), what did `services/` hold at the base\n * commit (`listBaseTree`), and what were one file's bytes there\n * (`showBaseFile`). No checkout, no temp writes — the base state is read\n * straight out of the object store with `rev-parse`/`ls-tree`/`show`.\n *\n * The doctrine here is deliberately NOT provenance's. `../provenance/git.ts`\n * answers every git decline with \"git will not say\" — null, no finding —\n * because provenance has no denominator without git and nothing to report.\n * Diff is the opposite case: without the base there is no honest diff at all,\n * and a silently empty base would report the whole fleet as ADDED — the exact\n * \"green over zero services\" failure `docsRepoReady` exists to prevent, one\n * step later. So every decline travels as a typed outcome the command REFUSES\n * on, carrying git's own words (bounded) so the refusal can say why.\n *\n * What is shared with provenance is the mechanics: the one timeout and the\n * capped stdout reader, so rule 20 (every child spawn bounded) holds by\n * construction.\n */\nimport { spawn } from \"node:child_process\";\nimport { collectStderr, declineDetail, GIT_TIMEOUT_MS, gitSaid, gitText } from \"../provenance/git.js\";\nimport type { DocsDir } from \"../kernel/ids/dirs.js\";\n\n/**\n * How many bytes one base file may be — the same generosity as\n * `../provenance/git.ts`'s stdout cap, restated here because that constant is\n * private to its module and this one collects BYTES, not text (a base\n * contract's UTF-8-ness is a fact to grade, and `setEncoding(\"utf8\")` would\n * substitute U+FFFD before anyone could check). Past the cap the child is\n * killed and the file reads as unreadable for its subject, never truncated.\n *\n * The question-asking mechanics — `gitText`, `GitAnswer`, `gitSaid`,\n * `declineDetail`, `collectStderr` — are the shared set exported beside\n * `collectStdout`: `../provenance/gitq/vouched-ancestor.ts` asks with the\n * same shapes and the opposite consequence (it degrades to \"full read\" where\n * this module's callers REFUSE), and the helpers stay verdict-free so the two\n * doctrines cannot bleed into each other through a shared line.\n */\nconst MAX_BASE_FILE_BYTES = 64 * 1024 * 1024;\n\nexport type BaseResolution =\n | { kind: \"no-git\"; detail: string }\n | { kind: \"no-ref\"; detail: string }\n | { kind: \"ok\"; commit: string; prefix: string };\n\n/**\n * Resolve the base: is `docsDir` inside a git work tree, where does it sit in\n * that repository, and which commit does `ref` name?\n *\n * `--show-prefix` is asked FIRST and is not decoration: a docs repo checked\n * out as a subdirectory of a larger repository (a monorepo's `docs/`) answers\n * every later `ls-tree`/`show` only under that prefix. Dropping it makes every\n * path miss, and a diff whose base paths all miss reports the whole fleet as\n * added — silently, in exactly the repositories big enough to care.\n */\nexport async function resolveBase(docsDir: DocsDir, ref: string): Promise<BaseResolution> {\n const where = await gitText(docsDir, [\"rev-parse\", \"--show-prefix\"]);\n if (where.spawnError !== undefined || where.code !== 0) {\n return { kind: \"no-git\", detail: declineDetail(where) };\n }\n // A ref spelled like an option would be parsed as one by git, not resolved\n // as a revision — refuse it before it reaches an argv. Same reason the MCP\n // argv boundary refuses '-'-prefixed strings.\n const spelled = ref.trim();\n if (spelled === \"\" || spelled.startsWith(\"-\")) {\n return { kind: \"no-ref\", detail: \"a ref must be a revision name, not empty and not option-shaped.\" };\n }\n // `^{commit}` peels an annotated tag to the commit it tags, and refuses a\n // ref that names any other object kind — a tree or blob sha is not a base\n // state to diff against.\n const verified = await gitText(docsDir, [\"rev-parse\", \"--verify\", `${spelled}^{commit}`]);\n const commit = verified.out.trim();\n if (verified.code !== 0 || !/^[0-9a-f]{40}$/.test(commit)) {\n const said = gitSaid(verified);\n return { kind: \"no-ref\", detail: said === \"\" ? \"\" : `git said: ${said}` };\n }\n return { kind: \"ok\", commit, prefix: where.out.trim() };\n}\n\n/** The resolved base every later question is asked against. */\nexport interface ResolvedBase {\n docsDir: DocsDir;\n commit: string;\n /** The docs repo's path inside its repository, `\"\"` or `\"docs/\"`-shaped — `rev-parse --show-prefix`'s answer. */\n prefix: string;\n}\n\nexport type BaseTreeListing =\n | { kind: \"ok\"; paths: string[] }\n | { kind: \"failed\"; detail: string };\n\n/**\n * Every file path under `services/` at the base commit, DOCS-RELATIVE\n * (`services/...`, prefix already stripped). `--full-tree` anchors both the\n * pathspec and the output at the repository root regardless of cwd, so the\n * one prefix from `resolveBase` is the whole story; `-z` because git quotes\n * non-ASCII paths in line output. An empty answer is git ANSWERING — the base\n * commit simply has no `services/` — and only a non-zero exit is a failure.\n */\nexport async function listBaseTree(base: ResolvedBase): Promise<BaseTreeListing> {\n const answer = await gitText(base.docsDir, [\n \"ls-tree\", \"-r\", \"-z\", \"--name-only\", \"--full-tree\", base.commit, \"--\", `${base.prefix}services`,\n ]);\n if (answer.spawnError !== undefined || answer.code !== 0 || answer.overflowed) {\n return {\n kind: \"failed\",\n detail: answer.overflowed\n ? \"the base tree listing exceeded the output cap.\"\n : declineDetail(answer),\n };\n }\n return {\n kind: \"ok\",\n paths: answer.out\n .split(\"\\0\")\n .filter((p) => p.startsWith(base.prefix) && p !== \"\")\n .map((p) => p.slice(base.prefix.length)),\n };\n}\n\nexport type BaseFileRead =\n | { kind: \"ok\"; bytes: Buffer }\n | { kind: \"failed\"; detail: string };\n\n/**\n * One base file's bytes, by docs-relative path. Callers only ask for paths\n * `listBaseTree` returned, so there is no \"absent\" arm: a decline here is\n * abnormal and travels as `failed` for per-subject containment — that one\n * subject degrades with the detail, never the whole diff.\n */\nexport async function showBaseFile(base: ResolvedBase, rel: string): Promise<BaseFileRead> {\n return new Promise<BaseFileRead>((done) => {\n const child = spawn(\"git\", [\"show\", `${base.commit}:${base.prefix}${rel}`], {\n cwd: base.docsDir,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: GIT_TIMEOUT_MS,\n });\n // Bytes, not text: `collectStdout` decodes as UTF-8, and a base contract\n // whose bytes are NOT UTF-8 must arrive intact so base-state can grade it\n // unreadable instead of parsing a document nobody wrote.\n const chunks: Buffer[] = [];\n let held = 0;\n let overflowed = false;\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (overflowed) return;\n if (held + chunk.length > MAX_BASE_FILE_BYTES) {\n overflowed = true;\n child.kill();\n return;\n }\n chunks.push(chunk);\n held += chunk.length;\n });\n const err = collectStderr(child);\n child.on(\"error\", (e) => done({ kind: \"failed\", detail: `git could not be started: ${e.message}.` }));\n child.on(\"close\", (code) => {\n if (code !== 0 || overflowed) {\n done({\n kind: \"failed\",\n detail: overflowed\n ? \"the file exceeds the base-read byte cap.\"\n : declineDetail({ code, out: \"\", err: err(), overflowed }),\n });\n return;\n }\n done({ kind: \"ok\", bytes: Buffer.concat(chunks) });\n });\n });\n}\n"]}
|