@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.2
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 +2635 -86
- 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 +599 -0
- package/SCHEMA.md +2355 -256
- 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 +323 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +180 -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 +252 -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 +72 -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 +204 -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 +270 -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 +251 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +251 -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/{agents-stamp.js → agent/agents-stamp.js} +50 -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 +337 -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.js → asyncapi/read.js} +95 -109
- 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 +48 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +174 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/likec4.js +90 -0
- package/dist/core/c4/likec4.js.map +1 -0
- package/dist/core/c4/parsed/deployment.js +158 -0
- package/dist/core/c4/parsed/deployment.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js +132 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
- package/dist/core/c4/parsed/specification.js +78 -0
- package/dist/core/c4/parsed/specification.js.map +1 -0
- package/dist/core/c4/parsed/values.js +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 +187 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/project/staged.js +220 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/service.js +159 -0
- package/dist/core/c4/resolve/service.js.map +1 -0
- package/dist/core/c4/resolve/steps.js +144 -0
- package/dist/core/c4/resolve/steps.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 +139 -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 +174 -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 +287 -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/deployment/delta.js +188 -0
- package/dist/core/deployment/delta.js.map +1 -0
- package/dist/core/deployment/objects.js +145 -0
- package/dist/core/deployment/objects.js.map +1 -0
- package/dist/core/diff/base-git.js +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 +7 -64
- 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 +120 -78
- 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 +137 -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 +210 -0
- package/dist/core/repo/authored/paths.js.map +1 -0
- package/dist/core/repo/entries.js +126 -0
- package/dist/core/repo/entries.js.map +1 -0
- package/dist/core/repo/paths.js +277 -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 +196 -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 +197 -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 +72 -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 +58 -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 -295
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/migrate-openspec.js +0 -950
- package/dist/commands/migrate-openspec.js.map +0 -1
- package/dist/commands/new.js +0 -413
- package/dist/commands/new.js.map +0 -1
- package/dist/commands/rebase.js +0 -356
- package/dist/commands/rebase.js.map +0 -1
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/unarchive.js.map +0 -1
- package/dist/commands/validate.js +0 -1773
- package/dist/commands/validate.js.map +0 -1
- package/dist/commands/verify.js +0 -775
- package/dist/commands/verify.js.map +0 -1
- package/dist/commands/vouch.js +0 -421
- package/dist/commands/vouch.js.map +0 -1
- package/dist/core/agent.js +0 -2173
- package/dist/core/agent.js.map +0 -1
- package/dist/core/agents-stamp.js.map +0 -1
- package/dist/core/arch.js +0 -130
- package/dist/core/arch.js.map +0 -1
- package/dist/core/asyncapi.js.map +0 -1
- package/dist/core/brief.js +0 -755
- package/dist/core/brief.js.map +0 -1
- package/dist/core/coherence.js +0 -577
- package/dist/core/coherence.js.map +0 -1
- package/dist/core/concurrency.js.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/delta.js +0 -476
- package/dist/core/delta.js.map +0 -1
- package/dist/core/dependencies.js +0 -356
- package/dist/core/dependencies.js.map +0 -1
- package/dist/core/doctor.js +0 -596
- package/dist/core/doctor.js.map +0 -1
- package/dist/core/document-bytes.js.map +0 -1
- package/dist/core/explore.js.map +0 -1
- package/dist/core/frontmatter.js.map +0 -1
- package/dist/core/gherkin.js +0 -463
- package/dist/core/gherkin.js.map +0 -1
- package/dist/core/health.js +0 -67
- package/dist/core/health.js.map +0 -1
- package/dist/core/ids.js +0 -122
- package/dist/core/ids.js.map +0 -1
- package/dist/core/issue.js +0 -9
- package/dist/core/issue.js.map +0 -1
- package/dist/core/json.js +0 -74
- package/dist/core/json.js.map +0 -1
- package/dist/core/likec4.js +0 -489
- package/dist/core/likec4.js.map +0 -1
- package/dist/core/maturity.js +0 -66
- package/dist/core/maturity.js.map +0 -1
- package/dist/core/openapi-merge.js +0 -552
- package/dist/core/openapi-merge.js.map +0 -1
- package/dist/core/openapi.js.map +0 -1
- package/dist/core/openspec-inventory.js +0 -1440
- package/dist/core/openspec-inventory.js.map +0 -1
- package/dist/core/path-safety.js.map +0 -1
- package/dist/core/provenance.js +0 -787
- package/dist/core/provenance.js.map +0 -1
- package/dist/core/records.js.map +0 -1
- package/dist/core/repo.js +0 -438
- package/dist/core/repo.js.map +0 -1
- package/dist/core/report.js.map +0 -1
- package/dist/core/spec.js +0 -505
- package/dist/core/spec.js.map +0 -1
- package/dist/core/staging.js +0 -890
- package/dist/core/staging.js.map +0 -1
- package/dist/core/status.js +0 -1132
- package/dist/core/status.js.map +0 -1
- package/dist/core/steps.js +0 -72
- package/dist/core/steps.js.map +0 -1
- package/dist/core/verify.js +0 -807
- package/dist/core/verify.js.map +0 -1
- package/dist/core/version.js.map +0 -1
- /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
- /package/dist/core/{records.js → kernel/records.js} +0 -0
|
@@ -0,0 +1,275 @@
|
|
|
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
|
+
// A producer OUTSIDE the fleet, expressed rather than left implicit. Without
|
|
236
|
+
// this edge notification-service's `consumes 'crm.CustomerUpdated'` would be
|
|
237
|
+
// 'spine.message-unproduced` (error) — nobody in the fleet declares it is
|
|
238
|
+
// sent — and the exit ramp people take from that error is deleting the link.
|
|
239
|
+
// The edge moves the contract question to the one file that can settle it:
|
|
240
|
+
// the consumer's own asyncapi.yaml, which must define the payload
|
|
241
|
+
// ('spine.message-external` fires while it does not).
|
|
242
|
+
salesforce -> kafka.crmEvents 'Publishes CustomerUpdated' {
|
|
243
|
+
metadata {
|
|
244
|
+
publishes 'crm.CustomerUpdated'
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
kafka.crmEvents -> marketplace.notificationService 'CustomerUpdated refreshes contact details' {
|
|
248
|
+
metadata {
|
|
249
|
+
consumes 'crm.CustomerUpdated'
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Views are LikeC4's renderer's, never loam's — nothing below is read by any
|
|
255
|
+
// check. Three of them rather than one `include *`, because at fleet scale a
|
|
256
|
+
// single view holding every call is both the slow one to compute and the one
|
|
257
|
+
// nobody can read: the synchronous map, the event spine and the platform
|
|
258
|
+
// dependencies answer different questions and belong on different pages.
|
|
259
|
+
views {
|
|
260
|
+
view landscape {
|
|
261
|
+
title 'Fleet — calls between our own services'
|
|
262
|
+
include *
|
|
263
|
+
exclude element.tag = #external
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
view events {
|
|
267
|
+
title 'Fleet — the event spine'
|
|
268
|
+
include kafka, kafka.*, * -> kafka.*, kafka.* -> *
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
view platform {
|
|
272
|
+
title 'Fleet — who depends on shared infrastructure'
|
|
273
|
+
include element.tag = #platform, * -> element.tag = #platform
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# The async contract — the messages this service puts on the bus.
|
|
2
|
+
#
|
|
3
|
+
# AsyncAPI 3.0 only. Its operations are named top-level objects carrying
|
|
4
|
+
# `action: send|receive`, which is what makes a message's direction legible;
|
|
5
|
+
# 2.x spells the same thing as publish/subscribe under a channel, where the
|
|
6
|
+
# two words are ambiguous about whose perspective they take.
|
|
7
|
+
#
|
|
8
|
+
# loam reads message NAMES and the `action` of the operation carrying them.
|
|
9
|
+
# It never joins on anything inside `payload` — the one look inside is a
|
|
10
|
+
# presence probe (a payload declaring no shape at all warns, a non-JSON
|
|
11
|
+
# `schemaFormat` is skipped) — which is what keeps swapping JSON Schema for
|
|
12
|
+
# Avro a `schemaFormat` line here rather than a change in loam.
|
|
13
|
+
#
|
|
14
|
+
# The name is the spine: the landscape edge's `metadata { publishes }`, the
|
|
15
|
+
# requirement's `Publishes:` line and `name` below are one name spelled three
|
|
16
|
+
# times, and they must be identical.
|
|
17
|
+
asyncapi: 3.0.0
|
|
18
|
+
info:
|
|
19
|
+
title: payment-service events
|
|
20
|
+
version: "1.0"
|
|
21
|
+
|
|
22
|
+
channels:
|
|
23
|
+
paymentEvents:
|
|
24
|
+
address: payment.events.v1
|
|
25
|
+
description: Payment lifecycle events, published by the outbox relay
|
|
26
|
+
messages:
|
|
27
|
+
PaymentAuthorized:
|
|
28
|
+
$ref: '#/components/messages/PaymentAuthorized'
|
|
29
|
+
PaymentCaptured:
|
|
30
|
+
$ref: '#/components/messages/PaymentCaptured'
|
|
31
|
+
|
|
32
|
+
operations:
|
|
33
|
+
sendPaymentAuthorized:
|
|
34
|
+
action: send
|
|
35
|
+
channel:
|
|
36
|
+
$ref: '#/channels/paymentEvents'
|
|
37
|
+
messages:
|
|
38
|
+
- $ref: '#/channels/paymentEvents/messages/PaymentAuthorized'
|
|
39
|
+
sendPaymentCaptured:
|
|
40
|
+
action: send
|
|
41
|
+
channel:
|
|
42
|
+
$ref: '#/channels/paymentEvents'
|
|
43
|
+
messages:
|
|
44
|
+
- $ref: '#/channels/paymentEvents/messages/PaymentCaptured'
|
|
45
|
+
|
|
46
|
+
components:
|
|
47
|
+
messages:
|
|
48
|
+
PaymentAuthorized:
|
|
49
|
+
# Namespaced by the domain that owns it. One message has exactly one
|
|
50
|
+
# producer: two services declaring they send this name is
|
|
51
|
+
# `asyncapi.message-contested`, and then which contract a consumer reads
|
|
52
|
+
# is a coin flip.
|
|
53
|
+
name: payment.PaymentAuthorized
|
|
54
|
+
title: Payment authorized
|
|
55
|
+
# JSON Schema today, because this fleet runs no schema registry. An Avro
|
|
56
|
+
# record here later needs a `schemaFormat:` line and no other change:
|
|
57
|
+
# everything below is opaque to loam.
|
|
58
|
+
payload:
|
|
59
|
+
type: object
|
|
60
|
+
required: [paymentId, orderId, amount, currency, authorizedAt]
|
|
61
|
+
properties:
|
|
62
|
+
paymentId:
|
|
63
|
+
type: string
|
|
64
|
+
format: uuid
|
|
65
|
+
orderId:
|
|
66
|
+
type: string
|
|
67
|
+
amount:
|
|
68
|
+
type: integer
|
|
69
|
+
description: minor units
|
|
70
|
+
currency:
|
|
71
|
+
type: string
|
|
72
|
+
pattern: '^[A-Z]{3}$'
|
|
73
|
+
authorizedAt:
|
|
74
|
+
type: string
|
|
75
|
+
format: date-time
|
|
76
|
+
PaymentCaptured:
|
|
77
|
+
name: payment.PaymentCaptured
|
|
78
|
+
title: Payment captured
|
|
79
|
+
payload:
|
|
80
|
+
type: object
|
|
81
|
+
required: [paymentId, orderId, capturedAmount, currency, capturedAt]
|
|
82
|
+
properties:
|
|
83
|
+
paymentId:
|
|
84
|
+
type: string
|
|
85
|
+
format: uuid
|
|
86
|
+
orderId:
|
|
87
|
+
type: string
|
|
88
|
+
capturedAmount:
|
|
89
|
+
type: integer
|
|
90
|
+
description: minor units
|
|
91
|
+
currency:
|
|
92
|
+
type: string
|
|
93
|
+
pattern: '^[A-Z]{3}$'
|
|
94
|
+
capturedAt:
|
|
95
|
+
type: string
|
|
96
|
+
format: date-time
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
service: payment-service
|
|
3
|
+
status: draft
|
|
4
|
+
owner: payments-team
|
|
5
|
+
sources:
|
|
6
|
+
- src/main/java/
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# payment-service
|
|
10
|
+
|
|
11
|
+
Owns payment authorization and capture. This is the **living spec** — the complete current
|
|
12
|
+
state. Feature deltas (ADDED/MODIFIED/REMOVED requirements) merge in here on `loam archive`;
|
|
13
|
+
`features/archive/` keeps every one of those deltas, so "which change introduced this
|
|
14
|
+
requirement" stays a search rather than a record somebody has to maintain.
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
### Requirement: Authorize a payment
|
|
19
|
+
|
|
20
|
+
Requirement-ID: PAY-AUTHORIZE
|
|
21
|
+
The service SHALL reserve funds for an order before capture, and SHALL treat an authorization
|
|
22
|
+
request as idempotent by order id so that a caller's timeout-and-retry never reserves twice.
|
|
23
|
+
|
|
24
|
+
Operations: authorizePayment
|
|
25
|
+
Publishes: payment.PaymentAuthorized
|
|
26
|
+
Realizes: checkout#CHECKOUT-CHARGE-ONCE
|
|
27
|
+
|
|
28
|
+
#### Scenario: Successful authorization
|
|
29
|
+
- **Given** an order with a valid payment method
|
|
30
|
+
- **When** authorization is requested
|
|
31
|
+
- **Then** funds are reserved and a `PaymentAuthorized` event is emitted
|
|
32
|
+
|
|
33
|
+
#### Scenario: A retry of the same authorization returns the first result
|
|
34
|
+
- **Given** an authorization already reserved for order "A-1"
|
|
35
|
+
- **When** the same request arrives again after a caller timeout
|
|
36
|
+
- **Then** the original authorization is returned and no second reservation is made
|
|
37
|
+
|
|
38
|
+
#### Scenario: A second authorization for the same order with a different amount is refused
|
|
39
|
+
- **Given** an authorization already reserved for order "A-1" of 100.00 USD
|
|
40
|
+
- **When** an authorization of 120.00 USD is requested for the same order
|
|
41
|
+
- **Then** the request is refused with 409 and the first reservation stands
|
|
42
|
+
|
|
43
|
+
### Requirement: Capture an authorized payment
|
|
44
|
+
|
|
45
|
+
Requirement-ID: PAY-CAPTURE
|
|
46
|
+
The service SHALL settle a previously authorized payment, and SHALL refuse to capture a payment
|
|
47
|
+
it never authorized.
|
|
48
|
+
|
|
49
|
+
Operations: capturePayment
|
|
50
|
+
Publishes: payment.PaymentCaptured
|
|
51
|
+
Requires: service/payments:capture
|
|
52
|
+
|
|
53
|
+
#### Scenario: Capture an authorized payment
|
|
54
|
+
- **Given** an authorized payment
|
|
55
|
+
- **When** capture is requested
|
|
56
|
+
- **Then** the payment is settled and a `PaymentCaptured` event is emitted
|
|
57
|
+
|
|
58
|
+
#### Scenario: Capturing an unknown payment is refused
|
|
59
|
+
- **Given** a payment id no authorization ever created
|
|
60
|
+
- **When** capture is requested for it
|
|
61
|
+
- **Then** the request is refused with 404 and nothing is settled
|
|
62
|
+
|
|
63
|
+
### Requirement: Refund a captured payment
|
|
64
|
+
|
|
65
|
+
Requirement-ID: PAY-REFUND
|
|
66
|
+
The service SHALL return captured funds to the customer's payment method, SHALL reconcile the
|
|
67
|
+
refund against the acquirer before reporting it complete, and SHALL refuse a second refund of a
|
|
68
|
+
payment it has already refunded.
|
|
69
|
+
|
|
70
|
+
Operations: refundPayment
|
|
71
|
+
Requires: user/payments:refund
|
|
72
|
+
|
|
73
|
+
#### Scenario: Refund a captured payment in full
|
|
74
|
+
- **Given** a captured payment of 100.00 USD
|
|
75
|
+
- **When** a refund is requested for it
|
|
76
|
+
- **Then** 100.00 USD is returned to the customer's payment method
|
|
77
|
+
- **And** the payment is recorded as refunded
|
|
78
|
+
|
|
79
|
+
#### Scenario: A second refund of the same payment is refused
|
|
80
|
+
- **Given** a payment already refunded in full
|
|
81
|
+
- **When** a refund is requested for it again
|
|
82
|
+
- **Then** the request is refused with 409 and no second refund is issued
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# The async contract — read-only. Every operation here carries `action: receive`:
|
|
2
|
+
# this service produces no message and exposes no HTTP operation, so the whole of
|
|
3
|
+
# what it promises the fleet is what it does with three topics.
|
|
4
|
+
#
|
|
5
|
+
# AsyncAPI 3.0 only. Its operations are named top-level objects carrying
|
|
6
|
+
# `action: send|receive`, which is what makes a message's direction legible;
|
|
7
|
+
# 2.x spells the same thing as publish/subscribe under a channel, where the two
|
|
8
|
+
# words are ambiguous about whose perspective they take — and a 2.x document
|
|
9
|
+
# reads here as a contract with no messages at all.
|
|
10
|
+
#
|
|
11
|
+
# The name is the spine: the landscape edge's `metadata { consumes }`, the
|
|
12
|
+
# requirement's `Consumes:` line and `name` below are one name spelled three
|
|
13
|
+
# times, and they must be identical. For a consumer the line that grades THIS
|
|
14
|
+
# file is the requirement's — a `Consumes:` naming a message no operation here
|
|
15
|
+
# receives is `spec-event.message-undefined`. The edge's copy answers the other
|
|
16
|
+
# question, the one no single repository can: whether anybody publishes the
|
|
17
|
+
# name at all. Deleting a `Consumes:` line therefore does not move a check onto
|
|
18
|
+
# the landscape, it removes one.
|
|
19
|
+
#
|
|
20
|
+
# WHY THE PAYLOADS ARE HERE AT ALL, and why one of them is different in kind:
|
|
21
|
+
#
|
|
22
|
+
# * `order.OrderPlaced` and `payment.PaymentCaptured` are produced INSIDE the
|
|
23
|
+
# fleet, so order-service's and payment-service's own asyncapi.yaml are the
|
|
24
|
+
# authoritative contracts. What is restated below is the subset this consumer
|
|
25
|
+
# actually reads — enough that the handler is codeable from this file, not a
|
|
26
|
+
# second source of truth for the event.
|
|
27
|
+
#
|
|
28
|
+
# * `crm.CustomerUpdated` is produced by `salesforce`, an `#external` element in
|
|
29
|
+
# the landscape. There is no services/salesforce/, there never will be, and so
|
|
30
|
+
# no producer contract exists anywhere in this docs repo. That is a legal
|
|
31
|
+
# shape — loam recognizes an external producer and does not report
|
|
32
|
+
# `spine.message-unproduced` — but it shifts the contract question onto the
|
|
33
|
+
# only file that can answer it: this one. `spine.message-external` (warn)
|
|
34
|
+
# fires for exactly as long as this document defines no shape for the message,
|
|
35
|
+
# and stops the moment it does. The payload below is therefore not a
|
|
36
|
+
# convenience copy; it IS the fleet's contract for that message, and the
|
|
37
|
+
# reason the finding is absent from this service's validate output.
|
|
38
|
+
asyncapi: 3.0.0
|
|
39
|
+
info:
|
|
40
|
+
title: notification-service events
|
|
41
|
+
version: "1.0"
|
|
42
|
+
|
|
43
|
+
channels:
|
|
44
|
+
orderEvents:
|
|
45
|
+
address: order.events.v1
|
|
46
|
+
description: Order lifecycle events, produced by order-service
|
|
47
|
+
messages:
|
|
48
|
+
OrderPlaced:
|
|
49
|
+
$ref: '#/components/messages/OrderPlaced'
|
|
50
|
+
paymentEvents:
|
|
51
|
+
address: payment.events.v1
|
|
52
|
+
description: Payment lifecycle events, produced by payment-service's outbox relay
|
|
53
|
+
messages:
|
|
54
|
+
PaymentCaptured:
|
|
55
|
+
$ref: '#/components/messages/PaymentCaptured'
|
|
56
|
+
crmEvents:
|
|
57
|
+
address: crm.events.v1
|
|
58
|
+
description: Customer master-data events, produced by salesforce (outside the fleet)
|
|
59
|
+
messages:
|
|
60
|
+
CustomerUpdated:
|
|
61
|
+
$ref: '#/components/messages/CustomerUpdated'
|
|
62
|
+
|
|
63
|
+
# One operation per message rather than one per channel, so that adding a second
|
|
64
|
+
# message to a topic later is an addition here instead of a silent widening: an
|
|
65
|
+
# operation that lists no messages applies to EVERY message of its channel, and
|
|
66
|
+
# would start receiving contracts nobody read.
|
|
67
|
+
operations:
|
|
68
|
+
receiveOrderPlaced:
|
|
69
|
+
action: receive
|
|
70
|
+
channel:
|
|
71
|
+
$ref: '#/channels/orderEvents'
|
|
72
|
+
messages:
|
|
73
|
+
- $ref: '#/channels/orderEvents/messages/OrderPlaced'
|
|
74
|
+
receivePaymentCaptured:
|
|
75
|
+
action: receive
|
|
76
|
+
channel:
|
|
77
|
+
$ref: '#/channels/paymentEvents'
|
|
78
|
+
messages:
|
|
79
|
+
- $ref: '#/channels/paymentEvents/messages/PaymentCaptured'
|
|
80
|
+
receiveCustomerUpdated:
|
|
81
|
+
action: receive
|
|
82
|
+
channel:
|
|
83
|
+
$ref: '#/channels/crmEvents'
|
|
84
|
+
messages:
|
|
85
|
+
- $ref: '#/channels/crmEvents/messages/CustomerUpdated'
|
|
86
|
+
|
|
87
|
+
components:
|
|
88
|
+
messages:
|
|
89
|
+
OrderPlaced:
|
|
90
|
+
# Namespaced by the domain that OWNS the message, never by the service
|
|
91
|
+
# reading it: `order.` says order-service is the one producer, and two
|
|
92
|
+
# services declaring they send this name would be
|
|
93
|
+
# `asyncapi.message-contested` — which contract a consumer reads must not
|
|
94
|
+
# be a coin flip.
|
|
95
|
+
name: order.OrderPlaced
|
|
96
|
+
title: Order placed
|
|
97
|
+
payload:
|
|
98
|
+
type: object
|
|
99
|
+
# A payload declaring no shape — absent, or a bare `type: object` — is
|
|
100
|
+
# `asyncapi.payload-undescribed`: the name joins the spine while nothing
|
|
101
|
+
# says what a handler would read. loam probes for presence and never
|
|
102
|
+
# reads a field, which is what keeps a later move to Avro a
|
|
103
|
+
# `schemaFormat:` line here and no change in loam.
|
|
104
|
+
required: [orderId, customerId, placedAt]
|
|
105
|
+
properties:
|
|
106
|
+
orderId:
|
|
107
|
+
type: string
|
|
108
|
+
format: uuid
|
|
109
|
+
description: The idempotency key for the confirmation — one send per orderId
|
|
110
|
+
customerId:
|
|
111
|
+
type: string
|
|
112
|
+
format: uuid
|
|
113
|
+
placedAt:
|
|
114
|
+
type: string
|
|
115
|
+
format: date-time
|
|
116
|
+
PaymentCaptured:
|
|
117
|
+
name: payment.PaymentCaptured
|
|
118
|
+
title: Payment captured
|
|
119
|
+
payload:
|
|
120
|
+
type: object
|
|
121
|
+
required: [paymentId, orderId, capturedAmount, currency, capturedAt]
|
|
122
|
+
properties:
|
|
123
|
+
paymentId:
|
|
124
|
+
type: string
|
|
125
|
+
format: uuid
|
|
126
|
+
orderId:
|
|
127
|
+
type: string
|
|
128
|
+
format: uuid
|
|
129
|
+
description: What joins a receipt to the order the customer was told about
|
|
130
|
+
capturedAmount:
|
|
131
|
+
type: integer
|
|
132
|
+
description: minor units, restated on the receipt exactly as captured
|
|
133
|
+
currency:
|
|
134
|
+
type: string
|
|
135
|
+
pattern: '^[A-Z]{3}$'
|
|
136
|
+
capturedAt:
|
|
137
|
+
type: string
|
|
138
|
+
format: date-time
|
|
139
|
+
CustomerUpdated:
|
|
140
|
+
name: crm.CustomerUpdated
|
|
141
|
+
title: Customer contact details updated
|
|
142
|
+
payload:
|
|
143
|
+
type: object
|
|
144
|
+
# `version` is load-bearing rather than descriptive: the CRM redelivers
|
|
145
|
+
# and reorders, and the "out-of-order update is ignored" scenario in
|
|
146
|
+
# spec.md is only implementable because this field is in the contract.
|
|
147
|
+
# Nothing outside this document defines it.
|
|
148
|
+
required: [customerId, version, updatedAt]
|
|
149
|
+
properties:
|
|
150
|
+
customerId:
|
|
151
|
+
type: string
|
|
152
|
+
format: uuid
|
|
153
|
+
version:
|
|
154
|
+
type: integer
|
|
155
|
+
description: Monotonic per customer; an update at or below the stored version is dropped
|
|
156
|
+
email:
|
|
157
|
+
type: string
|
|
158
|
+
format: email
|
|
159
|
+
phone:
|
|
160
|
+
type: string
|
|
161
|
+
description: E.164; absent when the customer has no phone on record
|
|
162
|
+
updatedAt:
|
|
163
|
+
type: string
|
|
164
|
+
format: date-time
|