@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
package/README.md
CHANGED
|
@@ -1,41 +1,163 @@
|
|
|
1
1
|
# loam
|
|
2
2
|
|
|
3
|
-
**Architecture-first
|
|
3
|
+
**Architecture-first semantic integrity and change governance for evolving software systems.**
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|

|
|
7
7
|
[](https://github.com/ybotok/loam/actions/workflows/ci.yml)
|
|
8
|
-
|
|
8
|
+
[](https://www.npmjs.com/package/@ybotok/loam)
|
|
9
9
|
|
|
10
|
-
> **Pre-release: `0.
|
|
10
|
+
> **Pre-release: `0.2.0-alpha.2`**, the second release of the 0.2 line and the newest published
|
|
11
|
+
> version of [`@ybotok/loam`](https://www.npmjs.com/package/@ybotok/loam). It publishes under the
|
|
12
|
+
> `alpha` npm dist-tag: `npm i @ybotok/loam@alpha`, or the exact version, always installs this
|
|
13
|
+
> line. `latest` is moved onto a release by hand once it has published, so a plain
|
|
14
|
+
> `npm i @ybotok/loam` may still resolve to `0.1.0-beta.3` until it is. See [Status](#status).
|
|
11
15
|
|
|
12
|
-
`loam`
|
|
16
|
+
`loam` keeps an authored C4 model, requirements, API and event contracts, permissions, domain
|
|
17
|
+
vocabulary and verification evidence in explicit agreement as a system changes. The same lifecycle
|
|
18
|
+
governs a modular monolith, a distributed service fleet, or a hybrid of both; the CLI and filesystem
|
|
19
|
+
call each governed implementation boundary a `service`, but it need not be a network service.
|
|
20
|
+
|
|
21
|
+
For an existing boundary, `loam` briefs an agent to document it **by reading its code**, then checks
|
|
22
|
+
the result without pretending to extract architectural meaning itself. Forward changes start from
|
|
23
|
+
an authored C4 delta: `loam` projects it onto each affected boundary, generates digest-stamped
|
|
24
|
+
Gherkin, and checks that behavior, architecture, contracts and evidence still join.
|
|
13
25
|
|
|
14
26
|
## Contents
|
|
15
27
|
|
|
16
|
-
- [Why](#why) · [
|
|
17
|
-
|
|
18
|
-
- [
|
|
19
|
-
|
|
28
|
+
- [Why](#why) · [System shapes](#one-lifecycle-several-system-shapes) · [Install](#install) ·
|
|
29
|
+
[Quick start](#quick-start) · [Commands](#commands) · [Working with AI agents](#working-with-ai-agents)
|
|
30
|
+
- [Docs](#docs) · [Development](#development) · [Status](#status) · [Contributing](#contributing) ·
|
|
31
|
+
[Security](#security) · [License](#license)
|
|
32
|
+
- Companion pages: [QUICKSTART.md](QUICKSTART.md) — install-to-first-change ·
|
|
33
|
+
[WORKFLOW.md](WORKFLOW.md) — the protocol · [SCHEMA.md](SCHEMA.md) — the reference ·
|
|
34
|
+
[ROADMAP.md](ROADMAP.md) · [COMPARISON.md](COMPARISON.md)
|
|
20
35
|
|
|
21
36
|
## Why
|
|
22
37
|
|
|
23
|
-
|
|
38
|
+
Software architecture does not live in one artifact. A business-simple feature can cross modules,
|
|
39
|
+
processes or services while C4 diagrams, requirements, API contracts, permissions and test evidence
|
|
40
|
+
drift independently. `loam` makes the authored C4 model the center and gives those artifacts
|
|
41
|
+
referential integrity: every join below is an exact token spelled in two places, never a heuristic
|
|
42
|
+
over prose.
|
|
43
|
+
|
|
44
|
+
| The join | Ties |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `Operations:` ↔ OpenAPI `operationId` | a requirement to the endpoint it governs |
|
|
47
|
+
| `Publishes:` / `Consumes:` ↔ AsyncAPI message names | a requirement to the event spine |
|
|
48
|
+
| `Covers:` ↔ C4 elements, `#obl-` tags, `health.yaml` ids | an architectural obligation to what it accounts for |
|
|
49
|
+
| `Requires:` ↔ `architecture/permissions.yaml` | a requirement to the system-wide authorization vocabulary |
|
|
50
|
+
| `Realizes:` ↔ `capabilities/<cap>/spec.md` | a service requirement to the business promise it keeps |
|
|
51
|
+
| `#cap-` / `#req-` on a `dynamic view` ↔ a capability requirement | a cross-service use case to the promise it keeps |
|
|
52
|
+
| a Markdown link ↔ `glossary/<term>.md` | a document to the word it uses |
|
|
53
|
+
|
|
54
|
+
Architecture has its own requirement axis (`arch.spec.md`) because a business spec will not mention
|
|
55
|
+
the transactional outbox, retries or alerts.
|
|
56
|
+
|
|
57
|
+
### One lifecycle, several system shapes
|
|
58
|
+
|
|
59
|
+
Topology changes where loam's checks pay off; it does not change the lifecycle:
|
|
60
|
+
|
|
61
|
+
- **A modular monolith is one governed boundary.** Bind one root element to one
|
|
62
|
+
`services/<app>/` directory and draw modules, components and their relationships beneath it.
|
|
63
|
+
`Covers:` can name those nested elements and edges, and a feature's `delta.likec4` can change
|
|
64
|
+
them through the same validate/archive transaction as any fleet change.
|
|
65
|
+
- **A distributed system is several governed boundaries.** Each service gets its own directory and
|
|
66
|
+
binding; cross-boundary edges can join to provider OpenAPI operations or AsyncAPI messages, and a
|
|
67
|
+
feature is projected onto every boundary it touches.
|
|
68
|
+
- **A hybrid uses both shapes at once.** A modular application can sit beside independently
|
|
69
|
+
deployed services and external systems in the same landscape. The binding, not the C4 kind or
|
|
70
|
+
nesting depth, decides which `services/<id>/` owns an element.
|
|
71
|
+
|
|
72
|
+
For example, the frozen `service` term can name an application while its internal modules remain
|
|
73
|
+
ordinary C4 elements:
|
|
74
|
+
|
|
75
|
+
```likec4
|
|
76
|
+
specification {
|
|
77
|
+
element softwareSystem
|
|
78
|
+
element component
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
model {
|
|
82
|
+
commerce = softwareSystem 'commerce-app' {
|
|
83
|
+
metadata {
|
|
84
|
+
service 'commerce-app'
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
orders = component 'Orders module'
|
|
88
|
+
billing = component 'Billing module'
|
|
89
|
+
orders -> billing 'Reserves credit'
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
An internal edge normally carries no `metadata { op }`: that key specifically joins a call to the
|
|
95
|
+
governed boundary's OpenAPI contract. An architecture requirement can instead say
|
|
96
|
+
`Covers: commerce.orders -> commerce.billing`. Fleet-level maturity, dependency and scorecard views
|
|
97
|
+
still aggregate at the bound `service`; nested elements get architecture coverage and feature
|
|
98
|
+
lifecycle, not a separate deployment status invented for each module.
|
|
99
|
+
|
|
100
|
+
**There is no extractor, and there will not be one.** Nothing deterministic reads a legacy service
|
|
101
|
+
and says what its architecture *means*, and a model that was guessed is worse than none — everyone
|
|
102
|
+
downstream has to re-derive it to know whether to believe it. So loam takes the half of the job that
|
|
103
|
+
is mechanical: it **states the work** and it **checks the result**. An agent does the reading, and
|
|
104
|
+
both halves are written down: the question in the brief or the checklist, the answer in `sources` or
|
|
105
|
+
`verification.yaml`.
|
|
106
|
+
|
|
107
|
+
### What green means here, and what it does not
|
|
108
|
+
|
|
109
|
+
Most of this category will tell you what it checks. loam ships the other list too, in the binary:
|
|
110
|
+
**[`src/core/brief/unchecked.ts`](https://github.com/ybotok/loam/blob/main/src/core/brief/unchecked.ts)
|
|
111
|
+
is sixteen statements of what no check will ever tell you**, printed into the adoption brief beside
|
|
112
|
+
the checks that do run. It says, in loam's own words, that nothing here knows whether the model is
|
|
113
|
+
the architecture the code actually has, whether a requirement is *true*, whether an `operationId` is
|
|
114
|
+
the one the code serves, or whether `sources` names the files anybody read. And it says the one that
|
|
115
|
+
matters most: **completeness is unchecked** — forty behaviours documented as one requirement passes
|
|
116
|
+
every check loam has, and so does a service with one endpoint documented out of thirty.
|
|
117
|
+
|
|
118
|
+
That list exists because a check that is silent for want of anything to ask must never read as a
|
|
119
|
+
check that passed. Green here means *the documents agree with each other* — never that they are
|
|
120
|
+
true, and never that they are complete.
|
|
121
|
+
|
|
122
|
+
The same refusal runs through the evidence model. `loam verify` records who answered every claim,
|
|
123
|
+
and keeps two answers permanently distinguishable:
|
|
124
|
+
|
|
125
|
+
- **`verified`** — a digest-tagged scenario answered by a green test run. The digest is taken over
|
|
126
|
+
the scenario's *body*, so rewording a `Given` breaks the link on purpose. Tag-based coverage
|
|
127
|
+
(`@REQ-1234` and its relatives) survives any rewrite and goes on asserting a claim nobody
|
|
128
|
+
re-checked.
|
|
129
|
+
- **`attested`** — an agent's word, with `file:line` evidence at an attested commit. Recorded in
|
|
130
|
+
full, labelled on every surface, and never promoted. A feature whose scenarios rest on attestation
|
|
131
|
+
does not become verified because a gate would be greener if it did.
|
|
132
|
+
|
|
133
|
+
Neither gates the archive. The claim loam makes for its evidence is persistence and honest
|
|
134
|
+
provenance — not that every recorded judgement is true.
|
|
135
|
+
|
|
136
|
+
Files stay the source of truth. Delete `loam` and every artifact remains as Markdown, LikeC4 DSL,
|
|
137
|
+
Gherkin and YAML — no server, no database, no state file, three runtime dependencies. The two flows
|
|
138
|
+
this implies, what gates and what only advises, are in [WORKFLOW.md](WORKFLOW.md).
|
|
24
139
|
|
|
25
140
|
## Install
|
|
26
141
|
|
|
27
|
-
**Node ≥ 22.22.3** (the `engines` floor in `package.json`) is the only prerequisite for everything
|
|
142
|
+
**Node ≥ 22.22.3** (the `engines` floor in `package.json`) is the only prerequisite for everything
|
|
143
|
+
loam derives from the docs repo. C4 modeling uses **[LikeC4](https://likec4.dev)** (pinned exact),
|
|
144
|
+
an ordinary npm runtime dependency loaded in-process (TypeScript-native): no JVM, no external CLI.
|
|
145
|
+
The one outside binary loam ever calls is **`git`** — read-only questions in whichever repository
|
|
146
|
+
the command is about (`verify --service`, `vouch`'s source digest, `subsystem move`/`history`, and
|
|
147
|
+
`diff --base`), plus the one blessed `git add` that stages a subsystem move's renames. Never the
|
|
148
|
+
network.
|
|
28
149
|
|
|
29
150
|
```bash
|
|
30
151
|
npm install -g @ybotok/loam
|
|
31
152
|
loam --version
|
|
32
153
|
```
|
|
33
154
|
|
|
34
|
-
`loam doctor` is the wiring check, not the install check: run where no `loam.json` is in scope, it
|
|
155
|
+
`loam doctor` is the wiring check, not the install check: run where no `loam.json` is in scope, it
|
|
156
|
+
reports `doctor.config-missing` and exits 1 by design. Save it for after `loam init`.
|
|
35
157
|
|
|
36
158
|
A per-repo dev dependency works the same way: `npm i -D @ybotok/loam`, then `npx loam …`.
|
|
37
159
|
|
|
38
|
-
|
|
160
|
+
To work on loam itself — or to run an unreleased commit — install from a clone:
|
|
39
161
|
|
|
40
162
|
```bash
|
|
41
163
|
git clone https://github.com/ybotok/loam.git && cd loam
|
|
@@ -46,170 +168,328 @@ Drop `--link` to build without a global `loam`; on Windows run `npm ci && npm ru
|
|
|
46
168
|
|
|
47
169
|
## Quick start
|
|
48
170
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
echo '{ "docsDir": "examples/docs" }' > loam.json # relative, resolved against this file
|
|
53
|
-
npm run dev -- list # what the fleet looks like
|
|
54
|
-
npm run dev -- validate --all # the CI gate: 0 errors, 3 deliberate warnings
|
|
55
|
-
npm run dev -- archive FEAT-101 --dry-run # the whole three-axis merge plan, writing nothing
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
`test/examples.test.ts` pins the validate summary and every finding code, and the archive plan file-for-file, so those outcomes cannot drift from the code; the `list` rendering is not pinned.
|
|
171
|
+
For the shortest install-to-first-feature path, including the exact chat commands and local problem
|
|
172
|
+
report flow, use [QUICKSTART.md](QUICKSTART.md). The routes below explain the alternative starting
|
|
173
|
+
positions in more depth.
|
|
59
174
|
|
|
60
|
-
|
|
175
|
+
`loam --help` ends by naming where to start and the way out, and this section is the same two
|
|
176
|
+
commands in the same order: **`loam init --create`** first — every other command needs the docs repo
|
|
177
|
+
it writes — and **`loam doctor`** whenever a later run does not do what you expected, which reports
|
|
178
|
+
the runtime, the resolved `docsDir`, the access, the binding, and any finding with its `fix:` line.
|
|
179
|
+
Each path below is that first command aimed at a different starting position; `loam diff` is the one
|
|
180
|
+
that needs neither.
|
|
61
181
|
|
|
62
|
-
|
|
182
|
+
### Start from the fleet spine
|
|
63
183
|
|
|
64
|
-
|
|
184
|
+
The path that pays off first, because it is the only one whose checks have two sides to compare.
|
|
185
|
+
It needs **no requirement Markdown, no `loam adopt`, and no `loam vouch`** — just the map and the
|
|
186
|
+
contracts you already have.
|
|
65
187
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
| Executability | `/opsx:verify` asks an agent to inspect implementation and tests; advisory | digest-stamped Gherkin; a green cucumber run confirms a scenario mechanically, and a scenario confirmed on an agent's word instead is recorded as **attested, not verified** (`verify.scenario-attested`) |
|
|
70
|
-
| Drift control | structural CLI validation plus agent-led verification on demand; no persisted digests to compare against later | persisted source/content digests + human vouch. `content.stale` is checkable fleet-wide; `sources.stale` only inside each service's own repo. Both are warnings — `--strict` is the CI escalation |
|
|
71
|
-
| Change merge | validates prepared requirement updates, supports `RENAMED`, then writes specs sequentially | transactional 3-axis merge behind a coherence gate, digest-checked byte-level undo, and a commit journal that repairs an interrupted merge |
|
|
72
|
-
| Agent surface | skills + commands for 34 tools at v1.7.0; `openspec update` regenerates them in place, skipping ones already current | skills for 20 tools and commands for the 19 that read them (Codex takes skills only); `--json` on every command; generated files carry a version stamp and are **never** regenerated — drift is reported (`doctor.agent-files-stale`) and repaired by hand |
|
|
73
|
-
| Entry curve | minutes | you learn LikeC4 + frontmatter + the operationId spine first |
|
|
188
|
+
Write a `fleet.yaml` naming your services and who calls whom
|
|
189
|
+
([`examples/fleet.yaml`](https://github.com/ybotok/loam/blob/main/examples/fleet.yaml) is a real
|
|
190
|
+
one), then:
|
|
74
191
|
|
|
75
|
-
|
|
192
|
+
```bash
|
|
193
|
+
loam init --docs . --create # in an empty directory: the docs repo
|
|
194
|
+
loam seed --from fleet.yaml # the fleet map + one services/<id>/ per service
|
|
195
|
+
```
|
|
76
196
|
|
|
77
|
-
|
|
197
|
+
Now do the two things only you can do:
|
|
78
198
|
|
|
79
|
-
|
|
199
|
+
1. **Drop each service's existing `openapi.yaml`** into `services/<id>/`. Copy the one your build
|
|
200
|
+
already produces — loam never generates it and never reads your code.
|
|
201
|
+
2. **Name the operation on each call edge** in `architecture/landscape.likec4`:
|
|
202
|
+
`metadata { op 'createOrder' }`. This is the labour, and it is also the artifact nothing else
|
|
203
|
+
produces — a drawn arrow becomes a checked join.
|
|
80
204
|
|
|
81
|
-
|
|
205
|
+
```bash
|
|
206
|
+
loam validate --all
|
|
207
|
+
```
|
|
82
208
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
209
|
+
That already convicts the fleet's real edges: a call naming an operation its provider does not
|
|
210
|
+
define is `spine.op-undefined`, an **error**, and one letter is enough — `authorisePayment` against
|
|
211
|
+
a contract spelling it `authorizePayment` fails here and nowhere else a team normally runs.
|
|
212
|
+
|
|
213
|
+
**Expect a red run, and read it correctly.** Five seeded services with no C4 centre report
|
|
214
|
+
`service.no-model` (error) five times, and `service.no-spec` (warn) five times. Those are not
|
|
215
|
+
misconfiguration: they are a truthful reading of a fleet where adoption has not started, and they
|
|
216
|
+
stay until you write those documents. The finding you came for is the spine one.
|
|
217
|
+
[`test/spine-first.test.ts`](https://github.com/ybotok/loam/blob/main/test/spine-first.test.ts)
|
|
218
|
+
pins this whole sequence against the shipped `examples/fleet.yaml`, so the recipe cannot drift from
|
|
219
|
+
the binary.
|
|
220
|
+
|
|
221
|
+
From here, [WORKFLOW.md's day zero](WORKFLOW.md#day-zero-onboarding-a-fleet) is the rest: bind each
|
|
222
|
+
service repo, adopt, grade, promote.
|
|
223
|
+
|
|
224
|
+
### Guard the fleet's edges on every PR
|
|
225
|
+
|
|
226
|
+
Two commands, each installable on its own with no part of the workflow above adopted. **`loam diff`
|
|
227
|
+
exits 1 when a pull request removes an operation or an event message the fleet still consumes**,
|
|
228
|
+
and names the consumers. That question — *who still calls this?* — is the one a fleet answers wrong,
|
|
229
|
+
and it is answerable only from a document that knows the whole fleet. **`loam validate --all --base
|
|
230
|
+
<ref>` grades only the boundaries the branch touched**, which is what lets a strict gate go in on
|
|
231
|
+
the first day of adoption and tighten as the system gets written down.
|
|
232
|
+
|
|
233
|
+
```yaml
|
|
234
|
+
# .github/workflows/fleet-edges.yml — in the docs repo
|
|
235
|
+
name: fleet edges
|
|
236
|
+
on: pull_request
|
|
237
|
+
jobs:
|
|
238
|
+
edges:
|
|
239
|
+
runs-on: ubuntu-latest
|
|
240
|
+
steps:
|
|
241
|
+
- uses: actions/checkout@v4
|
|
242
|
+
with: { fetch-depth: 0 } # both read the base out of git history
|
|
243
|
+
- uses: actions/setup-node@v4
|
|
244
|
+
with: { node-version: 22 }
|
|
245
|
+
# did you break a consumer?
|
|
246
|
+
- run: npx -y @ybotok/loam diff --base origin/${{ github.base_ref }}
|
|
247
|
+
# did you document what you touched?
|
|
248
|
+
- run: npx -y @ybotok/loam validate --all --base origin/${{ github.base_ref }} --strict
|
|
249
|
+
```
|
|
86
250
|
|
|
87
|
-
|
|
251
|
+
Two gates, two different questions, and neither is the other's cheaper form. `diff` reports every
|
|
252
|
+
removal against the system's current consumers rather than against a rule list, which is why it
|
|
253
|
+
repays installation before anything else exists. `validate --base` grades the boundaries this
|
|
254
|
+
branch changed, at full strictness, and says out loud how much of the system that was — a run with
|
|
255
|
+
nothing in scope prints that it graded nothing rather than the word valid. Unscoped, neither
|
|
256
|
+
setting is usable on a partly-documented system: `loam validate --all` is green over boundaries
|
|
257
|
+
nobody has written yet, because warnings do not gate, and `--strict` over all of them is red from
|
|
258
|
+
the first minute of adoption until the last one is done.
|
|
88
259
|
|
|
89
|
-
|
|
260
|
+
**A `--base`-scoped validate cannot see a victim boundary the change did not touch.** Remove an
|
|
261
|
+
operation `payment-service` owns, and `checkout-web` — whose living requirement still names it —
|
|
262
|
+
is not in scope, so nothing in that gate reports the broken join. That is `loam diff --base`'s
|
|
263
|
+
question, it stays `loam diff --base`'s, and a green scoped validate is not a statement about the
|
|
264
|
+
consumers of what changed. [WORKFLOW.md](WORKFLOW.md#what-actually-gates) has what each does and
|
|
265
|
+
does not grade — including the oasdiff invocation for the byte-level OpenAPI breaking-change
|
|
266
|
+
catalogue, which loam deliberately does not reimplement.
|
|
90
267
|
|
|
91
|
-
|
|
268
|
+
### Try loam on one governed system in five minutes
|
|
92
269
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
loam doctor # confirms the wiring
|
|
96
|
-
```
|
|
270
|
+
The full model may be one application or a fleet; the trial is one repository. In the codebase you
|
|
271
|
+
know best (after [installing](#install)):
|
|
97
272
|
|
|
98
|
-
|
|
273
|
+
```bash
|
|
274
|
+
loam init --docs loam-docs --create --service commerce-app
|
|
275
|
+
```
|
|
99
276
|
|
|
100
|
-
|
|
277
|
+
One run does two things: it scaffolds a new docs repo at `loam-docs/` — `services/`, `features/`,
|
|
278
|
+
`architecture/landscape.likec4`, its own `AGENTS.md` and `loam.json` — and it binds this repository
|
|
279
|
+
to the id `commerce-app` in a committed `loam.json` beside your code (plus the slash commands and
|
|
280
|
+
Agent Skills for the AI tools it detects here — [Working with AI agents](#working-with-ai-agents)).
|
|
281
|
+
`init` ends by printing the first hour, which is this loop:
|
|
101
282
|
|
|
102
|
-
|
|
283
|
+
```bash
|
|
284
|
+
loam adopt --service commerce-app --json # the brief: an agent reads the code, writes the baseline as draft
|
|
285
|
+
loam validate --service commerce-app # grade the result in this repo
|
|
286
|
+
loam vouch --service commerce-app # you, not the agent: draft -> verified
|
|
287
|
+
loam status # what to do next, derived from the files
|
|
288
|
+
```
|
|
103
289
|
|
|
104
|
-
|
|
290
|
+
What the trial pays off on is the adopt → validate → vouch mechanics: the brief, the graded
|
|
291
|
+
baseline, the human promotion that makes later staleness detectable. In a modular monolith,
|
|
292
|
+
`arch.spec.md` and `Covers:` can already govern the nested model inside this one boundary. The
|
|
293
|
+
cross-boundary contract spine needs a second service — one boundary has no remote edge to join.
|
|
294
|
+
When a second service wants in, graduate to the full wiring:
|
|
295
|
+
[WORKFLOW.md's day zero](WORKFLOW.md#day-zero-onboarding-a-fleet) is the same steps, pluralized.
|
|
105
296
|
|
|
106
|
-
|
|
297
|
+
### Explore the example fleet
|
|
107
298
|
|
|
108
|
-
|
|
299
|
+
Installed from npm rather than cloned? The example fleet ships inside the package, and one command
|
|
300
|
+
copies it out — through the same journaled write path every other loam writer uses, byte for byte.
|
|
301
|
+
It binds no repository, records no `docsDir`, and writes nothing outside the directory you name:
|
|
109
302
|
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
FORWARD (per feature, generative):
|
|
115
|
-
intent → C4 delta → Gherkin (BDD) → tests → code [truth = model]
|
|
116
|
-
▲ │
|
|
117
|
-
└──── done-check: verify ◄──────────┘
|
|
118
|
-
(a checklist of the feature's own promises,
|
|
119
|
-
answered against the code, with evidence)
|
|
303
|
+
```bash
|
|
304
|
+
loam init --example ./loam-demo
|
|
305
|
+
cd loam-demo && loam validate --all # 0 errors, 10 deliberate warnings
|
|
120
306
|
```
|
|
121
307
|
|
|
122
|
-
|
|
308
|
+
That tree is the one the repo ships under
|
|
309
|
+
[`examples/docs/`](https://github.com/ybotok/loam/tree/main/examples/docs) — five services, two
|
|
310
|
+
features already shipped, two in flight, the event spine, the permission vocabulary, the business
|
|
311
|
+
tree, and two verification records that read `attested` and `verified` so the difference between
|
|
312
|
+
them can be seen standing.
|
|
313
|
+
[`examples/README.md`](https://github.com/ybotok/loam/blob/main/examples/README.md) is the guided
|
|
314
|
+
tour: what each service is there to show, and what every one of the ten deliberate warnings
|
|
315
|
+
demonstrates. From a clone, step into the fleet where it sits and run the real commands — it carries
|
|
316
|
+
its own committed `loam.json`, so there is nothing to write first and nothing to delete afterwards
|
|
317
|
+
(working from source instead of an installed binary, substitute `npx tsx ../../src/cli.ts` for
|
|
318
|
+
`loam`):
|
|
123
319
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
320
|
+
```bash
|
|
321
|
+
cd examples/docs # the tree governs itself: its loam.json says "docsDir": "."
|
|
322
|
+
loam list # the fleet and its maturity ladder
|
|
323
|
+
loam status # what to do next, derived from the files
|
|
324
|
+
loam validate --all # the CI gate: 0 errors, 10 deliberate warnings
|
|
325
|
+
loam archive FEAT-101 --dry-run # the whole three-axis merge plan, writing nothing
|
|
326
|
+
loam archive FEAT-112 --dry-run # an operation being retired, writing nothing
|
|
327
|
+
loam verify FEAT-088 # a shipped feature's done-check: attested
|
|
328
|
+
loam verify FEAT-120 # its pair, same check: verified
|
|
329
|
+
```
|
|
129
330
|
|
|
130
|
-
|
|
131
|
-
-
|
|
132
|
-
- **Mechanical vs semantic.** Deterministic checks validate *shape* (valid DSL, resolvable IDs, coverage); an LLM writes *narrative* (the docs, the Gherkin behavior).
|
|
133
|
-
- **loam never guesses about code.** It reads the docs repo; inside a service repo it only ever hashes or locates what a document already named — the files a `sources` list covers, the `file:line` an answer cites, the cucumber report `--results` was handed. It never parses code or derives meaning from it. Where a judgement about a codebase is needed — what this service is, whether that scenario has a test — loam states the **question**, precisely and repeatably, and an agent answers it. Both halves are written down: the question in the brief or the checklist, the answer in `sources` or `verification.yaml`.
|
|
331
|
+
`test/examples.test.ts` pins the validate summary and every finding code, and both archive plans
|
|
332
|
+
file-for-file, so those outcomes cannot drift from the code; the `list` rendering is not pinned.
|
|
134
333
|
|
|
135
334
|
## Commands
|
|
136
335
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
| `loam doctor` | Read-only preflight for runtime, config, docs-repo access, fleet roots, counts, and the current service binding. Blockers exit 1; incomplete optional bindings stay warnings. |
|
|
143
|
-
| `loam dependencies [<FEAT>]` | Derive the active-feature dependency graph and same-identity conflicts from requirement deltas and OpenAPI operationIds. Optional focus includes transitive prerequisites. |
|
|
144
|
-
| `loam explore [<service>...]` | Read the fleet around a change nobody has written down yet: the ring one hop out, each service's maturity and living operations, the features already in flight over the same ground, and the `loam new` line the seeds imply. `--op <id>` seeds from an operation. Writes nothing. |
|
|
145
|
-
| `loam instructions [<workflow>] [args...]` | Print one of the six workflow protocols, `$1`/`$2` filled in — version-matched to this binary, which is what the generated command and skill files point at. Reads no config. |
|
|
146
|
-
| `loam new <FEAT> [--title <t>] [--touches <id>] [--new-service <id>]` | Scaffold a feature: intent, C4 delta, and a requirement delta for every service named by `--touches` / `--new-service` (both repeatable). The title is optional and becomes the directory slug. |
|
|
147
|
-
| `loam show <service\|FEAT>` | Everything loam knows about one service or feature. |
|
|
148
|
-
| `loam adopt --service <id>` | Brief an agent to write this service's baseline into the docs repo as `draft`. Writes nothing. |
|
|
149
|
-
| `loam delta <FEAT> [--service <id>]` | Project a feature onto one service: the intent, its requirement deltas with every requirement body and every Given/When/Then line reproduced verbatim, the endpoints it adds or retires, and the edges around it. The output doubles as a coding-agent task. |
|
|
150
|
-
| `loam gherkin [<FEAT>] [--service <id>]` | Emit spec scenarios as digest-stamped Gherkin `.feature` files into the service repo's `<gherkinDir>/loam/`. |
|
|
151
|
-
| `loam rebase <FEAT> [--service <id>]` | Pin the feature to the living versions it was written against, on the requirement axis and the contract axis. `--dry-run` shows what would be pinned. |
|
|
152
|
-
| `loam validate [<id>] [--service <id>\|--feature <id>] [--all]` | Validate one service or feature, or the whole fleet in one run (the docs repo's CI gate). The positional id resolves a feature first; `--service` / `--feature` force the reading. `--strict` exits 1 on warnings too. |
|
|
153
|
-
| `loam verify <FEAT> [--service <id>]` | The done-check: derive a checklist of the feature's own promises, and record the answers with their evidence. |
|
|
154
|
-
| `loam vouch --service <id>` | The human promotion `draft` → `verified`: stamp a living spec against the code it was written from. Run in the service's own repo. |
|
|
155
|
-
| `loam archive <FEAT>` | Merge a shipped feature into the living specs, API and landscape; gated on gating coherence issues, on what only the computed merge can see, and on living documents the merge cannot rewrite safely. `--approve` overrides the judgement calls, never the mechanical losses. `--dry-run` prints the plan and writes nothing. |
|
|
156
|
-
| `loam unarchive <FEAT>` | Take that back: restore the living docs from the snapshot archive left behind, and re-open the feature. |
|
|
157
|
-
| `loam audit-openspec <root>` | Read-only inventory of an OpenSpec checkout/workspace/Store checkout. Writes nothing; `--write-mapping <path>` emits the decision skeleton you fill in. |
|
|
158
|
-
| `loam migrate-openspec <root> --map <path>` | Validate a completed mapping against a re-read of the source, and materialize staged migration docs. Dry-run is the default. |
|
|
159
|
-
|
|
160
|
-
Every command takes `--json`: findings carry stable codes (`c4.valid`, `spine.op-undefined`, `coherence.ok` …) so an agent branches on the code, not on prose. The envelope keeps three different questions apart, each on the command that can answer it — `ok` (the command ran) on every envelope, `valid` (the docs pass) on `validate`, and `verified` (every claim is confirmed **and** every scenario claim came from a test run) on `verify`, beside `verdict`, which carries the third state, `attested`, for a record whose scenarios rest on an agent's word.
|
|
161
|
-
|
|
162
|
-
### Command notes
|
|
163
|
-
|
|
164
|
-
**`loam init`** — `--docs` **joins** an existing docs repo; `--create` is required to make a new one, so a mistyped path cannot scaffold a second source of truth. `--service <id>` is what a **service** repo needs: it is the binding `vouch`, `gherkin` and `verify --service --record`/`--results` require before they will write for that service. `--tools <ids>|all` overrides the tool scan; `--no-commands` / `--no-skills` drop one delivery — and the two are exclusive, refused together, since one names the files to write and the other suppresses them. `docsDir` is stored exactly as you typed it and resolved against `loam.json`, so a relative `../docs-repo` works on every clone — and `--docs` wins only when you actually pass it, so a re-run in a wired repo keeps the pointer its committed `loam.json` already spells, `--create` included (`docsDirSource: "flag" | "config" | "default"` in `--json` says which).
|
|
165
|
-
|
|
166
|
-
**`loam status`** — the question an agent has when it joins a repo halfway or loses its session. Artifacts come back `missing`/`blocked`/`draft`/`ready`/`done`, and `next[]` is ordered, each entry a stable code plus the literal command. It takes the union of what `validate --feature` errors on and what `archive` refuses to merge, so it may be redder than either and is never greener than both. There is no state file to go stale.
|
|
167
|
-
|
|
168
|
-
**`loam new`** — the scaffold passes `loam validate --feature` with **zero errors**; the warning left standing is the `owner` you have to fill in yourself, and a feature that introduces a service starts on a second, `c4.uncovered`, until its `arch.spec.md` delta carries a `Covers:` line for the element the delta adds. For a requirements-only feature you delete the scaffolded `delta.likec4` yourself — `new` says so on the way out, and the feature validates clean without it.
|
|
169
|
-
|
|
170
|
-
**`loam adopt`** — the brief names the target paths, the grammar of each, what the landscape already says, the checks that follow, and the ones that do not exist.
|
|
171
|
-
|
|
172
|
-
**`loam gherkin`** — a feature's changed requirements, or (without a feature) the full living suite. Deterministic, digest-stamped, regeneration-owned; run in the service's own repo.
|
|
173
|
-
|
|
174
|
-
**`loam rebase`** — writes `Based-On:` on every MODIFIED/REMOVED requirement and `x-loam-based-on` on every operation in the contract delta that the living docs already hold; what this feature is *adding* has nothing to pin against, and the output says so per item. On the requirement axis that stops a second feature rewriting the same requirement from landing on top of the first in silence; on the contract axis it also marks the rest of the delta as **quotation** — an `openapi.yaml` is a complete document, so without the pin the merge upserts operations you only restated and reverts whatever landed on them. Restamping is the last step of resolving a collision, not the resolution — the output says which pins moved.
|
|
175
|
-
|
|
176
|
-
**`loam verify`** — `--results <report.json>` answers the scenario claims from a cucumber JSON run, digest-matched, so only a green run confirms one, and the record writes down which file it read (path, sha256, mtime). It answers *only* those claims, so on a feature with open `service.exists` / `api.exposes` claims it is passed alongside `--record` or refused (`answers-mismatch`). `--record <answers.json>` takes the agent's answers, refusing anything unevidenced — under `--service`, refusing a `file:line` that does not resolve in that repo at the attested commit — and a scenario claim answered that way makes the record `attested` rather than `verified`. A cross-service feature is recorded **once per service repo** with `--service <id>`, each run adding its own commit-bound attestation to one shared record; the `--service`-less `--record` form writes the whole record from one place and is refused (`record-federated`) once anyone else has attested.
|
|
177
|
-
|
|
178
|
-
**`loam unarchive`** — it refuses rather than guesses: `snapshot-stale` when a merged file moved since (`--force` says that was meant), and `snapshot-corrupt` when a pre-image no longer hashes to what the archive recorded for it, which `--force` deliberately does **not** override — the damage there is to the undo itself.
|
|
336
|
+
Every command takes `--json`; findings carry stable codes (`c4.valid`, `spine.op-undefined`,
|
|
337
|
+
`coherence.ok` …) so an agent branches on the code, not on prose. Flags are listed in full below —
|
|
338
|
+
`loam <command> --help` is the same list from the binary you are running, and
|
|
339
|
+
[WORKFLOW.md's command notes](WORKFLOW.md#command-notes) is the per-command behavior that a table
|
|
340
|
+
cannot hold.
|
|
179
341
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
342
|
+
| Command | Flags | What it does |
|
|
343
|
+
|---|---|---|
|
|
344
|
+
| `loam init` | `--docs <dir>` `--service <id>` `--create` `--force` `--tools <ids>` `--agent-profile <full\|service\|docs>` `--example <dir>` `--no-commands` `--no-skills` `--mcp` `--mcp-author` | Bind this repository to the single shared docs repo: a committed local `loam.json`, plus command and Agent Skill pointers for detected AI tools. Profiles narrow the six lifecycle workflows to a repo's role; the support-only `loam-report` stays in every profile. Re-running init refreshes only unchanged loam-owned pointers; edited files are preserved. `--mcp` writes the read-only host entry, while `--mcp-author` opts into the bounded authoring tools. `--create` scaffolds the docs repo; `--example` copies the packaged example and stops |
|
|
345
|
+
| `loam seed` | `--from <file>` | Template the fleet map and one `services/<id>/` directory per service from a tiny human-authored `fleet.yaml`. Mechanical, never a guess: a human stated every fact. Refuses once the landscape has been hand-edited |
|
|
346
|
+
| `loam list [services\|features\|capabilities\|glossary]` | `--archived` `--needs-work` `--review-order` `--subsystem <name>` `--owners <path>` | What is in the docs repo, and what is missing from it. `capabilities` rolls up who realizes each promise; `glossary` rolls up each term with the documents that cite it |
|
|
347
|
+
| `loam status [<FEAT>]` | `--service <id>` | Where the work stands and what to do next, as a projection over the two gates. Each `next[]` row has an `execution` object that says whether it is runnable, where, and what input or edit is still needed. Derived every run; writes nothing |
|
|
348
|
+
| `loam doctor` | — | Read-only preflight for runtime, config, docs-repo access, fleet roots, counts, and the current service binding. Blockers exit 1; incomplete optional bindings stay warnings |
|
|
349
|
+
| `loam dependencies [<FEAT>]` | — | The active-feature dependency graph and same-identity conflicts, derived from requirement deltas and OpenAPI operationIds |
|
|
350
|
+
| `loam diff` | `--base <ref>` | Semantic diff of the living docs against a base git ref of the docs repo — the review lens for a docs-repo PR, with the current consumers of every removal named. Exit 1 on a removal the fleet still consumes |
|
|
351
|
+
| `loam explore [<service>...]` | `--op <operationId>` `--capability <id>` `--as <FEAT>` | Read the fleet around a change nobody has written down yet: the ring one hop out, each service's maturity and living operations, the features already in flight over the same ground, and the `loam new` line the seeds imply |
|
|
352
|
+
| `loam context <service>` | `--feature <FEAT>` | Assemble one service's docs slice — living requirements verbatim, both contracts, the fleet edges around it, permissions, capabilities, provenance, and every active feature's delta over it — as one deterministic briefing |
|
|
353
|
+
| `loam steps` | `--service <id>` `--duplicates` `--json` | Inventory the step phrases of one service's scenarios: how many distinct steps its suite is written in, how few definitions cover most of them, and which phrases differ only by an article or a trailing clause. Reads the living specs, writes nothing — the work-list a team writes its step definitions from, diffed against the optional `services/<svc>/steps.yaml` catalogue when one exists |
|
|
354
|
+
| `loam instructions [<workflow>] [args...]` | `--no-fix-tables` | Print one of the six workflow protocols, the separate `loam-report` support protocol, or one of the four reference pages `loam-codes`, `loam-spine`, `loam-authoring` and `loam-done-check`, version-matched to this binary. Workflow `$1`/`$2` placeholders are filled; support/reference pages take no arguments. Reads no config. `--no-fix-tables` collapses the per-code fix tables to a line each, keeping the paragraph that says which scope graded them: `loam-check`'s page goes 84,151 bytes to 3,541, while a support/reference page holds no such table and comes back byte-identical |
|
|
355
|
+
| `loam explain [<subject>]` | `--codes` | Explain a finding code, a refusal code, or a concept term. Most finding prose is parsed at runtime from the shipped fix tables, so it cannot drift from the binary; the `doctor.*`, `next.*`, `diff.*` and `gate.*` families, which no fix table grades, are answered from a registry written beside them. Every text-mode refusal prints `<code> · loam explain <code>` on stderr and every non-`ok` finding line carries its code in parentheses, so the lookup is reachable without re-running under `--json`. Omit the subject to list the terms; `--codes` lists the whole vocabulary — 293 finding codes and 46 refusal codes, each row the same answer `explain <code> --json` gives for that one |
|
|
356
|
+
| `loam open` | `--root <dir>` `--out <file>` `--force` | Write a `.code-workspace` joining the docs repo and every service checkout whose committed `loam.json` binds to it. Never overwrites without `--force` |
|
|
357
|
+
| `loam mcp` | `--author` | Serve fourteen read tools, version-matched instruction resources and a declared envelope output schema over MCP. `--author` adds `new`, `rebase`, `gherkin` and an archive dry-run; it never exposes `vouch`, verification recording or a committing archive — [the MCP server](WORKFLOW.md#the-mcp-server) |
|
|
358
|
+
| `loam new <FEAT>` | `--title <text>` `--touches <id>` `--new-service <id>` `--capability <id>` | Scaffold a feature: intent, C4 delta, a requirement delta per service named by `--touches`/`--new-service`, and a capability delta per promise named by `--capability` (all repeatable) |
|
|
359
|
+
| `loam show <service\|FEAT>` | `--type <kind>` | Everything loam knows about one service or feature. A feature's JSON includes a semantic `review` pack: intent, exact architecture objects, API/event slices, dependencies, artifacts, verification, blockers and next actions. `--type` forces an ambiguous reading |
|
|
360
|
+
| `loam subsystem <verb> [names...]` | `--into <name>` `--under <name>` `--title <text>` `--description <text>` `--owner <name>` | Manage the grouping tree under `services/` — a navigable tree no identity depends on. `new`/`rm`, `move … --into`, `rename`, `list`, `history`, `sync` |
|
|
361
|
+
| `loam adopt` | `--service <id>` `--subsystem <name>` `--targets` | Brief an agent to write this service's baseline into the docs repo as `draft`: the target paths, the grammar of each, what the landscape already says, and the checks that follow. Writes nothing. `--targets` narrows it to what varies by service — the walk, the 37 checks and the sixteen statements of what nothing checks are the same bytes everywhere, so a `full` field names the one run that carries them: 42,873 bytes to 17,805 |
|
|
362
|
+
| `loam delta <FEAT>` | `--service <id>` | Project a feature onto one service: the intent, its requirement deltas with every body and Given/When/Then line verbatim, the endpoints it adds or retires, and the edges around it. Doubles as a coding-agent task |
|
|
363
|
+
| `loam gherkin [<FEAT>]` | `--service <id>` `--dry-run` | Emit spec scenarios as digest-stamped Gherkin `.feature` files into the service repo's `<gherkinDir>/loam/` |
|
|
364
|
+
| `loam rebase [<FEAT>]` | `--service <id>` `--dry-run` `--living` | Pin the feature to the living versions it was written against, on the requirement axis and the contract axis. `--living` takes no feature: it pins the living corpus's `Realizes:` entries to the capability requirements they name, which is what makes `capability.realizes-stale` able to fire later |
|
|
365
|
+
| `loam validate [<id>]` | `--service <id>` `--feature <id>` `--all` `--base <ref>` `--strict` `--errors-only` | Validate one service or feature, or the whole fleet in one run. JSON findings carry `locations[]`: an exact primary location when the check knows one, otherwise the narrowest proved scope. `--base` is the adoption ratchet, not a substitute for `loam diff`; `--strict` exits 1 on warnings; `--errors-only` drops the `ok` confirmations from the text view, keeping every warning |
|
|
366
|
+
| `loam verify <FEAT>` | `--record <file>` `--results <file>` `--contract-results <file>` `--diff-answers <files...>` `--service <id>` | The done-check: derive a checklist of the feature's own promises, and record the answers with their evidence. `--results`/`--contract-results` answer claims from a test report; `--diff-answers` cross-examines two blind answer sets |
|
|
367
|
+
| `loam vouch` | `--service <id>` `--yes` `--pack` `--sample <n>` | The human promotion `draft` → `verified`: stamp a living spec against the code it was written from. `--pack` prints the re-vouch reading pack; `--sample <n>` records a partial read as one. Run in the service's own repo |
|
|
368
|
+
| `loam gate` | `--service <id>` `--strict` | Can this service deploy? A pure query over recorded evidence for deploy pipelines outside loam's lifecycle. Executes nothing, writes nothing; errors exit 1, warnings stay advisory |
|
|
369
|
+
| `loam archive <FEAT>` | `--approve` `--dry-run` | Merge a shipped feature into the living specs, API, events, business tree and landscape; gated on what only the computed merge can see. `--approve` overrides the judgement calls, never the mechanical losses |
|
|
370
|
+
| `loam unarchive <FEAT>` | `--force` | Take that back: restore the living docs from the snapshot archive left behind, and re-open the feature |
|
|
371
|
+
| `loam audit-openspec <root>` | `--write-mapping <path>` | Read-only inventory of an OpenSpec checkout/workspace/Store checkout. `--write-mapping` emits the decision skeleton you fill in |
|
|
372
|
+
| `loam migrate-openspec <root>` | `--map <path>` `--mapping <path>` `--apply` `--target <directory>` | Validate a completed mapping against a re-read of the source, and materialize staged migration docs. Dry-run is the default |
|
|
373
|
+
|
|
374
|
+
The envelope keeps three different questions apart, each on the command that can answer it — `ok`
|
|
375
|
+
(the command ran) on every envelope, `valid` (the docs pass) on `validate`, and `verified` (every
|
|
376
|
+
claim is confirmed **and** every scenario claim came from a test run) on `verify`, beside `verdict`,
|
|
377
|
+
which carries the third state, `attested`, for a record whose scenarios rest on an agent's word.
|
|
378
|
+
Every envelope also says what answered it — `contractVersion` for the shape and `version` for the
|
|
379
|
+
binary — because the two move independently: a release bumps one and leaves the other alone, so a
|
|
380
|
+
new build never reads as a contract break, and a green run from a loam that is behind is
|
|
381
|
+
recognisable as one. Every success payload carries `command`, so a host holding a pile of envelopes
|
|
382
|
+
branches on one field instead of guessing from the presence of `valid` or `services`.
|
|
189
383
|
|
|
190
384
|
## Working with AI agents
|
|
191
385
|
|
|
192
|
-
`loam init --create` writes `AGENTS.md` into the docs repo — the process contract, travelling with
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
386
|
+
`loam init --create` writes `AGENTS.md` into the docs repo — the process contract, travelling with
|
|
387
|
+
the thing it describes; a join finds it there and refuses a `--docs` target without one. Into the
|
|
388
|
+
repo it runs in, every `init` writes pointers for the six workflow bodies (`loam-adopt`,
|
|
389
|
+
`loam-feature`, `loam-implement`, `loam-check`, `loam-verify`, `loam-ship`) plus the separate
|
|
390
|
+
`loam-report` support protocol, **twice each for nineteen of the
|
|
391
|
+
twenty-one targets**: as a command file you type — `/loam-check` for most, `/loam:check` where the
|
|
392
|
+
tool namespaces by directory, `@loam-check` in Amazon Q's prompt library — and as an Agent Skill
|
|
393
|
+
at `<tool-dir>/skills/loam-<x>/SKILL.md`, which the model loads by itself when the task matches. Two
|
|
394
|
+
targets are skills only: Codex reads `.codex/skills/` and loads no custom command files, and
|
|
395
|
+
`agents` is not a tool at all but the vendor-neutral `.agents/skills/` root that Cursor, GitHub
|
|
396
|
+
Copilot, Codex, Gemini CLI, Zed and Roo Code each document reading — one copy those six share
|
|
397
|
+
instead of six copies of the same bytes. `--no-commands` and `--no-skills` each suppress one
|
|
398
|
+
delivery.
|
|
399
|
+
|
|
400
|
+
**The explicit command is the recommended, predictable entry point; natural language remains a
|
|
401
|
+
shortcut.** A normal chat lifecycle is `/loam-feature FEAT-101 "Split payments"` to propose,
|
|
402
|
+
`/loam-implement FEAT-101 payment-service` in each affected checkout, `/loam-check`,
|
|
403
|
+
`/loam-verify FEAT-101`, then `/loam-ship FEAT-101`. Most hosts use the flat slash spelling;
|
|
404
|
+
Gemini namespaces it as `/loam:feature`, Amazon Q exposes `@loam-feature`, and a skills-only host
|
|
405
|
+
uses its explicit skill syntax such as `$loam-feature`. Saying “implement FEAT-101” may load that
|
|
406
|
+
same skill automatically. Both routes reach the same binary-owned protocol; after entry, the agent
|
|
407
|
+
runs the status/edit/validate loop rather than asking the user to type every internal command.
|
|
408
|
+
|
|
409
|
+
When the binary or agent integration behaves unexpectedly, `/loam-report` (or `$loam-report` on a
|
|
410
|
+
skills-only host) collects a sanitized, reproducible local report under `loam-reports/`. It records
|
|
411
|
+
the version, doctor/status evidence, stable codes, write state and the smallest safe reproduction;
|
|
412
|
+
it does not repair the repo, retry a writer, include secrets, or upload anything. The support
|
|
413
|
+
protocol ships in every agent profile but remains outside the six-step lifecycle.
|
|
414
|
+
|
|
415
|
+
Which tools is detected from the repo: `init` scans each of the 21 targets it knows for its own
|
|
416
|
+
marker paths — usually just its dot-directory, but Copilot's are the files *inside* `.github/` and
|
|
417
|
+
the vendor-neutral one's is `.agents/skills/` rather than `.agents/`, because almost every repo has
|
|
418
|
+
a `.github/`, a `.agents/` is claimed by other conventions too, and almost none of either means the
|
|
419
|
+
tool. It writes for the ones it finds, and falls back to Claude Code when it finds none.
|
|
420
|
+
`--tools <ids>|all` overrides the scan; an unknown id is refused, not skipped. `--agent-profile`
|
|
421
|
+
selects `full`, `service` or `docs`, so a service checkout need not install feature-authoring and
|
|
422
|
+
shipping entry points. `loam.json` records the tools, profile and sha256 of every pointer loam owns;
|
|
423
|
+
that is how `doctor` distinguishes missing managed files from workflows nobody selected.
|
|
424
|
+
|
|
425
|
+
**A generated file is a pointer, not a protocol.** It carries what does not move between releases —
|
|
426
|
+
what the workflow is for, and the verbs in order — and defers this release's flags, finding codes
|
|
427
|
+
and fix tables to `loam instructions <workflow>`, which ships inside the binary you are about to
|
|
428
|
+
run. That split exists because the two go stale in opposite directions and only one of them is
|
|
429
|
+
fixable: embedded protocol text eventually describes a different loam with total confidence, while
|
|
430
|
+
the command cannot. Pointing at the binary is also what makes the protocol
|
|
431
|
+
affordable to load: `loam instructions loam-check --no-fix-tables` prints the same page with its
|
|
432
|
+
per-code fix tables collapsed to a line each — 84,151 bytes down to 3,541 — and
|
|
433
|
+
`loam explain <code> --json` answers, in 473 bytes, whichever two or three of those rows a run
|
|
434
|
+
actually reported. A copy frozen into the generated file would have charged the full 84 KB every
|
|
435
|
+
session, and gone stale doing it. `AGENTS.md` itself was the one generated file that argument did
|
|
436
|
+
not reach — it was the process contract *and* the reference manual, and every session paid for all
|
|
437
|
+
of it — so four **reference pages** now come out of the binary instead, printed by
|
|
438
|
+
`loam instructions`: `loam-codes` (which codes each invocation can raise), `loam-spine` (every join
|
|
439
|
+
between the artifacts, and the `Based-On:` pins), `loam-authoring` (`arch.spec.md`, the generated
|
|
440
|
+
Gherkin suite, frontmatter) and `loam-done-check` (how `loam verify` derives its claims, and
|
|
441
|
+
verified versus attested). What stayed is what a reader needs to form a question at all: the layout,
|
|
442
|
+
the cycle, which element is which service, the validator's rules and the archive gate. The current
|
|
443
|
+
orientation is **8,762 bytes**, below both the 32,768-byte Codex chain limit and the smaller 12,000
|
|
444
|
+
workspace-rule ceiling. Detailed pages are fetched only when the task reaches them. `loam init`
|
|
445
|
+
writes **no file** for a reference page: a page printed on demand describes the loam you are
|
|
446
|
+
running, not the one that scaffolded the repository.
|
|
447
|
+
|
|
448
|
+
The code inventory is that same split applied twice, and the largest page is what it left behind.
|
|
449
|
+
`loam instructions loam-codes` lists which codes each invocation can raise — 331 of the 335 the
|
|
450
|
+
scaffolded docs name between them, the one fact no other surface carries — and no longer says what
|
|
451
|
+
any of them means, because `loam explain <code>` answers that from the binary actually running and a
|
|
452
|
+
paragraph written once at `init` cannot. Dropping the duplicated gloss came first and took the file
|
|
453
|
+
from 120,896 bytes to 109,399; moving the inventory off it took the remaining 79,679. The OpenSpec
|
|
454
|
+
migration codes keep their notes inline on the page, because they are 49 of the 51 codes
|
|
455
|
+
`loam explain` does not answer yet, and a pointer to an explanation that does not exist is worse
|
|
456
|
+
than the prose it replaced.
|
|
457
|
+
|
|
458
|
+
**Refresh is ownership-aware.** Re-running `loam init` may replace a pointer only when its bytes
|
|
459
|
+
still match the digest recorded when loam last wrote it. The first human edit breaks that equality
|
|
460
|
+
and permanently wins; loam preserves the file and `doctor` reports its stale stamp for review.
|
|
461
|
+
Missing pointers are created. This gives unchanged repositories current entry points without an
|
|
462
|
+
`openspec update`-style overwrite of team customizations.
|
|
463
|
+
|
|
464
|
+
For hosts that reach tools through MCP rather than a shell, see [the MCP server](WORKFLOW.md#the-mcp-server).
|
|
465
|
+
Read tools declare `readOnlyHint`; every tool declares the shared envelope output schema; the compact
|
|
466
|
+
orientation and all workflow/support/reference pages are MCP resources, including a compact loam-check
|
|
467
|
+
resource without the 223-row fix table. `loam init --mcp` writes the
|
|
468
|
+
read-only host entry. `--mcp-author` is a separate explicit choice that adds bounded writers while
|
|
469
|
+
still excluding vouch, evidence recording and a committing archive. An existing `.mcp.json` is
|
|
470
|
+
always preserved byte for byte, with the entry printed for manual merge.
|
|
205
471
|
|
|
206
472
|
## Docs
|
|
207
473
|
|
|
208
|
-
- [
|
|
209
|
-
-
|
|
210
|
-
- [
|
|
211
|
-
|
|
212
|
-
|
|
474
|
+
- [QUICKSTART.md](QUICKSTART.md) — the shortest complete path from install to adoption, the first
|
|
475
|
+
agent-driven feature, and a local problem report when something behaves unexpectedly.
|
|
476
|
+
- [WORKFLOW.md](WORKFLOW.md) — the working protocol: day zero, the artifact graph and its derived
|
|
477
|
+
states, what gates and what only advises, the six workflows, the per-command notes, and how an
|
|
478
|
+
agent drives the cycle from `--json`.
|
|
479
|
+
- [SCHEMA.md](SCHEMA.md) — the docs-repo layout, each artifact's grammar, and the decisions behind
|
|
480
|
+
them: the coherence rules, how `archive` writes and `unarchive` undoes, operating at fleet scale.
|
|
481
|
+
- [COMPARISON.md](COMPARISON.md) — where loam fits beside architecture-as-code tools, software and
|
|
482
|
+
event catalogs, contract verification and diff engines, requirements traceability, and code-level
|
|
483
|
+
architecture checks. Each is treated as a neighbouring specialist, not an opponent loam needs to
|
|
484
|
+
replace.
|
|
485
|
+
- [MIGRATING-from-OpenSpec.md](MIGRATING-from-OpenSpec.md) — moving an OpenSpec repo onto loam: what
|
|
486
|
+
maps, what is lost, what must be added.
|
|
487
|
+
- [ROADMAP.md](ROADMAP.md) — the evidence-backed improvement plan, priorities, non-goals and exit
|
|
488
|
+
criteria.
|
|
489
|
+
- [CHANGELOG.md](CHANGELOG.md) — released beta.1–alpha.2 plus the changes on `main` under
|
|
490
|
+
`[Unreleased]`.
|
|
491
|
+
- [docs/BENCHMARKS.md](https://github.com/ybotok/loam/blob/main/docs/BENCHMARKS.md) — what a
|
|
492
|
+
fleet-sized run costs, with the method, the machine and the committed runs behind every number.
|
|
213
493
|
|
|
214
494
|
## Development
|
|
215
495
|
|
|
@@ -218,31 +498,51 @@ npm run setup # or: npm ci && npm run build
|
|
|
218
498
|
npm run dev -- --help # run the CLI from source
|
|
219
499
|
npm run lint
|
|
220
500
|
npm run typecheck
|
|
501
|
+
npm run arch:check # package-level dependency graph stays acyclic
|
|
221
502
|
npm test # vitest
|
|
222
503
|
npm run test:coverage # full src/**/*.ts coverage with enforced thresholds
|
|
223
504
|
npm run test:package # clean, pack, install the tarball, run its loam binary
|
|
224
|
-
|
|
225
|
-
# optional, against the exact upstream checkout named in "loam vs OpenSpec" (the
|
|
505
|
+
# optional, against the exact upstream checkout named in MIGRATING-from-OpenSpec.md (the
|
|
226
506
|
# flag matters: --baseline defaults to canary, and the sweep refuses a checkout
|
|
227
507
|
# at any other HEAD):
|
|
228
508
|
npm run test:openspec-corpus -- --baseline release /path/to/OpenSpec
|
|
229
509
|
```
|
|
230
510
|
|
|
231
|
-
`npm run setup` is `bash scripts/setup.sh`, so on Windows use `npm ci && npm run build`.
|
|
511
|
+
`npm run setup` is `bash scripts/setup.sh`, so on Windows use `npm ci && npm run build`.
|
|
512
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) has the rest — the local loop, what a reviewable change looks
|
|
513
|
+
like, and the release posture.
|
|
232
514
|
|
|
233
515
|
## Status
|
|
234
516
|
|
|
235
|
-
Every command in the table is implemented, `verify --results`
|
|
236
|
-
|
|
237
|
-
|
|
517
|
+
Every command in the table is implemented, including `verify --results` and its contract-test
|
|
518
|
+
sibling `verify --contract-results`, the full AsyncAPI feature lifecycle, OpenAPI path-item and
|
|
519
|
+
component baselines, the `architecture/permissions.yaml` authorization vocabulary, the declared- and
|
|
520
|
+
authored-capability axes with the `Realizes:` join, use cases graded as `dynamic view`s, the
|
|
521
|
+
`glossary/<term>.md` domain vocabulary checked through the links that cite it, and the
|
|
522
|
+
`architecture/obligations.yaml` architectural obligations checked through `#obl-` tags and
|
|
523
|
+
`Covers:`. Known limits, each with its owner in [ROADMAP.md](ROADMAP.md): the complete gate still
|
|
524
|
+
needs repeatable CI and installed-package evidence observed from an actual push. Speculative
|
|
525
|
+
`render`, health composition and UI generation come later. Behind that status stand **157 test files** (counted 2026-09-02): the count is graded
|
|
526
|
+
against a live readdir by `test/docs-facts.test.ts`, so this sentence fails the suite the moment it
|
|
527
|
+
trails the tree.
|
|
528
|
+
|
|
529
|
+
The package is published as [`@ybotok/loam`](https://www.npmjs.com/package/@ybotok/loam), currently
|
|
530
|
+
`0.2.0-alpha.2`: the unscoped `loam` name is taken by an unrelated GDAL wrapper, so the package ships
|
|
531
|
+
under the maintainer's own npm user scope. Releases are tag-driven and maintainer-only
|
|
532
|
+
([CONTRIBUTING.md](CONTRIBUTING.md)); the version this line names is pinned to `package.json` by a
|
|
533
|
+
drift test, so it cannot silently trail a release.
|
|
238
534
|
|
|
239
535
|
## Contributing
|
|
240
536
|
|
|
241
|
-
Issues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for the local
|
|
537
|
+
Issues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for the complete local
|
|
538
|
+
gate and what a reviewable change looks like here.
|
|
242
539
|
|
|
243
540
|
## Security
|
|
244
541
|
|
|
245
|
-
|
|
542
|
+
Do not put vulnerability details in a public issue. Report privately through
|
|
543
|
+
[GitHub Private Vulnerability Reporting](https://github.com/ybotok/loam/security/advisories/new),
|
|
544
|
+
which is enabled for this repository; [SECURITY.md](SECURITY.md) says what to include and what to
|
|
545
|
+
leave out.
|
|
246
546
|
|
|
247
547
|
## License
|
|
248
548
|
|