@ybotok/loam 0.2.0-alpha.1 → 0.2.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3448 -0
- package/COMPARISON.md +91 -3
- package/CONTRIBUTING.md +37 -0
- package/MIGRATING-from-OpenSpec.md +47 -23
- package/QUICKSTART.md +189 -12
- package/README.md +274 -65
- package/ROADMAP.md +572 -31
- package/SCHEMA.md +1709 -155
- package/WORKFLOW.md +298 -72
- package/dist/cli.js +26 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +5 -10
- package/dist/commands/adopt/adopt.js.map +1 -1
- package/dist/commands/adopt/render.js +50 -9
- package/dist/commands/adopt/render.js.map +1 -1
- package/dist/commands/archive/archive.js +16 -19
- package/dist/commands/archive/archive.js.map +1 -1
- package/dist/commands/archive/closing.js +42 -0
- package/dist/commands/archive/closing.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +36 -42
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -1
- package/dist/commands/archive/plan/contracts/consumers.js +56 -0
- package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +77 -43
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -1
- package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
- package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
- package/dist/commands/archive/plan/document/head.js +151 -0
- package/dist/commands/archive/plan/document/head.js.map +1 -0
- package/dist/commands/archive/plan/document/links.js +284 -0
- package/dist/commands/archive/plan/document/links.js.map +1 -0
- package/dist/commands/archive/plan/document/run.js +136 -0
- package/dist/commands/archive/plan/document/run.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +21 -19
- package/dist/commands/archive/plan/gate.js.map +1 -1
- package/dist/commands/archive/plan/landscape.js +167 -30
- package/dist/commands/archive/plan/landscape.js.map +1 -1
- package/dist/commands/archive/plan/model/extending.js +85 -0
- package/dist/commands/archive/plan/model/extending.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +14 -19
- package/dist/commands/archive/plan/refusal.js.map +1 -1
- package/dist/commands/archive/plan/specs.js +137 -56
- package/dist/commands/archive/plan/specs.js.map +1 -1
- package/dist/commands/archive/plan/state.js +3 -0
- package/dist/commands/archive/plan/state.js.map +1 -1
- package/dist/commands/archive/run.js +134 -30
- package/dist/commands/archive/run.js.map +1 -1
- package/dist/commands/archive/shipped.js +49 -0
- package/dist/commands/archive/shipped.js.map +1 -0
- package/dist/commands/context/context.js +85 -18
- package/dist/commands/context/context.js.map +1 -1
- package/dist/commands/context/print.js +29 -7
- package/dist/commands/context/print.js.map +1 -1
- package/dist/commands/delta/delta.js +102 -14
- package/dist/commands/delta/delta.js.map +1 -1
- package/dist/commands/delta/print.js +17 -1
- package/dist/commands/delta/print.js.map +1 -1
- package/dist/commands/dependencies.js +3 -7
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +20 -27
- package/dist/commands/diff/diff.js.map +1 -1
- package/dist/commands/doctor.js +60 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +89 -13
- package/dist/commands/explain/explain.js.map +1 -1
- package/dist/commands/explore.js +16 -10
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +45 -8
- package/dist/commands/gate/gate.js.map +1 -1
- package/dist/commands/gate/print.js +15 -3
- package/dist/commands/gate/print.js.map +1 -1
- package/dist/commands/gherkin/commit.js +13 -54
- package/dist/commands/gherkin/commit.js.map +1 -1
- package/dist/commands/gherkin/gherkin.js +36 -20
- package/dist/commands/gherkin/gherkin.js.map +1 -1
- package/dist/commands/gherkin/reconcile.js +10 -13
- package/dist/commands/gherkin/reconcile.js.map +1 -1
- package/dist/commands/init/first-hour.js +44 -0
- package/dist/commands/init/first-hour.js.map +1 -1
- package/dist/commands/init/init.js +18 -22
- package/dist/commands/init/init.js.map +1 -1
- package/dist/commands/list/campaign/campaign.js +4 -6
- package/dist/commands/list/campaign/campaign.js.map +1 -1
- package/dist/commands/list/json.js +5 -7
- package/dist/commands/list/json.js.map +1 -1
- package/dist/commands/list/list.js +44 -29
- package/dist/commands/list/list.js.map +1 -1
- package/dist/commands/list/print.js +52 -9
- package/dist/commands/list/print.js.map +1 -1
- package/dist/commands/list/suites/suites.js +140 -0
- package/dist/commands/list/suites/suites.js.map +1 -0
- package/dist/commands/list/views.js +37 -34
- package/dist/commands/list/views.js.map +1 -1
- package/dist/commands/mcp/dispatch.js +91 -36
- package/dist/commands/mcp/dispatch.js.map +1 -1
- package/dist/commands/mcp/mcp.js +56 -15
- package/dist/commands/mcp/mcp.js.map +1 -1
- package/dist/commands/mcp/serve.js.map +1 -1
- package/dist/commands/migrate-openspec/materialize/active.js +27 -22
- package/dist/commands/migrate-openspec/materialize/active.js.map +1 -1
- package/dist/commands/migrate-openspec/materialize/stage.js +4 -3
- package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -1
- package/dist/commands/migrate-openspec/materialize/target.js +2 -2
- package/dist/commands/migrate-openspec/materialize/target.js.map +1 -1
- package/dist/commands/migrate-openspec/openspec/decisions.js +9 -14
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -1
- package/dist/commands/migrate-openspec/openspec/error.js +7 -8
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -1
- package/dist/commands/migrate-openspec/openspec/mapping.js +1 -9
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -1
- package/dist/commands/migrate-openspec/openspec/paths.js +3 -6
- package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -1
- package/dist/commands/new/capability-template.js +118 -0
- package/dist/commands/new/capability-template.js.map +1 -0
- package/dist/commands/new/commit.js +8 -22
- package/dist/commands/new/commit.js.map +1 -1
- package/dist/commands/new/modifies.js +206 -0
- package/dist/commands/new/modifies.js.map +1 -0
- package/dist/commands/new/new.js +59 -14
- package/dist/commands/new/new.js.map +1 -1
- package/dist/commands/new/templates.js +48 -124
- package/dist/commands/new/templates.js.map +1 -1
- package/dist/commands/open.js +3 -7
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/policy/gate.js +27 -0
- package/dist/commands/policy/gate.js.map +1 -1
- package/dist/commands/rebase/plan.js +2 -2
- package/dist/commands/rebase/plan.js.map +1 -1
- package/dist/commands/rebase/rebase.js +60 -35
- package/dist/commands/rebase/rebase.js.map +1 -1
- package/dist/commands/seed/commit.js +55 -26
- package/dist/commands/seed/commit.js.map +1 -1
- package/dist/commands/seed/plan.js +158 -13
- package/dist/commands/seed/plan.js.map +1 -1
- package/dist/commands/seed/seed.js +13 -11
- package/dist/commands/seed/seed.js.map +1 -1
- package/dist/commands/show/feature.js +9 -5
- package/dist/commands/show/feature.js.map +1 -1
- package/dist/commands/show/introduced.js +157 -0
- package/dist/commands/show/introduced.js.map +1 -0
- package/dist/commands/show/marks.js +35 -6
- package/dist/commands/show/marks.js.map +1 -1
- package/dist/commands/show/service.js +41 -33
- package/dist/commands/show/service.js.map +1 -1
- package/dist/commands/show/show.js +17 -7
- package/dist/commands/show/show.js.map +1 -1
- package/dist/commands/status/fleet-next.js +90 -0
- package/dist/commands/status/fleet-next.js.map +1 -0
- package/dist/commands/status/json.js +2 -0
- package/dist/commands/status/json.js.map +1 -1
- package/dist/commands/status/print.js +89 -37
- package/dist/commands/status/print.js.map +1 -1
- package/dist/commands/status/status.js +3 -7
- package/dist/commands/status/status.js.map +1 -1
- package/dist/commands/steps/steps.js +103 -23
- package/dist/commands/steps/steps.js.map +1 -1
- package/dist/commands/subsystem/edit.js +7 -7
- package/dist/commands/subsystem/edit.js.map +1 -1
- package/dist/commands/subsystem/move.js +106 -46
- package/dist/commands/subsystem/move.js.map +1 -1
- package/dist/commands/subsystem/query.js +2 -4
- package/dist/commands/subsystem/query.js.map +1 -1
- package/dist/commands/subsystem/subsystem.js +4 -7
- package/dist/commands/subsystem/subsystem.js.map +1 -1
- package/dist/commands/subsystem/sync.js +289 -74
- package/dist/commands/subsystem/sync.js.map +1 -1
- package/dist/commands/subsystem/txn/exclude.js +132 -0
- package/dist/commands/subsystem/txn/exclude.js.map +1 -0
- package/dist/commands/subsystem/txn/links.js +128 -0
- package/dist/commands/subsystem/txn/links.js.map +1 -0
- package/dist/commands/subsystem/txn/report.js +174 -0
- package/dist/commands/subsystem/txn/report.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +147 -45
- package/dist/commands/subsystem/txn/txn.js.map +1 -1
- package/dist/commands/subsystem/txn/views.js +200 -21
- package/dist/commands/subsystem/txn/views.js.map +1 -1
- package/dist/commands/tasks/actions.js +107 -0
- package/dist/commands/tasks/actions.js.map +1 -0
- package/dist/commands/tasks/render.js +253 -0
- package/dist/commands/tasks/render.js.map +1 -0
- package/dist/commands/tasks/tasks.js +119 -0
- package/dist/commands/tasks/tasks.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +42 -26
- package/dist/commands/unarchive/manifest.js.map +1 -1
- package/dist/commands/unarchive/restore.js +83 -33
- package/dist/commands/unarchive/restore.js.map +1 -1
- package/dist/commands/unarchive/unarchive.js +22 -30
- package/dist/commands/unarchive/unarchive.js.map +1 -1
- package/dist/commands/validate/arch-coverage.js +78 -27
- package/dist/commands/validate/arch-coverage.js.map +1 -1
- package/dist/commands/validate/checks/fleet-shape.js +34 -126
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -1
- package/dist/commands/validate/checks/health-deps.js +9 -6
- package/dist/commands/validate/checks/health-deps.js.map +1 -1
- package/dist/commands/validate/checks/introduced.js +102 -0
- package/dist/commands/validate/checks/introduced.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +18 -8
- package/dist/commands/validate/checks/requirements.js.map +1 -1
- package/dist/commands/validate/checks/sources.js +11 -2
- package/dist/commands/validate/checks/sources.js.map +1 -1
- package/dist/commands/validate/coverage/covers-after.js +105 -0
- package/dist/commands/validate/coverage/covers-after.js.map +1 -0
- package/dist/commands/validate/feature.js +26 -20
- package/dist/commands/validate/feature.js.map +1 -1
- package/dist/commands/validate/fleet/census.js +37 -13
- package/dist/commands/validate/fleet/census.js.map +1 -1
- package/dist/commands/validate/fleet/landscape.js +144 -126
- package/dist/commands/validate/fleet/landscape.js.map +1 -1
- package/dist/commands/validate/fleet/load.js +66 -0
- package/dist/commands/validate/fleet/load.js.map +1 -1
- package/dist/commands/validate/fleet/map/attest.js +98 -0
- package/dist/commands/validate/fleet/map/attest.js.map +1 -0
- package/dist/commands/validate/fleet/map/bindings.js +107 -0
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
- package/dist/commands/validate/fleet/map/consumers.js +244 -0
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
- package/dist/commands/validate/fleet/map/isolation.js +116 -0
- package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
- package/dist/commands/validate/fleet/map/usecases.js +54 -0
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +44 -14
- package/dist/commands/validate/fleet/obligations.js.map +1 -1
- package/dist/commands/validate/fleet/scorecard/print.js +10 -2
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -1
- package/dist/commands/validate/fleet/scorecard/scorecard.js +17 -11
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -1
- package/dist/commands/validate/fleet/usecases/place.js.map +1 -1
- package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +50 -15
- package/dist/commands/validate/fleet/views/ids.js.map +1 -1
- package/dist/commands/validate/fleet/views/projects.js +278 -0
- package/dist/commands/validate/fleet/views/projects.js.map +1 -0
- package/dist/commands/validate/fleet/views/root-documents.js +83 -0
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +40 -47
- package/dist/commands/validate/fleet/views/stale.js.map +1 -1
- package/dist/commands/validate/links/corpus.js +1 -4
- package/dist/commands/validate/links/corpus.js.map +1 -1
- package/dist/commands/validate/links/glossary.js.map +1 -1
- package/dist/commands/validate/render/repeats.js +63 -0
- package/dist/commands/validate/render/repeats.js.map +1 -0
- package/dist/commands/validate/render/rollups.js +115 -0
- package/dist/commands/validate/render/rollups.js.map +1 -0
- package/dist/commands/validate/render/text.js +199 -0
- package/dist/commands/validate/render/text.js.map +1 -0
- package/dist/commands/validate/report.js +36 -160
- package/dist/commands/validate/report.js.map +1 -1
- package/dist/commands/validate/scope.js +113 -0
- package/dist/commands/validate/scope.js.map +1 -0
- package/dist/commands/validate/service/api.js +21 -107
- package/dist/commands/validate/service/api.js.map +1 -1
- package/dist/commands/validate/service/contracts/generated.js +134 -0
- package/dist/commands/validate/service/contracts/generated.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +36 -14
- package/dist/commands/validate/service/events/events.js.map +1 -1
- package/dist/commands/validate/service/events/message-producers.js +1 -1
- package/dist/commands/validate/service/events/message-producers.js.map +1 -1
- package/dist/commands/validate/service/evidence-pins.js +56 -10
- package/dist/commands/validate/service/evidence-pins.js.map +1 -1
- package/dist/commands/validate/service/model/diverged.js +226 -0
- package/dist/commands/validate/service/model/diverged.js.map +1 -0
- package/dist/commands/validate/service/model/grade.js +163 -0
- package/dist/commands/validate/service/model/grade.js.map +1 -0
- package/dist/commands/validate/service/service.js +121 -61
- package/dist/commands/validate/service/service.js.map +1 -1
- package/dist/commands/validate/service/specs.js +88 -28
- package/dist/commands/validate/service/specs.js.map +1 -1
- package/dist/commands/validate/service/spine.js +38 -3
- package/dist/commands/validate/service/spine.js.map +1 -1
- package/dist/commands/validate/service/usecases/tags.js +113 -0
- package/dist/commands/validate/service/usecases/tags.js.map +1 -0
- package/dist/commands/validate/service/usecases/usecases.js +209 -0
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/validate.js +85 -60
- package/dist/commands/validate/validate.js.map +1 -1
- package/dist/commands/verify/cross/diff.js +2 -6
- package/dist/commands/verify/cross/diff.js.map +1 -1
- package/dist/commands/verify/evidence/contract.js +1 -1
- package/dist/commands/verify/evidence/contract.js.map +1 -1
- package/dist/commands/verify/evidence/read.js +12 -3
- package/dist/commands/verify/evidence/read.js.map +1 -1
- package/dist/commands/verify/frozen.js +45 -23
- package/dist/commands/verify/frozen.js.map +1 -1
- package/dist/commands/verify/record.js +69 -17
- package/dist/commands/verify/record.js.map +1 -1
- package/dist/commands/verify/report.js +27 -44
- package/dist/commands/verify/report.js.map +1 -1
- package/dist/commands/verify/results.js +112 -30
- package/dist/commands/verify/results.js.map +1 -1
- package/dist/commands/verify/verify.js +55 -52
- package/dist/commands/verify/verify.js.map +1 -1
- package/dist/commands/vouch/pack/pack.js +2 -2
- package/dist/commands/vouch/pack/pack.js.map +1 -1
- package/dist/commands/vouch/pack/print.js +1 -6
- package/dist/commands/vouch/pack/print.js.map +1 -1
- package/dist/commands/vouch/pack/sections.js +1 -2
- package/dist/commands/vouch/pack/sections.js.map +1 -1
- package/dist/commands/vouch/run.js +26 -81
- package/dist/commands/vouch/run.js.map +1 -1
- package/dist/commands/vouch/sample/plan.js +20 -34
- package/dist/commands/vouch/sample/plan.js.map +1 -1
- package/dist/commands/vouch/vet/verify.js +39 -7
- package/dist/commands/vouch/vet/verify.js.map +1 -1
- package/dist/commands/vouch/vouch.js +10 -17
- package/dist/commands/vouch/vouch.js.map +1 -1
- package/dist/core/agent/agents-md/command-map.js +81 -106
- package/dist/core/agent/agents-md/command-map.js.map +1 -1
- package/dist/core/agent/agents-md/map/explain.js +21 -9
- package/dist/core/agent/agents-md/map/explain.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/context.js +17 -8
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/diff.js +33 -20
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/gate.js +13 -5
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -1
- package/dist/core/agent/agents-md/map/mcp.js +10 -7
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -1
- package/dist/core/agent/agents-md/map/status.js +24 -8
- package/dist/core/agent/agents-md/map/status.js.map +1 -1
- package/dist/core/agent/agents-md/map/subsystem.js +80 -8
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -1
- package/dist/core/agent/agents-md/map/usecases.js +88 -10
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -1
- package/dist/core/agent/agents-md/refusals.js +49 -22
- package/dist/core/agent/agents-md/refusals.js.map +1 -1
- package/dist/core/agent/agents-md.js +39 -6
- package/dist/core/agent/agents-md.js.map +1 -1
- package/dist/core/agent/agents-stamp.js +10 -0
- package/dist/core/agent/agents-stamp.js.map +1 -1
- package/dist/core/agent/protocol.js +1 -1
- package/dist/core/agent/protocol.js.map +1 -1
- package/dist/core/agent/scaffold.js +10 -15
- package/dist/core/agent/scaffold.js.map +1 -1
- package/dist/core/agent/support/report.js +46 -5
- package/dist/core/agent/support/report.js.map +1 -1
- package/dist/core/agent/tools/dialects.js +1 -0
- package/dist/core/agent/tools/dialects.js.map +1 -1
- package/dist/core/agent/tools/registry.js +41 -76
- package/dist/core/agent/tools/registry.js.map +1 -1
- package/dist/core/agent/workflows/adopt.js +158 -11
- package/dist/core/agent/workflows/adopt.js.map +1 -1
- package/dist/core/agent/workflows/check.js +78 -39
- package/dist/core/agent/workflows/check.js.map +1 -1
- package/dist/core/agent/workflows/closing.js +88 -27
- package/dist/core/agent/workflows/closing.js.map +1 -1
- package/dist/core/agent/workflows/feature.js +128 -13
- package/dist/core/agent/workflows/feature.js.map +1 -1
- package/dist/core/agent/workflows/implement.js +96 -13
- package/dist/core/agent/workflows/implement.js.map +1 -1
- package/dist/core/agent/workflows/reference/authoring.js +106 -4
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -1
- package/dist/core/agent/workflows/reference/codes.js +8 -6
- package/dist/core/agent/workflows/reference/codes.js.map +1 -1
- package/dist/core/agent/workflows/reference/done-check.js +37 -15
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -1
- package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
- package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +6 -3
- package/dist/core/agent/workflows/reference/reference.js.map +1 -1
- package/dist/core/agent/workflows/reference/spine.js +68 -27
- package/dist/core/agent/workflows/reference/spine.js.map +1 -1
- package/dist/core/asyncapi/baseline/plan.js +14 -81
- package/dist/core/asyncapi/baseline/plan.js.map +1 -1
- package/dist/core/asyncapi/digest.js +30 -25
- package/dist/core/asyncapi/digest.js.map +1 -1
- package/dist/core/asyncapi/merge/components.js +5 -4
- package/dist/core/asyncapi/merge/components.js.map +1 -1
- package/dist/core/asyncapi/merge/error.js +7 -2
- package/dist/core/asyncapi/merge/error.js.map +1 -1
- package/dist/core/asyncapi/merge/markers.js +32 -50
- package/dist/core/asyncapi/merge/markers.js.map +1 -1
- package/dist/core/asyncapi/merge/merge.js +33 -53
- package/dist/core/asyncapi/merge/merge.js.map +1 -1
- package/dist/core/asyncapi/merge/pin.js +12 -36
- package/dist/core/asyncapi/merge/pin.js.map +1 -1
- package/dist/core/asyncapi/model.js.map +1 -1
- package/dist/core/asyncapi/read.js +36 -12
- package/dist/core/asyncapi/read.js.map +1 -1
- package/dist/core/brief/brief.js +96 -36
- package/dist/core/brief/brief.js.map +1 -1
- package/dist/core/brief/checks.js +138 -3
- package/dist/core/brief/checks.js.map +1 -1
- package/dist/core/brief/landscape.js +209 -130
- package/dist/core/brief/landscape.js.map +1 -1
- package/dist/core/brief/map/extend.js +84 -0
- package/dist/core/brief/map/extend.js.map +1 -0
- package/dist/core/brief/map/owed.js +266 -0
- package/dist/core/brief/map/owed.js.map +1 -0
- package/dist/core/brief/targets.js +109 -31
- package/dist/core/brief/targets.js.map +1 -1
- package/dist/core/brief/unchecked.js +14 -3
- package/dist/core/brief/unchecked.js.map +1 -1
- package/dist/core/c4/arch.js +90 -182
- package/dist/core/c4/arch.js.map +1 -1
- package/dist/core/c4/direction/direction.js +114 -0
- package/dist/core/c4/direction/direction.js.map +1 -0
- package/dist/core/c4/likec4.js +169 -14
- package/dist/core/c4/likec4.js.map +1 -1
- package/dist/core/c4/locate/unlocated.js +150 -0
- package/dist/core/c4/locate/unlocated.js.map +1 -0
- package/dist/core/c4/parsed/deployment.js +160 -0
- package/dist/core/c4/parsed/deployment.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -1
- package/dist/core/c4/parsed/values.js +54 -1
- package/dist/core/c4/parsed/values.js.map +1 -1
- package/dist/core/c4/parsed/view-ids.js +39 -1
- package/dist/core/c4/parsed/view-ids.js.map +1 -1
- package/dist/core/c4/prefetch/fleet.js +134 -0
- package/dist/core/c4/prefetch/fleet.js.map +1 -0
- package/dist/core/c4/project/architecture.js +123 -7
- package/dist/core/c4/project/architecture.js.map +1 -1
- package/dist/core/c4/project/batch.js +140 -0
- package/dist/core/c4/project/batch.js.map +1 -0
- package/dist/core/c4/project/documents.js +43 -12
- package/dist/core/c4/project/documents.js.map +1 -1
- package/dist/core/c4/project/load.js +79 -43
- package/dist/core/c4/project/load.js.map +1 -1
- package/dist/core/c4/project/staged.js +277 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/attested.js +0 -0
- package/dist/core/c4/resolve/attested.js.map +1 -0
- package/dist/core/c4/resolve/external.js +51 -0
- package/dist/core/c4/resolve/external.js.map +1 -0
- package/dist/core/c4/resolve/service.js +78 -17
- package/dist/core/c4/resolve/service.js.map +1 -1
- package/dist/core/c4/resolve/steps.js +290 -0
- package/dist/core/c4/resolve/steps.js.map +1 -0
- package/dist/core/c4/resolve/systems.js +154 -0
- package/dist/core/c4/resolve/systems.js.map +1 -0
- package/dist/core/c4/root-project/exclude.js +352 -0
- package/dist/core/c4/root-project/exclude.js.map +1 -0
- package/dist/core/c4/seed/template.js +65 -1
- package/dist/core/c4/seed/template.js.map +1 -1
- package/dist/core/c4/service-model/created/models.js +96 -0
- package/dist/core/c4/service-model/created/models.js.map +1 -0
- package/dist/core/c4/service-model/documents.js +47 -0
- package/dist/core/c4/service-model/documents.js.map +1 -0
- package/dist/core/c4/service-model/fleet/extending.js +82 -0
- package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
- package/dist/core/c4/service-model/load.js +165 -0
- package/dist/core/c4/service-model/load.js.map +1 -0
- package/dist/core/c4/service-model/renderer.js +128 -0
- package/dist/core/c4/service-model/renderer.js.map +1 -0
- package/dist/core/c4/service-model/shape.js +106 -0
- package/dist/core/c4/service-model/shape.js.map +1 -0
- package/dist/core/c4/service-model/slice.js +188 -0
- package/dist/core/c4/service-model/slice.js.map +1 -0
- package/dist/core/c4/source-mask.js +297 -10
- package/dist/core/c4/source-mask.js.map +1 -1
- package/dist/core/c4/source-scan.js +222 -141
- package/dist/core/c4/source-scan.js.map +1 -1
- package/dist/core/c4/splice/authored-source.js +79 -13
- package/dist/core/c4/splice/authored-source.js.map +1 -1
- package/dist/core/c4/splice/contract.js +20 -0
- package/dist/core/c4/splice/contract.js.map +1 -1
- package/dist/core/c4/splice/delta-blocks.js +20 -20
- package/dist/core/c4/splice/delta-blocks.js.map +1 -1
- package/dist/core/c4/splice/identity/declared.js +87 -0
- package/dist/core/c4/splice/identity/declared.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +37 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -1
- package/dist/core/c4/splice/identity/existing.js +80 -0
- package/dist/core/c4/splice/identity/existing.js.map +1 -0
- package/dist/core/c4/splice/identity/interior.js +80 -0
- package/dist/core/c4/splice/identity/interior.js.map +1 -0
- package/dist/core/c4/splice/identity/owner.js +50 -0
- package/dist/core/c4/splice/identity/owner.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +182 -114
- package/dist/core/c4/splice/landscape-merge.js.map +1 -1
- package/dist/core/c4/splice/model/merge.js +151 -0
- package/dist/core/c4/splice/model/merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +160 -56
- package/dist/core/c4/splice/placement.js.map +1 -1
- package/dist/core/c4/splice/text/spot.js +131 -0
- package/dist/core/c4/splice/text/spot.js.map +1 -0
- package/dist/core/c4/workspace.js +13 -19
- package/dist/core/c4/workspace.js.map +1 -1
- package/dist/core/capabilities/capabilities.js +6 -6
- package/dist/core/capabilities/capabilities.js.map +1 -1
- package/dist/core/capabilities/delta/doc.js +7 -10
- package/dist/core/capabilities/delta/doc.js.map +1 -1
- package/dist/core/capabilities/delta/uncovered.js +2 -2
- package/dist/core/capabilities/delta/uncovered.js.map +1 -1
- package/dist/core/capabilities/findings.js +18 -22
- package/dist/core/capabilities/findings.js.map +1 -1
- package/dist/core/capabilities/realizes/findings.js +12 -19
- package/dist/core/capabilities/realizes/findings.js.map +1 -1
- package/dist/core/capabilities/realizes/join.js +0 -20
- package/dist/core/capabilities/realizes/join.js.map +1 -1
- package/dist/core/capabilities/rollup.js +6 -0
- package/dist/core/capabilities/rollup.js.map +1 -1
- package/dist/core/capabilities/tree.js +6 -28
- package/dist/core/capabilities/tree.js.map +1 -1
- package/dist/core/capabilities/usecase-join.js +3 -13
- package/dist/core/capabilities/usecase-join.js.map +1 -1
- package/dist/core/coherence/authoring/scaffold.js +11 -3
- package/dist/core/coherence/authoring/scaffold.js.map +1 -1
- package/dist/core/coherence/authoring/sentinels.js +2 -1
- package/dist/core/coherence/authoring/sentinels.js.map +1 -1
- package/dist/core/coherence/calls/called.js +52 -0
- package/dist/core/coherence/calls/called.js.map +1 -0
- package/dist/core/coherence/coherence.js +103 -22
- package/dist/core/coherence/coherence.js.map +1 -1
- package/dist/core/coherence/consumed/operations.js +70 -0
- package/dist/core/coherence/consumed/operations.js.map +1 -0
- package/dist/core/coherence/consumed/refusal.js +38 -0
- package/dist/core/coherence/consumed/refusal.js.map +1 -0
- package/dist/core/coherence/covers/health.js +85 -0
- package/dist/core/coherence/covers/health.js.map +1 -0
- package/dist/core/coherence/declared.js +60 -34
- package/dist/core/coherence/declared.js.map +1 -1
- package/dist/core/coherence/events/declared.js +44 -59
- package/dist/core/coherence/events/declared.js.map +1 -1
- package/dist/core/coherence/events/events.js +147 -16
- package/dist/core/coherence/events/events.js.map +1 -1
- package/dist/core/coherence/events/grades.js +31 -8
- package/dist/core/coherence/events/grades.js.map +1 -1
- package/dist/core/coherence/events/lookups.js +28 -87
- package/dist/core/coherence/events/lookups.js.map +1 -1
- package/dist/core/coherence/events/produced.js +100 -0
- package/dist/core/coherence/events/produced.js.map +1 -0
- package/dist/core/coherence/lookups.js +18 -78
- package/dist/core/coherence/lookups.js.map +1 -1
- package/dist/core/coherence/retired/archived.js +285 -0
- package/dist/core/coherence/retired/archived.js.map +1 -0
- package/dist/core/coherence/retired/event-pair.js +62 -0
- package/dist/core/coherence/retired/event-pair.js.map +1 -0
- package/dist/core/coherence/retired/merged.js +79 -0
- package/dist/core/coherence/retired/merged.js.map +1 -0
- package/dist/core/coherence/retired/retirement.js +49 -0
- package/dist/core/coherence/retired/retirement.js.map +1 -0
- package/dist/core/coherence/retired/revival/arrivals.js +131 -0
- package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
- package/dist/core/coherence/retired/revival/revived.js +297 -0
- package/dist/core/coherence/retired/revival/revived.js.map +1 -0
- package/dist/core/consumers/after.js +113 -0
- package/dist/core/consumers/after.js.map +1 -0
- package/dist/core/consumers/consumers.js +296 -0
- package/dist/core/consumers/consumers.js.map +1 -0
- package/dist/core/consumers/current.js +211 -0
- package/dist/core/consumers/current.js.map +1 -0
- package/dist/core/consumers/scan.js +46 -0
- package/dist/core/consumers/scan.js.map +1 -0
- package/dist/core/consumers/state.js +27 -0
- package/dist/core/consumers/state.js.map +1 -0
- package/dist/core/delta/delta.js +51 -6
- package/dist/core/delta/delta.js.map +1 -1
- package/dist/core/dependencies/fanin.js +2 -2
- package/dist/core/dependencies/fanin.js.map +1 -1
- package/dist/core/deployment/delta.js +191 -0
- package/dist/core/deployment/delta.js.map +1 -0
- package/dist/core/deployment/objects.js +145 -0
- package/dist/core/deployment/objects.js.map +1 -0
- package/dist/core/diff/base-git.js +94 -12
- package/dist/core/diff/base-git.js.map +1 -1
- package/dist/core/diff/base-state.js +49 -21
- package/dist/core/diff/base-state.js.map +1 -1
- package/dist/core/diff/joins.js +136 -0
- package/dist/core/diff/joins.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +22 -6
- package/dist/core/diff/scope/changed-paths.js.map +1 -1
- package/dist/core/diff/scope/edges.js +82 -0
- package/dist/core/diff/scope/edges.js.map +1 -0
- package/dist/core/diff/semantic.js +100 -31
- package/dist/core/diff/semantic.js.map +1 -1
- package/dist/core/docs.js +31 -22
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +34 -18
- package/dist/core/doctor/agents.js.map +1 -1
- package/dist/core/doctor/config.js +7 -3
- package/dist/core/doctor/config.js.map +1 -1
- package/dist/core/doctor/doctor.js +91 -11
- package/dist/core/doctor/doctor.js.map +1 -1
- package/dist/core/doctor/report.js.map +1 -1
- package/dist/core/doctor/reports/scan.js +242 -0
- package/dist/core/doctor/reports/scan.js.map +1 -0
- package/dist/core/document/apply.js +158 -11
- package/dist/core/document/apply.js.map +1 -1
- package/dist/core/document/frontmatter.js +55 -0
- package/dist/core/document/frontmatter.js.map +1 -1
- package/dist/core/document/parse.js +29 -6
- package/dist/core/document/parse.js.map +1 -1
- package/dist/core/document/scenarios.js +17 -0
- package/dist/core/document/scenarios.js.map +1 -1
- package/dist/core/document/spec.js +4 -11
- package/dist/core/document/spec.js.map +1 -1
- package/dist/core/envelope/config.js +10 -0
- package/dist/core/envelope/config.js.map +1 -1
- package/dist/core/envelope/json.js +34 -0
- package/dist/core/envelope/json.js.map +1 -1
- package/dist/core/explain/families.js +26 -21
- package/dist/core/explain/families.js.map +1 -1
- package/dist/core/explain/lookup.js +14 -1
- package/dist/core/explain/lookup.js.map +1 -1
- package/dist/core/explain/refusals.js +5 -5
- package/dist/core/explain/refusals.js.map +1 -1
- package/dist/core/explain/terms/documents.js +227 -0
- package/dist/core/explain/terms/documents.js.map +1 -0
- package/dist/core/explain/terms/done-check.js +144 -0
- package/dist/core/explain/terms/done-check.js.map +1 -0
- package/dist/core/explain/terms/entry.js +14 -0
- package/dist/core/explain/terms/entry.js.map +1 -0
- package/dist/core/explain/terms/stages.js +71 -0
- package/dist/core/explain/terms/stages.js.map +1 -0
- package/dist/core/explain/terms/tasks.js +97 -0
- package/dist/core/explain/terms/tasks.js.map +1 -0
- package/dist/core/explain/terms.js +68 -109
- package/dist/core/explain/terms.js.map +1 -1
- package/dist/core/explore/explore.js +40 -10
- package/dist/core/explore/explore.js.map +1 -1
- package/dist/core/fleet-context.js +81 -95
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +11 -4
- package/dist/core/gate/checks.js.map +1 -1
- package/dist/core/gate/partners.js +69 -28
- package/dist/core/gate/partners.js.map +1 -1
- package/dist/core/gate/report.js.map +1 -1
- package/dist/core/gate/verification.js +75 -12
- package/dist/core/gate/verification.js.map +1 -1
- package/dist/core/gherkin/stale.js +13 -37
- package/dist/core/gherkin/stale.js.map +1 -1
- package/dist/core/glossary/delta.js +10 -7
- package/dist/core/glossary/delta.js.map +1 -1
- package/dist/core/glossary/tree.js +6 -19
- package/dist/core/glossary/tree.js.map +1 -1
- package/dist/core/kernel/concurrency.js +19 -0
- package/dist/core/kernel/concurrency.js.map +1 -1
- package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
- package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
- package/dist/core/kernel/path-safety.js +38 -0
- package/dist/core/kernel/path-safety.js.map +1 -1
- package/dist/core/kernel/records.js +11 -0
- package/dist/core/kernel/records.js.map +1 -1
- package/dist/core/links/backlinks.js +1 -3
- package/dist/core/links/backlinks.js.map +1 -1
- package/dist/core/links/corpus.js +51 -37
- package/dist/core/links/corpus.js.map +1 -1
- package/dist/core/links/findings.js.map +1 -1
- package/dist/core/links/parse.js +38 -9
- package/dist/core/links/parse.js.map +1 -1
- package/dist/core/mcp/argv.js +101 -0
- package/dist/core/mcp/argv.js.map +1 -1
- package/dist/core/mcp/author-tools.js +2 -1
- package/dist/core/mcp/author-tools.js.map +1 -1
- package/dist/core/mcp/protocol.js +2 -2
- package/dist/core/mcp/protocol.js.map +1 -1
- package/dist/core/mcp/tools.js +43 -33
- package/dist/core/mcp/tools.js.map +1 -1
- package/dist/core/openapi/baseline/gate.js +53 -12
- package/dist/core/openapi/baseline/gate.js.map +1 -1
- package/dist/core/openapi/baseline/plan.js +40 -10
- package/dist/core/openapi/baseline/plan.js.map +1 -1
- package/dist/core/openapi/baseline/record.js +0 -1
- package/dist/core/openapi/baseline/record.js.map +1 -1
- package/dist/core/openapi/contract-text.js +33 -0
- package/dist/core/openapi/contract-text.js.map +1 -0
- package/dist/core/openapi/contract-tree.js +301 -0
- package/dist/core/openapi/contract-tree.js.map +1 -0
- package/dist/core/openapi/depth.js +38 -24
- package/dist/core/openapi/depth.js.map +1 -1
- package/dist/core/openapi/digest.js +52 -2
- package/dist/core/openapi/digest.js.map +1 -1
- package/dist/core/openapi/doc.js +12 -4
- package/dist/core/openapi/doc.js.map +1 -1
- package/dist/core/openapi/merge/components.js +25 -60
- package/dist/core/openapi/merge/components.js.map +1 -1
- package/dist/core/openapi/merge/error.js +3 -13
- package/dist/core/openapi/merge/error.js.map +1 -1
- package/dist/core/openapi/merge/markers.js +26 -30
- package/dist/core/openapi/merge/markers.js.map +1 -1
- package/dist/core/openapi/merge/merge.js +28 -52
- package/dist/core/openapi/merge/merge.js.map +1 -1
- package/dist/core/openapi/merge/pin.js +17 -35
- package/dist/core/openapi/merge/pin.js.map +1 -1
- package/dist/core/openspec/decide/verdict.js.map +1 -1
- package/dist/core/openspec/inventory.js +4 -5
- package/dist/core/openspec/inventory.js.map +1 -1
- package/dist/core/openspec/model/mapping.js +30 -28
- package/dist/core/openspec/model/mapping.js.map +1 -1
- package/dist/core/openspec/model/model.js +12 -7
- package/dist/core/openspec/model/model.js.map +1 -1
- package/dist/core/openspec/scan/changes.js +10 -4
- package/dist/core/openspec/scan/changes.js.map +1 -1
- package/dist/core/openspec/scan/config.js +7 -16
- package/dist/core/openspec/scan/config.js.map +1 -1
- package/dist/core/openspec/scan/shape.js +63 -19
- package/dist/core/openspec/scan/shape.js.map +1 -1
- package/dist/core/openspec/scan/walk.js +21 -38
- package/dist/core/openspec/scan/walk.js.map +1 -1
- package/dist/core/pack/living.js +43 -4
- package/dist/core/pack/living.js.map +1 -1
- package/dist/core/pack/pack.js +50 -6
- package/dist/core/pack/pack.js.map +1 -1
- package/dist/core/projection/arch-slice.js +2 -2
- package/dist/core/projection/arch-slice.js.map +1 -1
- package/dist/core/projection/introduced.js +14 -0
- package/dist/core/projection/introduced.js.map +1 -0
- package/dist/core/provenance/findings.js +48 -12
- package/dist/core/provenance/findings.js.map +1 -1
- package/dist/core/provenance/git.js +33 -57
- package/dist/core/provenance/git.js.map +1 -1
- package/dist/core/provenance/gitq/moves.js +71 -114
- package/dist/core/provenance/gitq/moves.js.map +1 -1
- package/dist/core/provenance/gitq/vouched-ancestor.js +2 -2
- package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -1
- package/dist/core/provenance/sources.js +23 -6
- package/dist/core/provenance/sources.js.map +1 -1
- package/dist/core/provenance/stamp.js +5 -17
- package/dist/core/provenance/stamp.js.map +1 -1
- package/dist/core/repo/authored/paths.js +18 -0
- package/dist/core/repo/authored/paths.js.map +1 -1
- package/dist/core/repo/entries.js.map +1 -1
- package/dist/core/repo/paths.js +92 -6
- package/dist/core/repo/paths.js.map +1 -1
- package/dist/core/repo/repo.js +74 -14
- package/dist/core/repo/repo.js.map +1 -1
- package/dist/core/repo/tree/find.js +12 -3
- package/dist/core/repo/tree/find.js.map +1 -1
- package/dist/core/repo/tree/fs.js +27 -1
- package/dist/core/repo/tree/fs.js.map +1 -1
- package/dist/core/repo/tree/render/body.js +258 -0
- package/dist/core/repo/tree/render/body.js.map +1 -0
- package/dist/core/repo/tree/render/projects.js +182 -0
- package/dist/core/repo/tree/render/projects.js.map +1 -0
- package/dist/core/repo/tree/render/service/header.js +125 -0
- package/dist/core/repo/tree/render/service/header.js.map +1 -0
- package/dist/core/repo/tree/render/service/peers.js +28 -0
- package/dist/core/repo/tree/render/service/peers.js.map +1 -0
- package/dist/core/repo/tree/render/service/view-id.js +67 -0
- package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
- package/dist/core/repo/tree/render/service/views.js +78 -0
- package/dist/core/repo/tree/render/service/views.js.map +1 -0
- package/dist/core/repo/tree/render/stale.js +42 -0
- package/dist/core/repo/tree/render/stale.js.map +1 -0
- package/dist/core/repo/tree/render/text.js +84 -0
- package/dist/core/repo/tree/render/text.js.map +1 -0
- package/dist/core/repo/tree/render/views.js +293 -0
- package/dist/core/repo/tree/render/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +53 -32
- package/dist/core/repo/tree/walk.js.map +1 -1
- package/dist/core/results.js +47 -12
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +121 -13
- package/dist/core/scaffold/landscape.js.map +1 -1
- package/dist/core/scaffold/legacy.js +271 -0
- package/dist/core/scaffold/legacy.js.map +1 -0
- package/dist/core/staging/commit.js +26 -15
- package/dist/core/staging/commit.js.map +1 -1
- package/dist/core/staging/lock.js +74 -12
- package/dist/core/staging/lock.js.map +1 -1
- package/dist/core/staging/recovery/intent.js +2 -5
- package/dist/core/staging/recovery/intent.js.map +1 -1
- package/dist/core/staging/recovery/recover.js +84 -6
- package/dist/core/staging/recovery/recover.js.map +1 -1
- package/dist/core/staging/snapshot/manifest.js +188 -0
- package/dist/core/staging/snapshot/manifest.js.map +1 -0
- package/dist/core/staging/{snapshot.js → snapshot/snapshot.js} +39 -45
- package/dist/core/staging/snapshot/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +24 -14
- package/dist/core/staging/txn/forward.js.map +1 -1
- package/dist/core/staging/writes.js.map +1 -1
- package/dist/core/status/actions/execution.js +11 -0
- package/dist/core/status/actions/execution.js.map +1 -1
- package/dist/core/status/contracts.js +39 -15
- package/dist/core/status/contracts.js.map +1 -1
- package/dist/core/status/feature/artifacts.js +33 -8
- package/dist/core/status/feature/artifacts.js.map +1 -1
- package/dist/core/status/feature/feature.js +24 -17
- package/dist/core/status/feature/feature.js.map +1 -1
- package/dist/core/status/feature/next.js +20 -7
- package/dist/core/status/feature/next.js.map +1 -1
- package/dist/core/status/feature/words.js +96 -0
- package/dist/core/status/feature/words.js.map +1 -0
- package/dist/core/status/fleet/fleet.js +43 -14
- package/dist/core/status/fleet/fleet.js.map +1 -1
- package/dist/core/status/fleet/next.js +153 -58
- package/dist/core/status/fleet/next.js.map +1 -1
- package/dist/core/status/report.js.map +1 -1
- package/dist/core/status/scan.js.map +1 -1
- package/dist/core/status/verification.js +30 -15
- package/dist/core/status/verification.js.map +1 -1
- package/dist/core/tasks/packet.js +199 -0
- package/dist/core/tasks/packet.js.map +1 -0
- package/dist/core/tasks/record.js +43 -0
- package/dist/core/tasks/record.js.map +1 -0
- package/dist/core/tasks/sources.js +181 -0
- package/dist/core/tasks/sources.js.map +1 -0
- package/dist/core/tasks/stamps.js +76 -0
- package/dist/core/tasks/stamps.js.map +1 -0
- package/dist/core/tasks/unit.js +0 -0
- package/dist/core/tasks/unit.js.map +1 -0
- package/dist/core/usecases/capability.js +11 -14
- package/dist/core/usecases/capability.js.map +1 -1
- package/dist/core/usecases/delta/claims.js +31 -7
- package/dist/core/usecases/delta/claims.js.map +1 -1
- package/dist/core/usecases/delta/flows.js +5 -7
- package/dist/core/usecases/delta/flows.js.map +1 -1
- package/dist/core/usecases/delta/modified.js +315 -0
- package/dist/core/usecases/delta/modified.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +32 -191
- package/dist/core/usecases/delta/overlay.js.map +1 -1
- package/dist/core/usecases/fleet.js +195 -36
- package/dist/core/usecases/fleet.js.map +1 -1
- package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/capability-tag.js +8 -9
- package/dist/core/usecases/grade/capability-tag.js.map +1 -0
- package/dist/core/usecases/grade/feature.js +88 -0
- package/dist/core/usecases/grade/feature.js.map +1 -0
- package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/requirement-tag.js +3 -4
- package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
- package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/steps.js +102 -33
- package/dist/core/usecases/grade/steps.js.map +1 -0
- package/dist/{commands/validate/fleet/usecases → core/usecases/grade}/usecases.js +23 -10
- package/dist/core/usecases/grade/usecases.js.map +1 -0
- package/dist/core/usecases/operations.js +26 -14
- package/dist/core/usecases/operations.js.map +1 -1
- package/dist/core/usecases/place.js.map +1 -1
- package/dist/core/usecases/service/exclude.js +119 -0
- package/dist/core/usecases/service/exclude.js.map +1 -0
- package/dist/core/usecases/service/flows.js +164 -0
- package/dist/core/usecases/service/flows.js.map +1 -0
- package/dist/core/usecases/suites/participants.js +83 -0
- package/dist/core/usecases/suites/participants.js.map +1 -0
- package/dist/core/usecases/suites/suites.js +45 -0
- package/dist/core/usecases/suites/suites.js.map +1 -0
- package/dist/core/verify/answers.js +12 -5
- package/dist/core/verify/answers.js.map +1 -1
- package/dist/core/verify/build.js +102 -82
- package/dist/core/verify/build.js.map +1 -1
- package/dist/core/verify/checklist.js +70 -12
- package/dist/core/verify/checklist.js.map +1 -1
- package/dist/core/verify/location.js +67 -0
- package/dist/core/verify/location.js.map +1 -0
- package/dist/core/verify/pins/lint.js +3 -2
- package/dist/core/verify/pins/lint.js.map +1 -1
- package/dist/core/verify/pins/pin.js +1 -1
- package/dist/core/verify/pins/pin.js.map +1 -1
- package/dist/core/verify/read/file.js +224 -0
- package/dist/core/verify/read/file.js.map +1 -0
- package/dist/core/verify/{file.js → read/shape.js} +16 -104
- package/dist/core/verify/read/shape.js.map +1 -0
- package/dist/core/verify/read/union.js +105 -0
- package/dist/core/verify/read/union.js.map +1 -0
- package/dist/core/verify/record.js +35 -12
- package/dist/core/verify/record.js.map +1 -1
- package/dist/core/verify/store/commit.js +40 -30
- package/dist/core/verify/store/commit.js.map +1 -1
- package/dist/core/verify/store/render.js +8 -4
- package/dist/core/verify/store/render.js.map +1 -1
- package/dist/core/vocabulary/issue.js +4 -0
- package/dist/core/vocabulary/issue.js.map +1 -1
- package/dist/core/vocabulary/maturity.js +75 -4
- package/dist/core/vocabulary/maturity.js.map +1 -1
- package/dist/core/vocabulary/report.js +16 -1
- package/dist/core/vocabulary/report.js.map +1 -1
- package/examples/README.md +54 -11
- package/examples/docs/architecture/landscape.likec4 +62 -6
- package/examples/docs/architecture/services.likec4 +70 -0
- package/examples/docs/architecture/subsystems.likec4 +7 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +16 -7
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +11 -8
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +6 -6
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +4 -1
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +13 -10
- package/examples/docs/likec4.config.json +0 -1
- package/examples/docs/services/checkout-web/model.likec4 +39 -56
- package/examples/docs/services/order-service/arch.spec.md +13 -6
- package/examples/docs/services/order-service/asyncapi.yaml +3 -2
- package/examples/docs/services/order-service/model.likec4 +58 -70
- package/examples/docs/services/payment-service/arch.spec.md +7 -4
- package/examples/docs/services/payment-service/model.likec4 +38 -37
- package/examples/docs/services/platform/identity-service/arch.spec.md +7 -4
- package/examples/docs/services/platform/identity-service/model.likec4 +35 -37
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +2 -1
- package/examples/docs/services/platform/notification-service/health.yaml +8 -3
- package/examples/docs/services/platform/notification-service/model.likec4 +43 -64
- package/package.json +1 -1
- package/dist/commands/validate/checks/vocabulary.js +0 -31
- package/dist/commands/validate/checks/vocabulary.js.map +0 -1
- package/dist/commands/validate/fleet/usecases/capability-tag.js.map +0 -1
- package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +0 -1
- package/dist/commands/validate/fleet/usecases/steps.js.map +0 -1
- package/dist/commands/validate/fleet/usecases/usecases.js.map +0 -1
- package/dist/core/agent/agents-md/artifacts.js +0 -220
- package/dist/core/agent/agents-md/artifacts.js.map +0 -1
- package/dist/core/agent/agents-md/cycle.js +0 -165
- package/dist/core/agent/agents-md/cycle.js.map +0 -1
- package/dist/core/agent/agents-md/shipped/archive-gate.js +0 -98
- package/dist/core/agent/agents-md/shipped/archive-gate.js.map +0 -1
- package/dist/core/agent/agents-md/spine.js +0 -40
- package/dist/core/agent/agents-md/spine.js.map +0 -1
- package/dist/core/coherence/events/merged.js +0 -40
- package/dist/core/coherence/events/merged.js.map +0 -1
- package/dist/core/diff/current-state.js +0 -96
- package/dist/core/diff/current-state.js.map +0 -1
- package/dist/core/diff/victims.js +0 -247
- package/dist/core/diff/victims.js.map +0 -1
- package/dist/core/repo/tree/views.js +0 -172
- package/dist/core/repo/tree/views.js.map +0 -1
- package/dist/core/staging/snapshot.js.map +0 -1
- package/dist/core/verify/file.js.map +0 -1
package/ROADMAP.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Roadmap
|
|
2
2
|
|
|
3
|
-
_Assessed 2026-
|
|
3
|
+
_Assessed 2026-09-03._
|
|
4
4
|
|
|
5
5
|
This is loam's canonical improvement sequence. It records priorities and exit criteria, not delivery
|
|
6
6
|
dates. An item is complete only when its exit criteria are supported by repeatable evidence; moving
|
|
@@ -18,26 +18,30 @@ acceptance tests, and implementation evidence remain ordinary files in repositor
|
|
|
18
18
|
state inside a service. The CLI is small enough to audit, and every writer — not only archive — now
|
|
19
19
|
commits through a locked, journaled transaction that a crash cannot leave half-applied.
|
|
20
20
|
|
|
21
|
-
The tree contains **
|
|
21
|
+
The tree contains **531 TypeScript modules in 166 source packages**, with an acyclic package graph
|
|
22
22
|
checked by
|
|
23
23
|
[scripts/package-graph.mjs](https://github.com/ybotok/loam/blob/main/scripts/package-graph.mjs). The
|
|
24
|
-
CLI exposes **
|
|
25
|
-
and the suite stands at **
|
|
24
|
+
CLI exposes **30 commands** from [src/cli.ts](https://github.com/ybotok/loam/blob/main/src/cli.ts),
|
|
25
|
+
and the suite stands at **205 test files**. Those four counts are deliberately stated OUTSIDE the
|
|
26
26
|
dated snapshot below: each derives from the tree in one readdir, so
|
|
27
27
|
[test/docs-facts.test.ts](https://github.com/ybotok/loam/blob/main/test/docs-facts.test.ts) grades
|
|
28
28
|
them live and this paragraph cannot quietly trail the code the way its predecessor did.
|
|
29
29
|
|
|
30
|
-
_Measured 2026-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
_Measured 2026-09-07 at `0.2.0-alpha.7`, and dated because neither number has a cheap derivation:_
|
|
31
|
+
lint, typecheck, `npm run arch:check` and `npm run meta:check` green; `npm test` passing
|
|
32
|
+
**3,802/3,802 tests**, with two `skipIf(asRoot)` cases the root gate container cannot run; the
|
|
33
|
+
coverage gate passing with **92.88% statements, 84.83% branches, 97.14% functions, and 94.70%
|
|
34
|
+
lines** against its thresholds of 91 / 82 / 95 / 93; and `npm run release:check` plus
|
|
35
|
+
`npm run test:package` green against the real tarball.
|
|
36
|
+
|
|
37
|
+
Most of that qualification is now closed by observation rather than by code. Measured 2026-09-03 on
|
|
38
|
+
pushed commits: `ci` at `1de7c97` green — `test` on Node 22.22.3 and 24, and the installed-package
|
|
39
|
+
`package` job on ubuntu (both Node lines) and windows — and the `release` workflow on tag
|
|
40
|
+
`v0.2.0-alpha.4` green end to end, `release-gate` (lint, typecheck, coverage, the packed candidate,
|
|
41
|
+
the smoke of that exact candidate, `release:check`) followed by `publish`, which put the tarball on
|
|
42
|
+
npm under the `alpha` dist-tag. What is left is one job: `stability` is SKIPPED on a push — it runs
|
|
43
|
+
on the weekly schedule and on dispatch — so it is still release evidence to collect, even though the
|
|
44
|
+
gate-stress proof passes locally. The runner class recorded on 2026-08-18 is
|
|
41
45
|
still the reading to apply to a red of that shape: a restricted filesystem sandbox that denies `tsx`
|
|
42
46
|
its local IPC socket fails only the
|
|
43
47
|
[test/cli-entry.test.ts](https://github.com/ybotok/loam/blob/main/test/cli-entry.test.ts) cases with
|
|
@@ -98,14 +102,19 @@ The strongest foundations to preserve are:
|
|
|
98
102
|
## Now
|
|
99
103
|
|
|
100
104
|
Nothing is queued behind code. Every integrity, enforcement and lifecycle item that preceded this
|
|
101
|
-
has landed (see [Recently landed](#recently-landed)) — the authored business axis
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
has landed (see [Recently landed](#recently-landed)) — the authored business axis, the use-case
|
|
106
|
+
axis, and as of 2026-09-02 the deployment axis, which is the first item this file ever wrote
|
|
107
|
+
directly into this section rather than promoting from [Later](#later--promote-only-from-evidence).
|
|
108
|
+
|
|
109
|
+
### Release evidence — one job left
|
|
104
110
|
|
|
105
111
|
What is left is the one thing this file cannot close by writing code, and it stays where it is
|
|
106
|
-
rather than being promoted
|
|
107
|
-
|
|
108
|
-
|
|
112
|
+
rather than being promoted for the shape of it. The installed-package half closed on 2026-09-03:
|
|
113
|
+
the `package` job ran green on a pushed commit across three runner/Node combinations, and the whole
|
|
114
|
+
publication path ran green on tag `v0.2.0-alpha.4`. The CI `stability` job has still to be OBSERVED
|
|
115
|
+
green — it is skipped on a push and runs on the weekly schedule — so it is still release evidence to
|
|
116
|
+
collect, not an improvement to make. `workflow_dispatch` is the way to collect it deliberately
|
|
117
|
+
rather than waiting for Monday.
|
|
109
118
|
|
|
110
119
|
An item returns to this section from [Later](#later--promote-only-from-evidence) when fleet evidence
|
|
111
120
|
names its operator, repeated task, failure mode, frequency, current workaround and measurable
|
|
@@ -118,9 +127,452 @@ exactly the invented need the non-goals forbid.
|
|
|
118
127
|
Closed since the 2026-08-18 assessment, each with the commit or commit range that landed it on
|
|
119
128
|
`main`. [CHANGELOG.md](CHANGELOG.md) is the user-facing record; the full item texts — required
|
|
120
129
|
changes, exit criteria, and what each review surfaced — are in this file's history (`git show
|
|
121
|
-
5cd3942:ROADMAP.md`). The
|
|
122
|
-
|
|
123
|
-
|
|
130
|
+
5cd3942:ROADMAP.md`). The four 2026-09-03 problem-report entries that follow — the extending model
|
|
131
|
+
and the report ordinal, the pair opening the 2026-09-04 group — landed together in `f751909`, one
|
|
132
|
+
change built as four disjoint workstreams and gated as one; the three before them — the edgeless
|
|
133
|
+
brief, the intra-service use case, and the styling paragraph under the generated views — landed
|
|
134
|
+
together in `0eaa101` the same way.
|
|
135
|
+
|
|
136
|
+
#### The work packet — the verify checklist read forwards
|
|
137
|
+
|
|
138
|
+
**Landed 2026-09-21.** loam could already say what a feature PROMISES (`loam verify`'s checklist)
|
|
139
|
+
and what to BUILD (`loam delta`), and nothing joined the two into the question an agent actually
|
|
140
|
+
opens a session with: which promise is still open, at which step, and what fact closes it. The
|
|
141
|
+
artifact a team reaches for to answer it is a `tasks.md` — the one document this project refuses,
|
|
142
|
+
because a task list authored beside a spec is a second mutable state that drifts the moment the
|
|
143
|
+
spec moves. That refusal (SCHEMA's "Deliberate limits of the workflow surface") is unchanged; what
|
|
144
|
+
this item settles is that the question was never the problem, only the file.
|
|
145
|
+
|
|
146
|
+
**What landed.** A read-only `loam tasks <FEAT> [--service <id>] [--next] [--json]`, and a
|
|
147
|
+
`loam_tasks` MCP tool beside it, projecting one work unit per verify-checklist claim under the
|
|
148
|
+
claim's own id — so the thing to do and the answer that closes it are one identity — plus a unit
|
|
149
|
+
of kind requirement.described for an ADDED or MODIFIED requirement with no scenario at all. Each
|
|
150
|
+
unit reports the step it waits on in `at` (`describe`, `generate`, `implement`, `attested`), and a
|
|
151
|
+
unit is retired by exactly one fact: a claim recorded `confirmed` in a `verification.yaml` that is
|
|
152
|
+
not stale against the current checklist. An agent-attested scenario deliberately stays on the list
|
|
153
|
+
at `attested`. `frontier` is the first ten open units, providers before consumers on the exact token
|
|
154
|
+
join and never on prose, and the order is advice rather than a lock; `--next` is the single leaf
|
|
155
|
+
packet — scenario verbatim, digest, the check that closes it, the follow-up command — that an
|
|
156
|
+
orchestrator hands one coding agent. Nothing is written to disk on any path, and no stable code was
|
|
157
|
+
minted: every fact in the payload is a projection of state other commands already grade. CHANGELOG
|
|
158
|
+
has every flag and payload key; SCHEMA's "The same checklist read forwards" has the unit model and
|
|
159
|
+
the done rule.
|
|
160
|
+
|
|
161
|
+
**Deliberately NOT built, each with its reason.** None of these is a gap nobody noticed.
|
|
162
|
+
|
|
163
|
+
- **`--results` refinement against a live red/green run** — it needs the report readers re-exposed
|
|
164
|
+
read-only, which is a seam rather than a flag.
|
|
165
|
+
- **A status rung for tasks in `loam status`'s `next[]`** — that is a new stable `next.*` code, and
|
|
166
|
+
minting one is a separate decision on a frozen surface.
|
|
167
|
+
- **Removal-direction units** — a retirement's consumers are answered in prose by the consumer
|
|
168
|
+
scans today, and a unit would be a second account of the same walk.
|
|
169
|
+
- **Obligation-coverage units** — `covers()` never checks that a scenario exists, so a unit derived
|
|
170
|
+
from an obligation would assert work nothing grades.
|
|
171
|
+
- **A `size.phrasesOwed` figure from `loam steps`** — the step inventory is a report about a
|
|
172
|
+
service's whole suite, not about one feature's units, and joining them would put a fleet-wide
|
|
173
|
+
number inside a per-feature packet.
|
|
174
|
+
- **A Jira (or any tracker) export protocol** — that is an agent workflow over `--json` and stays
|
|
175
|
+
one: an HTTP call from loam is the network dependency the product does not have.
|
|
176
|
+
|
|
177
|
+
**Exit criteria**, each answerable by one run rather than by a reading: a unit leaves the list only
|
|
178
|
+
when a confirmed claim in a non-stale record retires it, and an attested scenario is still on the
|
|
179
|
+
list at `attested`; the frontier's provider-before-consumer order comes from the exact operation
|
|
180
|
+
token join and from nowhere else; and a run writes no byte and mints no code, so the projection
|
|
181
|
+
cannot be behind the documents it projected.
|
|
182
|
+
|
|
183
|
+
#### One model, many documents — a service model may extend the fleet map
|
|
184
|
+
|
|
185
|
+
**Landed 2026-09-04** in `f751909`, from three problem reports that turned out to be one cause,
|
|
186
|
+
with a fourth landing beside it in the same change. #010 measured the cause: a service model must
|
|
187
|
+
parse alone, so it re-declares its own `specification` and every partner it names — 78 double
|
|
188
|
+
declarations in a 56-service fleet with four services adopted, projected to ~448 at full adoption —
|
|
189
|
+
and the copies had already diverged, `#platform` missing from every copy of the broker and the
|
|
190
|
+
identity provider but the map's, with no finding code for "two documents describe one element
|
|
191
|
+
differently" because no check read two documents together. #009 measured the symptom: 57 flat
|
|
192
|
+
entries in the renderer's project picker, 52 of them a single box, forced by the per-service
|
|
193
|
+
project file `0.2.0-alpha.5` had to write **because** the models could not share a project. #011 is
|
|
194
|
+
the structural proposal, every claim of it executed against copies of `examples/docs`: `extend`
|
|
195
|
+
resolves across documents of one project, a model rewritten that way makes its containers visible
|
|
196
|
+
in the fleet project with one copy of the broker in the whole model, and deleting a model's
|
|
197
|
+
`specification` under the old loader is eleven `c4.invalid` errors — so the change had to be
|
|
198
|
+
loam's, not a convention a repository could adopt. (#012, reports having no ordinal and loam never
|
|
199
|
+
reading `loam-reports/`, landed in the same commit and has its own entry below.)
|
|
200
|
+
|
|
201
|
+
**What landed.** The shape of a model is now read from the file's own grammar — a top-level
|
|
202
|
+
`specification { }` block containing an `element` declaration means STANDALONE, its absence means
|
|
203
|
+
EXTENDING — and each shape gets the grade the other cannot need: `c4.declaration-diverged` for a
|
|
204
|
+
standalone model whose copies of the map's elements disagree with it, `c4.element-unowned` for an
|
|
205
|
+
extending model that declares an element outside its own. Around them, the renderer wiring
|
|
206
|
+
`loam subsystem sync` now owns end to end (`service.likec4-config-stray`, `service.model-excluded`,
|
|
207
|
+
`service.model-unexcluded`, the narrowed `service.likec4-config-missing`, and the root project's
|
|
208
|
+
`exclude` rewritten to cover exactly the models that stand alone), and `c4.fleet-project-invalid`,
|
|
209
|
+
which loads the fleet project the way the renderer builds it and reports what only that load can
|
|
210
|
+
see. `examples/docs` is migrated whole, and its ten deliberate warnings are unchanged. CHANGELOG
|
|
211
|
+
has every code, key and message; SCHEMA's new "Two shapes of a service model" has the rules and the
|
|
212
|
+
migration recipe.
|
|
213
|
+
|
|
214
|
+
**Rejected, each with the reason.** Migrating repositories automatically — the recipe is documented
|
|
215
|
+
and an agent performs it, because a real model's comments are the team's and not loam's to reflow.
|
|
216
|
+
Making the shape a key in `loam.json` or `likec4.config.json` — the file's grammar already decides
|
|
217
|
+
how it can be read, and a key would be a second answer able to disagree with the first. Widening
|
|
218
|
+
loam's fleet map to the renderer's root project — the map is graded as `architecture/` alone so
|
|
219
|
+
that one broken service model cannot blank the fleet's own picture, which is why a cross-service
|
|
220
|
+
flow in `architecture/usecases/` still names service elements and never a container. Retiring the
|
|
221
|
+
standalone shape — it is what lets a service's docs be validated from the service's own repository,
|
|
222
|
+
and a fleet that wants that keeps it, now with a check on the divergence it costs.
|
|
223
|
+
|
|
224
|
+
**The deliberate remainder**, stated so nobody reads it as an oversight. A cross-service call still
|
|
225
|
+
exists TWICE: container-level in the model, service-level in the map (#011's item 6). The spine,
|
|
226
|
+
the platform census and every other fleet check read the map alone, and `landscape.service-isolated`
|
|
227
|
+
remains the nudge that carries an attested call up into it. Thinning the map to elements plus
|
|
228
|
+
cross-service edges is the [Later](#later--promote-only-from-evidence) "Landscape scaling" row, and
|
|
229
|
+
it is what would remove the duplication. Beside it sits #011's item 5, also deliberate: a
|
|
230
|
+
cross-service flow cannot name a container, because loam grades the fleet map as its own document
|
|
231
|
+
set. Revisit that one when a fleet asks for a cross-service flow whose hops are containers — the
|
|
232
|
+
renderer already resolves such a hop, so the ask will be concrete when it arrives.
|
|
233
|
+
|
|
234
|
+
**Verified 2026-09-04**, and three things the verification changed. The report's own "next thing to
|
|
235
|
+
check" was the one that did not compose: `loam archive` spliced a delta's nested additions into the
|
|
236
|
+
fleet map, and the extending model could then never declare them — the service went `c4.invalid`
|
|
237
|
+
(duplicate) the moment it wrote the container the adopt brief prescribed. The merge now ROUTES each
|
|
238
|
+
addition to the document that owns the interior, and proves the merged model parses beside the
|
|
239
|
+
merged map before writing either. Second, the consumer census read `architecture/` alone, so under
|
|
240
|
+
this shape a private store's consuming edges — which live in the models now — counted for nothing:
|
|
241
|
+
`landscape.datastore-private` went silent or named the wrong service, and a nested store two
|
|
242
|
+
services reach was graded nowhere. It reads every extending model's attested calls now, and
|
|
243
|
+
`landscape.datastore-shared` fires for a nested store. (That census still stands; the code named
|
|
244
|
+
here does not — `landscape.datastore-private` was retired on 2026-09-07, because where a store is
|
|
245
|
+
drawn is the team's choice. See the CHANGELOG entry.) Third, the wiring guard this entry landed
|
|
246
|
+
failed open on every root `exclude` spelling except `services/<tree>/**`, `loam subsystem sync`
|
|
247
|
+
never removed the stray per-service project file it told repositories to delete (and that file
|
|
248
|
+
CLAIMS the model, rather than holding nothing as the design note said), and
|
|
249
|
+
`c4.fleet-project-invalid` enumerated three roots rather than the renderer's — a `.likec4` in a
|
|
250
|
+
subsystem directory was in none of them. All three are closed; CHANGELOG's `[Unreleased]` has the
|
|
251
|
+
codes and keys.
|
|
252
|
+
|
|
253
|
+
**The `import` question is answered.** Reports #010 and #011 left open whether LikeC4's
|
|
254
|
+
cross-project `import` could have delivered this without merging the projects. Measured at the
|
|
255
|
+
1.59.2 pin: an import resolves REFERENCES across projects, and that is all — it carries no
|
|
256
|
+
`specification`, so a kind or tag the other project declares is not usable in this one, and it does
|
|
257
|
+
not support `extend`. A model importing the map could name the map's elements and still not add a
|
|
258
|
+
container to one. So the choice was never between two mechanisms; one project holding both
|
|
259
|
+
documents is what the shape requires.
|
|
260
|
+
|
|
261
|
+
**Known and carried, 2026-09-04.** The second verification round reproduced these and they were
|
|
262
|
+
NOT fixed. Each is written down with the repro that finds it again, so nobody spends a second
|
|
263
|
+
afternoon rediscovering one. They are carried, not closed.
|
|
264
|
+
|
|
265
|
+
- **Only the basename `likec4.config.json` is surveyed.** LikeC4 1.59.2 also accepts `.likec4rc` and
|
|
266
|
+
six other spellings; drop `{"name":"svc-a"}` into `services/svc-a/.likec4rc` on a synced extending
|
|
267
|
+
fleet and `validate --all`, `doctor` and `subsystem sync` all stay green while the renderer loads
|
|
268
|
+
three projects and refuses without `--project`. Carried on scope: the survey, the stray grade and
|
|
269
|
+
`sync`'s delete list are one table, and widening it is the same change as the two rows below —
|
|
270
|
+
worth doing once, together, with the pin's whole name list measured rather than guessed.
|
|
271
|
+
- **A `likec4.config.json` in a SUBSYSTEM directory claims every model beneath it.** Write one at
|
|
272
|
+
`services/platform/likec4.config.json` over three extending models and all three go
|
|
273
|
+
`Could not resolve reference to Element named 'svc_svc_d'` in the renderer, while loam names
|
|
274
|
+
nothing (`sync` → "nothing to write"). Carried on scope, with the row above: the checks look one
|
|
275
|
+
directory deep, at a service, and seeing this needs a walk of the whole docs tree.
|
|
276
|
+
- **`sync` keeps a config beside a model that is GONE, and that leftover project is not harmless.**
|
|
277
|
+
`rm services/svc-c/model.likec4` with its config left behind: loam is green everywhere, and
|
|
278
|
+
`likec4 validate` — and `likec4 build` — at the docs root then need `--project`. The keep is
|
|
279
|
+
deliberate ("that one really is the team's"), but its premise, that an empty nested project is
|
|
280
|
+
invisible to the renderer, is false at the pin. Carried on a design decision pending: deleting a
|
|
281
|
+
file loam never wrote needs a rule about whose file it is, not a bug fix.
|
|
282
|
+
- **`validate --feature` does not preview a merge refusal.** A delta drawing a cross-interior edge,
|
|
283
|
+
or naming a kind the map does not declare, validates clean and then refuses at `archive`
|
|
284
|
+
(`merge-failed`, nothing written). Carried on scope: the preview needs the archive's own merge
|
|
285
|
+
planner run from the validate path, which is a new seam rather than a message.
|
|
286
|
+
- **In the STANDALONE shape a broken UNTAGGED sibling is invisible to loam.** Make one service
|
|
287
|
+
standalone, `subsystem sync`, then write an unresolvable `services/<id>/usecases/plain.likec4`:
|
|
288
|
+
loam prints `c4.valid` and 0 errors while `likec4 validate --project <id> .` is Invalid. The
|
|
289
|
+
extending shape catches the same file through `c4.fleet-project-invalid`. Carried on scope: the
|
|
290
|
+
per-service load reads the model, and reading the standalone project the renderer builds is a
|
|
291
|
+
second loader.
|
|
292
|
+
- **A root `exclude` that no longer covers `features/**` is silent.** Delete that one entry from
|
|
293
|
+
`examples/docs`' config: loam reports 0 errors and `sync` says "nothing to write", while the
|
|
294
|
+
renderer's fleet project is at 346 errors. The scaffold always writes the entry, so this is a
|
|
295
|
+
hand edit, which is why it is carried rather than fixed — on the evidence bar: no repository has
|
|
296
|
+
hit it, and a grade on an entry loam did not write is a policy claim.
|
|
297
|
+
- **A root config the renderer REJECTS is reported only by `sync`'s note.** `"exclude": "services/**"`
|
|
298
|
+
as a string, or an array-valued `include`, is "loaded 0 projects out of 1" — nothing renders — and
|
|
299
|
+
`validate --all` is green; an unparseable file is the same. Carried on scope: loam reads the file
|
|
300
|
+
for one key, and schema-validating somebody else's config is a dependency on the renderer's own
|
|
301
|
+
schema at the pin.
|
|
302
|
+
- **`LivingSlice.landscape.modelled` is `false` where `adopt` says `null`.** Over an
|
|
303
|
+
`architecture/` project that did not parse, `loam context <svc> --json` says `modelled: false` and
|
|
304
|
+
`loam adopt --service <svc> --json` says `modelled: null` about the same tree. Carried on scope:
|
|
305
|
+
the field is typed non-nullable in the pack, so agreeing with `adopt` is a contract change.
|
|
306
|
+
- **`loam show` never mentions graded intra-service flows.** With a healthy `#req-…`-tagged flow
|
|
307
|
+
beside an extending model — `validate --service` prints "· 1 tagged flow(s) graded" — neither
|
|
308
|
+
`loam show <svc>` nor its `--json` names it anywhere. Carried on scope: `show`'s payload is a
|
|
309
|
+
frozen shape and the flow needs a section of its own.
|
|
310
|
+
- **`loam status` never names the isolated state.** `landscape.service-isolated` is a warning
|
|
311
|
+
`validate --all` prints and `status`'s next-action ladder has no rung for. Carried on a design
|
|
312
|
+
decision pending: the ladder is derived from artifact presence and provenance, and a finding-derived
|
|
313
|
+
rung is a different rule for what `next[0]` means.
|
|
314
|
+
- **The first ever container-level flow a FEATURE brings.** A cross-service flow cannot name a
|
|
315
|
+
container, because loam grades the fleet map as its own document set; the renderer already resolves
|
|
316
|
+
such a hop. Carried deliberately — the [Later](#later--promote-only-from-evidence) "Landscape
|
|
317
|
+
scaling" row owns it, and it is promoted when a fleet asks, not before.
|
|
318
|
+
|
|
319
|
+
#### Problem reports carry an ordinal, and loam reads the directory it prescribes
|
|
320
|
+
|
|
321
|
+
**Landed 2026-09-04**, from one problem report (#012). The `loam-report` protocol prescribed a
|
|
322
|
+
directory, a filename shape and a document structure and then stopped: files were named
|
|
323
|
+
`YYYY-MM-DD-<slug>.md` with a numeric suffix only on collision — a collision breaker, not an
|
|
324
|
+
identifier — so in a directory of eleven reports written in two days, none had one, four shared
|
|
325
|
+
their first eleven characters, and the discriminating part of every name sat far to the right of
|
|
326
|
+
what a terminal, a file picker or a chat message shows. There was no field anywhere in the document
|
|
327
|
+
for the one piece of state a report has (three of the eleven were already closed and one superseded,
|
|
328
|
+
all of it living in whoever remembered), and `validate --all`, `doctor`, `status` and `list`
|
|
329
|
+
mentioned `loam-reports` zero times between them. Landed: an unconditional ordinal at the front of
|
|
330
|
+
the name, which is the computation the protocol already described for its suffix applied where it is
|
|
331
|
+
visible; a `Status:` line in the template with a four-value vocabulary a report closes by editing;
|
|
332
|
+
and `loam doctor` reading the directory — total, per-status counts and the next ordinal — as an
|
|
333
|
+
additive `reports` key and one human row. Rejected: a `loam report list` verb (a new command for a
|
|
334
|
+
count `doctor` was already the place for, on a frozen CLI surface); an index file (the workaround
|
|
335
|
+
this replaces — a second place to keep in step, and the reason the state left the files in the first
|
|
336
|
+
place); grading the corpus (an open report is not a defect in the repository holding it, so `doctor`
|
|
337
|
+
reports it as state and `healthy` never moves); parsing past the first word of the status line (the
|
|
338
|
+
rest is prose an author writes for a reader). Cost: one `readdir` and one small read per report on
|
|
339
|
+
every `loam doctor`, and nothing is transmitted — which is the constraint the protocol is built
|
|
340
|
+
around and the reason the whole fix needed no new state.
|
|
341
|
+
|
|
342
|
+
#### The adopt brief on an edgeless landscape element
|
|
343
|
+
|
|
344
|
+
**Landed 2026-09-03**, from one problem report. `loam adopt` decided whether the fleet map still
|
|
345
|
+
owed a service from element EXISTENCE: a bound element with no edge — what
|
|
346
|
+
`loam seed --from fleet.yaml` leaves for every service absent from `calls:` — read as
|
|
347
|
+
`landscape.instruction: null`, no target, `inbound: []`, `outbound: []` in one payload, so an agent
|
|
348
|
+
following the protocol to the letter wrote a validating baseline and never drew one edge, and
|
|
349
|
+
`loam validate --all` stayed green over it. Landed: a fourth landscape state carried by two
|
|
350
|
+
additive keys (`landscape.touched`, and `landscape.attested` — the calls the service's own
|
|
351
|
+
model.likec4 declares across its boundary, derived once in `core/c4/resolve/attested.ts` for the
|
|
352
|
+
brief and the fleet check alike, so the two can never name different edges); a non-null instruction
|
|
353
|
+
in two arms (carry each attested call up as one edge on the existing element, naming the other
|
|
354
|
+
party as the map spells it; or, with nothing attested, draw NOTHING rather than invent — an edgeless
|
|
355
|
+
element that is true is a fact); the landscape target back as an edge-only `edit` whose shape
|
|
356
|
+
refuses a second element; the `EDGELESS` flag in the text view; the evidence-gated
|
|
357
|
+
`landscape.service-isolated` warning under `--all`; and a seventeenth unchecked statement about
|
|
358
|
+
visibility (placeholder tags, curated views, `include *` over a boundary). Rejected: folding the
|
|
359
|
+
state into `landscape.modelled` (an agent told `false` draws a second box); an unconditional "no
|
|
360
|
+
edge touches it" warning (no correct fix for a worker that calls nothing, and every seeded fleet
|
|
361
|
+
red-ish until adoption); grading the SET DIFFERENCE between the attested calls and the drawn edges
|
|
362
|
+
(loam cannot tell a call the map forgot from one the fleet does not draw at its own altitude, so
|
|
363
|
+
the difference reported as an omission is an invented edge with a code beside it — the check stays
|
|
364
|
+
touched/untouched, and the brief says so out loud); a check on placeholder tags or on what a view
|
|
365
|
+
shows (rule 26 — loam never
|
|
366
|
+
computes what a view shows). Cost: one LikeC4 load of `model.likec4`, only in the edgeless state, a
|
|
367
|
+
memo hit under `--all`.
|
|
368
|
+
|
|
369
|
+
**Corrected 2026-09-04** by the verification of this entry: the brief read
|
|
370
|
+
`architecture/landscape.likec4` alone where the fleet check reads the whole `architecture/` project,
|
|
371
|
+
so a fleet keeping a second `model { }` block in a sibling got a brief demanding edges it had
|
|
372
|
+
already drawn while `validate --all` reported `landscape.matched`. Both now read the project.
|
|
373
|
+
|
|
374
|
+
#### A home for an intra-service use case
|
|
375
|
+
|
|
376
|
+
**Landed 2026-09-03.** Measured: `architecture/usecases/` cannot resolve a container (one such file
|
|
377
|
+
is `landscape.invalid` plus a `spine.landscape-invalid` per service), and a view beside the model
|
|
378
|
+
rendered while nothing graded it. Landed: the service's own LikeC4 project as the slot — every
|
|
379
|
+
`.likec4` beside model.likec4 and any tagged view inside it — graded by `validate --service`/`--all`
|
|
380
|
+
with the five existing `usecase.*` codes, `#req-` scoped by the service's own Requirement-IDs,
|
|
381
|
+
`#cap-` refused by placement, a broken sibling one `usecase.flow-invalid` while the model keeps
|
|
382
|
+
grading; plus the tier-2 skip and the fourth `step-unlinked` guard in the shared graders. Rejected:
|
|
383
|
+
a fixed `usecases/` directory alone (the reporter's `views.likec4` would render ungraded),
|
|
384
|
+
`views.likec4` alone (a second file would be invisible), a new code for the broken sibling (nothing
|
|
385
|
+
branches differently), gating the read on `likec4.config.json` (create-only, deletable). Cost: one
|
|
386
|
+
recursive readdir per service; a workspace only where a view in model.likec4 opts in or a sibling
|
|
387
|
+
mentions a reserved prefix anywhere in its bytes — an untagged sibling is never graded, and once
|
|
388
|
+
the workspace is loaded a project that does not read is one `usecase.flow-invalid` whether or not a
|
|
389
|
+
view opted in.
|
|
390
|
+
|
|
391
|
+
#### The service model, renderable from the fleet root
|
|
392
|
+
|
|
393
|
+
**Landed 2026-09-03**, from one problem report. The root `likec4.config.json` that
|
|
394
|
+
`loam init --create` writes excludes `services/**` on purpose — every `model.likec4` declares its
|
|
395
|
+
own `specification` block, and a renderer merging the tree calls each one a duplicate — and the
|
|
396
|
+
cost of that exclusion had gone unstated for a release: the model `loam adopt` spends the most
|
|
397
|
+
effort on was a box with nothing inside it in the renderer opened at the docs root, and the only
|
|
398
|
+
documented path to its containers was one renderer invocation per service directory. The report's
|
|
399
|
+
hand-written workaround, one project file per service, is what this entry makes loam's.
|
|
400
|
+
|
|
401
|
+
**Measured** at the pinned likec4 before a line was written. A `services/<svc>/likec4.config.json`
|
|
402
|
+
is registered as a project of its own even though the root excludes the directory: the workspace
|
|
403
|
+
loads `fleet` plus one project per service with zero errors, the root project sees exactly the
|
|
404
|
+
files it saw before, and each service project carries an auto `index` view of the containers beside
|
|
405
|
+
the authored view. A nested project named `fleet` is silently registered as `fleet-1`. With more
|
|
406
|
+
than one project, `likec4 validate` at the root refuses with `Specify exact project` until given
|
|
407
|
+
`--project`. A nested project holding no `.likec4` file is silently absent from the project list. A
|
|
408
|
+
service model that does not parse breaks only its own project; siblings and `fleet` still compute.
|
|
409
|
+
And the project picker shows `title ?? id`, so the title is what a human reads.
|
|
410
|
+
|
|
411
|
+
**What landed.** `loam subsystem sync` writes the file — create-only, two keys, bytes a function of
|
|
412
|
+
the id alone — beside every service model that has none, once the root project file exists, and
|
|
413
|
+
reports them under an additive `projects` key. `loam validate --all` grades presence with one
|
|
414
|
+
warning per service, `service.likec4-config-missing`, whose fix is `sync`. No new command: the
|
|
415
|
+
[Later](#later--promote-only-from-evidence) Rendering row's evidence bar was met for the SCOPING
|
|
416
|
+
half of its trigger and answered by wiring — one file that tells the renderer where a project is —
|
|
417
|
+
not by a drawing verb; drawing stays LikeC4's, and the row says so now.
|
|
418
|
+
|
|
419
|
+
**Rejected.** A new command, because the report's problem was a missing file, not a missing verb,
|
|
420
|
+
and a verb would have put loam between a team and its renderer for good. The agent writing the file
|
|
421
|
+
from the adopt brief, because a file written by hand per service is the state the report found —
|
|
422
|
+
one of four adopted services had one — and loam already writes the root file and knows every
|
|
423
|
+
service directory. A generated-and-compared file with a `-stale` grade, because the bytes cannot go
|
|
424
|
+
stale and a compare would fight the `title` and styles LikeC4 lets a team add. Grading in `doctor`
|
|
425
|
+
alone, because the gap is per service and `doctor` reports on the repository, not on its services;
|
|
426
|
+
the docs repo's CI runs `validate --all`.
|
|
427
|
+
|
|
428
|
+
**Costs**, each where a user meets it. A repo with adopted services reports one warning per service
|
|
429
|
+
on its first `validate --all` after upgrading, until one `sync`; that `sync` leaves N untracked
|
|
430
|
+
files it does not `git add`; from the first service project on, `likec4 validate` at the docs root
|
|
431
|
+
needs `--project <name>` (`build` and `export` take every project without one — measured); the
|
|
432
|
+
renderer's project list grows by one per adopted service, and a fleet-map box is not a link into
|
|
433
|
+
that project (LikeC4 projects are separate models); and the project name is not injective (an id spelled billing.core beside one spelled
|
|
434
|
+
billing-core, `service-fleet` beside `fleet`), disclosed in SCHEMA rather than escaped away,
|
|
435
|
+
because the picker shows the id.
|
|
436
|
+
|
|
437
|
+
**Superseded for extending models, one day later.** The last of those costs — one picker entry per
|
|
438
|
+
adopted service — is what report #009 measured at 57 entries, and the entry that opens this list is
|
|
439
|
+
what removed its cause rather than its symptom: a model that extends the fleet map shares the root
|
|
440
|
+
project with it, so it is owed no project file and adds no entry, and `loam subsystem sync` writes
|
|
441
|
+
the file only for a model that stands alone. Everything measured here still holds for that shape,
|
|
442
|
+
and is why it is still supported; it is no longer what a new model is written as.
|
|
443
|
+
|
|
444
|
+
#### The generated subsystem views — a label, a boundary, and one reader of the map
|
|
445
|
+
|
|
446
|
+
**Landed 2026-09-03.** Three problem reports from a fleet running loam, one axis. The generated
|
|
447
|
+
`architecture/subsystems.likec4` exists only to be rendered and was the least readable object in a
|
|
448
|
+
docs repo: no `title`, so the renderer showed the hex-escaped view id, and leaf includes only, so a
|
|
449
|
+
fleet drawn as grouped C4 rendered flat. Each view now carries the marker's title (the directory
|
|
450
|
+
name when it has none) and description, and draws a boundary the LANDSCAPE decides: the model's own
|
|
451
|
+
containing element when one holds exactly the members, a `group` mirroring the directory subtree
|
|
452
|
+
when the map nests nothing, and one `// model: no boundary — …` comment when the two disagree.
|
|
453
|
+
That comment is the whole answer to the drift the third report asked about — disclosure in a
|
|
454
|
+
generated artifact, never a finding, because grading placement against the map is the policy the
|
|
455
|
+
tree is defined not to carry. The graded alternative is written down under
|
|
456
|
+
[Later](#later--promote-only-from-evidence) with the evidence bar it has to clear.
|
|
457
|
+
|
|
458
|
+
The hunt found what neither report did: `validate --all` graded that file against the whole
|
|
459
|
+
`architecture/` project while every writer rendered it from `landscape.likec4` alone, so a
|
|
460
|
+
use-case document binding one element could produce a `subsystem.views-stale` that
|
|
461
|
+
`loam subsystem sync` reported as `current` — reproduced on `examples/docs`, and fixed by pointing
|
|
462
|
+
both sides at the same read.
|
|
463
|
+
|
|
464
|
+
**And the repository's palette (2026-09-03).** A generated view can carry no inline `style` rule —
|
|
465
|
+
the file is regenerated wholesale — and the one mechanism LikeC4 gives a view for borrowing a
|
|
466
|
+
repository's styling is a reference to a global style by id, which is a parse error that blanks the
|
|
467
|
+
whole `architecture/` project when nothing declares it. So the convention is one reserved name:
|
|
468
|
+
declare `global { styleGroup subsystems { … } }` anywhere in the `architecture/` project and every
|
|
469
|
+
generated view references it; declare nothing and the file is what it was. Rejected: reading the id
|
|
470
|
+
off a key in `likec4.config.json` (create-only, never re-read, and not a LikeC4 document whose
|
|
471
|
+
contents a parse can check), and "reference the single declared group" (a second group declared for
|
|
472
|
+
a hand-drawn view would silently switch the generated views' styling off and restale the file on a
|
|
473
|
+
change that touched no subsystem). The presence read is a census of the keys of
|
|
474
|
+
`$data.globals.styles`, a declaration read like `specification`; seven tripwire assertions in
|
|
475
|
+
`test/likec4-view-shape.test.ts` pin the shape so a likec4 bump fails there before it reaches a
|
|
476
|
+
generated file.
|
|
477
|
+
|
|
478
|
+
#### The deployment axis — topology joined to requirements
|
|
479
|
+
|
|
480
|
+
**Promoted 2026-09-02, and authored as a feature in loam's own docs repo** rather than as an item
|
|
481
|
+
text here: `meta/docs/features/archive/FEAT-1-the-deployment-axis/`, whose `intent.md` carries the
|
|
482
|
+
four measurements and whose `specs/loam/arch.spec.md` carries the five rules the change establishes,
|
|
483
|
+
each with scenarios. This entry is the decision and the gate; that feature is the specification, and
|
|
484
|
+
the two must not be allowed to become two accounts of the same change.
|
|
485
|
+
|
|
486
|
+
**Landed 2026-09-02, complete.** Every step is in, and step 4 was corrected rather than built
|
|
487
|
+
(below) — the item specified two finding codes that the implementation showed it should not mint.
|
|
488
|
+
FEAT-1 archived once every edge it claimed existed —
|
|
489
|
+
and it archived having been CORRECTED against the tree twice, which is the argument for the route
|
|
490
|
+
rather than a footnote to it: the delta predicted a `core/kernel/` dependency that turned out to be
|
|
491
|
+
type-only (a brand costs an annotation, not an import) and missed `core/coherence/` entirely.
|
|
492
|
+
`npm run meta:check` was red for the whole of the build and went green with the archive, which is
|
|
493
|
+
the axis working rather than a gap in it.
|
|
494
|
+
|
|
495
|
+
The whole change is reviewable as five commits on `feat/deployment-axis`, and the one thing to read
|
|
496
|
+
first is what the implementation taught the plan: two of the codes this item specified were not
|
|
497
|
+
minted, and the reasons are in step 4.
|
|
498
|
+
|
|
499
|
+
**What is wrong today.** A LikeC4 `deployment { }` block is legal in a docs repo and completely
|
|
500
|
+
unread. The parser resolves every `instanceOf` in it — a container renamed out from under a
|
|
501
|
+
deployment node fails the gate as `landscape.invalid` — and after that nothing: no requirement can
|
|
502
|
+
name a node, no report counts one, and the context pack an agent implements from does not mention
|
|
503
|
+
topology at all. Two of the four measurements taken on a copy of `examples/docs` are the reason this
|
|
504
|
+
is an item rather than a wish. A `#obl-` tag on a `deploymentNode` is invisible to
|
|
505
|
+
`validate/fleet/obligations.ts`, which walks the logical model only — the same undeclared tag raises
|
|
506
|
+
`obligation.unknown` on a container and nothing on a datacenter, which is fail-open and a defect on
|
|
507
|
+
its own terms. And `parsedModel().deployment` already returns nodes with their tags, instances
|
|
508
|
+
carrying the id of the logical element each one instances, and relationships carrying metadata, so
|
|
509
|
+
the read costs no second parse, no new file format and no change to the frozen CLI surface.
|
|
510
|
+
|
|
511
|
+
**Required changes**, in the order the dependency graph forces:
|
|
512
|
+
|
|
513
|
+
1. Walk the deployment model in every `#obl-` grade. Fail-open becomes fail-closed; no new code.
|
|
514
|
+
2. A fourth `Covers:` entry form, `node:<id>`, with the same prefix accepted on either side of the
|
|
515
|
+
edge form. No new code.
|
|
516
|
+
3. The parse adapter in `src/core/c4/parsed/`, and the deployment records added to
|
|
517
|
+
`test/likec4-model-parity.test.ts` — a two-stage substitution nothing measures is an assumption.
|
|
518
|
+
`src/core/c4/` holds exactly five files, so this is a sub-package and not a sixth module.
|
|
519
|
+
4. **No new finding code, and this is a correction the implementation earned.** The item planned
|
|
520
|
+
two. The first, for a tagged node or edge no living arch requirement covers, turned out to be
|
|
521
|
+
`obligation.uncovered` asked of a second model: once step 1 walks the topology, the existing code
|
|
522
|
+
answers it, and a caller acts identically either way — write a `Covers:` line. A second code for
|
|
523
|
+
one question is exactly what the add-a-code checklist refuses. The second, for a container no
|
|
524
|
+
deployment instances, is declined outright: it asserts that everything modelled ought to be
|
|
525
|
+
deployed somewhere, which is a COMPLETENESS claim, and completeness is the one thing
|
|
526
|
+
`src/core/brief/unchecked.ts` says loam never checks. It is the same category error as the
|
|
527
|
+
at-least-two-datacenters rule below, one axis over.
|
|
528
|
+
5. `features/<FEAT>/deployment/<name>.likec4`, create-only and copied whole — `core/usecases/delta/`
|
|
529
|
+
one axis over. It works because `extend` was measured to resolve across documents of one project,
|
|
530
|
+
so no text splice is needed; `delta-blocks.ts` goes on refusing a `deployment { }` block inside
|
|
531
|
+
`delta.likec4` and its message names the new slot. The collision is on the FILE, never on what is
|
|
532
|
+
inside it: two features may both extend one living region from documents of their own and both
|
|
533
|
+
archive, which is the shape the fleet-wide change actually takes.
|
|
534
|
+
|
|
535
|
+
**Graded against the merge preview**, which shipped one commit behind the slot and is the
|
|
536
|
+
second code, `deployment.doc-invalid` (error, never overridable). This axis needs the post-merge
|
|
537
|
+
corpus more literally than the use-case one: a feature that stands a NEW service up in a cluster
|
|
538
|
+
declares it in `delta.likec4` and instances it in the topology, so the element the document names
|
|
539
|
+
exists only after the merge. The staging that makes that readable moved OUT of
|
|
540
|
+
`core/usecases/delta/overlay.ts` into `core/c4/project/staged.ts` rather than being copied — the
|
|
541
|
+
two axes would have disagreed first about the merge preview, which is the one thing both
|
|
542
|
+
refusals rest on. The extraction dropped `core/usecases/` → `core/kernel/`, which is a one-line
|
|
543
|
+
edge and was edited into the model directly.
|
|
544
|
+
6. The surfaces: the topology in the context pack (`context --json`'s `living.deployment`), the code
|
|
545
|
+
table `test/codes-drift.test.ts` requires, and one more statement in
|
|
546
|
+
`src/core/brief/unchecked.ts`. `loam explain` needed nothing — it parses the /loam-check fix
|
|
547
|
+
tables at runtime, so the rows added there ARE the entries. The scorecard row the item listed was
|
|
548
|
+
dropped: the fleet scorecard aggregates at the bound `service`, and a topology row there would
|
|
549
|
+
count deployment nodes against a denominator no service owns.
|
|
550
|
+
|
|
551
|
+
**Exit criteria.** Every step above green under the full gate; `covers.unknown` demonstrated firing
|
|
552
|
+
on a covered node that a topology change renamed, which is the acceptance criterion the trigger
|
|
553
|
+
names; the parity suite extended and shown to fail against an un-extended adapter; and
|
|
554
|
+
`test/self-model.test.ts` re-pinned once FEAT-1 archives.
|
|
555
|
+
|
|
556
|
+
**Out of scope, and each refusal is load-bearing.** No reading of Terraform, Helm or cluster state —
|
|
557
|
+
that is the extractor the non-goals forbid. No check that a service is deployed in at least two
|
|
558
|
+
datacenters: it would need `criticality` promoted from prose to a read field, and it would turn
|
|
559
|
+
`architecture/obligations.yaml` into the policy engine that file says in its own words it is not. A
|
|
560
|
+
multi-datacenter rule is an authored requirement whose `Covers:` line names the nodes; loam grades
|
|
561
|
+
the join and never the architecture. And no `environment` concept above LikeC4, because
|
|
562
|
+
`deploymentNode` is that mechanism and the fleet names its own kinds.
|
|
563
|
+
|
|
564
|
+
**The evidence, and its one gap stated plainly.** Operator: a team standing up a standby cluster in
|
|
565
|
+
a second datacenter. Repeated task: keeping RTO/RPO requirements attached to a topology that keeps
|
|
566
|
+
changing. Failure mode: a requirement about replication staying green after the node it described
|
|
567
|
+
was renamed or removed. Frequency: every topology change, which is the cadence a migration runs at.
|
|
568
|
+
Current workaround: a `Covers:` line that resolves to nothing, or no written requirement at all.
|
|
569
|
+
Acceptance criterion: a topology change that orphans a covered requirement is convicted without a
|
|
570
|
+
human noticing it first. **That is one operator, not two.** The maintainer judged the trigger
|
|
571
|
+
sufficient on the same basis recorded for landscape scaling and the authored business axis, and the
|
|
572
|
+
[Later](#later--promote-only-from-evidence) exit criteria are amended below to say so rather than
|
|
573
|
+
leaving the two paragraphs to contradict each other. Steps 1 and 2 do not rest on that judgement at
|
|
574
|
+
all: the first is a fail-open defect and the second is a grammar entry, and neither is a new axis.
|
|
575
|
+
|
|
124
576
|
|
|
125
577
|
- **A feature can bring a use case.** `features/<FEAT>/usecases/<name>.likec4` — a views-only
|
|
126
578
|
document `loam archive` copies into `architecture/usecases/` and `loam unarchive` takes back,
|
|
@@ -243,13 +695,99 @@ item gets promoted — it went from here to `## Now` and from there to
|
|
|
243
695
|
invocation, scoping, or artifact reproducibility is the recurring problem, and it must stay
|
|
244
696
|
outside validation so view computation cannot slow or change the gate. This item is about
|
|
245
697
|
**drawing**, and LikeC4 keeps that job. Reading a `dynamic view`'s declared steps is not rendering
|
|
246
|
-
and is not this item — see docs/DESIGN.md rule 26.
|
|
698
|
+
and is not this item — see docs/DESIGN.md rule 26. The scoping half of that bar was met and
|
|
699
|
+
answered on 2026-09-03 by the per-service project file `loam subsystem sync` writes (see
|
|
700
|
+
[Recently landed](#recently-landed)) — wiring rather than a verb; drawing stays LikeC4's.
|
|
247
701
|
- **UI generation:** begin with a disposable projection over the stable JSON contract only after CLI
|
|
248
702
|
consumers demonstrate a repeated navigation problem. It must not introduce a second mutable state,
|
|
249
703
|
hidden workflow state, or a required service.
|
|
250
|
-
- **
|
|
251
|
-
|
|
252
|
-
|
|
704
|
+
- **A graded subsystem/model correspondence:** a fleet that draws its landscape as grouped C4 states
|
|
705
|
+
its grouping twice — once as directories under `services/`, once as the nesting of the elements —
|
|
706
|
+
and `loam subsystem move` changes the first while the second stays put. Since 2026-09-02 the
|
|
707
|
+
generated views file DISCLOSES that (the `// model: no boundary — …` line; see
|
|
708
|
+
[SCHEMA.md](SCHEMA.md)), and nothing grades it, because grading placement against the map is the
|
|
709
|
+
policy the tree is defined not to carry. The shape a graded version would take is known and
|
|
710
|
+
measured: an author's opt-in `metadata { subsystem '<name>' }` on the grouping element, read
|
|
711
|
+
through the existing metadata reader, the NAME rather than the path (names are unique in one flat
|
|
712
|
+
namespace and survive a move, which a path binding would not), with the check structurally silent
|
|
713
|
+
for every fleet that never writes one. Promote only on evidence from a second fleet, after living
|
|
714
|
+
with the disclosure — the first report classified itself `inconclusive`, and one fleet is not
|
|
715
|
+
enough to qualify an invariant that says placement is never part of any identity.
|
|
716
|
+
- **A feature brings an intra-service flow.** `features/<FEAT>/specs/<svc>/usecases/<name>.likec4`,
|
|
717
|
+
copied create-only by `loam archive` into `services/<…>/<svc>/usecases/` and taken back by
|
|
718
|
+
`loam unarchive`, graded before the copy against the service's own LikeC4 project with the
|
|
719
|
+
feature's `specs/<svc>/` requirement deltas in `#req-` scope — `usecase.flow-exists` and
|
|
720
|
+
`usecase.flow-invalid` reused, never `--approve`-overridable. Deliberately NOT built with the
|
|
721
|
+
living slot (2026-09-03): the version-3 snapshot manifest already carries an artifact path with a
|
|
722
|
+
directory in it, so nothing about the undo changes when it lands, and no model delta exists to
|
|
723
|
+
preview — what it waits for is one fleet asking for a container-level flow to ship in the same
|
|
724
|
+
change as the `arch.spec.md` requirement it answers. Until then a service-local flow is written
|
|
725
|
+
directly into the service directory in the same pull request, where git produces the conflict;
|
|
726
|
+
building the feature route ahead of that evidence is the invented need the non-goals forbid.
|
|
727
|
+
- **A subsystem-scoped use-case slot.** A flow whose hops all sit inside one subsystem's subtree
|
|
728
|
+
looks like it wants a home between the two that exist — `architecture/usecases/` is the fleet's
|
|
729
|
+
slot, `services/<…>/<svc>/usecases/` is one service's. Deliberately NOT built (2026-09-07), and
|
|
730
|
+
the reason is that the capability is already there: a subsystem-scoped flow IS a fleet use case
|
|
731
|
+
whose hops happen to share a subtree, `architecture/usecases/<name>.likec4` already grades it, and
|
|
732
|
+
its view already folds into the same title-path folders as the generated subsystem view above it.
|
|
733
|
+
A second slot would duplicate the grader, the tag vocabulary and the archive route for no
|
|
734
|
+
capability that does not exist today. Promote only on evidence that a fleet's subsystem flows are
|
|
735
|
+
being lost among its fleet flows in the renderer's view list — which is a naming problem before it
|
|
736
|
+
is a slot problem, and one the title convention answers first.
|
|
737
|
+
- **A flow-untagged check** (it would be spelled usecase.flow-untagged): a `.likec4` beside a
|
|
738
|
+
service's model that mentions a `req-` prefix while no view in that project carries the tag — an
|
|
739
|
+
author who reached for the intra-service use-case axis and missed, whose flow renders and is
|
|
740
|
+
graded by nothing. It grades a view that EXISTS rather than an absence, so docs/DESIGN.md rule 26
|
|
741
|
+
permits it, unlike the service.usecases-missing nobody may ever build. Not built (2026-09-07) for
|
|
742
|
+
a mechanical reason worth stating: `core/brief/checks.ts` sits at 399 of 400 lines inside a
|
|
743
|
+
five-file-capped package, so a new non-ok code forces a split-module commit before any behaviour
|
|
744
|
+
can land, and that split should be chosen for a seam rather than for a code. Promote when a second
|
|
745
|
+
fleet reports a flow that rendered and was graded by nothing.
|
|
746
|
+
- **What the closed `flows-dynamic-views` branch had and main still lacks.** The branch drew
|
|
747
|
+
cross-service journeys as fleet-level dynamic views before main grew its own use-case axis; it was
|
|
748
|
+
closed as superseded on 2026-10-10, its one piece main lacked outright — suites, the participant
|
|
749
|
+
union a test stand needs — was ported onto that axis (`#suite-<name>`, `loam list suites`), and its
|
|
750
|
+
reference implementation stays reachable at the tag `archive/flows-dynamic-views` — commit
|
|
751
|
+
`d90b6f9`, the closed branch's head, which is the name to use where the tag was never fetched
|
|
752
|
+
(`git show d90b6f9:<path>`). Five things remain, and each waits for the same evidence — pilot
|
|
753
|
+
teams actually writing tagged use cases — because each would freeze a code, a grammar or a
|
|
754
|
+
generated file, and the two checks among them are advisory heuristics:
|
|
755
|
+
- **Per-view outcome counting against scenarios** — a view's `alt`/`opt`/`try` arms summed (not
|
|
756
|
+
multiplied) and compared with the scenarios covering it (it would be spelled
|
|
757
|
+
usecase.outcomes-uncovered, warn). `core/c4/parsed/dynamic-views.ts` flattens the block tree
|
|
758
|
+
it would need, and the count says how many outcomes lack a scenario, never which. Waits for
|
|
759
|
+
flows with branches being written and a team asking which outcomes go untested.
|
|
760
|
+
- **A feature-scope warning for a `#FEAT` cross-service edge no journey traverses** (it would be
|
|
761
|
+
spelled usecase.edge-unrepresented, adopt-gated on the fleet having a tagged use case). Main sees
|
|
762
|
+
only the removal direction (`diff.op-removed-consumed`). Waits for a fleet whose journeys are
|
|
763
|
+
kept at all — on one with none it is noise.
|
|
764
|
+
- **`Covers: view:<id>`** — a join from an arch-axis requirement to a journey that needs no
|
|
765
|
+
capability axis. It runs the opposite way to `#req-` (two answers to "what covers this flow"),
|
|
766
|
+
and a bare view id can now be stolen by a service-local view of the same name. Waits for
|
|
767
|
+
evidence that legacy teams will not write `capabilities/` — the one case where main has no way
|
|
768
|
+
to join a cross-service flow to a runner-verified arch-level outcome.
|
|
769
|
+
- **Generated per-suite views** (a `flow-groups.likec4`, a sync verb, a staleness code) —
|
|
770
|
+
rendering only. Waits for a team asking to SEE a suite rather than list it.
|
|
771
|
+
- **Changing an existing journey through a feature** (replace by view id, with a conflict
|
|
772
|
+
warning). Main declined it on purpose — the feature route is create-only and an existing flow is
|
|
773
|
+
edited in the pull request — and it waits for concurrent journey edits conflicting more often
|
|
774
|
+
than review absorbs.
|
|
775
|
+
- **Landscape scaling:** retain one landscape while conflicts are exceptional, and half of what
|
|
776
|
+
this row once asked for arrived on 2026-09-04. Per-service internals now live in
|
|
777
|
+
`services/<svc>/model.likec4` by default: `loam archive` routes a delta's fqn-spelled interior
|
|
778
|
+
into the owning service's extending model, and a team adopting a service adds nothing to
|
|
779
|
+
`architecture/landscape.likec4` but one element and its cross-service edges. The map holds a
|
|
780
|
+
service's interior only where a team puts it on purpose — a store nested under its owner so a
|
|
781
|
+
second service can name it (SCHEMA's "Private stores") — or where a delta spells its parent by
|
|
782
|
+
title rather than by the map's id (the archive's documented remainder). What is
|
|
783
|
+
left is the CROSS-SERVICE EDGE, which still exists twice — container-level in the model,
|
|
784
|
+
service-level in the map — and that duplication is **deliberate**, not a leftover: the spine, the
|
|
785
|
+
platform census, `landscape.service-isolated` and every other fleet check read the map alone,
|
|
786
|
+
which is what lets a fleet answer "who calls this service" from one diffable document without
|
|
787
|
+
parsing sixty. Thinning the map to elements plus cross-service edges means teaching those checks
|
|
788
|
+
to read the edges out of the models that attest them, and paying the blast radius that comes with
|
|
789
|
+
it. If same-service conflicts become routine — the current trigger in [SCHEMA.md](SCHEMA.md) is
|
|
790
|
+
weekly rather than monthly — evaluate that. Migration must
|
|
253
791
|
preserve archive/undo, deterministic resolution, and readable plain files.
|
|
254
792
|
- **Authored business axis — PROMOTED 2026-08-27, and landed in full; see
|
|
255
793
|
[Recently landed](#recently-landed).** The gate asked for evidence of authorship: analyst edits
|
|
@@ -264,8 +802,11 @@ item gets promoted — it went from here to `## Now` and from there to
|
|
|
264
802
|
|
|
265
803
|
Exit criteria for promoting a Later item:
|
|
266
804
|
|
|
267
|
-
- Evidence comes from at least two independent operators or fleets, except landscape scaling
|
|
268
|
-
authored business axis, whose recorded
|
|
805
|
+
- Evidence comes from at least two independent operators or fleets, except landscape scaling, the
|
|
806
|
+
authored business axis and — added 2026-09-02 — the deployment axis in [Now](#now), whose recorded
|
|
807
|
+
triggers are sufficient. Three exceptions is where this criterion starts describing the rule
|
|
808
|
+
rather than the exception: the next single-operator promotion has to say why the criterion should
|
|
809
|
+
survive, or retire it.
|
|
269
810
|
- An ADR compares the existing workflow, external tooling, and the smallest loam-owned change.
|
|
270
811
|
- A prototype is measured against a predeclared acceptance criterion and preserves every non-goal
|
|
271
812
|
below.
|
|
@@ -276,7 +817,7 @@ Exit criteria for promoting a Later item:
|
|
|
276
817
|
|
|
277
818
|
Placed in a section of its own, and the placement is the argument. This is not a `## Now` item, and
|
|
278
819
|
nothing here may be mistaken for one. It is not a "Later" candidate either: promotion
|
|
279
|
-
from that section requires evidence from at least two independent operators or fleets (bar the
|
|
820
|
+
from that section requires evidence from at least two independent operators or fleets (bar the three
|
|
280
821
|
whose recorded triggers were judged sufficient when they were written), and loam's own repository is
|
|
281
822
|
one operator by construction, so a Later entry could only ever be a permanent exception to the rule
|
|
282
823
|
it sits under. Nor is its value speculative — the trigger below is a defect this repository has
|