@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,280 @@
|
|
|
1
|
+
// Global C4 fleet landscape — the LIVING current state.
|
|
2
|
+
// `loam archive` folds a feature's #FEAT-tagged elements/relationships in here.
|
|
3
|
+
// One landscape file, by decision: conflicts resolve through PRs. See SCHEMA.md,
|
|
4
|
+
// "Operating at fleet scale", for the trigger that would change this.
|
|
5
|
+
//
|
|
6
|
+
// `loam validate --all` cross-checks this file against services/: every service
|
|
7
|
+
// directory needs an element here (error), and every element that looks like a
|
|
8
|
+
// service needs a directory (warning). An element is tied to its directory by
|
|
9
|
+
// `metadata { service '<id>' }`, or by its title when there is no binding.
|
|
10
|
+
// Systems that are not ours carry #external and are exempt.
|
|
11
|
+
specification {
|
|
12
|
+
// A grouping element — it stands for no service and owns no directory. The
|
|
13
|
+
// service checks WALK the tree rather than reading only top-level elements:
|
|
14
|
+
// an element is graded at service level when no ancestor already stands for a
|
|
15
|
+
// service, so nesting the fleet inside a boundary costs nothing, and the
|
|
16
|
+
// group itself never raises `landscape.service-undocumented` because it
|
|
17
|
+
// CONTAINS services rather than being one.
|
|
18
|
+
element group
|
|
19
|
+
element softwareSystem
|
|
20
|
+
// Declared here because archive SPLICES a delta's additions verbatim: FEAT-101's
|
|
21
|
+
// new system carries its `api` container along, and the kind has to be legal in
|
|
22
|
+
// THIS document for the merged landscape to parse (archive refuses otherwise).
|
|
23
|
+
element container
|
|
24
|
+
element person
|
|
25
|
+
// A topic is an element, and the kind carries #external rather than each
|
|
26
|
+
// instance doing it: LikeC4 does NOT inherit tags, so a topic nested inside
|
|
27
|
+
// the #external broker is not external itself, and `loam validate --all`
|
|
28
|
+
// would ask for a services/payment.events/ nobody owes
|
|
29
|
+
// (`landscape.service-undocumented`).
|
|
30
|
+
element topic {
|
|
31
|
+
#external
|
|
32
|
+
// The channel is platform too, and the tag has to be HERE rather than on
|
|
33
|
+
// the broker alone: `landscape.platform-candidate` grades each drawn
|
|
34
|
+
// element by how many services consume it, and once the edges point at
|
|
35
|
+
// topics it is the topics that collect three consumers each — tagging only
|
|
36
|
+
// `kafka` would leave three untagged hubs behind.
|
|
37
|
+
#platform
|
|
38
|
+
style {
|
|
39
|
+
shape queue
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
tag external
|
|
43
|
+
// Ubiquitous infrastructure. Three consuming services is where an untagged
|
|
44
|
+
// external hub starts warning (`landscape.platform-candidate`), because that
|
|
45
|
+
// is where one more edge per modelled service stops being a fact about two
|
|
46
|
+
// services and starts being the shape of the map. Tagging keeps both pictures:
|
|
47
|
+
// the fleet view below excludes #platform, and the platform view keeps "who
|
|
48
|
+
// depends on it" answerable during an incident. LikeC4 refuses an undeclared
|
|
49
|
+
// tag, so the declaration here and the tag on the element are both needed.
|
|
50
|
+
tag platform
|
|
51
|
+
// The capability a use case opts in with. `architecture/usecases/` declares
|
|
52
|
+
// no 'specification` of its own — the whole directory is ONE LikeC4 project,
|
|
53
|
+
// and a second declaration there is a duplicate error blamed on both files —
|
|
54
|
+
// so a tag a flow carries is declared here, beside the kinds.
|
|
55
|
+
tag cap-order-notifications
|
|
56
|
+
// The requirement tag beside it: a flow says WHICH of the capability's named
|
|
57
|
+
// promises it keeps, and the id is spelled with every character a tag name
|
|
58
|
+
// cannot carry flattened to `-`. Declared here for the same reason — one
|
|
59
|
+
// specification block serves the whole `architecture/` project.
|
|
60
|
+
tag req-NOTIFY-ONCE
|
|
61
|
+
// An ARCHITECTURAL OBLIGATION, declared in architecture/obligations.yaml and
|
|
62
|
+
// applied HERE, on the objects it holds for. The decision itself is
|
|
63
|
+
// architecture/adrs/0001-transactional-outbox.md; this tag is the architect
|
|
64
|
+
// saying where it applies, and payment-service's ARCH-PAY-OUTBOX is the team
|
|
65
|
+
// saying it is met. Applied to the edge rather than to the service, because
|
|
66
|
+
// an outbox is a property of publishing, and payment-service also calls an
|
|
67
|
+
// API that owes nothing of the kind.
|
|
68
|
+
tag obl-outbox
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
model {
|
|
72
|
+
customer = person 'Customer'
|
|
73
|
+
|
|
74
|
+
// Our own fleet, drawn inside a boundary the way ordinary grouped C4 is. The
|
|
75
|
+
// group has no `metadata { service }` and no directory under services/: it is
|
|
76
|
+
// scenery for the reader, and every check below resolves through it to the
|
|
77
|
+
// element that really stands for each service.
|
|
78
|
+
marketplace = group 'Marketplace' {
|
|
79
|
+
description 'Everything this organisation runs'
|
|
80
|
+
|
|
81
|
+
checkoutWeb = softwareSystem 'checkout-web' {
|
|
82
|
+
description 'Customer-facing checkout UI'
|
|
83
|
+
metadata {
|
|
84
|
+
service 'checkout-web'
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
orderService = softwareSystem 'order-service' {
|
|
88
|
+
description 'Owns the order lifecycle'
|
|
89
|
+
metadata {
|
|
90
|
+
service 'order-service'
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
paymentService = softwareSystem 'payment-service' {
|
|
94
|
+
description 'Owns payment authorization/capture'
|
|
95
|
+
metadata {
|
|
96
|
+
service 'payment-service'
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
identityService = softwareSystem 'identity-service' {
|
|
100
|
+
description 'Issues and introspects access tokens'
|
|
101
|
+
metadata {
|
|
102
|
+
service 'identity-service'
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
notificationService = softwareSystem 'notification-service' {
|
|
106
|
+
description 'Turns events into customer email and push'
|
|
107
|
+
metadata {
|
|
108
|
+
service 'notification-service'
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
kafka = softwareSystem 'kafka' {
|
|
114
|
+
// Not one of ours: no services/kafka/ is expected, and none is asked for.
|
|
115
|
+
#external
|
|
116
|
+
// Three of our services reach it, which is exactly the count at which the
|
|
117
|
+
// untagged version of this element becomes `landscape.platform-candidate`.
|
|
118
|
+
#platform
|
|
119
|
+
description 'Event backbone'
|
|
120
|
+
// Edges point HERE, not at the broker. Two producers make no difference;
|
|
121
|
+
// sixty do — a broker drawn as one element is the node every service in the
|
|
122
|
+
// fleet points at, and a view over it is a star nobody can read. The topic
|
|
123
|
+
// is also the truer target: what a producer and a consumer share is the
|
|
124
|
+
// channel, never the server it happens to live on.
|
|
125
|
+
paymentEvents = topic 'payment.events'
|
|
126
|
+
orderEvents = topic 'order.events'
|
|
127
|
+
crmEvents = topic 'crm.events'
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
stripe = softwareSystem 'stripe' {
|
|
131
|
+
#external
|
|
132
|
+
description 'Card acquirer'
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
salesforce = softwareSystem 'salesforce' {
|
|
136
|
+
#external
|
|
137
|
+
description 'CRM of record — the fleet reads its events and writes none'
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
customer -> marketplace.checkoutWeb 'Uses'
|
|
141
|
+
|
|
142
|
+
// The synchronous spine. Every one of these resolves against the TARGET's
|
|
143
|
+
// openapi.yaml: `loam validate` fails the fleet when an `op` names an
|
|
144
|
+
// operation the callee does not define ('spine.op-undefined`), which is what
|
|
145
|
+
// turns a rename in one repository into a red build in the one that depended
|
|
146
|
+
// on it.
|
|
147
|
+
marketplace.checkoutWeb -> marketplace.orderService 'Calls createOrder' {
|
|
148
|
+
metadata {
|
|
149
|
+
op 'createOrder'
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
marketplace.checkoutWeb -> marketplace.orderService 'Calls getOrder' {
|
|
153
|
+
metadata {
|
|
154
|
+
op 'getOrder'
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Deliberately unlinked, and the example's demonstration of
|
|
158
|
+
// 'spine.op-link-missing` (warn): an edge whose title starts with "Call" and
|
|
159
|
+
// carries no `metadata { op }` is drawn but joined to nothing, so no check can
|
|
160
|
+
// tell whether the operation behind it still exists. Every other call edge
|
|
161
|
+
// here carries its op; this one is what the warning looks like.
|
|
162
|
+
marketplace.checkoutWeb -> marketplace.paymentService 'Calls the payment API'
|
|
163
|
+
marketplace.orderService -> marketplace.paymentService 'Calls authorizePayment' {
|
|
164
|
+
metadata {
|
|
165
|
+
op 'authorizePayment'
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
marketplace.orderService -> marketplace.identityService 'Calls introspectToken' {
|
|
169
|
+
metadata {
|
|
170
|
+
op 'introspectToken'
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// The other half of the deprecation story, and the example's
|
|
174
|
+
// 'spine.op-deprecated` (warn): identity-service still DEFINES validateToken,
|
|
175
|
+
// so the contract holds and this is not an error — but its OpenAPI marks the
|
|
176
|
+
// operation `deprecated: true`, and this edge is the consumer that has not
|
|
177
|
+
// migrated yet. The warning is addressed to payment-service, not to identity.
|
|
178
|
+
marketplace.paymentService -> marketplace.identityService 'Calls validateToken' {
|
|
179
|
+
metadata {
|
|
180
|
+
op 'validateToken'
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// An edge into a system nobody owns a directory for. It carries no `op`
|
|
184
|
+
// because there is no contract in this repository to resolve one against, and
|
|
185
|
+
// it raises no warning because its title does not claim to be a call into a
|
|
186
|
+
// fleet service.
|
|
187
|
+
marketplace.paymentService -> stripe 'Authorizes cards'
|
|
188
|
+
|
|
189
|
+
// The event spine, the async mirror of `metadata { op }`: the name must be a
|
|
190
|
+
// message the PRODUCER's own asyncapi.yaml declares an `action: send` for, or
|
|
191
|
+
// 'spine.message-undefined` fires. A consumer's edge carries
|
|
192
|
+
// `metadata { consumes }` instead, and its name has to have a producer
|
|
193
|
+
// SOMEWHERE in the fleet — the one check no single repository can answer.
|
|
194
|
+
//
|
|
195
|
+
// THE ARROW FOLLOWS THE MESSAGE, and that is load-bearing rather than
|
|
196
|
+
// aesthetic. `publishes` binds the edge's SOURCE and `consumes` binds its
|
|
197
|
+
// TARGET, so a consume edge drawn the other way round — `orderService ->
|
|
198
|
+
// kafka.paymentEvents` — binds to nothing at all: the metadata parses, the
|
|
199
|
+
// document validates, and the check silently grades zero edges. Producer to
|
|
200
|
+
// topic, topic to consumer, every time.
|
|
201
|
+
marketplace.paymentService -> kafka.paymentEvents 'Publishes PaymentAuthorized' {
|
|
202
|
+
#obl-outbox
|
|
203
|
+
metadata {
|
|
204
|
+
publishes 'payment.PaymentAuthorized'
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
marketplace.paymentService -> kafka.paymentEvents 'Publishes PaymentCaptured' {
|
|
208
|
+
metadata {
|
|
209
|
+
publishes 'payment.PaymentCaptured'
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
kafka.paymentEvents -> marketplace.orderService 'PaymentAuthorized advances the order' {
|
|
213
|
+
metadata {
|
|
214
|
+
consumes 'payment.PaymentAuthorized'
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
marketplace.orderService -> kafka.orderEvents 'Publishes OrderPlaced' {
|
|
218
|
+
metadata {
|
|
219
|
+
publishes 'order.OrderPlaced'
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
marketplace.orderService -> marketplace.paymentService 'Calls refundPayment' {
|
|
223
|
+
metadata { op 'refundPayment' }
|
|
224
|
+
}
|
|
225
|
+
kafka.orderEvents -> marketplace.notificationService 'OrderPlaced triggers the confirmation' {
|
|
226
|
+
metadata {
|
|
227
|
+
consumes 'order.OrderPlaced'
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
kafka.paymentEvents -> marketplace.notificationService 'PaymentCaptured triggers the receipt' {
|
|
231
|
+
metadata {
|
|
232
|
+
consumes 'payment.PaymentCaptured'
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
kafka.paymentEvents -> marketplace.notificationService 'PaymentRefunded triggers the refund notice' {
|
|
236
|
+
metadata {
|
|
237
|
+
consumes 'payment.PaymentRefunded'
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// A producer OUTSIDE the fleet, expressed rather than left implicit. Without
|
|
241
|
+
// this edge notification-service's `consumes 'crm.CustomerUpdated'` would be
|
|
242
|
+
// 'spine.message-unproduced` (error) — nobody in the fleet declares it is
|
|
243
|
+
// sent — and the exit ramp people take from that error is deleting the link.
|
|
244
|
+
// The edge moves the contract question to the one file that can settle it:
|
|
245
|
+
// the consumer's own asyncapi.yaml, which must define the payload
|
|
246
|
+
// ('spine.message-external` fires while it does not).
|
|
247
|
+
salesforce -> kafka.crmEvents 'Publishes CustomerUpdated' {
|
|
248
|
+
metadata {
|
|
249
|
+
publishes 'crm.CustomerUpdated'
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
kafka.crmEvents -> marketplace.notificationService 'CustomerUpdated refreshes contact details' {
|
|
253
|
+
metadata {
|
|
254
|
+
consumes 'crm.CustomerUpdated'
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Views are LikeC4's renderer's, never loam's — nothing below is read by any
|
|
260
|
+
// check. Three of them rather than one `include *`, because at fleet scale a
|
|
261
|
+
// single view holding every call is both the slow one to compute and the one
|
|
262
|
+
// nobody can read: the synchronous map, the event spine and the platform
|
|
263
|
+
// dependencies answer different questions and belong on different pages.
|
|
264
|
+
views {
|
|
265
|
+
view landscape {
|
|
266
|
+
title 'Fleet — calls between our own services'
|
|
267
|
+
include *
|
|
268
|
+
exclude element.tag = #external
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
view events {
|
|
272
|
+
title 'Fleet — the event spine'
|
|
273
|
+
include kafka, kafka.*, * -> kafka.*, kafka.* -> *
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
view platform {
|
|
277
|
+
title 'Fleet — who depends on shared infrastructure'
|
|
278
|
+
include element.tag = #platform, * -> element.tag = #platform
|
|
279
|
+
}
|
|
280
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# The fleet's ARCHITECTURAL OBLIGATIONS: rules an architect decided once and
|
|
2
|
+
# applies where they apply. The decision itself lives in an ADR; a `#obl-<id>`
|
|
3
|
+
# tag on architecture/landscape.likec4 says WHERE it holds; and the owning
|
|
4
|
+
# team's `Covers:` line in its arch.spec.md says it is met, with a scenario.
|
|
5
|
+
#
|
|
6
|
+
# The three grades this file earns are the point of declaring names at all: a
|
|
7
|
+
# tag naming nothing here is `obligation.unknown` (error — a typo reads exactly
|
|
8
|
+
# like a rule), a name nothing tags is `obligation.unapplied` (warn), and a
|
|
9
|
+
# tagged object no living requirement covers is `obligation.uncovered` (warn).
|
|
10
|
+
#
|
|
11
|
+
# An id is its own tag suffix, so it may hold letters, digits, `_` and `-` only.
|
|
12
|
+
obligations:
|
|
13
|
+
outbox:
|
|
14
|
+
description: >-
|
|
15
|
+
A service that publishes a domain event writes the event and the state
|
|
16
|
+
change it reports in one transaction, relayed to the broker afterwards —
|
|
17
|
+
never a dual write.
|
|
18
|
+
adr: architecture/adrs/0001-transactional-outbox.md
|
|
19
|
+
idempotency-key:
|
|
20
|
+
description: >-
|
|
21
|
+
A write a caller may retry accepts an idempotency key and returns the
|
|
22
|
+
first result for a repeat. Declared and applied nowhere yet, which is
|
|
23
|
+
what `obligation.unapplied` is for.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# The fleet's authorization vocabulary, joined to requirements by `Requires:`.
|
|
2
|
+
#
|
|
3
|
+
# Opt-in: a fleet with no `Requires:` line owes no file at all. The first such line makes an
|
|
4
|
+
# absent declaration an error rather than letting each service invent a permission locally,
|
|
5
|
+
# which is how one capability ends up spelled three ways across three repositories.
|
|
6
|
+
#
|
|
7
|
+
# The unit is the pair `<subject>/<permission>`. The subject is the entity the check is
|
|
8
|
+
# performed ON — `user` for a customer acting on their own data, `service` for a fleet service
|
|
9
|
+
# acting on its own behalf — not necessarily the caller. `loam validate` grades exactly two
|
|
10
|
+
# things here: that every `Requires:` pair is declared (`permissions.unknown`, error), and that
|
|
11
|
+
# every declared pair is named by some requirement (`permissions.unenforced`, warning — the
|
|
12
|
+
# authorization mirror of `api.ungoverned`).
|
|
13
|
+
#
|
|
14
|
+
# `owned_by` and `enforced_by` are explanatory and are NOT resolved against services/. This is a
|
|
15
|
+
# spelling and coverage join, not an identity-provider audit: nothing here proves the running
|
|
16
|
+
# system implements a declared permission, and pretending otherwise would be the most dangerous
|
|
17
|
+
# green tick in the repository.
|
|
18
|
+
subjects:
|
|
19
|
+
user:
|
|
20
|
+
description: a human account acting on its own data
|
|
21
|
+
service:
|
|
22
|
+
description: a fleet service acting on its own behalf, with a machine token
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
user:
|
|
26
|
+
payments:refund:
|
|
27
|
+
description: refund a captured payment
|
|
28
|
+
owned_by: identity-service
|
|
29
|
+
enforced_by: [payment-service]
|
|
30
|
+
orders:cancel:
|
|
31
|
+
description: cancel an order that has not shipped
|
|
32
|
+
owned_by: identity-service
|
|
33
|
+
enforced_by: [order-service]
|
|
34
|
+
# Declared, and named by no requirement anywhere in the fleet — the example's
|
|
35
|
+
# `permissions.unenforced` (warning) demonstration. It is the shape a vocabulary drifts
|
|
36
|
+
# into: a permission survives the feature that introduced it, the requirement that needed
|
|
37
|
+
# it is rewritten, and the declaration stays behind looking enforced.
|
|
38
|
+
profile:read:
|
|
39
|
+
description: read a customer's own profile
|
|
40
|
+
owned_by: identity-service
|
|
41
|
+
enforced_by: [identity-service]
|
|
42
|
+
service:
|
|
43
|
+
payments:capture:
|
|
44
|
+
description: capture funds a previous authorization reserved
|
|
45
|
+
owned_by: identity-service
|
|
46
|
+
enforced_by: [payment-service]
|
|
47
|
+
tokens:introspect:
|
|
48
|
+
description: ask identity-service what a token currently grants
|
|
49
|
+
owned_by: identity-service
|
|
50
|
+
enforced_by: [identity-service]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// generated by loam — the subsystem tree under services/, one view per subsystem.
|
|
2
|
+
// Do not edit: `loam subsystem sync` regenerates this file from the directories,
|
|
3
|
+
// and `loam validate --all` reports `subsystem.views-stale` when it drifts.
|
|
4
|
+
|
|
5
|
+
views {
|
|
6
|
+
// services/platform
|
|
7
|
+
view subsystem_platform {
|
|
8
|
+
include marketplace.identityService
|
|
9
|
+
include marketplace.notificationService
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// A fleet use case: the ordered hops that fulfil one business capability.
|
|
2
|
+
//
|
|
3
|
+
// This file is the whole shape of the axis. A `dynamic view` tagged
|
|
4
|
+
// `#cap-<slug>` opts in to grading; an untagged one is somebody's hand-drawn
|
|
5
|
+
// diagram and loam never says a word about it. The slug is the capability id
|
|
6
|
+
// from architecture/capabilities.yaml with every `/` flattened to `-`, because
|
|
7
|
+
// a LikeC4 tag name cannot carry a slash — `identity/tokens` would be
|
|
8
|
+
// `#cap-identity-tokens`.
|
|
9
|
+
//
|
|
10
|
+
// It lives in its own file rather than in architecture/landscape.likec4 for a
|
|
11
|
+
// reason that is about people, not parsing: the map belongs to whoever owns the
|
|
12
|
+
// fleet's topology, and a flow changes when a business need changes. Different
|
|
13
|
+
// reasons to edit are different files. The whole `architecture/` directory is
|
|
14
|
+
// read as ONE LikeC4 project, so the steps below resolve against the landscape's
|
|
15
|
+
// elements even though this file declares none — which also means exactly one
|
|
16
|
+
// file in this directory declares the `specification` block, and it is not this
|
|
17
|
+
// one.
|
|
18
|
+
//
|
|
19
|
+
// THE TAG MUST BE THE FIRST THING IN THE VIEW BODY. Written after `title` it is
|
|
20
|
+
// five parse errors, none of which mentions tags. That is the mistake every
|
|
21
|
+
// author makes once.
|
|
22
|
+
//
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
//
|
|
25
|
+
// Two things about this particular flow are worth reading before you copy it.
|
|
26
|
+
//
|
|
27
|
+
// The first hop is a PERSON, and it is here on purpose: `customer ->
|
|
28
|
+
// checkoutWeb` is backed by a real edge that carries no `metadata { op }`, and
|
|
29
|
+
// checkout-web is a real services/ directory — so every condition of
|
|
30
|
+
// `usecase.step-unlinked` is met except the one that matters, which is that a
|
|
31
|
+
// person is not a caller. Somebody clicking a button owes no operationId. Delete
|
|
32
|
+
// that exemption from the checker and this file is what notices: the example
|
|
33
|
+
// fleet's warning count moves from eight to nine and test/examples.test.ts
|
|
34
|
+
// fails.
|
|
35
|
+
//
|
|
36
|
+
// The hop from checkout-web to order-service is DELIBERATELY NOT DRAWN, and its
|
|
37
|
+
// absence is the more useful half of the lesson. The landscape declares two
|
|
38
|
+
// edges for that pair — `Calls createOrder` and `Calls getOrder` — so a step
|
|
39
|
+
// between those two elements names two operations, and loam refuses to guess
|
|
40
|
+
// which one the flow exercises: `usecase.step-contested` (warn), listing both
|
|
41
|
+
// candidates. That is the check working. The two fixes are the ones the message
|
|
42
|
+
// offers: draw the hop between elements that name exactly one operation, or give
|
|
43
|
+
// the candidates one operation between them.
|
|
44
|
+
|
|
45
|
+
views {
|
|
46
|
+
dynamic view uc_order_notification {
|
|
47
|
+
#cap-order-notifications
|
|
48
|
+
#req-NOTIFY-ONCE
|
|
49
|
+
title 'Order notification'
|
|
50
|
+
description 'A placed order reaches the customer as exactly one confirmation'
|
|
51
|
+
|
|
52
|
+
// A person, not a caller — see above.
|
|
53
|
+
customer -> marketplace.checkoutWeb 'places the order'
|
|
54
|
+
|
|
55
|
+
// Producer to topic: the edge carries `publishes`, so the hop reaches a
|
|
56
|
+
// declared API — an AsyncAPI one — and loam does not also demand an HTTP
|
|
57
|
+
// operationId for it. The event spine grades this edge on its own terms.
|
|
58
|
+
marketplace.orderService -> kafka.orderEvents 'announces OrderPlaced'
|
|
59
|
+
|
|
60
|
+
// Topic to consumer, the same exemption from the other side. Modelling the
|
|
61
|
+
// TOPIC rather than the broker is what keeps this readable: an edge into
|
|
62
|
+
// `kafka` itself would put every service in the fleet on one node.
|
|
63
|
+
kafka.orderEvents -> marketplace.notificationService 'sends the confirmation'
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Checkout
|
|
2
|
+
|
|
3
|
+
The customer has chosen what to buy and now wants to be done. Everything from
|
|
4
|
+
the filled cart to the confirmed, paid [order](../../glossary/order.md) is this
|
|
5
|
+
capability: the prices they were shown, the money leaving their card exactly
|
|
6
|
+
once, and the confirmation that tells them it worked. Exactly once means one
|
|
7
|
+
[authorization](../../glossary/payments/authorization.md), which is a word this
|
|
8
|
+
fleet uses in one sense and writes down.
|
|
9
|
+
|
|
10
|
+
This narrative slot is why the tree exists at all. `architecture/capabilities.yaml`
|
|
11
|
+
can declare the word `checkout` and nothing more; the paragraph above is what a
|
|
12
|
+
business analyst actually writes, and before this file there was nowhere in a
|
|
13
|
+
loam docs repo to put it. It is also the loam equivalent of OpenSpec's
|
|
14
|
+
`## Purpose` prose, which the migrator used to drop into `legacy/`.
|
|
15
|
+
|
|
16
|
+
The requirements below are the analyst's, and each one is a promise a customer
|
|
17
|
+
could check from outside — no operationId, no element id, no message name, and
|
|
18
|
+
no service named. That is the rule the tree is held to, and half of it is
|
|
19
|
+
checked: `Operations:`, `Covers:`, `Publishes:` and `Consumes:` are refused here
|
|
20
|
+
(`capability.requirement-service-scoped`), while "names no service" is an
|
|
21
|
+
authoring rule this file keeps and pull-request review holds, because matching
|
|
22
|
+
service names in prose would be a heuristic and loam does not guess.
|
|
23
|
+
|
|
24
|
+
Which services carry which part of this is not written here and must not be:
|
|
25
|
+
that is the fleet map's question, and `loam list capabilities` answers it from
|
|
26
|
+
the `Capability:` lines the service specs already carry.
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
### Requirement: A confirmed order charges the customer exactly once
|
|
31
|
+
Requirement-ID: CHECKOUT-CHARGE-ONCE
|
|
32
|
+
The fleet SHALL charge a customer at most once for a single confirmed order,
|
|
33
|
+
and SHALL confirm an order only after that charge has been authorized.
|
|
34
|
+
|
|
35
|
+
#### Scenario: The customer submits the same order twice
|
|
36
|
+
- **Given** a customer who has confirmed an order
|
|
37
|
+
- **When** they submit the same order again without changing it
|
|
38
|
+
- **Then** they are shown the order they already placed
|
|
39
|
+
- **And** their card is charged only for the first one
|
|
40
|
+
|
|
41
|
+
#### Scenario: Authorization is declined
|
|
42
|
+
- **Given** a customer whose card is declined
|
|
43
|
+
- **When** they confirm the order
|
|
44
|
+
- **Then** no order is confirmed
|
|
45
|
+
- **And** they are told the payment did not go through
|
|
46
|
+
|
|
47
|
+
### Requirement: The price shown is the price charged
|
|
48
|
+
Requirement-ID: CHECKOUT-PRICE-HONOURED
|
|
49
|
+
The fleet SHALL charge the total the customer was shown at the moment they
|
|
50
|
+
confirmed, even if a price changes while the order is being placed.
|
|
51
|
+
|
|
52
|
+
#### Scenario: A price changes mid-checkout
|
|
53
|
+
- **Given** a customer looking at a total of 40.00
|
|
54
|
+
- **When** the price of an item rises before they confirm
|
|
55
|
+
- **Then** confirming still charges 40.00
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Identity tokens
|
|
2
|
+
|
|
3
|
+
Somebody signs in once and stays signed in for a while; the fleet has to keep
|
|
4
|
+
answering "is this still them?" without asking again, and has to stop answering
|
|
5
|
+
yes the moment it should not.
|
|
6
|
+
|
|
7
|
+
This file also demonstrates NESTING, which is the part of the tree that is easy
|
|
8
|
+
to get wrong when reading the layout. The id is `identity/tokens` — one id, with
|
|
9
|
+
the slash inside it, exactly as `architecture/capabilities.yaml` spells the key
|
|
10
|
+
and exactly as a requirement's `Capability:` line writes it. The tree does not
|
|
11
|
+
collapse it and does not invent a separator: the id's own slashes ARE the
|
|
12
|
+
directories, so the document lives at `capabilities/identity/tokens/spec.md`.
|
|
13
|
+
|
|
14
|
+
`capabilities/identity/` therefore holds no `spec.md` of its own, and that earns
|
|
15
|
+
no finding: a directory with a capability beneath it is a group. It would earn
|
|
16
|
+
`capability.doc-missing` only if it held neither a document nor anything below.
|
|
17
|
+
If the fleet later decides that `identity` is a capability in its own right,
|
|
18
|
+
adding `capabilities/identity/spec.md` makes it one — a directory may be both a
|
|
19
|
+
capability and the parent of others, because that is what the ids already say.
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
### Requirement: A revoked session stops working everywhere
|
|
24
|
+
Requirement-ID: IDENTITY-REVOKE-EVERYWHERE
|
|
25
|
+
When a person's session is revoked, the fleet SHALL stop honouring it — in
|
|
26
|
+
every part of the product, not only the one they revoked it from.
|
|
27
|
+
|
|
28
|
+
#### Scenario: Signing out of a lost phone
|
|
29
|
+
- **Given** a person signed in on two devices
|
|
30
|
+
- **When** they sign out one of them from the other
|
|
31
|
+
- **Then** the signed-out device can no longer act as them
|
|
32
|
+
|
|
33
|
+
### Requirement: A refused sign-in never says which half was wrong
|
|
34
|
+
Requirement-ID: IDENTITY-ONE-REFUSAL
|
|
35
|
+
When a sign-in is refused, the fleet SHALL give the same answer whether the
|
|
36
|
+
account does not exist or the secret was wrong — a refusal that tells them apart
|
|
37
|
+
lets anyone test which accounts exist.
|
|
38
|
+
|
|
39
|
+
#### Scenario: An account that does not exist
|
|
40
|
+
- **Given** a sign-in attempt for an account nobody has registered
|
|
41
|
+
- **When** it is refused
|
|
42
|
+
- **Then** the refusal is word for word the one a wrong password gets
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Order notifications
|
|
2
|
+
|
|
3
|
+
The customer has bought something and now wants to know it worked. Every event
|
|
4
|
+
in an [order](../../glossary/order.md)'s life that they would want to hear about
|
|
5
|
+
reaches them, once.
|
|
6
|
+
|
|
7
|
+
This capability carries the example's demonstration of the axis's second
|
|
8
|
+
realizer, and it is the reason the tree exists at all. The promise below is
|
|
9
|
+
**cross-service by construction**: an order is placed in one service, the event
|
|
10
|
+
crosses a broker, and a third service sends the message. No single service's
|
|
11
|
+
`spec.md` can promise "exactly one confirmation", because each of them promises
|
|
12
|
+
only its own part — `order-service` promises to announce the order,
|
|
13
|
+
`notification-service` promises to send what it receives, and neither can
|
|
14
|
+
promise what happens between them.
|
|
15
|
+
|
|
16
|
+
A USE CASE can, because it IS the hop sequence. So
|
|
17
|
+
`architecture/usecases/order-notification.likec4` carries `#req-NOTIFY-ONCE`
|
|
18
|
+
beside its `#cap-order-notifications` tag, and that tag is the architect's
|
|
19
|
+
answer to this promise: these hops, in this order, are what keeps it. loam
|
|
20
|
+
grades the claim down to the operation, and `capability.requirement-unrealized`
|
|
21
|
+
stays silent for this requirement because a flow keeps it.
|
|
22
|
+
|
|
23
|
+
Written with no `Operations:`, `Covers:`, `Publishes:` or `Consumes:` line —
|
|
24
|
+
those resolve against one service's own contract, and a capability requirement
|
|
25
|
+
must be observable from outside the fleet.
|
|
26
|
+
|
|
27
|
+
## Requirements
|
|
28
|
+
|
|
29
|
+
### Requirement: A placed order produces exactly one confirmation
|
|
30
|
+
Requirement-ID: NOTIFY-ONCE
|
|
31
|
+
The fleet SHALL send a customer exactly one confirmation for an order they
|
|
32
|
+
placed — not none if a service restarts mid-flight, and not two if a message is
|
|
33
|
+
delivered twice.
|
|
34
|
+
|
|
35
|
+
#### Scenario: The order is placed and the customer is told
|
|
36
|
+
- **Given** a customer who has just placed an order
|
|
37
|
+
- **When** the order is accepted
|
|
38
|
+
- **Then** they receive one confirmation naming that order
|
|
39
|
+
|
|
40
|
+
#### Scenario: The same event arrives twice
|
|
41
|
+
- **Given** a confirmation already sent for an order
|
|
42
|
+
- **When** the same event is delivered again
|
|
43
|
+
- **Then** the customer receives nothing further
|
package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ADR-FEAT-101-0001
|
|
3
|
+
status: accepted
|
|
4
|
+
date: 2026-07-20
|
|
5
|
+
feature: FEAT-101
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 1. Introduce a dedicated payment-split-service
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
Splitting logic is non-trivial and will be reused beyond checkout.
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
Create a new bounded-context service `payment-split-service` rather than embedding the logic in `payment-service`.
|
|
15
|
+
|
|
16
|
+
## Consequences
|
|
17
|
+
- +1 service to operate, with clean ownership.
|
|
18
|
+
- `payment-service` gains a synchronous dependency — modeled as `criticality: degradable` in its `health.yaml`.
|