@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
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* The two change for different reasons: a new artifact edits the first, better
|
|
10
10
|
* advice to a new fleet edits the second.
|
|
11
11
|
*/
|
|
12
|
+
import { LEGACY_LANDSCAPE_STUBS } from "./legacy.js";
|
|
12
13
|
/**
|
|
13
14
|
* The fleet map, empty but valid.
|
|
14
15
|
*
|
|
@@ -38,6 +39,20 @@
|
|
|
38
39
|
* The `views` block below has a deliberate second copy: `core/c4/seed/template.ts` emits the
|
|
39
40
|
* same two views into a seeded landscape (two strikes; extract on a third), and test/seed.test.ts
|
|
40
41
|
* compares the two blocks byte for byte — comments included — so whichever copy drifts fails.
|
|
42
|
+
*
|
|
43
|
+
* The seven RELATIONSHIP kinds are scaffolded for the element kinds' reason:
|
|
44
|
+
* they are vocabulary, not a guess about this fleet. Declared here, every
|
|
45
|
+
* extending model and every adoption borrows them, so the first edge anybody
|
|
46
|
+
* draws can say what it carries and which way it points. A real fleet drawn
|
|
47
|
+
* without them ended with every arrow pointing into its broker and its stores,
|
|
48
|
+
* because deployment configuration says only that two things are connected. A
|
|
49
|
+
* declaration here also keeps a feature archivable: the archive copies a
|
|
50
|
+
* delta's edge into this file and never a declaration, so a kind this file
|
|
51
|
+
* lacks refuses the merge (`merge-failed`). A `legend` view is NOT scaffolded:
|
|
52
|
+
* a view names only elements the model declares, this model is empty, and an
|
|
53
|
+
* invented example would be a box every fleet check grades. The comment says
|
|
54
|
+
* when to write one. The kinds block has the same deliberate second copy in
|
|
55
|
+
* `core/c4/seed/template.ts`, pinned the same way by test/seed.test.ts.
|
|
41
56
|
*/
|
|
42
57
|
export const LANDSCAPE_STUB = `// The fleet map: every service in services/ appears here, and every call
|
|
43
58
|
// between two of them is an edge. This file is written by hand — loam never
|
|
@@ -54,16 +69,37 @@ export const LANDSCAPE_STUB = `// The fleet map: every service in services/ appe
|
|
|
54
69
|
// and give each call the operationId it uses, so requirements, C4 and OpenAPI
|
|
55
70
|
// can be cross-checked:
|
|
56
71
|
//
|
|
57
|
-
// checkoutWeb -> paymentService 'Authorizes' {
|
|
72
|
+
// checkoutWeb -[calls]-> paymentService 'Authorizes' {
|
|
58
73
|
// metadata { op 'authorizePayment' }
|
|
59
74
|
// }
|
|
60
75
|
//
|
|
76
|
+
// Every edge says what it carries with one of the relationship kinds declared
|
|
77
|
+
// below, and points the way the evidence says — never a guess:
|
|
78
|
+
//
|
|
79
|
+
// checkoutWeb -[calls]-> orderService a synchronous request
|
|
80
|
+
// orderService -[publishes]-> kafka.orderEvents producer to topic
|
|
81
|
+
// kafka.orderEvents -[delivers]-> paymentService topic to consumer
|
|
82
|
+
// paymentService -[reads]-> ordersDb always service to store; the
|
|
83
|
+
// style puts the head on the reader
|
|
84
|
+
// orderService -[connects]-> kafka no direction established yet
|
|
85
|
+
//
|
|
86
|
+
// Configuration that only names an address says two things are connected and
|
|
87
|
+
// nothing more: that is \`connects\`, and adopting the service from its code
|
|
88
|
+
// turns it into the real kind. Once the map has a real edge of each kind, add
|
|
89
|
+
// a \`legend\` view that draws one of each. \`loam instructions loam-drawing\`
|
|
90
|
+
// has the whole convention.
|
|
91
|
+
//
|
|
61
92
|
// The \`views\` block at the bottom is for LikeC4's own tooling — loam reads
|
|
62
93
|
// the model and never a view. Render with \`npx likec4 start\` from the docs
|
|
63
|
-
// repo root, which likec4.config.json scopes to this directory.
|
|
64
|
-
// model
|
|
65
|
-
// \`
|
|
66
|
-
//
|
|
94
|
+
// repo root, which likec4.config.json scopes to this directory. A service's
|
|
95
|
+
// \`services/<id>/model.likec4\` EXTENDS this map: it declares no
|
|
96
|
+
// \`specification\` block of its own, so it belongs to THIS project and renders
|
|
97
|
+
// with it, containers and all. A model that declares its own \`specification\`
|
|
98
|
+
// stands alone instead — it renders only from its own directory
|
|
99
|
+
// (\`npx likec4 start services/<id>\`), and the \`exclude\` list in the root
|
|
100
|
+
// likec4.config.json has to cover that directory or its declarations collide
|
|
101
|
+
// with this file's. \`loam subsystem sync\` maintains both, so neither is
|
|
102
|
+
// hand-edited. Keep views
|
|
67
103
|
// scoped, because computing one is superlinear in the number of edges — the
|
|
68
104
|
// \`fleet\` view below stays affordable precisely because it excludes the
|
|
69
105
|
// platform hubs.
|
|
@@ -96,6 +132,48 @@ specification {
|
|
|
96
132
|
// without losing "who depends on the Identity Provider", which the platform
|
|
97
133
|
// view answers.
|
|
98
134
|
tag platform
|
|
135
|
+
|
|
136
|
+
// One kind per kind of traffic, each with one direction. The style is the
|
|
137
|
+
// picture: amber for messages, green for data at rest, gray and dashed for
|
|
138
|
+
// a connection nobody has given a direction yet. Never tag a kind: LikeC4
|
|
139
|
+
// copies a kind's tags onto every edge of it.
|
|
140
|
+
relationship publishes {
|
|
141
|
+
color amber
|
|
142
|
+
line solid
|
|
143
|
+
head normal
|
|
144
|
+
}
|
|
145
|
+
relationship delivers {
|
|
146
|
+
color amber
|
|
147
|
+
line solid
|
|
148
|
+
head normal
|
|
149
|
+
}
|
|
150
|
+
relationship reads {
|
|
151
|
+
color green
|
|
152
|
+
head none
|
|
153
|
+
tail normal
|
|
154
|
+
}
|
|
155
|
+
relationship writes {
|
|
156
|
+
color green
|
|
157
|
+
head normal
|
|
158
|
+
}
|
|
159
|
+
relationship readsWrites {
|
|
160
|
+
color green
|
|
161
|
+
head normal
|
|
162
|
+
tail normal
|
|
163
|
+
}
|
|
164
|
+
relationship calls {
|
|
165
|
+
color secondary
|
|
166
|
+
line solid
|
|
167
|
+
head normal
|
|
168
|
+
}
|
|
169
|
+
relationship connects {
|
|
170
|
+
color gray
|
|
171
|
+
line dashed
|
|
172
|
+
head none
|
|
173
|
+
// A marker at the source: an edge with no arrowhead at either end is laid
|
|
174
|
+
// out unconstrained, and enough of them flatten a view into one band.
|
|
175
|
+
tail odot
|
|
176
|
+
}
|
|
99
177
|
}
|
|
100
178
|
|
|
101
179
|
model {
|
|
@@ -115,17 +193,47 @@ views {
|
|
|
115
193
|
}
|
|
116
194
|
`;
|
|
117
195
|
/**
|
|
118
|
-
*
|
|
196
|
+
* The one thing loam itself ever writes ABOVE the stub: `core/docs.ts`'s
|
|
197
|
+
* `landscapePreamble`, spliced in as `${preamble.trimEnd()}\n//\n` — comment
|
|
198
|
+
* lines, closed by a bare `//` that separates the caller's sentence from the
|
|
199
|
+
* scaffold's own opening paragraph. `migrate-openspec` is the only caller.
|
|
200
|
+
*
|
|
201
|
+
* Matched as a SHAPE rather than as the migrator's exact sentence because the
|
|
202
|
+
* preamble is a parameter, and because the alternative is a second copy of that
|
|
203
|
+
* sentence in a package `core/scaffold/` must not import from
|
|
204
|
+
* (`commands/migrate-openspec/materialize/target.ts`). The shape is tight where
|
|
205
|
+
* it has to be: the closing bare `//` is what a hand-written note above the map
|
|
206
|
+
* does not have.
|
|
207
|
+
*/
|
|
208
|
+
const LOAM_PREAMBLE = /^(?:\/\/[^\n]*\n)*\/\/\n$/;
|
|
209
|
+
/**
|
|
210
|
+
* Whether the fleet map is still a scaffold's own bytes — the sentinel
|
|
119
211
|
* doctrine of core/coherence/authoring/sentinels.ts: the writer above and this
|
|
120
|
-
* checker read ONE string, so they cannot drift apart.
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
212
|
+
* checker read ONE string, so they cannot drift apart. CRLF-normalised because
|
|
213
|
+
* a checkout under core.autocrlf is still untouched. Every generation loam ever
|
|
214
|
+
* wrote counts, not just the current one — see `LEGACY_LANDSCAPE_STUBS`. A
|
|
215
|
+
* hand-edit inside the stub body breaks the match — the safe failure mode is a
|
|
216
|
+
* false "authored", which merely drops one teaching step from `loam status`'s
|
|
217
|
+
* empty-fleet ladder (core/status/fleet/next.ts).
|
|
218
|
+
*
|
|
219
|
+
* ANCHORED AT BOTH ENDS, past a preamble loam wrote itself. This was a bare
|
|
220
|
+
* `endsWith`, so anything a person put ABOVE the stub was invisible to the
|
|
221
|
+
* guard: `loam seed` overwrote a two-line "OWNED BY THE ARCHITECTURE GUILD — do
|
|
222
|
+
* not regenerate" header while printing "replaced the scaffold's untouched
|
|
223
|
+
* stub", against its own promise that "Seed never overwrites human work"
|
|
224
|
+
* (`commands/seed/commit.ts`; verification 2026-09-04, second pass). The suffix
|
|
225
|
+
* match existed for the migration preamble alone, so that is now the only
|
|
226
|
+
* prefix accepted, and everything else above the stub makes the file authored.
|
|
126
227
|
*/
|
|
127
228
|
export function isLandscapeStub(content) {
|
|
128
229
|
const normal = (s) => s.replace(/\r\n/g, "\n").trimEnd();
|
|
129
|
-
|
|
230
|
+
const seen = normal(content);
|
|
231
|
+
return [LANDSCAPE_STUB, ...LEGACY_LANDSCAPE_STUBS].some((stub) => {
|
|
232
|
+
const body = normal(stub);
|
|
233
|
+
if (!seen.endsWith(body))
|
|
234
|
+
return false;
|
|
235
|
+
const prefix = seen.slice(0, seen.length - body.length);
|
|
236
|
+
return prefix === "" || LOAM_PREAMBLE.test(prefix);
|
|
237
|
+
});
|
|
130
238
|
}
|
|
131
239
|
//# sourceMappingURL=landscape.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"landscape.js","sourceRoot":"","sources":["../../../src/core/scaffold/landscape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0E7B,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,MAAM,MAAM,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IACzE,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,CAAC","sourcesContent":["/**\n * The bytes a brand-new docs repo's fleet map starts with, and the one\n * question anybody asks of them afterwards: has a human touched this yet?\n *\n * Split out of `../docs.ts` when the README joined the scaffold and the file\n * reached its line limit, and the seam was already there: `docs.ts` says what\n * a docs repo is MADE OF — which directories, which files, in what order —\n * while this package holds the CONTENT of the authored templates it lays down.\n * The two change for different reasons: a new artifact edits the first, better\n * advice to a new fleet edits the second.\n */\n\n/**\n * The fleet map, empty but valid.\n *\n * Nobody writes this file automatically — `adopt` deliberately does not touch\n * it, because who calls whom is a human judgement and a generated landscape\n * would be a guess presented as the map. But \"nobody writes it\" used to mean\n * \"it is simply absent\", and an absent landscape is the one artifact whose\n * absence silences the fleet-wide checks entirely: every cross-service breach\n * `validate` exists to find is invisible on a repo with no landscape.\n *\n * So the scaffold lays down the empty map instead: the four element kinds a\n * fleet actually uses are declared, the model is empty, and the comments say\n * what to add and why. The first `loam adopt` then has somewhere to be drawn.\n *\n * A `views` block IS scaffolded — reversing the decision this comment used to\n * record, which was: no views, because computing one is superlinear in edge\n * count and a scaffolded `include *` handed every repo a fleet-sized bill for\n * the first tool that renders. That cost was real and still is; what changed\n * is the shape of the block. A fleet map stops being readable at the third\n * service unless platform infrastructure is split out, and the split's\n * `exclude element.tag = #platform` is exactly the\n * pruning that keeps the fleet view's render affordable — the scaffold now\n * pays the old objection instead of ignoring it. loam itself still reads\n * elements and relationships and never a view. The platform view's predicate\n * is scaffolded because it is the line users mistype: the obvious spelling\n * draws boxes with no edges.\n * The `views` block below has a deliberate second copy: `core/c4/seed/template.ts` emits the\n * same two views into a seeded landscape (two strikes; extract on a third), and test/seed.test.ts\n * compares the two blocks byte for byte — comments included — so whichever copy drifts fails.\n */\nexport const LANDSCAPE_STUB = `// The fleet map: every service in services/ appears here, and every call\n// between two of them is an edge. This file is written by hand — loam never\n// guesses it, because \"who calls whom\" is the one fact no generator can read\n// off a repository.\n//\n// After \\`loam adopt --service <id>\\`, add the service here:\n//\n// paymentService = softwareSystem 'payment-service' {\n// description 'Owns payment authorization/capture'\n// metadata { service 'payment-service' } // binds the box to services/<id>/\n// }\n//\n// and give each call the operationId it uses, so requirements, C4 and OpenAPI\n// can be cross-checked:\n//\n// checkoutWeb -> paymentService 'Authorizes' {\n// metadata { op 'authorizePayment' }\n// }\n//\n// The \\`views\\` block at the bottom is for LikeC4's own tooling — loam reads\n// the model and never a view. Render with \\`npx likec4 start\\` from the docs\n// repo root, which likec4.config.json scopes to this directory. (A service\n// model or a feature delta renders from its OWN directory, e.g.\n// \\`npx likec4 start services/<id>\\`: each declares its own \\`specification\\`\n// block, so the renderer can only be given one of them at a time.) Keep views\n// scoped, because computing one is superlinear in the number of edges — the\n// \\`fleet\\` view below stays affordable precisely because it excludes the\n// platform hubs.\n//\n// One shape is worth getting right before the fleet is drawn: a shared broker.\n// Kafka as a single element becomes the node every service points at, and any\n// view over it is a star nobody can read. Model the TOPIC instead — a \\`topic\\`\n// nested inside the broker's element, edges pointing at \\`kafka.<topic>\\` — which\n// splits one hub of degree sixty into a dozen small ones and is the truer model\n// besides. Tag the KIND, not just the broker: LikeC4 does not inherit tags, so a\n// topic under an \\`#external\\` broker is not external itself and \\`validate\\` asks\n// for a services/ directory nobody owes.\n//\n// specification {\n// element topic {\n// #external\n// style { shape queue }\n// }\n// }\n\nspecification {\n element person\n element softwareSystem\n element container\n element database\n\n // Ubiquitous infrastructure — logging Kafka, auth, service discovery — takes\n // one inbound edge per service, and by the third service the fleet view is a\n // hairball. Tag those elements #platform: the fleet view excludes them\n // without losing \"who depends on the Identity Provider\", which the platform\n // view answers.\n tag platform\n}\n\nmodel {\n}\n\nviews {\n view fleet {\n include *\n exclude element.tag = #platform\n }\n // The obvious spelling — \\`include element.tag = #platform\\` — draws the\n // platform boxes with NO edges and no consumers. The predicate that works is\n // the relationship form below.\n view platform {\n include * -> element.tag = #platform\n }\n}\n`;\n\n/**\n * Whether the fleet map is still the scaffold's own bytes — the sentinel\n * doctrine of core/coherence/authoring/sentinels.ts: the writer above and this\n * checker read ONE string, so they cannot drift apart. `endsWith`, not\n * equality, because `migrate-openspec` prepends a `landscapePreamble` to the\n * identical stub; CRLF-normalised because a checkout under core.autocrlf is\n * still untouched. A hand-edit inside the stub body breaks the suffix match —\n * the safe failure mode is a false \"authored\", which merely drops one teaching\n * step from `loam status`'s empty-fleet ladder (core/status/fleet/next.ts).\n */\nexport function isLandscapeStub(content: string): boolean {\n const normal = (s: string): string => s.replace(/\\r\\n/g, \"\\n\").trimEnd();\n return normal(content).endsWith(normal(LANDSCAPE_STUB));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"landscape.js","sourceRoot":"","sources":["../../../src/core/scaffold/landscape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyI7B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAElD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,MAAM,MAAM,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IACzE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,cAAc,EAAE,GAAG,sBAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QACxD,OAAO,MAAM,KAAK,EAAE,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * The bytes a brand-new docs repo's fleet map starts with, and the one\n * question anybody asks of them afterwards: has a human touched this yet?\n *\n * Split out of `../docs.ts` when the README joined the scaffold and the file\n * reached its line limit, and the seam was already there: `docs.ts` says what\n * a docs repo is MADE OF — which directories, which files, in what order —\n * while this package holds the CONTENT of the authored templates it lays down.\n * The two change for different reasons: a new artifact edits the first, better\n * advice to a new fleet edits the second.\n */\n\nimport { LEGACY_LANDSCAPE_STUBS } from \"./legacy.js\";\n\n/**\n * The fleet map, empty but valid.\n *\n * Nobody writes this file automatically — `adopt` deliberately does not touch\n * it, because who calls whom is a human judgement and a generated landscape\n * would be a guess presented as the map. But \"nobody writes it\" used to mean\n * \"it is simply absent\", and an absent landscape is the one artifact whose\n * absence silences the fleet-wide checks entirely: every cross-service breach\n * `validate` exists to find is invisible on a repo with no landscape.\n *\n * So the scaffold lays down the empty map instead: the four element kinds a\n * fleet actually uses are declared, the model is empty, and the comments say\n * what to add and why. The first `loam adopt` then has somewhere to be drawn.\n *\n * A `views` block IS scaffolded — reversing the decision this comment used to\n * record, which was: no views, because computing one is superlinear in edge\n * count and a scaffolded `include *` handed every repo a fleet-sized bill for\n * the first tool that renders. That cost was real and still is; what changed\n * is the shape of the block. A fleet map stops being readable at the third\n * service unless platform infrastructure is split out, and the split's\n * `exclude element.tag = #platform` is exactly the\n * pruning that keeps the fleet view's render affordable — the scaffold now\n * pays the old objection instead of ignoring it. loam itself still reads\n * elements and relationships and never a view. The platform view's predicate\n * is scaffolded because it is the line users mistype: the obvious spelling\n * draws boxes with no edges.\n * The `views` block below has a deliberate second copy: `core/c4/seed/template.ts` emits the\n * same two views into a seeded landscape (two strikes; extract on a third), and test/seed.test.ts\n * compares the two blocks byte for byte — comments included — so whichever copy drifts fails.\n *\n * The seven RELATIONSHIP kinds are scaffolded for the element kinds' reason:\n * they are vocabulary, not a guess about this fleet. Declared here, every\n * extending model and every adoption borrows them, so the first edge anybody\n * draws can say what it carries and which way it points. A real fleet drawn\n * without them ended with every arrow pointing into its broker and its stores,\n * because deployment configuration says only that two things are connected. A\n * declaration here also keeps a feature archivable: the archive copies a\n * delta's edge into this file and never a declaration, so a kind this file\n * lacks refuses the merge (`merge-failed`). A `legend` view is NOT scaffolded:\n * a view names only elements the model declares, this model is empty, and an\n * invented example would be a box every fleet check grades. The comment says\n * when to write one. The kinds block has the same deliberate second copy in\n * `core/c4/seed/template.ts`, pinned the same way by test/seed.test.ts.\n */\nexport const LANDSCAPE_STUB = `// The fleet map: every service in services/ appears here, and every call\n// between two of them is an edge. This file is written by hand — loam never\n// guesses it, because \"who calls whom\" is the one fact no generator can read\n// off a repository.\n//\n// After \\`loam adopt --service <id>\\`, add the service here:\n//\n// paymentService = softwareSystem 'payment-service' {\n// description 'Owns payment authorization/capture'\n// metadata { service 'payment-service' } // binds the box to services/<id>/\n// }\n//\n// and give each call the operationId it uses, so requirements, C4 and OpenAPI\n// can be cross-checked:\n//\n// checkoutWeb -[calls]-> paymentService 'Authorizes' {\n// metadata { op 'authorizePayment' }\n// }\n//\n// Every edge says what it carries with one of the relationship kinds declared\n// below, and points the way the evidence says — never a guess:\n//\n// checkoutWeb -[calls]-> orderService a synchronous request\n// orderService -[publishes]-> kafka.orderEvents producer to topic\n// kafka.orderEvents -[delivers]-> paymentService topic to consumer\n// paymentService -[reads]-> ordersDb always service to store; the\n// style puts the head on the reader\n// orderService -[connects]-> kafka no direction established yet\n//\n// Configuration that only names an address says two things are connected and\n// nothing more: that is \\`connects\\`, and adopting the service from its code\n// turns it into the real kind. Once the map has a real edge of each kind, add\n// a \\`legend\\` view that draws one of each. \\`loam instructions loam-drawing\\`\n// has the whole convention.\n//\n// The \\`views\\` block at the bottom is for LikeC4's own tooling — loam reads\n// the model and never a view. Render with \\`npx likec4 start\\` from the docs\n// repo root, which likec4.config.json scopes to this directory. A service's\n// \\`services/<id>/model.likec4\\` EXTENDS this map: it declares no\n// \\`specification\\` block of its own, so it belongs to THIS project and renders\n// with it, containers and all. A model that declares its own \\`specification\\`\n// stands alone instead — it renders only from its own directory\n// (\\`npx likec4 start services/<id>\\`), and the \\`exclude\\` list in the root\n// likec4.config.json has to cover that directory or its declarations collide\n// with this file's. \\`loam subsystem sync\\` maintains both, so neither is\n// hand-edited. Keep views\n// scoped, because computing one is superlinear in the number of edges — the\n// \\`fleet\\` view below stays affordable precisely because it excludes the\n// platform hubs.\n//\n// One shape is worth getting right before the fleet is drawn: a shared broker.\n// Kafka as a single element becomes the node every service points at, and any\n// view over it is a star nobody can read. Model the TOPIC instead — a \\`topic\\`\n// nested inside the broker's element, edges pointing at \\`kafka.<topic>\\` — which\n// splits one hub of degree sixty into a dozen small ones and is the truer model\n// besides. Tag the KIND, not just the broker: LikeC4 does not inherit tags, so a\n// topic under an \\`#external\\` broker is not external itself and \\`validate\\` asks\n// for a services/ directory nobody owes.\n//\n// specification {\n// element topic {\n// #external\n// style { shape queue }\n// }\n// }\n\nspecification {\n element person\n element softwareSystem\n element container\n element database\n\n // Ubiquitous infrastructure — logging Kafka, auth, service discovery — takes\n // one inbound edge per service, and by the third service the fleet view is a\n // hairball. Tag those elements #platform: the fleet view excludes them\n // without losing \"who depends on the Identity Provider\", which the platform\n // view answers.\n tag platform\n\n // One kind per kind of traffic, each with one direction. The style is the\n // picture: amber for messages, green for data at rest, gray and dashed for\n // a connection nobody has given a direction yet. Never tag a kind: LikeC4\n // copies a kind's tags onto every edge of it.\n relationship publishes {\n color amber\n line solid\n head normal\n }\n relationship delivers {\n color amber\n line solid\n head normal\n }\n relationship reads {\n color green\n head none\n tail normal\n }\n relationship writes {\n color green\n head normal\n }\n relationship readsWrites {\n color green\n head normal\n tail normal\n }\n relationship calls {\n color secondary\n line solid\n head normal\n }\n relationship connects {\n color gray\n line dashed\n head none\n // A marker at the source: an edge with no arrowhead at either end is laid\n // out unconstrained, and enough of them flatten a view into one band.\n tail odot\n }\n}\n\nmodel {\n}\n\nviews {\n view fleet {\n include *\n exclude element.tag = #platform\n }\n // The obvious spelling — \\`include element.tag = #platform\\` — draws the\n // platform boxes with NO edges and no consumers. The predicate that works is\n // the relationship form below.\n view platform {\n include * -> element.tag = #platform\n }\n}\n`;\n\n/**\n * The one thing loam itself ever writes ABOVE the stub: `core/docs.ts`'s\n * `landscapePreamble`, spliced in as `${preamble.trimEnd()}\\n//\\n` — comment\n * lines, closed by a bare `//` that separates the caller's sentence from the\n * scaffold's own opening paragraph. `migrate-openspec` is the only caller.\n *\n * Matched as a SHAPE rather than as the migrator's exact sentence because the\n * preamble is a parameter, and because the alternative is a second copy of that\n * sentence in a package `core/scaffold/` must not import from\n * (`commands/migrate-openspec/materialize/target.ts`). The shape is tight where\n * it has to be: the closing bare `//` is what a hand-written note above the map\n * does not have.\n */\nconst LOAM_PREAMBLE = /^(?:\\/\\/[^\\n]*\\n)*\\/\\/\\n$/;\n\n/**\n * Whether the fleet map is still a scaffold's own bytes — the sentinel\n * doctrine of core/coherence/authoring/sentinels.ts: the writer above and this\n * checker read ONE string, so they cannot drift apart. CRLF-normalised because\n * a checkout under core.autocrlf is still untouched. Every generation loam ever\n * wrote counts, not just the current one — see `LEGACY_LANDSCAPE_STUBS`. A\n * hand-edit inside the stub body breaks the match — the safe failure mode is a\n * false \"authored\", which merely drops one teaching step from `loam status`'s\n * empty-fleet ladder (core/status/fleet/next.ts).\n *\n * ANCHORED AT BOTH ENDS, past a preamble loam wrote itself. This was a bare\n * `endsWith`, so anything a person put ABOVE the stub was invisible to the\n * guard: `loam seed` overwrote a two-line \"OWNED BY THE ARCHITECTURE GUILD — do\n * not regenerate\" header while printing \"replaced the scaffold's untouched\n * stub\", against its own promise that \"Seed never overwrites human work\"\n * (`commands/seed/commit.ts`; verification 2026-09-04, second pass). The suffix\n * match existed for the migration preamble alone, so that is now the only\n * prefix accepted, and everything else above the stub makes the file authored.\n */\nexport function isLandscapeStub(content: string): boolean {\n const normal = (s: string): string => s.replace(/\\r\\n/g, \"\\n\").trimEnd();\n const seen = normal(content);\n return [LANDSCAPE_STUB, ...LEGACY_LANDSCAPE_STUBS].some((stub) => {\n const body = normal(stub);\n if (!seen.endsWith(body)) return false;\n const prefix = seen.slice(0, seen.length - body.length);\n return prefix === \"\" || LOAM_PREAMBLE.test(prefix);\n });\n}\n"]}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every fleet map an earlier loam scaffolded, frozen, so `isLandscapeStub` in
|
|
3
|
+
* ./landscape.ts can still tell an untouched old scaffold from a hand-drawn map.
|
|
4
|
+
*
|
|
5
|
+
* Moved out of ./landscape.ts when that file neared its line limit, along the
|
|
6
|
+
* seam the two halves already had: ./landscape.ts holds the stub loam writes
|
|
7
|
+
* NOW and the predicate that reads it, this module holds what loam wrote
|
|
8
|
+
* before. The first changes whenever the advice to a new fleet improves; this
|
|
9
|
+
* one only ever grows by one entry, when that happens.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Stubs earlier versions of loam wrote, FROZEN — never re-derived from
|
|
13
|
+
* `LANDSCAPE_STUB` in ./landscape.ts, or an edit to it would silently rewrite
|
|
14
|
+
* history.
|
|
15
|
+
*
|
|
16
|
+
* `isLandscapeStub` is a suffix match on the exact bytes, and `loam seed`
|
|
17
|
+
* refuses (`seed-landscape-edited`) on a map it judges authored. So editing
|
|
18
|
+
* the stub reclassifies every untouched older scaffold as hand-edited, in
|
|
19
|
+
* repositories nobody has touched — the teaching step disappears from `loam
|
|
20
|
+
* status` and `seed` refuses a map its own scaffold wrote. Each entry is one
|
|
21
|
+
* shipped generation of the file, OLDEST FIRST, appended when
|
|
22
|
+
* `LANDSCAPE_STUB`'s text changes — every generation loam ever wrote is here,
|
|
23
|
+
* not just the previous one, since a repository scaffolded two releases ago is
|
|
24
|
+
* as untouched as one scaffolded yesterday.
|
|
25
|
+
*
|
|
26
|
+
* Generation 1 (v0.1.0-beta.1, .2): the stub lived in core/docs.ts, carried no
|
|
27
|
+
* `views` block at all ("on purpose: loam reads the model and never a view")
|
|
28
|
+
* and no `tag platform`.
|
|
29
|
+
* Generation 2 (v0.1.0-beta.3): the same file with the render paragraph
|
|
30
|
+
* rewritten — still no `views` block, still no `tag platform`.
|
|
31
|
+
* Generation 3 (v0.2.0-alpha.1 through .5): the `views` paragraph taught the
|
|
32
|
+
* retired shape — that a service model "renders from its OWN directory" and
|
|
33
|
+
* "each declares its own `specification` block" — which was written before an
|
|
34
|
+
* extending model belonged to the root project.
|
|
35
|
+
* Generation 4 (v0.2.0-alpha.6 through .11): the extending shape's render
|
|
36
|
+
* paragraph and the shared-broker advice, with no relationship kinds — every
|
|
37
|
+
* edge a plain `->`, which is how a fleet drawn from deployment configuration
|
|
38
|
+
* ended with every arrow pointing into its broker and its stores.
|
|
39
|
+
*/
|
|
40
|
+
export const LEGACY_LANDSCAPE_STUBS = [
|
|
41
|
+
`// The fleet map: every service in services/ appears here, and every call
|
|
42
|
+
// between two of them is an edge. This file is written by hand — loam never
|
|
43
|
+
// guesses it, because "who calls whom" is the one fact no generator can read
|
|
44
|
+
// off a repository.
|
|
45
|
+
//
|
|
46
|
+
// After \`loam adopt --service <id>\`, add the service here:
|
|
47
|
+
//
|
|
48
|
+
// paymentService = softwareSystem 'payment-service' {
|
|
49
|
+
// description 'Owns payment authorization/capture'
|
|
50
|
+
// metadata { service 'payment-service' } // binds the box to services/<id>/
|
|
51
|
+
// }
|
|
52
|
+
//
|
|
53
|
+
// and give each call the operationId it uses, so requirements, C4 and OpenAPI
|
|
54
|
+
// can be cross-checked:
|
|
55
|
+
//
|
|
56
|
+
// checkoutWeb -> paymentService 'Authorizes' {
|
|
57
|
+
// metadata { op 'authorizePayment' }
|
|
58
|
+
// }
|
|
59
|
+
//
|
|
60
|
+
// There is no \`views\` block, on purpose: loam reads the model and never a
|
|
61
|
+
// view, so it would draw nothing. Add views here if you want diagrams, and
|
|
62
|
+
// render them with LikeC4's own tooling (\`npx likec4 start\`) — but scope them,
|
|
63
|
+
// because computing a view is superlinear in the number of edges and an
|
|
64
|
+
// \`include *\` over a whole fleet takes minutes.
|
|
65
|
+
|
|
66
|
+
specification {
|
|
67
|
+
element person
|
|
68
|
+
element softwareSystem
|
|
69
|
+
element container
|
|
70
|
+
element database
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
model {
|
|
74
|
+
}
|
|
75
|
+
`,
|
|
76
|
+
`// The fleet map: every service in services/ appears here, and every call
|
|
77
|
+
// between two of them is an edge. This file is written by hand — loam never
|
|
78
|
+
// guesses it, because "who calls whom" is the one fact no generator can read
|
|
79
|
+
// off a repository.
|
|
80
|
+
//
|
|
81
|
+
// After \`loam adopt --service <id>\`, add the service here:
|
|
82
|
+
//
|
|
83
|
+
// paymentService = softwareSystem 'payment-service' {
|
|
84
|
+
// description 'Owns payment authorization/capture'
|
|
85
|
+
// metadata { service 'payment-service' } // binds the box to services/<id>/
|
|
86
|
+
// }
|
|
87
|
+
//
|
|
88
|
+
// and give each call the operationId it uses, so requirements, C4 and OpenAPI
|
|
89
|
+
// can be cross-checked:
|
|
90
|
+
//
|
|
91
|
+
// checkoutWeb -> paymentService 'Authorizes' {
|
|
92
|
+
// metadata { op 'authorizePayment' }
|
|
93
|
+
// }
|
|
94
|
+
//
|
|
95
|
+
// There is no \`views\` block, on purpose: loam reads the model and never a
|
|
96
|
+
// view, so it would draw nothing. Add views here if you want diagrams, and
|
|
97
|
+
// render them with LikeC4's own tooling — \`npx likec4 start\` from the docs
|
|
98
|
+
// repo root, which likec4.config.json scopes to this directory. (A service
|
|
99
|
+
// model or a feature delta renders from its OWN directory, e.g.
|
|
100
|
+
// \`npx likec4 start services/<id>\`: each declares its own \`specification\`
|
|
101
|
+
// block, so the renderer can only be given one of them at a time.) Scope your
|
|
102
|
+
// views, because computing one is superlinear in the number of edges and an
|
|
103
|
+
// \`include *\` over a whole fleet takes minutes.
|
|
104
|
+
|
|
105
|
+
specification {
|
|
106
|
+
element person
|
|
107
|
+
element softwareSystem
|
|
108
|
+
element container
|
|
109
|
+
element database
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
model {
|
|
113
|
+
}
|
|
114
|
+
`,
|
|
115
|
+
`// The fleet map: every service in services/ appears here, and every call
|
|
116
|
+
// between two of them is an edge. This file is written by hand — loam never
|
|
117
|
+
// guesses it, because "who calls whom" is the one fact no generator can read
|
|
118
|
+
// off a repository.
|
|
119
|
+
//
|
|
120
|
+
// After \`loam adopt --service <id>\`, add the service here:
|
|
121
|
+
//
|
|
122
|
+
// paymentService = softwareSystem 'payment-service' {
|
|
123
|
+
// description 'Owns payment authorization/capture'
|
|
124
|
+
// metadata { service 'payment-service' } // binds the box to services/<id>/
|
|
125
|
+
// }
|
|
126
|
+
//
|
|
127
|
+
// and give each call the operationId it uses, so requirements, C4 and OpenAPI
|
|
128
|
+
// can be cross-checked:
|
|
129
|
+
//
|
|
130
|
+
// checkoutWeb -> paymentService 'Authorizes' {
|
|
131
|
+
// metadata { op 'authorizePayment' }
|
|
132
|
+
// }
|
|
133
|
+
//
|
|
134
|
+
// The \`views\` block at the bottom is for LikeC4's own tooling — loam reads
|
|
135
|
+
// the model and never a view. Render with \`npx likec4 start\` from the docs
|
|
136
|
+
// repo root, which likec4.config.json scopes to this directory. (A service
|
|
137
|
+
// model or a feature delta renders from its OWN directory, e.g.
|
|
138
|
+
// \`npx likec4 start services/<id>\`: each declares its own \`specification\`
|
|
139
|
+
// block, so the renderer can only be given one of them at a time.) Keep views
|
|
140
|
+
// scoped, because computing one is superlinear in the number of edges — the
|
|
141
|
+
// \`fleet\` view below stays affordable precisely because it excludes the
|
|
142
|
+
// platform hubs.
|
|
143
|
+
//
|
|
144
|
+
// One shape is worth getting right before the fleet is drawn: a shared broker.
|
|
145
|
+
// Kafka as a single element becomes the node every service points at, and any
|
|
146
|
+
// view over it is a star nobody can read. Model the TOPIC instead — a \`topic\`
|
|
147
|
+
// nested inside the broker's element, edges pointing at \`kafka.<topic>\` — which
|
|
148
|
+
// splits one hub of degree sixty into a dozen small ones and is the truer model
|
|
149
|
+
// besides. Tag the KIND, not just the broker: LikeC4 does not inherit tags, so a
|
|
150
|
+
// topic under an \`#external\` broker is not external itself and \`validate\` asks
|
|
151
|
+
// for a services/ directory nobody owes.
|
|
152
|
+
//
|
|
153
|
+
// specification {
|
|
154
|
+
// element topic {
|
|
155
|
+
// #external
|
|
156
|
+
// style { shape queue }
|
|
157
|
+
// }
|
|
158
|
+
// }
|
|
159
|
+
|
|
160
|
+
specification {
|
|
161
|
+
element person
|
|
162
|
+
element softwareSystem
|
|
163
|
+
element container
|
|
164
|
+
element database
|
|
165
|
+
|
|
166
|
+
// Ubiquitous infrastructure — logging Kafka, auth, service discovery — takes
|
|
167
|
+
// one inbound edge per service, and by the third service the fleet view is a
|
|
168
|
+
// hairball. Tag those elements #platform: the fleet view excludes them
|
|
169
|
+
// without losing "who depends on the Identity Provider", which the platform
|
|
170
|
+
// view answers.
|
|
171
|
+
tag platform
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
model {
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
views {
|
|
178
|
+
view fleet {
|
|
179
|
+
include *
|
|
180
|
+
exclude element.tag = #platform
|
|
181
|
+
}
|
|
182
|
+
// The obvious spelling — \`include element.tag = #platform\` — draws the
|
|
183
|
+
// platform boxes with NO edges and no consumers. The predicate that works is
|
|
184
|
+
// the relationship form below.
|
|
185
|
+
view platform {
|
|
186
|
+
include * -> element.tag = #platform
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
`,
|
|
190
|
+
`// The fleet map: every service in services/ appears here, and every call
|
|
191
|
+
// between two of them is an edge. This file is written by hand — loam never
|
|
192
|
+
// guesses it, because "who calls whom" is the one fact no generator can read
|
|
193
|
+
// off a repository.
|
|
194
|
+
//
|
|
195
|
+
// After \`loam adopt --service <id>\`, add the service here:
|
|
196
|
+
//
|
|
197
|
+
// paymentService = softwareSystem 'payment-service' {
|
|
198
|
+
// description 'Owns payment authorization/capture'
|
|
199
|
+
// metadata { service 'payment-service' } // binds the box to services/<id>/
|
|
200
|
+
// }
|
|
201
|
+
//
|
|
202
|
+
// and give each call the operationId it uses, so requirements, C4 and OpenAPI
|
|
203
|
+
// can be cross-checked:
|
|
204
|
+
//
|
|
205
|
+
// checkoutWeb -> paymentService 'Authorizes' {
|
|
206
|
+
// metadata { op 'authorizePayment' }
|
|
207
|
+
// }
|
|
208
|
+
//
|
|
209
|
+
// The \`views\` block at the bottom is for LikeC4's own tooling — loam reads
|
|
210
|
+
// the model and never a view. Render with \`npx likec4 start\` from the docs
|
|
211
|
+
// repo root, which likec4.config.json scopes to this directory. A service's
|
|
212
|
+
// \`services/<id>/model.likec4\` EXTENDS this map: it declares no
|
|
213
|
+
// \`specification\` block of its own, so it belongs to THIS project and renders
|
|
214
|
+
// with it, containers and all. A model that declares its own \`specification\`
|
|
215
|
+
// stands alone instead — it renders only from its own directory
|
|
216
|
+
// (\`npx likec4 start services/<id>\`), and the \`exclude\` list in the root
|
|
217
|
+
// likec4.config.json has to cover that directory or its declarations collide
|
|
218
|
+
// with this file's. \`loam subsystem sync\` maintains both, so neither is
|
|
219
|
+
// hand-edited. Keep views
|
|
220
|
+
// scoped, because computing one is superlinear in the number of edges — the
|
|
221
|
+
// \`fleet\` view below stays affordable precisely because it excludes the
|
|
222
|
+
// platform hubs.
|
|
223
|
+
//
|
|
224
|
+
// One shape is worth getting right before the fleet is drawn: a shared broker.
|
|
225
|
+
// Kafka as a single element becomes the node every service points at, and any
|
|
226
|
+
// view over it is a star nobody can read. Model the TOPIC instead — a \`topic\`
|
|
227
|
+
// nested inside the broker's element, edges pointing at \`kafka.<topic>\` — which
|
|
228
|
+
// splits one hub of degree sixty into a dozen small ones and is the truer model
|
|
229
|
+
// besides. Tag the KIND, not just the broker: LikeC4 does not inherit tags, so a
|
|
230
|
+
// topic under an \`#external\` broker is not external itself and \`validate\` asks
|
|
231
|
+
// for a services/ directory nobody owes.
|
|
232
|
+
//
|
|
233
|
+
// specification {
|
|
234
|
+
// element topic {
|
|
235
|
+
// #external
|
|
236
|
+
// style { shape queue }
|
|
237
|
+
// }
|
|
238
|
+
// }
|
|
239
|
+
|
|
240
|
+
specification {
|
|
241
|
+
element person
|
|
242
|
+
element softwareSystem
|
|
243
|
+
element container
|
|
244
|
+
element database
|
|
245
|
+
|
|
246
|
+
// Ubiquitous infrastructure — logging Kafka, auth, service discovery — takes
|
|
247
|
+
// one inbound edge per service, and by the third service the fleet view is a
|
|
248
|
+
// hairball. Tag those elements #platform: the fleet view excludes them
|
|
249
|
+
// without losing "who depends on the Identity Provider", which the platform
|
|
250
|
+
// view answers.
|
|
251
|
+
tag platform
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
model {
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
views {
|
|
258
|
+
view fleet {
|
|
259
|
+
include *
|
|
260
|
+
exclude element.tag = #platform
|
|
261
|
+
}
|
|
262
|
+
// The obvious spelling — \`include element.tag = #platform\` — draws the
|
|
263
|
+
// platform boxes with NO edges and no consumers. The predicate that works is
|
|
264
|
+
// the relationship form below.
|
|
265
|
+
view platform {
|
|
266
|
+
include * -> element.tag = #platform
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
`,
|
|
270
|
+
];
|
|
271
|
+
//# sourceMappingURL=legacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy.js","sourceRoot":"","sources":["../../../src/core/scaffold/legacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAsB;IACvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCD;IACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsCD;IACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0ED;IACC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+ED;CACA,CAAC","sourcesContent":["/**\n * Every fleet map an earlier loam scaffolded, frozen, so `isLandscapeStub` in\n * ./landscape.ts can still tell an untouched old scaffold from a hand-drawn map.\n *\n * Moved out of ./landscape.ts when that file neared its line limit, along the\n * seam the two halves already had: ./landscape.ts holds the stub loam writes\n * NOW and the predicate that reads it, this module holds what loam wrote\n * before. The first changes whenever the advice to a new fleet improves; this\n * one only ever grows by one entry, when that happens.\n */\n\n/**\n * Stubs earlier versions of loam wrote, FROZEN — never re-derived from\n * `LANDSCAPE_STUB` in ./landscape.ts, or an edit to it would silently rewrite\n * history.\n *\n * `isLandscapeStub` is a suffix match on the exact bytes, and `loam seed`\n * refuses (`seed-landscape-edited`) on a map it judges authored. So editing\n * the stub reclassifies every untouched older scaffold as hand-edited, in\n * repositories nobody has touched — the teaching step disappears from `loam\n * status` and `seed` refuses a map its own scaffold wrote. Each entry is one\n * shipped generation of the file, OLDEST FIRST, appended when\n * `LANDSCAPE_STUB`'s text changes — every generation loam ever wrote is here,\n * not just the previous one, since a repository scaffolded two releases ago is\n * as untouched as one scaffolded yesterday.\n *\n * Generation 1 (v0.1.0-beta.1, .2): the stub lived in core/docs.ts, carried no\n * `views` block at all (\"on purpose: loam reads the model and never a view\")\n * and no `tag platform`.\n * Generation 2 (v0.1.0-beta.3): the same file with the render paragraph\n * rewritten — still no `views` block, still no `tag platform`.\n * Generation 3 (v0.2.0-alpha.1 through .5): the `views` paragraph taught the\n * retired shape — that a service model \"renders from its OWN directory\" and\n * \"each declares its own `specification` block\" — which was written before an\n * extending model belonged to the root project.\n * Generation 4 (v0.2.0-alpha.6 through .11): the extending shape's render\n * paragraph and the shared-broker advice, with no relationship kinds — every\n * edge a plain `->`, which is how a fleet drawn from deployment configuration\n * ended with every arrow pointing into its broker and its stores.\n */\nexport const LEGACY_LANDSCAPE_STUBS: readonly string[] = [\n `// The fleet map: every service in services/ appears here, and every call\n// between two of them is an edge. This file is written by hand — loam never\n// guesses it, because \"who calls whom\" is the one fact no generator can read\n// off a repository.\n//\n// After \\`loam adopt --service <id>\\`, add the service here:\n//\n// paymentService = softwareSystem 'payment-service' {\n// description 'Owns payment authorization/capture'\n// metadata { service 'payment-service' } // binds the box to services/<id>/\n// }\n//\n// and give each call the operationId it uses, so requirements, C4 and OpenAPI\n// can be cross-checked:\n//\n// checkoutWeb -> paymentService 'Authorizes' {\n// metadata { op 'authorizePayment' }\n// }\n//\n// There is no \\`views\\` block, on purpose: loam reads the model and never a\n// view, so it would draw nothing. Add views here if you want diagrams, and\n// render them with LikeC4's own tooling (\\`npx likec4 start\\`) — but scope them,\n// because computing a view is superlinear in the number of edges and an\n// \\`include *\\` over a whole fleet takes minutes.\n\nspecification {\n element person\n element softwareSystem\n element container\n element database\n}\n\nmodel {\n}\n`,\n `// The fleet map: every service in services/ appears here, and every call\n// between two of them is an edge. This file is written by hand — loam never\n// guesses it, because \"who calls whom\" is the one fact no generator can read\n// off a repository.\n//\n// After \\`loam adopt --service <id>\\`, add the service here:\n//\n// paymentService = softwareSystem 'payment-service' {\n// description 'Owns payment authorization/capture'\n// metadata { service 'payment-service' } // binds the box to services/<id>/\n// }\n//\n// and give each call the operationId it uses, so requirements, C4 and OpenAPI\n// can be cross-checked:\n//\n// checkoutWeb -> paymentService 'Authorizes' {\n// metadata { op 'authorizePayment' }\n// }\n//\n// There is no \\`views\\` block, on purpose: loam reads the model and never a\n// view, so it would draw nothing. Add views here if you want diagrams, and\n// render them with LikeC4's own tooling — \\`npx likec4 start\\` from the docs\n// repo root, which likec4.config.json scopes to this directory. (A service\n// model or a feature delta renders from its OWN directory, e.g.\n// \\`npx likec4 start services/<id>\\`: each declares its own \\`specification\\`\n// block, so the renderer can only be given one of them at a time.) Scope your\n// views, because computing one is superlinear in the number of edges and an\n// \\`include *\\` over a whole fleet takes minutes.\n\nspecification {\n element person\n element softwareSystem\n element container\n element database\n}\n\nmodel {\n}\n`,\n `// The fleet map: every service in services/ appears here, and every call\n// between two of them is an edge. This file is written by hand — loam never\n// guesses it, because \"who calls whom\" is the one fact no generator can read\n// off a repository.\n//\n// After \\`loam adopt --service <id>\\`, add the service here:\n//\n// paymentService = softwareSystem 'payment-service' {\n// description 'Owns payment authorization/capture'\n// metadata { service 'payment-service' } // binds the box to services/<id>/\n// }\n//\n// and give each call the operationId it uses, so requirements, C4 and OpenAPI\n// can be cross-checked:\n//\n// checkoutWeb -> paymentService 'Authorizes' {\n// metadata { op 'authorizePayment' }\n// }\n//\n// The \\`views\\` block at the bottom is for LikeC4's own tooling — loam reads\n// the model and never a view. Render with \\`npx likec4 start\\` from the docs\n// repo root, which likec4.config.json scopes to this directory. (A service\n// model or a feature delta renders from its OWN directory, e.g.\n// \\`npx likec4 start services/<id>\\`: each declares its own \\`specification\\`\n// block, so the renderer can only be given one of them at a time.) Keep views\n// scoped, because computing one is superlinear in the number of edges — the\n// \\`fleet\\` view below stays affordable precisely because it excludes the\n// platform hubs.\n//\n// One shape is worth getting right before the fleet is drawn: a shared broker.\n// Kafka as a single element becomes the node every service points at, and any\n// view over it is a star nobody can read. Model the TOPIC instead — a \\`topic\\`\n// nested inside the broker's element, edges pointing at \\`kafka.<topic>\\` — which\n// splits one hub of degree sixty into a dozen small ones and is the truer model\n// besides. Tag the KIND, not just the broker: LikeC4 does not inherit tags, so a\n// topic under an \\`#external\\` broker is not external itself and \\`validate\\` asks\n// for a services/ directory nobody owes.\n//\n// specification {\n// element topic {\n// #external\n// style { shape queue }\n// }\n// }\n\nspecification {\n element person\n element softwareSystem\n element container\n element database\n\n // Ubiquitous infrastructure — logging Kafka, auth, service discovery — takes\n // one inbound edge per service, and by the third service the fleet view is a\n // hairball. Tag those elements #platform: the fleet view excludes them\n // without losing \"who depends on the Identity Provider\", which the platform\n // view answers.\n tag platform\n}\n\nmodel {\n}\n\nviews {\n view fleet {\n include *\n exclude element.tag = #platform\n }\n // The obvious spelling — \\`include element.tag = #platform\\` — draws the\n // platform boxes with NO edges and no consumers. The predicate that works is\n // the relationship form below.\n view platform {\n include * -> element.tag = #platform\n }\n}\n`,\n `// The fleet map: every service in services/ appears here, and every call\n// between two of them is an edge. This file is written by hand — loam never\n// guesses it, because \"who calls whom\" is the one fact no generator can read\n// off a repository.\n//\n// After \\`loam adopt --service <id>\\`, add the service here:\n//\n// paymentService = softwareSystem 'payment-service' {\n// description 'Owns payment authorization/capture'\n// metadata { service 'payment-service' } // binds the box to services/<id>/\n// }\n//\n// and give each call the operationId it uses, so requirements, C4 and OpenAPI\n// can be cross-checked:\n//\n// checkoutWeb -> paymentService 'Authorizes' {\n// metadata { op 'authorizePayment' }\n// }\n//\n// The \\`views\\` block at the bottom is for LikeC4's own tooling — loam reads\n// the model and never a view. Render with \\`npx likec4 start\\` from the docs\n// repo root, which likec4.config.json scopes to this directory. A service's\n// \\`services/<id>/model.likec4\\` EXTENDS this map: it declares no\n// \\`specification\\` block of its own, so it belongs to THIS project and renders\n// with it, containers and all. A model that declares its own \\`specification\\`\n// stands alone instead — it renders only from its own directory\n// (\\`npx likec4 start services/<id>\\`), and the \\`exclude\\` list in the root\n// likec4.config.json has to cover that directory or its declarations collide\n// with this file's. \\`loam subsystem sync\\` maintains both, so neither is\n// hand-edited. Keep views\n// scoped, because computing one is superlinear in the number of edges — the\n// \\`fleet\\` view below stays affordable precisely because it excludes the\n// platform hubs.\n//\n// One shape is worth getting right before the fleet is drawn: a shared broker.\n// Kafka as a single element becomes the node every service points at, and any\n// view over it is a star nobody can read. Model the TOPIC instead — a \\`topic\\`\n// nested inside the broker's element, edges pointing at \\`kafka.<topic>\\` — which\n// splits one hub of degree sixty into a dozen small ones and is the truer model\n// besides. Tag the KIND, not just the broker: LikeC4 does not inherit tags, so a\n// topic under an \\`#external\\` broker is not external itself and \\`validate\\` asks\n// for a services/ directory nobody owes.\n//\n// specification {\n// element topic {\n// #external\n// style { shape queue }\n// }\n// }\n\nspecification {\n element person\n element softwareSystem\n element container\n element database\n\n // Ubiquitous infrastructure — logging Kafka, auth, service discovery — takes\n // one inbound edge per service, and by the third service the fleet view is a\n // hairball. Tag those elements #platform: the fleet view excludes them\n // without losing \"who depends on the Identity Provider\", which the platform\n // view answers.\n tag platform\n}\n\nmodel {\n}\n\nviews {\n view fleet {\n include *\n exclude element.tag = #platform\n }\n // The obvious spelling — \\`include element.tag = #platform\\` — draws the\n // platform boxes with NO edges and no consumers. The predicate that works is\n // the relationship form below.\n view platform {\n include * -> element.tag = #platform\n }\n}\n`,\n];\n"]}
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { existsSync } from "node:fs";
|
|
17
17
|
import { link, mkdir, readFile, rename, rm, rmdir, unlink, writeFile } from "node:fs/promises";
|
|
18
|
-
import { basename, dirname,
|
|
18
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
19
|
+
import { isPathInside, withoutNamespacePrefix } from "../kernel/path-safety.js";
|
|
19
20
|
import { sameBytes, toBytes } from "./writes.js";
|
|
20
21
|
/**
|
|
21
22
|
* The target changed between the pre-image staging read and the swap.
|
|
@@ -47,9 +48,7 @@ export async function stageWrites(writes) {
|
|
|
47
48
|
const staged = [];
|
|
48
49
|
try {
|
|
49
50
|
for (const [i, write] of writes.entries()) {
|
|
50
|
-
|
|
51
|
-
// handle a rollback needs to put the tree back the way it found it.
|
|
52
|
-
const createdDir = (await mkdir(dirname(write.path), { recursive: true })) ?? null;
|
|
51
|
+
const createdDir = await mkdirReportingCreated(dirname(write.path));
|
|
53
52
|
const before = existsSync(write.path) ? await readFile(write.path) : null;
|
|
54
53
|
const content = toBytes(write.content);
|
|
55
54
|
let tmp = null;
|
|
@@ -140,6 +139,21 @@ export async function rollbackStaged(staged) {
|
|
|
140
139
|
await discardStaged(staged);
|
|
141
140
|
return failures;
|
|
142
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* `mkdir -p`, reporting the topmost directory it had to create — the handle a
|
|
144
|
+
* rollback needs to put the tree back the way it found it — or null when every
|
|
145
|
+
* one already existed.
|
|
146
|
+
*
|
|
147
|
+
* The report is never handed on raw. On Windows, Node spells it with a `\\?\`
|
|
148
|
+
* prefix that no other path loam holds carries, and a rollback comparing the
|
|
149
|
+
* two spellings found nothing to prune (`withoutNamespacePrefix` has the
|
|
150
|
+
* measurement). Every caller that keeps a created directory for its rollback
|
|
151
|
+
* takes it from here, so the plain spelling is decided once.
|
|
152
|
+
*/
|
|
153
|
+
export async function mkdirReportingCreated(dir) {
|
|
154
|
+
const created = await mkdir(dir, { recursive: true });
|
|
155
|
+
return created === undefined ? null : withoutNamespacePrefix(created);
|
|
156
|
+
}
|
|
143
157
|
/** Write `content` to `path` through a temp file in the same directory. */
|
|
144
158
|
export async function atomicWrite(path, content) {
|
|
145
159
|
const tmp = tempPath(path, 0);
|
|
@@ -169,20 +183,11 @@ async function discardStaged(staged) {
|
|
|
169
183
|
await quietRm(s.tmp);
|
|
170
184
|
const roots = staged.filter((s) => s.createdDir !== null).map((s) => resolve(s.createdDir));
|
|
171
185
|
for (const s of [...staged].reverse()) {
|
|
172
|
-
const root = roots.find((candidate) =>
|
|
186
|
+
const root = roots.find((candidate) => isPathInside(candidate, s.write.path));
|
|
173
187
|
if (root !== undefined)
|
|
174
188
|
await quietPruneEmptyParents(dirname(s.write.path), root);
|
|
175
189
|
}
|
|
176
190
|
}
|
|
177
|
-
function contains(parent, candidate) {
|
|
178
|
-
const rel = relative(parent, resolve(candidate));
|
|
179
|
-
return rel === "" || (!rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel));
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Undo the directories a write had to create, from `start` up to and including
|
|
183
|
-
* `boundary`. Remove only directories that are still EMPTY: anything else in
|
|
184
|
-
* there arrived after we made it, and belongs to whoever put it there.
|
|
185
|
-
*/
|
|
186
191
|
/** Remove `dir` if it is empty. Best effort — a directory left standing is noise, not corruption. */
|
|
187
192
|
export async function quietRmdir(dir) {
|
|
188
193
|
try {
|
|
@@ -192,10 +197,16 @@ export async function quietRmdir(dir) {
|
|
|
192
197
|
// Not empty, or not ours.
|
|
193
198
|
}
|
|
194
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Undo the directories a write had to create, from `start` up to and including
|
|
202
|
+
* `boundary` — or, for unarchive, the ones a restore's deletes left empty.
|
|
203
|
+
* Remove only directories that are still EMPTY: anything else in there arrived
|
|
204
|
+
* after we made it, and belongs to whoever put it there.
|
|
205
|
+
*/
|
|
195
206
|
export async function quietPruneEmptyParents(start, boundary) {
|
|
196
207
|
let cursor = resolve(start);
|
|
197
208
|
const root = resolve(boundary);
|
|
198
|
-
while (
|
|
209
|
+
while (isPathInside(root, cursor)) {
|
|
199
210
|
try {
|
|
200
211
|
await rmdir(cursor);
|
|
201
212
|
}
|