@ybotok/loam 0.1.0-beta.3 → 0.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2635 -86
- package/COMPARISON.md +80 -63
- package/CONTRIBUTING.md +84 -0
- package/MIGRATING-from-OpenSpec.md +213 -54
- package/QUICKSTART.md +125 -0
- package/README.md +450 -150
- package/ROADMAP.md +599 -0
- package/SCHEMA.md +2355 -256
- package/SECURITY.md +21 -3
- package/WORKFLOW.md +701 -0
- package/dist/cli.js +113 -19
- package/dist/cli.js.map +1 -1
- package/dist/commands/adopt/adopt.js +209 -0
- package/dist/commands/adopt/adopt.js.map +1 -0
- package/dist/commands/adopt/render.js +268 -0
- package/dist/commands/adopt/render.js.map +1 -0
- package/dist/commands/archive/archive.js +77 -0
- package/dist/commands/archive/archive.js.map +1 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
- package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
- package/dist/commands/archive/plan/contracts/openapi.js +159 -0
- package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
- package/dist/commands/archive/plan/gate.js +323 -0
- package/dist/commands/archive/plan/gate.js.map +1 -0
- package/dist/commands/archive/plan/landscape.js +180 -0
- package/dist/commands/archive/plan/landscape.js.map +1 -0
- package/dist/commands/archive/plan/refusal.js +111 -0
- package/dist/commands/archive/plan/refusal.js.map +1 -0
- package/dist/commands/archive/plan/specs.js +237 -0
- package/dist/commands/archive/plan/specs.js.map +1 -0
- package/dist/commands/archive/plan/state.js +27 -0
- package/dist/commands/archive/plan/state.js.map +1 -0
- package/dist/commands/archive/run.js +252 -0
- package/dist/commands/archive/run.js.map +1 -0
- package/dist/commands/context/context.js +99 -0
- package/dist/commands/context/context.js.map +1 -0
- package/dist/commands/context/print.js +283 -0
- package/dist/commands/context/print.js.map +1 -0
- package/dist/commands/delta/delta.js +279 -0
- package/dist/commands/delta/delta.js.map +1 -0
- package/dist/commands/delta/print.js +205 -0
- package/dist/commands/delta/print.js.map +1 -0
- package/dist/commands/dependencies.js +9 -7
- package/dist/commands/dependencies.js.map +1 -1
- package/dist/commands/diff/diff.js +93 -0
- package/dist/commands/diff/diff.js.map +1 -0
- package/dist/commands/diff/print.js +38 -0
- package/dist/commands/diff/print.js.map +1 -0
- package/dist/commands/doctor.js +5 -4
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain/explain.js +151 -0
- package/dist/commands/explain/explain.js.map +1 -0
- package/dist/commands/explore.js +29 -24
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/gate/gate.js +115 -0
- package/dist/commands/gate/gate.js.map +1 -0
- package/dist/commands/gate/print.js +54 -0
- package/dist/commands/gate/print.js.map +1 -0
- package/dist/commands/gherkin/commit.js +146 -0
- package/dist/commands/gherkin/commit.js.map +1 -0
- package/dist/commands/gherkin/gherkin.js +246 -0
- package/dist/commands/gherkin/gherkin.js.map +1 -0
- package/dist/commands/gherkin/reconcile.js +149 -0
- package/dist/commands/gherkin/reconcile.js.map +1 -0
- package/dist/commands/gherkin/render.js +77 -0
- package/dist/commands/gherkin/render.js.map +1 -0
- package/dist/commands/init/example.js +204 -0
- package/dist/commands/init/example.js.map +1 -0
- package/dist/commands/init/first-hour.js +28 -0
- package/dist/commands/init/first-hour.js.map +1 -0
- package/dist/commands/{init.js → init/init.js} +146 -71
- package/dist/commands/init/init.js.map +1 -0
- package/dist/commands/init/mcp.js +131 -0
- package/dist/commands/init/mcp.js.map +1 -0
- package/dist/commands/init/options.js +78 -0
- package/dist/commands/init/options.js.map +1 -0
- package/dist/commands/instructions.js +72 -14
- package/dist/commands/instructions.js.map +1 -1
- package/dist/commands/list/campaign/campaign.js +65 -0
- package/dist/commands/list/campaign/campaign.js.map +1 -0
- package/dist/commands/list/campaign/owners.js +65 -0
- package/dist/commands/list/campaign/owners.js.map +1 -0
- package/dist/commands/list/json.js +157 -0
- package/dist/commands/list/json.js.map +1 -0
- package/dist/commands/list/list.js +343 -0
- package/dist/commands/list/list.js.map +1 -0
- package/dist/commands/list/print.js +301 -0
- package/dist/commands/list/print.js.map +1 -0
- package/dist/commands/list/review.js +120 -0
- package/dist/commands/list/review.js.map +1 -0
- package/dist/commands/list/views.js +105 -0
- package/dist/commands/list/views.js.map +1 -0
- package/dist/commands/mcp/dispatch.js +183 -0
- package/dist/commands/mcp/dispatch.js.map +1 -0
- package/dist/commands/mcp/mcp.js +34 -0
- package/dist/commands/mcp/mcp.js.map +1 -0
- package/dist/commands/mcp/serve.js +55 -0
- package/dist/commands/mcp/serve.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/active.js +170 -0
- package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
- package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/living.js +62 -0
- package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/stage.js +142 -0
- package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
- package/dist/commands/migrate-openspec/materialize/target.js +219 -0
- package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
- package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js +91 -0
- package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/error.js +19 -0
- package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
- package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/paths.js +43 -0
- package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
- package/dist/commands/migrate-openspec/openspec/read.js +49 -0
- package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
- package/dist/commands/migrate-openspec/print.js +89 -0
- package/dist/commands/migrate-openspec/print.js.map +1 -0
- package/dist/commands/new/commit.js +76 -0
- package/dist/commands/new/commit.js.map +1 -0
- package/dist/commands/new/new.js +283 -0
- package/dist/commands/new/new.js.map +1 -0
- package/dist/commands/new/templates.js +355 -0
- package/dist/commands/new/templates.js.map +1 -0
- package/dist/commands/open.js +203 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/policy/format.js +152 -0
- package/dist/commands/policy/format.js.map +1 -0
- package/dist/commands/{docs-repo-gate.js → policy/gate.js} +11 -11
- package/dist/commands/policy/gate.js.map +1 -0
- package/dist/commands/rebase/edit.js +106 -0
- package/dist/commands/rebase/edit.js.map +1 -0
- package/dist/commands/rebase/living.js +185 -0
- package/dist/commands/rebase/living.js.map +1 -0
- package/dist/commands/rebase/plan.js +245 -0
- package/dist/commands/rebase/plan.js.map +1 -0
- package/dist/commands/rebase/rebase.js +275 -0
- package/dist/commands/rebase/rebase.js.map +1 -0
- package/dist/commands/seed/commit.js +192 -0
- package/dist/commands/seed/commit.js.map +1 -0
- package/dist/commands/seed/plan.js +133 -0
- package/dist/commands/seed/plan.js.map +1 -0
- package/dist/commands/seed/seed.js +172 -0
- package/dist/commands/seed/seed.js.map +1 -0
- package/dist/commands/show/feature.js +178 -0
- package/dist/commands/show/feature.js.map +1 -0
- package/dist/commands/show/marks.js +24 -0
- package/dist/commands/show/marks.js.map +1 -0
- package/dist/commands/{show.js → show/service.js} +63 -152
- package/dist/commands/show/service.js.map +1 -0
- package/dist/commands/show/show.js +77 -0
- package/dist/commands/show/show.js.map +1 -0
- package/dist/commands/status/json.js +45 -0
- package/dist/commands/status/json.js.map +1 -0
- package/dist/commands/status/print.js +157 -0
- package/dist/commands/status/print.js.map +1 -0
- package/dist/commands/status/status.js +119 -0
- package/dist/commands/status/status.js.map +1 -0
- package/dist/commands/steps/steps.js +189 -0
- package/dist/commands/steps/steps.js.map +1 -0
- package/dist/commands/subsystem/edit.js +192 -0
- package/dist/commands/subsystem/edit.js.map +1 -0
- package/dist/commands/subsystem/move.js +265 -0
- package/dist/commands/subsystem/move.js.map +1 -0
- package/dist/commands/subsystem/query.js +115 -0
- package/dist/commands/subsystem/query.js.map +1 -0
- package/dist/commands/subsystem/subsystem.js +101 -0
- package/dist/commands/subsystem/subsystem.js.map +1 -0
- package/dist/commands/subsystem/sync.js +103 -0
- package/dist/commands/subsystem/sync.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +94 -0
- package/dist/commands/subsystem/txn/txn.js.map +1 -0
- package/dist/commands/subsystem/txn/views.js +70 -0
- package/dist/commands/subsystem/txn/views.js.map +1 -0
- package/dist/commands/unarchive/manifest.js +160 -0
- package/dist/commands/unarchive/manifest.js.map +1 -0
- package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
- package/dist/commands/unarchive/restore.js.map +1 -0
- package/dist/commands/unarchive/unarchive.js +67 -0
- package/dist/commands/unarchive/unarchive.js.map +1 -0
- package/dist/commands/validate/arch-coverage.js +204 -0
- package/dist/commands/validate/arch-coverage.js.map +1 -0
- package/dist/commands/validate/checks/fleet-shape.js +296 -0
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
- package/dist/commands/validate/checks/health-deps.js +55 -0
- package/dist/commands/validate/checks/health-deps.js.map +1 -0
- package/dist/commands/validate/checks/requirements.js +254 -0
- package/dist/commands/validate/checks/requirements.js.map +1 -0
- package/dist/commands/validate/checks/sources.js +76 -0
- package/dist/commands/validate/checks/sources.js.map +1 -0
- package/dist/commands/validate/checks/vocabulary.js +31 -0
- package/dist/commands/validate/checks/vocabulary.js.map +1 -0
- package/dist/commands/validate/feature.js +216 -0
- package/dist/commands/validate/feature.js.map +1 -0
- package/dist/commands/validate/fleet/census.js +69 -0
- package/dist/commands/validate/fleet/census.js.map +1 -0
- package/dist/commands/validate/fleet/kind-tags.js +39 -0
- package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
- package/dist/commands/validate/fleet/landscape.js +353 -0
- package/dist/commands/validate/fleet/landscape.js.map +1 -0
- package/dist/commands/validate/fleet/load.js +52 -0
- package/dist/commands/validate/fleet/load.js.map +1 -0
- package/dist/commands/validate/fleet/obligations.js +270 -0
- package/dist/commands/validate/fleet/obligations.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
- package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
- package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/print.js +63 -0
- package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
- package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
- package/dist/commands/validate/fleet/usecases/capability-tag.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/place.js +13 -0
- package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/requirement-tag.js +95 -0
- package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/steps.js +197 -0
- package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
- package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +40 -0
- package/dist/commands/validate/fleet/views/ids.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +59 -0
- package/dist/commands/validate/fleet/views/stale.js.map +1 -0
- package/dist/commands/validate/links/corpus.js +92 -0
- package/dist/commands/validate/links/corpus.js.map +1 -0
- package/dist/commands/validate/links/glossary.js +75 -0
- package/dist/commands/validate/links/glossary.js.map +1 -0
- package/dist/commands/validate/report.js +269 -0
- package/dist/commands/validate/report.js.map +1 -0
- package/dist/commands/validate/service/api.js +338 -0
- package/dist/commands/validate/service/api.js.map +1 -0
- package/dist/commands/validate/service/events/events.js +219 -0
- package/dist/commands/validate/service/events/events.js.map +1 -0
- package/dist/commands/validate/service/events/message-producers.js +77 -0
- package/dist/commands/validate/service/events/message-producers.js.map +1 -0
- package/dist/commands/validate/service/evidence-pins.js +131 -0
- package/dist/commands/validate/service/evidence-pins.js.map +1 -0
- package/dist/commands/validate/service/service.js +251 -0
- package/dist/commands/validate/service/service.js.map +1 -0
- package/dist/commands/validate/service/specs.js +251 -0
- package/dist/commands/validate/service/specs.js.map +1 -0
- package/dist/commands/validate/service/spine.js +113 -0
- package/dist/commands/validate/service/spine.js.map +1 -0
- package/dist/commands/validate/validate.js +338 -0
- package/dist/commands/validate/validate.js.map +1 -0
- package/dist/commands/verify/cross/diff.js +182 -0
- package/dist/commands/verify/cross/diff.js.map +1 -0
- package/dist/commands/verify/evidence/contract.js +32 -0
- package/dist/commands/verify/evidence/contract.js.map +1 -0
- package/dist/commands/verify/evidence/pins.js +52 -0
- package/dist/commands/verify/evidence/pins.js.map +1 -0
- package/dist/commands/verify/evidence/read.js +72 -0
- package/dist/commands/verify/evidence/read.js.map +1 -0
- package/dist/commands/verify/frozen.js +241 -0
- package/dist/commands/verify/frozen.js.map +1 -0
- package/dist/commands/verify/record.js +226 -0
- package/dist/commands/verify/record.js.map +1 -0
- package/dist/commands/verify/report.js +223 -0
- package/dist/commands/verify/report.js.map +1 -0
- package/dist/commands/verify/results.js +246 -0
- package/dist/commands/verify/results.js.map +1 -0
- package/dist/commands/verify/verify.js +217 -0
- package/dist/commands/verify/verify.js.map +1 -0
- package/dist/commands/vouch/contract.js +11 -0
- package/dist/commands/vouch/contract.js.map +1 -0
- package/dist/commands/vouch/pack/contract.js +2 -0
- package/dist/commands/vouch/pack/contract.js.map +1 -0
- package/dist/commands/vouch/pack/pack.js +266 -0
- package/dist/commands/vouch/pack/pack.js.map +1 -0
- package/dist/commands/vouch/pack/print.js +271 -0
- package/dist/commands/vouch/pack/print.js.map +1 -0
- package/dist/commands/vouch/pack/sections.js +142 -0
- package/dist/commands/vouch/pack/sections.js.map +1 -0
- package/dist/commands/vouch/prompt/confirm.js +46 -0
- package/dist/commands/vouch/prompt/confirm.js.map +1 -0
- package/dist/commands/vouch/report.js +101 -0
- package/dist/commands/vouch/report.js.map +1 -0
- package/dist/commands/vouch/run.js +285 -0
- package/dist/commands/vouch/run.js.map +1 -0
- package/dist/commands/vouch/sample/plan.js +125 -0
- package/dist/commands/vouch/sample/plan.js.map +1 -0
- package/dist/commands/vouch/sample/print.js +109 -0
- package/dist/commands/vouch/sample/print.js.map +1 -0
- package/dist/commands/vouch/vet/verify.js +123 -0
- package/dist/commands/vouch/vet/verify.js.map +1 -0
- package/dist/commands/vouch/vouch.js +176 -0
- package/dist/commands/vouch/vouch.js.map +1 -0
- package/dist/core/agent/agents-md/artifacts.js +220 -0
- package/dist/core/agent/agents-md/artifacts.js.map +1 -0
- package/dist/core/agent/agents-md/command-map.js +324 -0
- package/dist/core/agent/agents-md/command-map.js.map +1 -0
- package/dist/core/agent/agents-md/cycle.js +165 -0
- package/dist/core/agent/agents-md/cycle.js.map +1 -0
- package/dist/core/agent/agents-md/map/explain.js +34 -0
- package/dist/core/agent/agents-md/map/explain.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
- package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
- package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
- package/dist/core/agent/agents-md/map/mcp.js +41 -0
- package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
- package/dist/core/agent/agents-md/map/status.js +62 -0
- package/dist/core/agent/agents-md/map/status.js.map +1 -0
- package/dist/core/agent/agents-md/map/subsystem.js +32 -0
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
- package/dist/core/agent/agents-md/map/usecases.js +60 -0
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
- package/dist/core/agent/agents-md/refusals.js +246 -0
- package/dist/core/agent/agents-md/refusals.js.map +1 -0
- package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
- package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
- package/dist/core/agent/agents-md/spine.js +40 -0
- package/dist/core/agent/agents-md/spine.js.map +1 -0
- package/dist/core/agent/agents-md.js +170 -0
- package/dist/core/agent/agents-md.js.map +1 -0
- package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +50 -0
- package/dist/core/agent/agents-stamp.js.map +1 -0
- package/dist/core/agent/contract.js +2 -0
- package/dist/core/agent/contract.js.map +1 -0
- package/dist/core/agent/protocol.js +193 -0
- package/dist/core/agent/protocol.js.map +1 -0
- package/dist/core/agent/scaffold.js +259 -0
- package/dist/core/agent/scaffold.js.map +1 -0
- package/dist/core/agent/support/report.js +103 -0
- package/dist/core/agent/support/report.js.map +1 -0
- package/dist/core/agent/tools/dialects.js +150 -0
- package/dist/core/agent/tools/dialects.js.map +1 -0
- package/dist/core/agent/tools/registry.js +228 -0
- package/dist/core/agent/tools/registry.js.map +1 -0
- package/dist/core/agent/workflows/adopt.js +133 -0
- package/dist/core/agent/workflows/adopt.js.map +1 -0
- package/dist/core/agent/workflows/check.js +337 -0
- package/dist/core/agent/workflows/check.js.map +1 -0
- package/dist/core/agent/workflows/closing.js +262 -0
- package/dist/core/agent/workflows/closing.js.map +1 -0
- package/dist/core/agent/workflows/feature.js +105 -0
- package/dist/core/agent/workflows/feature.js.map +1 -0
- package/dist/core/agent/workflows/implement.js +105 -0
- package/dist/core/agent/workflows/implement.js.map +1 -0
- package/dist/core/agent/workflows/reference/authoring.js +209 -0
- package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
- package/dist/core/agent/workflows/reference/codes.js +65 -0
- package/dist/core/agent/workflows/reference/codes.js.map +1 -0
- package/dist/core/agent/workflows/reference/done-check.js +188 -0
- package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
- package/dist/core/agent/workflows/reference/reference.js +16 -0
- package/dist/core/agent/workflows/reference/reference.js.map +1 -0
- package/dist/core/agent/workflows/reference/spine.js +297 -0
- package/dist/core/agent/workflows/reference/spine.js.map +1 -0
- package/dist/core/asyncapi/baseline/plan.js +110 -0
- package/dist/core/asyncapi/baseline/plan.js.map +1 -0
- package/dist/core/asyncapi/baseline/surfaces.js +54 -0
- package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
- package/dist/core/asyncapi/depth.js +164 -0
- package/dist/core/asyncapi/depth.js.map +1 -0
- package/dist/core/asyncapi/digest.js +141 -0
- package/dist/core/asyncapi/digest.js.map +1 -0
- package/dist/core/asyncapi/merge/components.js +91 -0
- package/dist/core/asyncapi/merge/components.js.map +1 -0
- package/dist/core/asyncapi/merge/error.js +33 -0
- package/dist/core/asyncapi/merge/error.js.map +1 -0
- package/dist/core/asyncapi/merge/markers.js +308 -0
- package/dist/core/asyncapi/merge/markers.js.map +1 -0
- package/dist/core/asyncapi/merge/merge.js +215 -0
- package/dist/core/asyncapi/merge/merge.js.map +1 -0
- package/dist/core/asyncapi/merge/pin.js +107 -0
- package/dist/core/asyncapi/merge/pin.js.map +1 -0
- package/dist/core/asyncapi/model.js +11 -0
- package/dist/core/asyncapi/model.js.map +1 -0
- package/dist/core/asyncapi/producers.js +50 -0
- package/dist/core/asyncapi/producers.js.map +1 -0
- package/dist/core/{asyncapi.js → asyncapi/read.js} +95 -109
- package/dist/core/asyncapi/read.js.map +1 -0
- package/dist/core/brief/brief.js +225 -0
- package/dist/core/brief/brief.js.map +1 -0
- package/dist/core/brief/checks.js +250 -0
- package/dist/core/brief/checks.js.map +1 -0
- package/dist/core/brief/landscape.js +194 -0
- package/dist/core/brief/landscape.js.map +1 -0
- package/dist/core/brief/targets.js +226 -0
- package/dist/core/brief/targets.js.map +1 -0
- package/dist/core/brief/unchecked.js +48 -0
- package/dist/core/brief/unchecked.js.map +1 -0
- package/dist/core/c4/arch.js +174 -0
- package/dist/core/c4/arch.js.map +1 -0
- package/dist/core/c4/likec4.js +90 -0
- package/dist/core/c4/likec4.js.map +1 -0
- package/dist/core/c4/parsed/deployment.js +158 -0
- package/dist/core/c4/parsed/deployment.js.map +1 -0
- package/dist/core/c4/parsed/dynamic-views.js +132 -0
- package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
- package/dist/core/c4/parsed/specification.js +78 -0
- package/dist/core/c4/parsed/specification.js.map +1 -0
- package/dist/core/c4/parsed/values.js +57 -0
- package/dist/core/c4/parsed/values.js.map +1 -0
- package/dist/core/c4/parsed/view-ids.js +75 -0
- package/dist/core/c4/parsed/view-ids.js.map +1 -0
- package/dist/core/c4/project/architecture.js +45 -0
- package/dist/core/c4/project/architecture.js.map +1 -0
- package/dist/core/c4/project/documents.js +58 -0
- package/dist/core/c4/project/documents.js.map +1 -0
- package/dist/core/c4/project/load.js +187 -0
- package/dist/core/c4/project/load.js.map +1 -0
- package/dist/core/c4/project/staged.js +220 -0
- package/dist/core/c4/project/staged.js.map +1 -0
- package/dist/core/c4/resolve/service.js +159 -0
- package/dist/core/c4/resolve/service.js.map +1 -0
- package/dist/core/c4/resolve/steps.js +144 -0
- package/dist/core/c4/resolve/steps.js.map +1 -0
- package/dist/core/c4/seed/fleet-file.js +201 -0
- package/dist/core/c4/seed/fleet-file.js.map +1 -0
- package/dist/core/c4/seed/items.js +91 -0
- package/dist/core/c4/seed/items.js.map +1 -0
- package/dist/core/c4/seed/stamp.js +48 -0
- package/dist/core/c4/seed/stamp.js.map +1 -0
- package/dist/core/c4/seed/template.js +109 -0
- package/dist/core/c4/seed/template.js.map +1 -0
- package/dist/core/c4/source-mask.js +82 -0
- package/dist/core/c4/source-mask.js.map +1 -0
- package/dist/core/c4/source-scan.js +227 -0
- package/dist/core/c4/source-scan.js.map +1 -0
- package/dist/core/c4/splice/authored-source.js +101 -0
- package/dist/core/c4/splice/authored-source.js.map +1 -0
- package/dist/core/c4/splice/contract.js +10 -0
- package/dist/core/c4/splice/contract.js.map +1 -0
- package/dist/core/c4/splice/delta-blocks.js +139 -0
- package/dist/core/c4/splice/delta-blocks.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +36 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +269 -0
- package/dist/core/c4/splice/landscape-merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +194 -0
- package/dist/core/c4/splice/placement.js.map +1 -0
- package/dist/core/c4/workspace.js +174 -0
- package/dist/core/c4/workspace.js.map +1 -0
- package/dist/core/capabilities/authoring/notes.js +141 -0
- package/dist/core/capabilities/authoring/notes.js.map +1 -0
- package/dist/core/capabilities/capabilities.js +124 -0
- package/dist/core/capabilities/capabilities.js.map +1 -0
- package/dist/core/capabilities/delta/doc.js +50 -0
- package/dist/core/capabilities/delta/doc.js.map +1 -0
- package/dist/core/capabilities/delta/overlay.js +129 -0
- package/dist/core/capabilities/delta/overlay.js.map +1 -0
- package/dist/core/capabilities/delta/summary.js +57 -0
- package/dist/core/capabilities/delta/summary.js.map +1 -0
- package/dist/core/capabilities/delta/tree.js +43 -0
- package/dist/core/capabilities/delta/tree.js.map +1 -0
- package/dist/core/capabilities/delta/uncovered.js +222 -0
- package/dist/core/capabilities/delta/uncovered.js.map +1 -0
- package/dist/core/capabilities/findings.js +342 -0
- package/dist/core/capabilities/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/findings.js +181 -0
- package/dist/core/capabilities/realizes/findings.js.map +1 -0
- package/dist/core/capabilities/realizes/join.js +143 -0
- package/dist/core/capabilities/realizes/join.js.map +1 -0
- package/dist/core/capabilities/rollup.js +199 -0
- package/dist/core/capabilities/rollup.js.map +1 -0
- package/dist/core/capabilities/tree.js +126 -0
- package/dist/core/capabilities/tree.js.map +1 -0
- package/dist/core/capabilities/usecase-join.js +277 -0
- package/dist/core/capabilities/usecase-join.js.map +1 -0
- package/dist/core/coherence/authoring/scaffold.js +177 -0
- package/dist/core/coherence/authoring/scaffold.js.map +1 -0
- package/dist/core/coherence/authoring/sentinels.js +74 -0
- package/dist/core/coherence/authoring/sentinels.js.map +1 -0
- package/dist/core/coherence/coherence.js +287 -0
- package/dist/core/coherence/coherence.js.map +1 -0
- package/dist/core/coherence/declared.js +269 -0
- package/dist/core/coherence/declared.js.map +1 -0
- package/dist/core/coherence/events/declared.js +206 -0
- package/dist/core/coherence/events/declared.js.map +1 -0
- package/dist/core/coherence/events/events.js +204 -0
- package/dist/core/coherence/events/events.js.map +1 -0
- package/dist/core/coherence/events/grades.js +166 -0
- package/dist/core/coherence/events/grades.js.map +1 -0
- package/dist/core/coherence/events/lookups.js +122 -0
- package/dist/core/coherence/events/lookups.js.map +1 -0
- package/dist/core/coherence/events/merged.js +40 -0
- package/dist/core/coherence/events/merged.js.map +1 -0
- package/dist/core/coherence/living.js +198 -0
- package/dist/core/coherence/living.js.map +1 -0
- package/dist/core/coherence/lookups.js +155 -0
- package/dist/core/coherence/lookups.js.map +1 -0
- package/dist/core/coherence/pending.js +39 -0
- package/dist/core/coherence/pending.js.map +1 -0
- package/dist/core/conflict-markers.js +60 -0
- package/dist/core/conflict-markers.js.map +1 -0
- package/dist/core/delta/claims.js +73 -0
- package/dist/core/delta/claims.js.map +1 -0
- package/dist/core/delta/delta.js +296 -0
- package/dist/core/delta/delta.js.map +1 -0
- package/dist/core/delta/document.js +177 -0
- package/dist/core/delta/document.js.map +1 -0
- package/dist/core/delta/scope.js +48 -0
- package/dist/core/delta/scope.js.map +1 -0
- package/dist/core/delta/select.js +237 -0
- package/dist/core/delta/select.js.map +1 -0
- package/dist/core/dependencies/dependencies.js +141 -0
- package/dist/core/dependencies/dependencies.js.map +1 -0
- package/dist/core/dependencies/facts.js +165 -0
- package/dist/core/dependencies/facts.js.map +1 -0
- package/dist/core/dependencies/fanin.js +88 -0
- package/dist/core/dependencies/fanin.js.map +1 -0
- package/dist/core/dependencies/graph.js +106 -0
- package/dist/core/dependencies/graph.js.map +1 -0
- package/dist/core/deployment/delta.js +188 -0
- package/dist/core/deployment/delta.js.map +1 -0
- package/dist/core/deployment/objects.js +145 -0
- package/dist/core/deployment/objects.js.map +1 -0
- package/dist/core/diff/base-git.js +148 -0
- package/dist/core/diff/base-git.js.map +1 -0
- package/dist/core/diff/base-state.js +209 -0
- package/dist/core/diff/base-state.js.map +1 -0
- package/dist/core/diff/current-state.js +96 -0
- package/dist/core/diff/current-state.js.map +1 -0
- package/dist/core/diff/scope/changed-paths.js +188 -0
- package/dist/core/diff/scope/changed-paths.js.map +1 -0
- package/dist/core/diff/semantic.js +243 -0
- package/dist/core/diff/semantic.js.map +1 -0
- package/dist/core/diff/victims.js +247 -0
- package/dist/core/diff/victims.js.map +1 -0
- package/dist/core/docs.js +7 -64
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/agents.js +222 -0
- package/dist/core/doctor/agents.js.map +1 -0
- package/dist/core/doctor/config.js +135 -0
- package/dist/core/doctor/config.js.map +1 -0
- package/dist/core/doctor/doctor.js +275 -0
- package/dist/core/doctor/doctor.js.map +1 -0
- package/dist/core/doctor/report.js +13 -0
- package/dist/core/doctor/report.js.map +1 -0
- package/dist/core/doctor/residue.js +110 -0
- package/dist/core/doctor/residue.js.map +1 -0
- package/dist/core/document/apply.js +77 -0
- package/dist/core/document/apply.js.map +1 -0
- package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -2
- package/dist/core/document/frontmatter.js.map +1 -0
- package/dist/core/document/grammar/directives.js +143 -0
- package/dist/core/document/grammar/directives.js.map +1 -0
- package/dist/core/document/parse.js +263 -0
- package/dist/core/document/parse.js.map +1 -0
- package/dist/core/document/scenarios.js +221 -0
- package/dist/core/document/scenarios.js.map +1 -0
- package/dist/core/document/spec.js +241 -0
- package/dist/core/document/spec.js.map +1 -0
- package/dist/core/{config.js → envelope/config.js} +79 -18
- package/dist/core/envelope/config.js.map +1 -0
- package/dist/core/envelope/json.js +175 -0
- package/dist/core/envelope/json.js.map +1 -0
- package/dist/core/{version.js → envelope/version.js} +3 -3
- package/dist/core/envelope/version.js.map +1 -0
- package/dist/core/explain/families.js +175 -0
- package/dist/core/explain/families.js.map +1 -0
- package/dist/core/explain/fix-tables.js +178 -0
- package/dist/core/explain/fix-tables.js.map +1 -0
- package/dist/core/explain/lookup.js +181 -0
- package/dist/core/explain/lookup.js.map +1 -0
- package/dist/core/explain/refusals.js +49 -0
- package/dist/core/explain/refusals.js.map +1 -0
- package/dist/core/explain/terms.js +144 -0
- package/dist/core/explain/terms.js.map +1 -0
- package/dist/core/explore/describe.js +105 -0
- package/dist/core/explore/describe.js.map +1 -0
- package/dist/core/{explore.js → explore/explore.js} +50 -101
- package/dist/core/explore/explore.js.map +1 -0
- package/dist/core/fleet-context.js +120 -78
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/checks.js +201 -0
- package/dist/core/gate/checks.js.map +1 -0
- package/dist/core/gate/partners.js +205 -0
- package/dist/core/gate/partners.js.map +1 -0
- package/dist/core/gate/report.js +47 -0
- package/dist/core/gate/report.js.map +1 -0
- package/dist/core/gate/verification.js +113 -0
- package/dist/core/gate/verification.js.map +1 -0
- package/dist/core/gherkin/digest.js +60 -0
- package/dist/core/gherkin/digest.js.map +1 -0
- package/dist/core/gherkin/emit.js +177 -0
- package/dist/core/gherkin/emit.js.map +1 -0
- package/dist/core/gherkin/read.js +76 -0
- package/dist/core/gherkin/read.js.map +1 -0
- package/dist/core/gherkin/stale.js +234 -0
- package/dist/core/gherkin/stale.js.map +1 -0
- package/dist/core/gherkin/stamp.js +77 -0
- package/dist/core/gherkin/stamp.js.map +1 -0
- package/dist/core/gherkin/steps/catalogue.js +154 -0
- package/dist/core/gherkin/steps/catalogue.js.map +1 -0
- package/dist/core/gherkin/steps/inventory.js +98 -0
- package/dist/core/gherkin/steps/inventory.js.map +1 -0
- package/dist/core/gherkin/steps/phrase.js +72 -0
- package/dist/core/gherkin/steps/phrase.js.map +1 -0
- package/dist/core/glossary/delta.js +106 -0
- package/dist/core/glossary/delta.js.map +1 -0
- package/dist/core/glossary/tree.js +86 -0
- package/dist/core/glossary/tree.js.map +1 -0
- package/dist/core/kernel/concurrency.js.map +1 -0
- package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
- package/dist/core/kernel/document-bytes.js.map +1 -0
- package/dist/core/kernel/fences.js +42 -0
- package/dist/core/kernel/fences.js.map +1 -0
- package/dist/core/kernel/ids/capability.js +72 -0
- package/dist/core/kernel/ids/capability.js.map +1 -0
- package/dist/core/kernel/ids/dirs.js +33 -0
- package/dist/core/kernel/ids/dirs.js.map +1 -0
- package/dist/core/kernel/ids/feature.js +75 -0
- package/dist/core/kernel/ids/feature.js.map +1 -0
- package/dist/core/kernel/ids/service.js +156 -0
- package/dist/core/kernel/ids/service.js.map +1 -0
- package/dist/core/kernel/ids/subsystem.js +63 -0
- package/dist/core/kernel/ids/subsystem.js.map +1 -0
- package/dist/core/{path-safety.js → kernel/path-safety.js} +18 -4
- package/dist/core/kernel/path-safety.js.map +1 -0
- package/dist/core/kernel/records.js.map +1 -0
- package/dist/core/links/backlinks.js +68 -0
- package/dist/core/links/backlinks.js.map +1 -0
- package/dist/core/links/case.js +74 -0
- package/dist/core/links/case.js.map +1 -0
- package/dist/core/links/corpus.js +104 -0
- package/dist/core/links/corpus.js.map +1 -0
- package/dist/core/links/findings.js +110 -0
- package/dist/core/links/findings.js.map +1 -0
- package/dist/core/links/parse.js +236 -0
- package/dist/core/links/parse.js.map +1 -0
- package/dist/core/mcp/argv.js +111 -0
- package/dist/core/mcp/argv.js.map +1 -0
- package/dist/core/mcp/author-tools.js +72 -0
- package/dist/core/mcp/author-tools.js.map +1 -0
- package/dist/core/mcp/framing.js +46 -0
- package/dist/core/mcp/framing.js.map +1 -0
- package/dist/core/mcp/protocol.js +280 -0
- package/dist/core/mcp/protocol.js.map +1 -0
- package/dist/core/mcp/tools.js +314 -0
- package/dist/core/mcp/tools.js.map +1 -0
- package/dist/core/obligations/obligations.js +106 -0
- package/dist/core/obligations/obligations.js.map +1 -0
- package/dist/core/openapi/baseline/gate.js +166 -0
- package/dist/core/openapi/baseline/gate.js.map +1 -0
- package/dist/core/openapi/baseline/plan.js +112 -0
- package/dist/core/openapi/baseline/plan.js.map +1 -0
- package/dist/core/openapi/baseline/record.js +175 -0
- package/dist/core/openapi/baseline/record.js.map +1 -0
- package/dist/core/openapi/depth.js +122 -0
- package/dist/core/openapi/depth.js.map +1 -0
- package/dist/core/openapi/digest.js +189 -0
- package/dist/core/openapi/digest.js.map +1 -0
- package/dist/core/{openapi.js → openapi/doc.js} +44 -106
- package/dist/core/openapi/doc.js.map +1 -0
- package/dist/core/openapi/merge/components.js +234 -0
- package/dist/core/openapi/merge/components.js.map +1 -0
- package/dist/core/openapi/merge/error.js +26 -0
- package/dist/core/openapi/merge/error.js.map +1 -0
- package/dist/core/openapi/merge/markers.js +208 -0
- package/dist/core/openapi/merge/markers.js.map +1 -0
- package/dist/core/openapi/merge/merge.js +256 -0
- package/dist/core/openapi/merge/merge.js.map +1 -0
- package/dist/core/openapi/merge/pin.js +128 -0
- package/dist/core/openapi/merge/pin.js.map +1 -0
- package/dist/core/openspec/decide/capabilities.js +244 -0
- package/dist/core/openspec/decide/capabilities.js.map +1 -0
- package/dist/core/openspec/decide/dispositions.js +63 -0
- package/dist/core/openspec/decide/dispositions.js.map +1 -0
- package/dist/core/openspec/decide/renames.js +179 -0
- package/dist/core/openspec/decide/renames.js.map +1 -0
- package/dist/core/openspec/decide/verdict.js +84 -0
- package/dist/core/openspec/decide/verdict.js.map +1 -0
- package/dist/core/openspec/inventory.js +221 -0
- package/dist/core/openspec/inventory.js.map +1 -0
- package/dist/core/openspec/model/mapping.js +76 -0
- package/dist/core/openspec/model/mapping.js.map +1 -0
- package/dist/core/openspec/model/model.js +65 -0
- package/dist/core/openspec/model/model.js.map +1 -0
- package/dist/core/openspec/scan/changes.js +235 -0
- package/dist/core/openspec/scan/changes.js.map +1 -0
- package/dist/core/openspec/scan/config.js +200 -0
- package/dist/core/openspec/scan/config.js.map +1 -0
- package/dist/core/openspec/scan/shape.js +260 -0
- package/dist/core/openspec/scan/shape.js.map +1 -0
- package/dist/core/openspec/scan/walk.js +133 -0
- package/dist/core/openspec/scan/walk.js.map +1 -0
- package/dist/core/openspec/scan/workspace.js +71 -0
- package/dist/core/openspec/scan/workspace.js.map +1 -0
- package/dist/core/owners/codeowners.js +141 -0
- package/dist/core/owners/codeowners.js.map +1 -0
- package/dist/core/pack/features.js +120 -0
- package/dist/core/pack/features.js.map +1 -0
- package/dist/core/pack/joins.js +112 -0
- package/dist/core/pack/joins.js.map +1 -0
- package/dist/core/pack/living.js +137 -0
- package/dist/core/pack/living.js.map +1 -0
- package/dist/core/pack/pack.js +76 -0
- package/dist/core/pack/pack.js.map +1 -0
- package/dist/core/permissions/permissions.js +87 -0
- package/dist/core/permissions/permissions.js.map +1 -0
- package/dist/core/projection/api.js +84 -0
- package/dist/core/projection/api.js.map +1 -0
- package/dist/core/projection/arch-slice.js +63 -0
- package/dist/core/projection/arch-slice.js.map +1 -0
- package/dist/core/projection/events.js +34 -0
- package/dist/core/projection/events.js.map +1 -0
- package/dist/core/provenance/findings.js +208 -0
- package/dist/core/provenance/findings.js.map +1 -0
- package/dist/core/provenance/git.js +225 -0
- package/dist/core/provenance/git.js.map +1 -0
- package/dist/core/provenance/gitq/moves.js +182 -0
- package/dist/core/provenance/gitq/moves.js.map +1 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
- package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
- package/dist/core/provenance/sample/scope.js +238 -0
- package/dist/core/provenance/sample/scope.js.map +1 -0
- package/dist/core/provenance/sample/sections.js +61 -0
- package/dist/core/provenance/sample/sections.js.map +1 -0
- package/dist/core/provenance/sources.js +263 -0
- package/dist/core/provenance/sources.js.map +1 -0
- package/dist/core/provenance/stamp.js +232 -0
- package/dist/core/provenance/stamp.js.map +1 -0
- package/dist/core/provenance/walk.js +157 -0
- package/dist/core/provenance/walk.js.map +1 -0
- package/dist/core/repo/authored/paths.js +210 -0
- package/dist/core/repo/authored/paths.js.map +1 -0
- package/dist/core/repo/entries.js +126 -0
- package/dist/core/repo/entries.js.map +1 -0
- package/dist/core/repo/paths.js +277 -0
- package/dist/core/repo/paths.js.map +1 -0
- package/dist/core/repo/repo.js +248 -0
- package/dist/core/repo/repo.js.map +1 -0
- package/dist/core/repo/service-target.js +153 -0
- package/dist/core/repo/service-target.js.map +1 -0
- package/dist/core/repo/state.js +58 -0
- package/dist/core/repo/state.js.map +1 -0
- package/dist/core/repo/tree/find.js +52 -0
- package/dist/core/repo/tree/find.js.map +1 -0
- package/dist/core/repo/tree/fs.js +64 -0
- package/dist/core/repo/tree/fs.js.map +1 -0
- package/dist/core/repo/tree/marker.js +61 -0
- package/dist/core/repo/tree/marker.js.map +1 -0
- package/dist/core/repo/tree/views.js +172 -0
- package/dist/core/repo/tree/views.js.map +1 -0
- package/dist/core/repo/tree/walk.js +234 -0
- package/dist/core/repo/tree/walk.js.map +1 -0
- package/dist/core/results.js +99 -2
- package/dist/core/results.js.map +1 -1
- package/dist/core/scaffold/landscape.js +131 -0
- package/dist/core/scaffold/landscape.js.map +1 -0
- package/dist/core/scaffold/readme.js +84 -0
- package/dist/core/scaffold/readme.js.map +1 -0
- package/dist/core/staging/commit.js +241 -0
- package/dist/core/staging/commit.js.map +1 -0
- package/dist/core/staging/interrupted.js +96 -0
- package/dist/core/staging/interrupted.js.map +1 -0
- package/dist/core/staging/lock.js +206 -0
- package/dist/core/staging/lock.js.map +1 -0
- package/dist/core/staging/recovery/finding.js +35 -0
- package/dist/core/staging/recovery/finding.js.map +1 -0
- package/dist/core/staging/recovery/intent.js +98 -0
- package/dist/core/staging/recovery/intent.js.map +1 -0
- package/dist/core/staging/recovery/recover.js +126 -0
- package/dist/core/staging/recovery/recover.js.map +1 -0
- package/dist/core/staging/recovery/residue.js +62 -0
- package/dist/core/staging/recovery/residue.js.map +1 -0
- package/dist/core/staging/snapshot.js +202 -0
- package/dist/core/staging/snapshot.js.map +1 -0
- package/dist/core/staging/txn/forward.js +171 -0
- package/dist/core/staging/txn/forward.js.map +1 -0
- package/dist/core/staging/txn/journal.js +139 -0
- package/dist/core/staging/txn/journal.js.map +1 -0
- package/dist/core/staging/txn/transaction.js +75 -0
- package/dist/core/staging/txn/transaction.js.map +1 -0
- package/dist/core/staging/writes.js +113 -0
- package/dist/core/staging/writes.js.map +1 -0
- package/dist/core/status/actions/execution.js +49 -0
- package/dist/core/status/actions/execution.js.map +1 -0
- package/dist/core/status/contracts.js +102 -0
- package/dist/core/status/contracts.js.map +1 -0
- package/dist/core/status/feature/artifacts.js +196 -0
- package/dist/core/status/feature/artifacts.js.map +1 -0
- package/dist/core/status/feature/feature.js +207 -0
- package/dist/core/status/feature/feature.js.map +1 -0
- package/dist/core/status/feature/next.js +150 -0
- package/dist/core/status/feature/next.js.map +1 -0
- package/dist/core/status/feature/state.js +21 -0
- package/dist/core/status/feature/state.js.map +1 -0
- package/dist/core/status/fleet/fleet.js +197 -0
- package/dist/core/status/fleet/fleet.js.map +1 -0
- package/dist/core/status/fleet/next.js +207 -0
- package/dist/core/status/fleet/next.js.map +1 -0
- package/dist/core/status/interrupted.js +97 -0
- package/dist/core/status/interrupted.js.map +1 -0
- package/dist/core/status/report.js +31 -0
- package/dist/core/status/report.js.map +1 -0
- package/dist/core/status/scan.js +41 -0
- package/dist/core/status/scan.js.map +1 -0
- package/dist/core/status/verification.js +201 -0
- package/dist/core/status/verification.js.map +1 -0
- package/dist/core/usecases/capability.js +169 -0
- package/dist/core/usecases/capability.js.map +1 -0
- package/dist/core/usecases/delta/claims.js +116 -0
- package/dist/core/usecases/delta/claims.js.map +1 -0
- package/dist/core/usecases/delta/flows.js +103 -0
- package/dist/core/usecases/delta/flows.js.map +1 -0
- package/dist/core/usecases/delta/overlay.js +72 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -0
- package/dist/core/usecases/fleet.js +137 -0
- package/dist/core/usecases/fleet.js.map +1 -0
- package/dist/core/usecases/operations.js +111 -0
- package/dist/core/usecases/operations.js.map +1 -0
- package/dist/core/usecases/place.js +44 -0
- package/dist/core/usecases/place.js.map +1 -0
- package/dist/core/usecases/touch.js +101 -0
- package/dist/core/usecases/touch.js.map +1 -0
- package/dist/core/verify/answers.js +173 -0
- package/dist/core/verify/answers.js.map +1 -0
- package/dist/core/verify/build.js +150 -0
- package/dist/core/verify/build.js.map +1 -0
- package/dist/core/verify/checklist.js +201 -0
- package/dist/core/verify/checklist.js.map +1 -0
- package/dist/core/verify/claims/identity.js +61 -0
- package/dist/core/verify/claims/identity.js.map +1 -0
- package/dist/core/verify/cross/diff.js +97 -0
- package/dist/core/verify/cross/diff.js.map +1 -0
- package/dist/core/verify/evidence/contract.js +169 -0
- package/dist/core/verify/evidence/contract.js.map +1 -0
- package/dist/core/verify/file.js +257 -0
- package/dist/core/verify/file.js.map +1 -0
- package/dist/core/verify/pins/lint.js +157 -0
- package/dist/core/verify/pins/lint.js.map +1 -0
- package/dist/core/verify/pins/pin.js +95 -0
- package/dist/core/verify/pins/pin.js.map +1 -0
- package/dist/core/verify/record.js +142 -0
- package/dist/core/verify/record.js.map +1 -0
- package/dist/core/verify/store/commit.js +89 -0
- package/dist/core/verify/store/commit.js.map +1 -0
- package/dist/core/verify/store/render.js +57 -0
- package/dist/core/verify/store/render.js.map +1 -0
- package/dist/core/vocabulary/health.js +91 -0
- package/dist/core/vocabulary/health.js.map +1 -0
- package/dist/core/vocabulary/issue.js +58 -0
- package/dist/core/vocabulary/issue.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +145 -0
- package/dist/core/vocabulary/maturity.js.map +1 -0
- package/dist/core/{report.js → vocabulary/report.js} +30 -2
- package/dist/core/vocabulary/report.js.map +1 -0
- package/dist/core/vocabulary/steps.js +266 -0
- package/dist/core/vocabulary/steps.js.map +1 -0
- package/dist/core/workspace/discover.js +239 -0
- package/dist/core/workspace/discover.js.map +1 -0
- package/dist/core/workspace/render.js +52 -0
- package/dist/core/workspace/render.js.map +1 -0
- package/examples/README.md +189 -0
- package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
- package/examples/docs/architecture/capabilities.yaml +31 -0
- package/examples/docs/architecture/landscape.likec4 +280 -0
- package/examples/docs/architecture/obligations.yaml +23 -0
- package/examples/docs/architecture/permissions.yaml +50 -0
- package/examples/docs/architecture/subsystems.likec4 +11 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +65 -0
- package/examples/docs/capabilities/checkout/spec.md +55 -0
- package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
- package/examples/docs/capabilities/order-notifications/spec.md +43 -0
- package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
- package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
- package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +129 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
- package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +28 -0
- package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
- package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
- package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
- package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +70 -0
- package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
- package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
- package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
- package/examples/docs/glossary/order.md +15 -0
- package/examples/docs/glossary/payments/authorization.md +14 -0
- package/examples/docs/likec4.config.json +9 -0
- package/examples/docs/loam.json +3 -0
- package/examples/docs/services/checkout-web/model.likec4 +109 -0
- package/examples/docs/services/checkout-web/spec.md +91 -0
- package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
- package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
- package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
- package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
- package/examples/docs/services/order-service/arch.spec.md +127 -0
- package/examples/docs/services/order-service/asyncapi.yaml +108 -0
- package/examples/docs/services/order-service/health.yaml +57 -0
- package/examples/docs/services/order-service/model.likec4 +138 -0
- package/examples/docs/services/order-service/openapi.yaml +257 -0
- package/examples/docs/services/order-service/runbook.md +62 -0
- package/examples/docs/services/order-service/spec.md +134 -0
- package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
- package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
- package/examples/docs/services/payment-service/arch.spec.md +73 -0
- package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
- package/examples/docs/services/payment-service/health.yaml +39 -0
- package/examples/docs/services/payment-service/model.likec4 +67 -0
- package/examples/docs/services/payment-service/openapi.yaml +151 -0
- package/examples/docs/services/payment-service/runbook.md +37 -0
- package/examples/docs/services/payment-service/spec.md +88 -0
- package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
- package/examples/docs/services/platform/identity-service/arch.spec.md +117 -0
- package/examples/docs/services/platform/identity-service/health.yaml +70 -0
- package/examples/docs/services/platform/identity-service/model.likec4 +83 -0
- package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
- package/examples/docs/services/platform/identity-service/runbook.md +95 -0
- package/examples/docs/services/platform/identity-service/spec.md +119 -0
- package/examples/docs/services/platform/notification-service/asyncapi.yaml +199 -0
- package/examples/docs/services/platform/notification-service/health.yaml +35 -0
- package/examples/docs/services/platform/notification-service/model.likec4 +118 -0
- package/examples/docs/services/platform/notification-service/runbook.md +48 -0
- package/examples/docs/services/platform/notification-service/spec.md +112 -0
- package/examples/docs/services/platform/subsystem.yaml +2 -0
- package/examples/fleet.yaml +57 -0
- package/package.json +19 -6
- package/dist/commands/adopt.js +0 -240
- package/dist/commands/adopt.js.map +0 -1
- package/dist/commands/archive.js +0 -1313
- package/dist/commands/archive.js.map +0 -1
- package/dist/commands/delta.js +0 -388
- package/dist/commands/delta.js.map +0 -1
- package/dist/commands/docs-repo-gate.js.map +0 -1
- package/dist/commands/format.js +0 -17
- package/dist/commands/format.js.map +0 -1
- package/dist/commands/gherkin.js +0 -309
- package/dist/commands/gherkin.js.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list.js +0 -295
- package/dist/commands/list.js.map +0 -1
- package/dist/commands/migrate-openspec.js +0 -950
- package/dist/commands/migrate-openspec.js.map +0 -1
- package/dist/commands/new.js +0 -413
- package/dist/commands/new.js.map +0 -1
- package/dist/commands/rebase.js +0 -356
- package/dist/commands/rebase.js.map +0 -1
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/status.js +0 -262
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/unarchive.js.map +0 -1
- package/dist/commands/validate.js +0 -1773
- package/dist/commands/validate.js.map +0 -1
- package/dist/commands/verify.js +0 -775
- package/dist/commands/verify.js.map +0 -1
- package/dist/commands/vouch.js +0 -421
- package/dist/commands/vouch.js.map +0 -1
- package/dist/core/agent.js +0 -2173
- package/dist/core/agent.js.map +0 -1
- package/dist/core/agents-stamp.js.map +0 -1
- package/dist/core/arch.js +0 -130
- package/dist/core/arch.js.map +0 -1
- package/dist/core/asyncapi.js.map +0 -1
- package/dist/core/brief.js +0 -755
- package/dist/core/brief.js.map +0 -1
- package/dist/core/coherence.js +0 -577
- package/dist/core/coherence.js.map +0 -1
- package/dist/core/concurrency.js.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/delta.js +0 -476
- package/dist/core/delta.js.map +0 -1
- package/dist/core/dependencies.js +0 -356
- package/dist/core/dependencies.js.map +0 -1
- package/dist/core/doctor.js +0 -596
- package/dist/core/doctor.js.map +0 -1
- package/dist/core/document-bytes.js.map +0 -1
- package/dist/core/explore.js.map +0 -1
- package/dist/core/frontmatter.js.map +0 -1
- package/dist/core/gherkin.js +0 -463
- package/dist/core/gherkin.js.map +0 -1
- package/dist/core/health.js +0 -67
- package/dist/core/health.js.map +0 -1
- package/dist/core/ids.js +0 -122
- package/dist/core/ids.js.map +0 -1
- package/dist/core/issue.js +0 -9
- package/dist/core/issue.js.map +0 -1
- package/dist/core/json.js +0 -74
- package/dist/core/json.js.map +0 -1
- package/dist/core/likec4.js +0 -489
- package/dist/core/likec4.js.map +0 -1
- package/dist/core/maturity.js +0 -66
- package/dist/core/maturity.js.map +0 -1
- package/dist/core/openapi-merge.js +0 -552
- package/dist/core/openapi-merge.js.map +0 -1
- package/dist/core/openapi.js.map +0 -1
- package/dist/core/openspec-inventory.js +0 -1440
- package/dist/core/openspec-inventory.js.map +0 -1
- package/dist/core/path-safety.js.map +0 -1
- package/dist/core/provenance.js +0 -787
- package/dist/core/provenance.js.map +0 -1
- package/dist/core/records.js.map +0 -1
- package/dist/core/repo.js +0 -438
- package/dist/core/repo.js.map +0 -1
- package/dist/core/report.js.map +0 -1
- package/dist/core/spec.js +0 -505
- package/dist/core/spec.js.map +0 -1
- package/dist/core/staging.js +0 -890
- package/dist/core/staging.js.map +0 -1
- package/dist/core/status.js +0 -1132
- package/dist/core/status.js.map +0 -1
- package/dist/core/steps.js +0 -72
- package/dist/core/steps.js.map +0 -1
- package/dist/core/verify.js +0 -807
- package/dist/core/verify.js.map +0 -1
- package/dist/core/version.js.map +0 -1
- /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
- /package/dist/core/{records.js → kernel/records.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../../../src/core/status/feature/artifacts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The artifact table: which files a feature owes, whether each is on disk, and\n * which finding turns a row `draft`. Nothing is graded here — the shared\n * checks already ran, and this module only attributes what they reported to\n * the file a reader should edit.\n */\nimport { existsSync } from \"node:fs\";\nimport { repoPath } from \"../../envelope/json.js\";\nimport type { CapabilityDoc } from \"../../capabilities/tree.js\";\nimport type { PathableService } from \"../../kernel/ids/service.js\";\nimport type { FeatureEntry } from \"../../repo/entries.js\";\nimport { featurePaths, featureSpecPaths } from \"../../repo/paths.js\";\nimport { verificationPath } from \"../../verify/record.js\";\nimport type { Finding } from \"../../vocabulary/report.js\";\nimport { owesContract } from \"../contracts.js\";\nimport type { ServiceEntry } from \"../../repo/entries.js\";\nimport type { ArtifactId, ArtifactState, ArtifactStatus, VerificationState } from \"../report.js\";\nimport { verificationStatus } from \"../verification.js\";\nimport type { DocsDir } from \"../../kernel/ids/dirs.js\";\n\n/**\n * The `capability.*` codes filed against a capability DOCUMENT rather than\n * against a service requirement's join line. Spelled out rather than matched by\n * prefix because the family straddles both corpora, and the whole point of this\n * table is to name one file.\n */\nconst CAPABILITY_DOCUMENT_CODES = new Set([\n \"capability.requirement-unidentified\",\n \"capability.requirement-service-scoped\",\n \"capability.requirement-inert-join\",\n \"capability.uncovered\",\n \"capability.remove-requirement-realized\",\n]);\n\n/**\n * Which artifact an error names.\n *\n * Attribution is by code family, because that is the only machine-readable\n * pointer an `Issue` carries: `subject` narrows to a NAME, never to a file.\n * The families are unambiguous — `c4-api.*`/`c4-event.*`/`c4.*` and the two\n * `delta.*` codes about the LikeC4 document itself grade the architecture\n * axis, `openapi.*` grades the API contract, `asyncapi.*` the event contract,\n * and the remaining `delta.*` codes plus `spec-api.*`/`spec-event.*` are the\n * delta-shape checks, every one of which is about a requirement in a spec\n * delta.\n *\n * An error that maps to nothing (or whose subject is unknown) still lands in\n * `checks.issues` and still drives `next.fix-coherence` — it just does not turn\n * any single artifact `draft`, because guessing which file to blame is how a\n * reader gets sent to edit the wrong one.\n *\n * THE BUSINESS CORPUS IS THE ONE PLACE THE CODE FAMILY IS NOT ENOUGH. A\n * `delta.*` issue's `subject` is a service id OR a capability id\n * (`core/delta/scope.ts`), and so is a `scaffold.placeholder`'s\n * (`core/coherence/authoring/scaffold.ts` files one per unedited capability\n * delta), and nothing in either code says which — so this\n * function answers `spec` for both and `featureArtifacts` below resolves it by\n * MEMBERSHIP, against the two lists it already holds. Where a name is only a\n * capability the capability row is turned `draft` and no service row is; where\n * a fleet holds a service AND a capability of the same name, BOTH are, which is\n * the pessimistic answer this module is required to give and strictly better\n * than the old one (it named the service's spec delta and was silently wrong).\n * The capability-document codes below need no such resolution: they are only\n * ever filed against a capability.\n */\nfunction faultedArtifact(code: string, subject?: string): ArtifactId | null {\n if (code === \"delta.invalid\" || code === \"delta.nothing-tagged\") return \"delta\";\n if (code.startsWith(\"c4-api.\") || code.startsWith(\"c4-event.\") || code.startsWith(\"c4.\")) return \"delta\";\n if (code.startsWith(\"openapi.\")) return \"openapi\";\n if (code.startsWith(\"asyncapi.\")) return \"asyncapi\";\n // The capability document's own grades, and the two halves of the `Realizes:`\n // join a feature can break — every one of them names a\n // `features/<FEAT>/capabilities/<id>/spec.md`, never a service delta. The two\n // `capability.*` codes deliberately absent are `capability.unknown` and\n // `capability.realizes-unknown`: those grade a SERVICE requirement's join\n // lines and carry a service id, so the prefix alone would send their reader\n // to the wrong file.\n if (CAPABILITY_DOCUMENT_CODES.has(code)) return \"capabilities\";\n if (code.startsWith(\"delta.\") || code.startsWith(\"spec-api.\") || code.startsWith(\"spec-event.\")) return \"spec\";\n // The two families validate contributes: the frontmatter checks read only\n // intent.md, and a requirement with no scenario is a requirement in a spec\n // delta. Both name exactly one file, so both may turn a row `draft`.\n if (code.startsWith(\"frontmatter.\")) return \"intent\";\n if (code === \"requirements.missing-scenarios\") return \"spec\";\n // The authoring gate names exactly one file per finding too — leaving these\n // unmapped had the table calling intent.md `done` (\"nothing is owed here\")\n // while the archive exited 1 because it says nothing. A placeholder finding\n // carries no subject when it is the C4 delta's scaffolded description; with a\n // subject it is a SPEC DELTA IN EITHER CORPUS — a service id when the text\n // sits in `specs/<svc>/`, a capability id when it sits in\n // `capabilities/<id>/` — which is why `spec` here is resolved by membership\n // below and must not be narrowed to the service list.\n if (code === \"intent.empty\") return \"intent\";\n if (code === \"scaffold.placeholder\") return subject === undefined ? \"delta\" : \"spec\";\n return null;\n}\n\n/**\n * The artifact table. Every entry is graded by two questions in order — is it\n * there, and does anything the shared checks reported name it — so a file that\n * exists and is wrong can never be reported the way one that was never written\n * is.\n */\n/** What the grading of one feature's files needs beyond the files themselves. */\nexport interface Grading {\n /** The findings that make an artifact `draft` rather than `done`. */\n blocking: Finding[];\n verification: VerificationState;\n /** Operations some OTHER feature's contract already holds. */\n contracted: ReadonlySet<string>;\n /** Operations this feature's own requirements govern. */\n governs: ReadonlySet<string>;\n /** The enumeration's entries by id — where each living service is and what it has (owesContract reads both). */\n living: ReadonlyMap<string, ServiceEntry>;\n /**\n * The capability documents this feature's delta carries. Empty for every\n * feature in a fleet that has not adopted the business axis, which is what\n * keeps the rows out of those payloads entirely.\n */\n capabilities: readonly CapabilityDoc[];\n}\n\nexport function featureArtifacts(\n docsDir: DocsDir,\n feature: FeatureEntry,\n services: readonly PathableService[],\n grading: Grading,\n): ArtifactState[] {\n const { blocking, verification, contracted, governs, living, capabilities } = grading;\n const paths = featurePaths(feature.dir);\n const rel = (abs: string): string => repoPath(docsDir, abs);\n const faults = blocking.map((f) => ({ artifact: faultedArtifact(f.code, f.subject), subject: f.subject }));\n const faulted = (id: ArtifactId, service: string | null): boolean =>\n faults.some((f) => f.artifact === id && (service === null || f.subject === service));\n\n const out: ArtifactState[] = [\n fileState(\"intent\", { service: null, path: rel(paths.intent), exists: existsSync(paths.intent) }, true, faulted(\"intent\", null)),\n fileState(\"delta\", { service: null, path: rel(paths.delta), exists: existsSync(paths.delta) }, false, faulted(\"delta\", null)),\n ];\n\n // One row per capability document the feature carries, and none at all when\n // it carries none: the row is the answer to \"which file do I edit\", and a\n // fleet that has not adopted the axis has no such file to name. Never\n // `required` — no feature owes a business change — so absence never shows up\n // as work owed, and only a fault turns one `draft`. A `delta.*` fault carries\n // the capability id in `subject` with nothing saying it is not a service, so\n // the membership test is the resolution the code family cannot give.\n for (const doc of capabilities) {\n out.push({\n id: \"capabilities\",\n service: null,\n capability: doc.id,\n path: rel(doc.spec),\n exists: existsSync(doc.spec),\n required: false,\n status: faulted(\"capabilities\", doc.id) || faulted(\"spec\", doc.id) ? \"draft\" : \"done\",\n blockedBy: [],\n });\n }\n\n for (const svc of services) {\n const p = featureSpecPaths(feature.dir, svc);\n const specFault = faulted(\"spec\", svc);\n // What a service delta owes is a REQUIREMENT DELTA, not specifically the\n // business one. `arch.spec.md` is the other corpus, with the same grammar\n // and the same delta algebra, and `featureChecklist` derives claims from\n // it — so a directory holding only the architectural document is a\n // complete delta, and every gate already reads it as one: `coherence`'s\n // `service.no-requirement-delta` counts the DIRECTORY, and\n // `validate --feature` grades an arch-only delta clean at exit 0.\n //\n // Requiring `spec.md` unconditionally made this module the one document\n // that disagreed. An architecture-only feature — an outbox added, a retry\n // policy, an alert; the changes `arch.spec.md` exists for because no\n // business scenario was ever going to carry them — reported `missing` and\n // emitted `next.author-spec`, sending the author to write business\n // requirements the change does not have, about a feature the gate accepts.\n // status may be redder than the gates on a question they also ask; it may\n // not invent an obligation they do not.\n const archExists = existsSync(p.archSpec);\n out.push(fileState(\"spec\", { service: svc, path: rel(p.spec), exists: existsSync(p.spec) }, !archExists, specFault));\n out.push(fileState(\"arch-spec\", { service: svc, path: rel(p.archSpec), exists: archExists }, false, specFault));\n out.push(\n fileState(\n \"openapi\",\n { service: svc, path: rel(p.openapi), exists: existsSync(p.openapi) },\n owesContract(living.get(svc), contracted.has(svc), governs.has(svc)),\n faulted(\"openapi\", svc),\n ),\n );\n // Never required: an event contract is genuinely optional — the axis's own\n // absence-grading rests on that — so absence is `done`, exactly like\n // arch.spec.md. Present and faulted still turns the row `draft`.\n out.push(\n fileState(\n \"asyncapi\",\n { service: svc, path: rel(p.asyncapi), exists: existsSync(p.asyncapi) },\n false,\n faulted(\"asyncapi\", svc),\n ),\n );\n }\n\n // The record is the one artifact with a real prerequisite: its checklist is\n // derived from the delta and the per-service deltas, so with none of them\n // written there is nothing to answer — authoring one is impossible rather\n // than merely premature, which is the whole distinction `blocked` carries.\n //\n // `capabilities` is excluded for exactly that reason and not by oversight:\n // `featureChecklist` derives no claim from a capability document — a business\n // promise is realized by service requirements, and those are what the record\n // answers — so counting one as a feeder would report a capability-only\n // feature as ready to verify against a checklist with nothing in it.\n //\n // `arch-spec` used to be excluded beside it, and that failed the same test\n // the comment above states: `featureChecklist` DOES read `arch.spec.md`\n // (`core/verify/checklist.ts`), and `loam verify` on an architecture-only\n // feature returns a real checklist. The row said `blocked … needs delta,\n // spec, openapi, asyncapi` and `next.verify` said there was nothing to derive\n // a checklist from, about a command that derives one — which is the failure\n // `blocked` is supposed to prevent, pointed the wrong way.\n const feeders = out.filter((a) => a.id !== \"intent\" && a.id !== \"capabilities\" && a.exists);\n out.push({\n id: \"verification\",\n service: null,\n path: rel(verificationPath(feature.dir)),\n exists: verification.state !== \"absent\",\n required: true,\n status: feeders.length === 0 ? \"blocked\" : verificationStatus(verification),\n blockedBy: feeders.length === 0 ? [\"delta\", \"spec\", \"arch-spec\", \"openapi\", \"asyncapi\"] : [],\n });\n return out;\n}\n\n/** Where an artifact is and whether it is there — the three facts a grade reads. */\ninterface FileFacts {\n service: string | null;\n path: string;\n exists: boolean;\n}\n\nfunction fileState(id: ArtifactId, file: FileFacts, required: boolean, faulted: boolean): ArtifactState {\n const { service, path, exists } = file;\n const status: ArtifactStatus = !exists\n ? required\n ? \"missing\"\n : \"done\"\n : faulted\n ? \"draft\"\n : \"done\";\n return { id, service, path, exists, required, status, blockedBy: [] };\n}\n"]}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One feature: the full report. `featureStatus` gathers what the shared gates
|
|
3
|
+
* say about a feature in flight — findings, the artifact table, the record,
|
|
4
|
+
* the dependency order — and rolls them up into the stage and the steps. The
|
|
5
|
+
* vocabulary it reports in lives in ../report.ts, whose header holds the rules
|
|
6
|
+
* this projection is held to.
|
|
7
|
+
*/
|
|
8
|
+
import { featureCoherence } from "../../coherence/coherence.js";
|
|
9
|
+
import { invalidSpecServiceFindings, livingMergeConflicts, unknownDeltaServices, } from "../../coherence/living.js";
|
|
10
|
+
import { analyzeDependencies } from "../../dependencies/dependencies.js";
|
|
11
|
+
import { repoPath } from "../../envelope/json.js";
|
|
12
|
+
import { FleetContext } from "../../fleet-context.js";
|
|
13
|
+
import { featureProvenance } from "../../provenance/findings.js";
|
|
14
|
+
import { featureSpecServices } from "../../repo/repo.js";
|
|
15
|
+
import { enumeratedServices } from "../../repo/service-target.js";
|
|
16
|
+
import { useCaseBlastRadius } from "../../usecases/touch.js";
|
|
17
|
+
import { issueFinding } from "../../vocabulary/issue.js";
|
|
18
|
+
import { contractOwners, contractsHeldElsewhere } from "../contracts.js";
|
|
19
|
+
import { readInterruptedCommit } from "../interrupted.js";
|
|
20
|
+
import { governedServices, scanDeltas } from "../scan.js";
|
|
21
|
+
import { fullyVerified, verificationState } from "../verification.js";
|
|
22
|
+
import { featureArtifacts } from "./artifacts.js";
|
|
23
|
+
import { featureNext, unshippable } from "./next.js";
|
|
24
|
+
import {} from "./state.js";
|
|
25
|
+
/**
|
|
26
|
+
* Everything about one feature in flight. `service` narrows the per-service
|
|
27
|
+
* artifacts and the per-service steps; the feature's own `services` list stays
|
|
28
|
+
* complete either way, because a narrowed view that also hid which other
|
|
29
|
+
* services exist would read as a feature that touches exactly one.
|
|
30
|
+
*/
|
|
31
|
+
export async function featureStatus(docsDir, feature, opts = {}) {
|
|
32
|
+
const context = opts.context ?? new FleetContext();
|
|
33
|
+
const interrupted = await readInterruptedCommit(docsDir);
|
|
34
|
+
const services = await featureSpecServices(feature.dir, context);
|
|
35
|
+
const narrowed = opts.service;
|
|
36
|
+
const inView = narrowed === undefined ? services : services.filter((s) => s === narrowed);
|
|
37
|
+
const scans = feature.archived ? [] : await scanDeltas(docsDir, feature, services, context);
|
|
38
|
+
const read = await verificationState(docsDir, feature);
|
|
39
|
+
const verification = read.state;
|
|
40
|
+
// An archived feature is history: its delta is already folded into the living
|
|
41
|
+
// docs, so coherence would grade the change against a world that has absorbed
|
|
42
|
+
// it and report contradictions that are only the merge having happened. The
|
|
43
|
+
// same reason `list` never calls an archived record stale.
|
|
44
|
+
const findings = feature.archived ? [] : await featureFindings(docsDir, feature, scans, context);
|
|
45
|
+
// `verify.scenario-attested` rides in the same array an agent already parses,
|
|
46
|
+
// under verify's own code — a feature confirmed the short way has to be
|
|
47
|
+
// MARKED here, not merely absent from `stage: done`. It is a warning and it
|
|
48
|
+
// gates nothing, so `coherent` is untouched.
|
|
49
|
+
if (!feature.archived && read.notice !== null) {
|
|
50
|
+
findings.push({ severity: read.notice.severity, code: read.notice.code, message: read.notice.message });
|
|
51
|
+
}
|
|
52
|
+
const errors = findings.filter((f) => f.severity === "error");
|
|
53
|
+
const warnings = findings.filter((f) => f.severity === "warn").length;
|
|
54
|
+
// The union of the two gates, and the set every verdict below is drawn from.
|
|
55
|
+
const blocking = findings.filter(unshippable);
|
|
56
|
+
const governs = governedServices(scans);
|
|
57
|
+
// The whole feature is graded, then the view is narrowed — never the other
|
|
58
|
+
// way round. `--service` is a lens on the table and the steps; a rollup that
|
|
59
|
+
// moved with it would report a feature `ready` because the one service you
|
|
60
|
+
// asked about happens to be written, while three others have nothing.
|
|
61
|
+
const living = new Map((await enumeratedServices(docsDir, context)).map((s) => [s.id, s]));
|
|
62
|
+
const graded = featureArtifacts(docsDir, feature, services, {
|
|
63
|
+
blocking,
|
|
64
|
+
verification,
|
|
65
|
+
contracted: contractsHeldElsewhere(await contractOwners(docsDir, context), feature.id),
|
|
66
|
+
governs,
|
|
67
|
+
// Tolerant on purpose: status must keep answering in a docs repo whose
|
|
68
|
+
// services/ is broken or missing — an unenumerable fleet is doctor's
|
|
69
|
+
// diagnosis, and here it simply means every service reads as never-adopted.
|
|
70
|
+
living,
|
|
71
|
+
// Through the context's memo — the same walk `featureFindings` above and
|
|
72
|
+
// the coherence pass inside it already ran. An archived feature carries no
|
|
73
|
+
// delta to name, and the walk is one `existsSync` besides.
|
|
74
|
+
capabilities: (await context.featureCapabilityDeltas(feature.dir)).docs,
|
|
75
|
+
});
|
|
76
|
+
const artifacts = narrowed === undefined ? graded : graded.filter((a) => a.service === null || a.service === narrowed);
|
|
77
|
+
// The dependency index rather than the `*-pending` issue codes: those name the
|
|
78
|
+
// other feature in prose, and prose is not an API — dependencies.ts opens with
|
|
79
|
+
// exactly that argument. An archived feature waits on nothing; it landed.
|
|
80
|
+
const graph = feature.archived
|
|
81
|
+
? null
|
|
82
|
+
: await analyzeDependencies(docsDir, feature.id, context);
|
|
83
|
+
const blockedBy = graph?.nodes.find((n) => n.id === feature.id)?.dependsOn ?? [];
|
|
84
|
+
// The flows the services in view are already hops of. The fleet set is the
|
|
85
|
+
// living services UNION the feature's own, so a service this feature
|
|
86
|
+
// introduces resolves to itself rather than to a container's title — and the
|
|
87
|
+
// load underneath gates itself, so a docs repo that declares no use case pays
|
|
88
|
+
// a readdir here rather than a LikeC4 workspace.
|
|
89
|
+
const useCases = await useCaseBlastRadius({
|
|
90
|
+
docsDir,
|
|
91
|
+
known: new Set([...living.keys(), ...services]),
|
|
92
|
+
services: new Set(inView),
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
interrupted,
|
|
96
|
+
feature: {
|
|
97
|
+
id: feature.id,
|
|
98
|
+
dirName: feature.dirName,
|
|
99
|
+
path: repoPath(docsDir, feature.dir),
|
|
100
|
+
archived: feature.archived,
|
|
101
|
+
stage: featureStage({ feature, services, artifacts: graded, findings, blockedBy, verification, scans, interrupted }, blocking.length),
|
|
102
|
+
services,
|
|
103
|
+
blockedBy,
|
|
104
|
+
},
|
|
105
|
+
service: narrowed ?? null,
|
|
106
|
+
artifacts,
|
|
107
|
+
checks: {
|
|
108
|
+
ran: !feature.archived,
|
|
109
|
+
coherent: errors.length === 0,
|
|
110
|
+
errors: errors.length,
|
|
111
|
+
warnings,
|
|
112
|
+
gating: findings.filter((f) => f.gates === true).length,
|
|
113
|
+
issues: findings,
|
|
114
|
+
},
|
|
115
|
+
verification,
|
|
116
|
+
useCases,
|
|
117
|
+
next: featureNext({ feature, services: inView, artifacts, findings, blockedBy, verification, scans, interrupted }, opts.boundService),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Everything `loam validate --feature` and `loam archive` would say about this
|
|
122
|
+
* feature, in one list, through the very functions they call.
|
|
123
|
+
*
|
|
124
|
+
* Coherence alone was not it. `validate --feature` also runs `featureProvenance`
|
|
125
|
+
* over intent.md and the scenario-coverage check over every per-service delta,
|
|
126
|
+
* and both grade ERRORS — so a feature whose requirements carry no scenario at
|
|
127
|
+
* all read `coherent: true` here while `validate` exited 1 on the same tree.
|
|
128
|
+
* The coherence findings carry `gates` resolved, because archive's question is
|
|
129
|
+
* not severity's (issue.ts) and no consumer should re-derive it.
|
|
130
|
+
*/
|
|
131
|
+
async function featureFindings(docsDir, feature, scans, context) {
|
|
132
|
+
const issues = await featureCoherence({ docsDir, featureDir: feature.dir, featureId: feature.id, context });
|
|
133
|
+
const out = issues.map(issueFinding);
|
|
134
|
+
out.push(...(await featureProvenance(feature.dir, feature.id)).filter((f) => f.severity !== "ok"));
|
|
135
|
+
// The three refusals `archive` makes before its merge plan runs, from the
|
|
136
|
+
// same functions it calls: a per-service delta addressed to a service that
|
|
137
|
+
// exists nowhere, a specs/ directory whose NAME the id grammar refuses
|
|
138
|
+
// (that one is refused before archive plans anything — the name itself is
|
|
139
|
+
// the path it would become), and a LIVING document still holding git
|
|
140
|
+
// conflict markers. None are coherence issues — one is about a service id
|
|
141
|
+
// that means nothing, one about a name that can never be a path, one about
|
|
142
|
+
// a LIVING document nobody wrote — so they reach archive outside
|
|
143
|
+
// `featureCoherence`, and a projection that only inherited coherence
|
|
144
|
+
// printed "ship it" over all three. Errors: each is a refusal, and the rule
|
|
145
|
+
// this module is held to is one-directional.
|
|
146
|
+
out.push(...(await unknownDeltaServices(docsDir, feature.dir, feature.id, { context })));
|
|
147
|
+
out.push(...(await invalidSpecServiceFindings(feature.dir, context)));
|
|
148
|
+
// The capability half of the same scan: status may be redder than the gates
|
|
149
|
+
// and never greener, so a living capability document this feature's delta
|
|
150
|
+
// would rewrite has to be looked at here too. Through the context's memo —
|
|
151
|
+
// this function always has one — so the walk is shared with the coherence
|
|
152
|
+
// pass above rather than repeated.
|
|
153
|
+
const capabilityDeltas = await context.featureCapabilityDeltas(feature.dir);
|
|
154
|
+
out.push(...(await livingMergeConflicts(docsDir, await featureSpecServices(feature.dir, context), capabilityDeltas.docs.map((d) => d.id), context)));
|
|
155
|
+
for (const scan of scans) {
|
|
156
|
+
if (scan.bare.length === 0)
|
|
157
|
+
continue;
|
|
158
|
+
out.push({
|
|
159
|
+
severity: "error",
|
|
160
|
+
code: "requirements.missing-scenarios",
|
|
161
|
+
subject: scan.service,
|
|
162
|
+
message: `${scan.label}: ${scan.bare.length} requirement(s) without a scenario`,
|
|
163
|
+
details: scan.bare.map((r) => r.name),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return out;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The feature's own rollup, worst first. The order is the order the work has to
|
|
170
|
+
* happen in, so the winning branch is also the phase the feature is in:
|
|
171
|
+
* unwritten artifacts come before an ordering problem (you can author while
|
|
172
|
+
* another feature is still in flight), an ordering problem comes before this
|
|
173
|
+
* feature's own errors (fixing them may be pointless until the other one
|
|
174
|
+
* lands), and everything comes before the record — answers written over a
|
|
175
|
+
* broken feature are answers to questions that are about to change.
|
|
176
|
+
*
|
|
177
|
+
* The record is excluded from the `missing` branch on purpose. It is not
|
|
178
|
+
* something an author writes: it is the done-check's output, and counting its
|
|
179
|
+
* absence as unwritten work would report every correctly-authored feature as
|
|
180
|
+
* `missing` right up until somebody ran `loam verify` — which is the state
|
|
181
|
+
* `ready` exists to name, and which the fleet form already names correctly.
|
|
182
|
+
*/
|
|
183
|
+
function featureStage(state, blocking) {
|
|
184
|
+
const { feature, artifacts, services, blockedBy, verification, interrupted } = state;
|
|
185
|
+
// Ahead of `archived`, and ahead of everything else: a killed commit may be
|
|
186
|
+
// this very feature's, half-applied, so "it shipped" is a claim about files
|
|
187
|
+
// nobody has established the contents of. `blocked` is the honest word — the
|
|
188
|
+
// work is stalled on something that is not this feature's artifact — and it
|
|
189
|
+
// is what stops the projection printing `done` over a half-merged repo.
|
|
190
|
+
if (interrupted !== null)
|
|
191
|
+
return "blocked";
|
|
192
|
+
if (feature.archived)
|
|
193
|
+
return "done";
|
|
194
|
+
// A feature with no `specs/<service>/` changes nothing. There is no artifact
|
|
195
|
+
// row to be missing — the rows are per service — so the emptiness itself is
|
|
196
|
+
// the finding, and `next.touch-service` is the step.
|
|
197
|
+
if (services.length === 0)
|
|
198
|
+
return "missing";
|
|
199
|
+
if (artifacts.some((a) => a.id !== "verification" && a.status === "missing"))
|
|
200
|
+
return "missing";
|
|
201
|
+
if (blockedBy.length > 0)
|
|
202
|
+
return "blocked";
|
|
203
|
+
if (blocking > 0)
|
|
204
|
+
return "draft";
|
|
205
|
+
return fullyVerified(verification) ? "done" : "ready";
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature.js","sourceRoot":"","sources":["../../../../src/core/status/feature/feature.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One feature: the full report. `featureStatus` gathers what the shared gates\n * say about a feature in flight — findings, the artifact table, the record,\n * the dependency order — and rolls them up into the stage and the steps. The\n * vocabulary it reports in lives in ../report.ts, whose header holds the rules\n * this projection is held to.\n */\nimport { featureCoherence } from \"../../coherence/coherence.js\";\nimport {\n invalidSpecServiceFindings,\n livingMergeConflicts,\n unknownDeltaServices,\n} from \"../../coherence/living.js\";\nimport { analyzeDependencies } from \"../../dependencies/dependencies.js\";\nimport { repoPath } from \"../../envelope/json.js\";\nimport { FleetContext } from \"../../fleet-context.js\";\nimport { featureProvenance } from \"../../provenance/findings.js\";\nimport type { FeatureEntry } from \"../../repo/entries.js\";\nimport { featureSpecServices } from \"../../repo/repo.js\";\nimport { enumeratedServices } from \"../../repo/service-target.js\";\nimport { useCaseBlastRadius } from \"../../usecases/touch.js\";\nimport { issueFinding, type Issue } from \"../../vocabulary/issue.js\";\nimport type { Finding } from \"../../vocabulary/report.js\";\nimport { contractOwners, contractsHeldElsewhere } from \"../contracts.js\";\nimport { readInterruptedCommit } from \"../interrupted.js\";\nimport type { ArtifactStatus, FeatureStatusReport } from \"../report.js\";\nimport { governedServices, scanDeltas, type DeltaScan } from \"../scan.js\";\nimport { fullyVerified, verificationState } from \"../verification.js\";\nimport { featureArtifacts } from \"./artifacts.js\";\nimport { featureNext, unshippable } from \"./next.js\";\nimport { type FeatureState } from \"./state.js\";\nimport type { DocsDir } from \"../../kernel/ids/dirs.js\";\n\n/**\n * Everything about one feature in flight. `service` narrows the per-service\n * artifacts and the per-service steps; the feature's own `services` list stays\n * complete either way, because a narrowed view that also hid which other\n * services exist would read as a feature that touches exactly one.\n */\nexport async function featureStatus(\n docsDir: DocsDir,\n feature: FeatureEntry,\n opts: { service?: string; boundService?: string; context?: FleetContext } = {},\n): Promise<FeatureStatusReport> {\n const context = opts.context ?? new FleetContext();\n const interrupted = await readInterruptedCommit(docsDir);\n const services = await featureSpecServices(feature.dir, context);\n const narrowed = opts.service;\n const inView = narrowed === undefined ? services : services.filter((s) => s === narrowed);\n\n const scans = feature.archived ? [] : await scanDeltas(docsDir, feature, services, context);\n const read = await verificationState(docsDir, feature);\n const verification = read.state;\n // An archived feature is history: its delta is already folded into the living\n // docs, so coherence would grade the change against a world that has absorbed\n // it and report contradictions that are only the merge having happened. The\n // same reason `list` never calls an archived record stale.\n const findings = feature.archived ? [] : await featureFindings(docsDir, feature, scans, context);\n // `verify.scenario-attested` rides in the same array an agent already parses,\n // under verify's own code — a feature confirmed the short way has to be\n // MARKED here, not merely absent from `stage: done`. It is a warning and it\n // gates nothing, so `coherent` is untouched.\n if (!feature.archived && read.notice !== null) {\n findings.push({ severity: read.notice.severity, code: read.notice.code, message: read.notice.message });\n }\n const errors = findings.filter((f) => f.severity === \"error\");\n const warnings = findings.filter((f) => f.severity === \"warn\").length;\n // The union of the two gates, and the set every verdict below is drawn from.\n const blocking = findings.filter(unshippable);\n\n const governs = governedServices(scans);\n // The whole feature is graded, then the view is narrowed — never the other\n // way round. `--service` is a lens on the table and the steps; a rollup that\n // moved with it would report a feature `ready` because the one service you\n // asked about happens to be written, while three others have nothing.\n const living = new Map((await enumeratedServices(docsDir, context)).map((s) => [s.id, s]));\n const graded = featureArtifacts(docsDir, feature, services, {\n blocking,\n verification,\n contracted: contractsHeldElsewhere(await contractOwners(docsDir, context), feature.id),\n governs,\n // Tolerant on purpose: status must keep answering in a docs repo whose\n // services/ is broken or missing — an unenumerable fleet is doctor's\n // diagnosis, and here it simply means every service reads as never-adopted.\n living,\n // Through the context's memo — the same walk `featureFindings` above and\n // the coherence pass inside it already ran. An archived feature carries no\n // delta to name, and the walk is one `existsSync` besides.\n capabilities: (await context.featureCapabilityDeltas(feature.dir)).docs,\n });\n const artifacts =\n narrowed === undefined ? graded : graded.filter((a) => a.service === null || a.service === narrowed);\n\n // The dependency index rather than the `*-pending` issue codes: those name the\n // other feature in prose, and prose is not an API — dependencies.ts opens with\n // exactly that argument. An archived feature waits on nothing; it landed.\n const graph = feature.archived\n ? null\n : await analyzeDependencies(docsDir, feature.id, context);\n const blockedBy = graph?.nodes.find((n) => n.id === feature.id)?.dependsOn ?? [];\n\n // The flows the services in view are already hops of. The fleet set is the\n // living services UNION the feature's own, so a service this feature\n // introduces resolves to itself rather than to a container's title — and the\n // load underneath gates itself, so a docs repo that declares no use case pays\n // a readdir here rather than a LikeC4 workspace.\n const useCases = await useCaseBlastRadius({\n docsDir,\n known: new Set([...living.keys(), ...services]),\n services: new Set(inView),\n });\n\n return {\n interrupted,\n feature: {\n id: feature.id,\n dirName: feature.dirName,\n path: repoPath(docsDir, feature.dir),\n archived: feature.archived,\n stage: featureStage(\n { feature, services, artifacts: graded, findings, blockedBy, verification, scans, interrupted },\n blocking.length,\n ),\n services,\n blockedBy,\n },\n service: narrowed ?? null,\n artifacts,\n checks: {\n ran: !feature.archived,\n coherent: errors.length === 0,\n errors: errors.length,\n warnings,\n gating: findings.filter((f) => f.gates === true).length,\n issues: findings,\n },\n verification,\n useCases,\n next: featureNext(\n { feature, services: inView, artifacts, findings, blockedBy, verification, scans, interrupted },\n opts.boundService,\n ),\n };\n}\n\n/**\n * Everything `loam validate --feature` and `loam archive` would say about this\n * feature, in one list, through the very functions they call.\n *\n * Coherence alone was not it. `validate --feature` also runs `featureProvenance`\n * over intent.md and the scenario-coverage check over every per-service delta,\n * and both grade ERRORS — so a feature whose requirements carry no scenario at\n * all read `coherent: true` here while `validate` exited 1 on the same tree.\n * The coherence findings carry `gates` resolved, because archive's question is\n * not severity's (issue.ts) and no consumer should re-derive it.\n */\nasync function featureFindings(\n docsDir: DocsDir,\n feature: FeatureEntry,\n scans: DeltaScan[],\n context: FleetContext,\n): Promise<Finding[]> {\n const issues: Issue[] = await featureCoherence({ docsDir, featureDir: feature.dir, featureId: feature.id, context });\n const out: Finding[] = issues.map(issueFinding);\n out.push(...(await featureProvenance(feature.dir, feature.id)).filter((f) => f.severity !== \"ok\"));\n // The three refusals `archive` makes before its merge plan runs, from the\n // same functions it calls: a per-service delta addressed to a service that\n // exists nowhere, a specs/ directory whose NAME the id grammar refuses\n // (that one is refused before archive plans anything — the name itself is\n // the path it would become), and a LIVING document still holding git\n // conflict markers. None are coherence issues — one is about a service id\n // that means nothing, one about a name that can never be a path, one about\n // a LIVING document nobody wrote — so they reach archive outside\n // `featureCoherence`, and a projection that only inherited coherence\n // printed \"ship it\" over all three. Errors: each is a refusal, and the rule\n // this module is held to is one-directional.\n out.push(...(await unknownDeltaServices(docsDir, feature.dir, feature.id, { context })));\n out.push(...(await invalidSpecServiceFindings(feature.dir, context)));\n // The capability half of the same scan: status may be redder than the gates\n // and never greener, so a living capability document this feature's delta\n // would rewrite has to be looked at here too. Through the context's memo —\n // this function always has one — so the walk is shared with the coherence\n // pass above rather than repeated.\n const capabilityDeltas = await context.featureCapabilityDeltas(feature.dir);\n out.push(\n ...(await livingMergeConflicts(docsDir, await featureSpecServices(feature.dir, context), capabilityDeltas.docs.map((d) => d.id), context)),\n );\n for (const scan of scans) {\n if (scan.bare.length === 0) continue;\n out.push({\n severity: \"error\",\n code: \"requirements.missing-scenarios\",\n subject: scan.service,\n message: `${scan.label}: ${scan.bare.length} requirement(s) without a scenario`,\n details: scan.bare.map((r) => r.name),\n });\n }\n return out;\n}\n\n/**\n * The feature's own rollup, worst first. The order is the order the work has to\n * happen in, so the winning branch is also the phase the feature is in:\n * unwritten artifacts come before an ordering problem (you can author while\n * another feature is still in flight), an ordering problem comes before this\n * feature's own errors (fixing them may be pointless until the other one\n * lands), and everything comes before the record — answers written over a\n * broken feature are answers to questions that are about to change.\n *\n * The record is excluded from the `missing` branch on purpose. It is not\n * something an author writes: it is the done-check's output, and counting its\n * absence as unwritten work would report every correctly-authored feature as\n * `missing` right up until somebody ran `loam verify` — which is the state\n * `ready` exists to name, and which the fleet form already names correctly.\n */\nfunction featureStage(state: FeatureState, blocking: number): ArtifactStatus {\n const { feature, artifacts, services, blockedBy, verification, interrupted } = state;\n // Ahead of `archived`, and ahead of everything else: a killed commit may be\n // this very feature's, half-applied, so \"it shipped\" is a claim about files\n // nobody has established the contents of. `blocked` is the honest word — the\n // work is stalled on something that is not this feature's artifact — and it\n // is what stops the projection printing `done` over a half-merged repo.\n if (interrupted !== null) return \"blocked\";\n if (feature.archived) return \"done\";\n // A feature with no `specs/<service>/` changes nothing. There is no artifact\n // row to be missing — the rows are per service — so the emptiness itself is\n // the finding, and `next.touch-service` is the step.\n if (services.length === 0) return \"missing\";\n if (artifacts.some((a) => a.id !== \"verification\" && a.status === \"missing\")) return \"missing\";\n if (blockedBy.length > 0) return \"blocked\";\n if (blocking > 0) return \"draft\";\n return fullyVerified(verification) ? \"done\" : \"ready\";\n}\n"]}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { recoverStep } from "../interrupted.js";
|
|
2
|
+
import { testStep, verifyStep } from "../verification.js";
|
|
3
|
+
import {} from "./state.js";
|
|
4
|
+
/**
|
|
5
|
+
* Would either gate refuse this? Severity answers `validate`'s question and
|
|
6
|
+
* `gates` answers archive's; a finding that fails EITHER is one an author has
|
|
7
|
+
* work to do about, and collapsing them to `severity === "error"` is how
|
|
8
|
+
* `status` came to print "ship it" beside a warning archive exits 1 on.
|
|
9
|
+
*/
|
|
10
|
+
export function unshippable(f) {
|
|
11
|
+
return f.severity === "error" || f.gates === true;
|
|
12
|
+
}
|
|
13
|
+
/** Codes whose one fix is `loam rebase`: a pin nobody ever wrote, on any of the three axes. */
|
|
14
|
+
const UNPINNED = new Set(["delta.baseline-missing", "openapi.baseline-missing", "asyncapi.baseline-missing"]);
|
|
15
|
+
export function featureNext(state, boundService) {
|
|
16
|
+
const { feature, services, artifacts, findings, blockedBy, verification, scans, interrupted } = state;
|
|
17
|
+
const id = feature.id;
|
|
18
|
+
// Before the archived shortcut: the interrupted commit may be this feature's
|
|
19
|
+
// own, and "it shipped" is not a thing to tell somebody whose living docs are
|
|
20
|
+
// half-written.
|
|
21
|
+
const first = interrupted === null ? [] : [recoverStep(interrupted)];
|
|
22
|
+
if (feature.archived) {
|
|
23
|
+
return [
|
|
24
|
+
...first,
|
|
25
|
+
{
|
|
26
|
+
code: "next.archived",
|
|
27
|
+
statement: `${id} is archived — it shipped, and its delta is already folded into the living docs.`,
|
|
28
|
+
command: `loam show ${id} --json`,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
const steps = [...first];
|
|
33
|
+
const owed = (kind, service) => artifacts.find((a) => a.id === kind && a.status === "missing" && (service === undefined || a.service === service));
|
|
34
|
+
const intent = owed("intent");
|
|
35
|
+
if (intent !== undefined) {
|
|
36
|
+
steps.push({
|
|
37
|
+
code: "next.author-intent",
|
|
38
|
+
statement: `Write ${intent.path} — what ${id} is for, in prose, before anything is derived from it.`,
|
|
39
|
+
command: `loam validate ${id} --json`,
|
|
40
|
+
artifact: "intent",
|
|
41
|
+
path: intent.path,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (services.length === 0) {
|
|
45
|
+
steps.push({
|
|
46
|
+
code: "next.touch-service",
|
|
47
|
+
statement: `${id} carries no per-service delta — add specs/<service>/spec.md for every service it changes.`,
|
|
48
|
+
command: "loam list services --json",
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
for (const svc of services) {
|
|
52
|
+
const spec = owed("spec", svc);
|
|
53
|
+
if (spec !== undefined) {
|
|
54
|
+
steps.push({
|
|
55
|
+
code: "next.author-spec",
|
|
56
|
+
statement: `Write ${spec.path} — the ADDED/MODIFIED/REMOVED requirements ${id} makes to ${svc}, each with a scenario.`,
|
|
57
|
+
command: `loam delta ${id} --service ${svc} --json`,
|
|
58
|
+
artifact: "spec",
|
|
59
|
+
service: svc,
|
|
60
|
+
path: spec.path,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const api = owed("openapi", svc);
|
|
64
|
+
if (api !== undefined) {
|
|
65
|
+
steps.push({
|
|
66
|
+
code: "next.author-openapi",
|
|
67
|
+
// Not "the service is not in the living docs": a service adopted
|
|
68
|
+
// without a contract is the commoner case, and that wording sent a
|
|
69
|
+
// reader looking for a directory that was right there. And not "the
|
|
70
|
+
// operations it governs" either — this step also fires for a service
|
|
71
|
+
// the feature INTRODUCES, where owesContract asks nothing about
|
|
72
|
+
// operations and the delta may tag none, so naming them promised the
|
|
73
|
+
// author a list they would go looking for and not find.
|
|
74
|
+
statement: `Write ${api.path} — nothing gives ${svc} a living openapi.yaml, so this feature is the only thing that can write down its API surface.`,
|
|
75
|
+
command: `loam delta ${id} --service ${svc} --json`,
|
|
76
|
+
artifact: "openapi",
|
|
77
|
+
service: svc,
|
|
78
|
+
path: api.path,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// A requirement with no scenario yields no generated .feature and no
|
|
83
|
+
// scenario.tested claim: a promise that reaches neither the suite nor the
|
|
84
|
+
// done-check, and that nothing downstream will ever mention again. One entry
|
|
85
|
+
// per service rather than per requirement — a delta with forty bare
|
|
86
|
+
// requirements would otherwise BE the payload (validate caps its details for
|
|
87
|
+
// the same reason).
|
|
88
|
+
for (const gap of scans) {
|
|
89
|
+
if (gap.bare.length === 0 || !services.includes(gap.service))
|
|
90
|
+
continue;
|
|
91
|
+
steps.push({
|
|
92
|
+
code: "next.author-scenarios",
|
|
93
|
+
statement: `${gap.bare.length} requirement(s) in ${gap.service}'s delta have no '#### Scenario:' ` +
|
|
94
|
+
`(starting with '${gap.bare[0].name}') — they generate no test and no verify claim.`,
|
|
95
|
+
command: `loam delta ${id} --service ${gap.service} --json`,
|
|
96
|
+
artifact: "spec",
|
|
97
|
+
service: gap.service,
|
|
98
|
+
path: gap.path,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (findings.some((f) => UNPINNED.has(f.code))) {
|
|
102
|
+
steps.push({
|
|
103
|
+
code: "next.rebase",
|
|
104
|
+
statement: `${id} carries requirements or operations with no baseline pin — until they have one the merge cannot tell what it EDITS from what it merely quotes.`,
|
|
105
|
+
command: `loam rebase ${id}`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (blockedBy.length > 0) {
|
|
109
|
+
steps.push({
|
|
110
|
+
code: "next.archive-first",
|
|
111
|
+
statement: `${id} builds on ${blockedBy.join(", ")}, which ${blockedBy.length === 1 ? "has" : "have"} to archive first.`,
|
|
112
|
+
command: `loam dependencies ${id} --json`,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// Everything either gate refuses on, not just the errors: a warning marked
|
|
116
|
+
// `gates: true` stops archive exactly as hard, and leaving it out of the
|
|
117
|
+
// steps was the other half of leaving it out of the stage.
|
|
118
|
+
const blocking = findings.filter(unshippable);
|
|
119
|
+
if (blocking.length > 0) {
|
|
120
|
+
const gating = blocking.filter((f) => f.gates === true && f.severity !== "error").length;
|
|
121
|
+
steps.push({
|
|
122
|
+
code: "next.fix-coherence",
|
|
123
|
+
statement: `${id} has ${blocking.length} finding(s) that stop it, starting with ${blocking[0].code}` +
|
|
124
|
+
(gating > 0
|
|
125
|
+
? ` — ${gating} of them ${gating === 1 ? "is a warning that GATES" : "are warnings that GATE"} archive, ` +
|
|
126
|
+
"which `validate` grades valid, so its exit code alone will not show you why archive refuses."
|
|
127
|
+
: " — the axes disagree, and archive refuses."),
|
|
128
|
+
command: `loam validate ${id} --json`,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// The implementation half of the forward flow, which next[] never named at
|
|
132
|
+
// all: an agent read "author the spec" and then "record the verification",
|
|
133
|
+
// with nothing in between saying where a test comes from — so the only way
|
|
134
|
+
// left to answer a scenario claim was its own word, through `--record`.
|
|
135
|
+
steps.push(...testStep(id, verification, { services, scans, boundService }));
|
|
136
|
+
steps.push(...verifyStep(id, verification, { artifacts, services, boundService }));
|
|
137
|
+
// Always last, and always present: a feature whose every artifact holds and
|
|
138
|
+
// whose record is complete still has one thing left to do, and an empty
|
|
139
|
+
// `next[]` would leave a caller unable to tell "finished" from "this command
|
|
140
|
+
// had nothing to say".
|
|
141
|
+
steps.push({
|
|
142
|
+
code: "next.archive",
|
|
143
|
+
statement: steps.length === 0
|
|
144
|
+
? `${id} is authored, coherent and verified — ship it.`
|
|
145
|
+
: `${id} ships once everything above is done; the dry run writes nothing and lists every file the merge would touch.`,
|
|
146
|
+
command: `loam archive ${id} --dry-run --json`,
|
|
147
|
+
});
|
|
148
|
+
return steps;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=next.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.js","sourceRoot":"","sources":["../../../../src/core/status/feature/next.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `next[]` — one feature.\n *\n * The payload's reason to exist. Each entry carries a stable `code` to branch\n * on, one sentence a person can read, and the literal command to run — ordered,\n * first entry first. `command` is the loam invocation that carries the step\n * forward: the one that does the work where loam does it (`rebase`, `archive`),\n * and the one that states or grades the work where the author does it (`delta`,\n * `validate`, `verify`). It is never a command that would write the artifact\n * behind the author's back — loam does not author.\n *\n * `next` is never empty. A feature with nothing outstanding still has a next\n * step (ship it), and a repository with nothing outstanding still has one (keep\n * the fleet green) — an empty array would be indistinguishable from a bug in\n * the caller's own parsing.\n */\nimport type { Finding } from \"../../vocabulary/report.js\";\nimport { recoverStep } from \"../interrupted.js\";\nimport type { ArtifactId, ArtifactState, NextStep } from \"../report.js\";\nimport { testStep, verifyStep } from \"../verification.js\";\nimport { type FeatureState } from \"./state.js\";\n\n/**\n * Would either gate refuse this? Severity answers `validate`'s question and\n * `gates` answers archive's; a finding that fails EITHER is one an author has\n * work to do about, and collapsing them to `severity === \"error\"` is how\n * `status` came to print \"ship it\" beside a warning archive exits 1 on.\n */\nexport function unshippable(f: Finding): boolean {\n return f.severity === \"error\" || f.gates === true;\n}\n\n/** Codes whose one fix is `loam rebase`: a pin nobody ever wrote, on any of the three axes. */\nconst UNPINNED = new Set([\"delta.baseline-missing\", \"openapi.baseline-missing\", \"asyncapi.baseline-missing\"]);\n\nexport function featureNext(state: FeatureState, boundService: string | undefined): NextStep[] {\n const { feature, services, artifacts, findings, blockedBy, verification, scans, interrupted } = state;\n const id = feature.id;\n // Before the archived shortcut: the interrupted commit may be this feature's\n // own, and \"it shipped\" is not a thing to tell somebody whose living docs are\n // half-written.\n const first = interrupted === null ? [] : [recoverStep(interrupted)];\n if (feature.archived) {\n return [\n ...first,\n {\n code: \"next.archived\",\n statement: `${id} is archived — it shipped, and its delta is already folded into the living docs.`,\n command: `loam show ${id} --json`,\n },\n ];\n }\n\n const steps: NextStep[] = [...first];\n const owed = (kind: ArtifactId, service?: string): ArtifactState | undefined =>\n artifacts.find(\n (a) => a.id === kind && a.status === \"missing\" && (service === undefined || a.service === service),\n );\n\n const intent = owed(\"intent\");\n if (intent !== undefined) {\n steps.push({\n code: \"next.author-intent\",\n statement: `Write ${intent.path} — what ${id} is for, in prose, before anything is derived from it.`,\n command: `loam validate ${id} --json`,\n artifact: \"intent\",\n path: intent.path,\n });\n }\n\n if (services.length === 0) {\n steps.push({\n code: \"next.touch-service\",\n statement: `${id} carries no per-service delta — add specs/<service>/spec.md for every service it changes.`,\n command: \"loam list services --json\",\n });\n }\n\n for (const svc of services) {\n const spec = owed(\"spec\", svc);\n if (spec !== undefined) {\n steps.push({\n code: \"next.author-spec\",\n statement: `Write ${spec.path} — the ADDED/MODIFIED/REMOVED requirements ${id} makes to ${svc}, each with a scenario.`,\n command: `loam delta ${id} --service ${svc} --json`,\n artifact: \"spec\",\n service: svc,\n path: spec.path,\n });\n }\n const api = owed(\"openapi\", svc);\n if (api !== undefined) {\n steps.push({\n code: \"next.author-openapi\",\n // Not \"the service is not in the living docs\": a service adopted\n // without a contract is the commoner case, and that wording sent a\n // reader looking for a directory that was right there. And not \"the\n // operations it governs\" either — this step also fires for a service\n // the feature INTRODUCES, where owesContract asks nothing about\n // operations and the delta may tag none, so naming them promised the\n // author a list they would go looking for and not find.\n statement: `Write ${api.path} — nothing gives ${svc} a living openapi.yaml, so this feature is the only thing that can write down its API surface.`,\n command: `loam delta ${id} --service ${svc} --json`,\n artifact: \"openapi\",\n service: svc,\n path: api.path,\n });\n }\n }\n\n // A requirement with no scenario yields no generated .feature and no\n // scenario.tested claim: a promise that reaches neither the suite nor the\n // done-check, and that nothing downstream will ever mention again. One entry\n // per service rather than per requirement — a delta with forty bare\n // requirements would otherwise BE the payload (validate caps its details for\n // the same reason).\n for (const gap of scans) {\n if (gap.bare.length === 0 || !services.includes(gap.service)) continue;\n steps.push({\n code: \"next.author-scenarios\",\n statement:\n `${gap.bare.length} requirement(s) in ${gap.service}'s delta have no '#### Scenario:' ` +\n `(starting with '${gap.bare[0]!.name}') — they generate no test and no verify claim.`,\n command: `loam delta ${id} --service ${gap.service} --json`,\n artifact: \"spec\",\n service: gap.service,\n path: gap.path,\n });\n }\n\n if (findings.some((f) => UNPINNED.has(f.code))) {\n steps.push({\n code: \"next.rebase\",\n statement: `${id} carries requirements or operations with no baseline pin — until they have one the merge cannot tell what it EDITS from what it merely quotes.`,\n command: `loam rebase ${id}`,\n });\n }\n\n if (blockedBy.length > 0) {\n steps.push({\n code: \"next.archive-first\",\n statement: `${id} builds on ${blockedBy.join(\", \")}, which ${blockedBy.length === 1 ? \"has\" : \"have\"} to archive first.`,\n command: `loam dependencies ${id} --json`,\n });\n }\n\n // Everything either gate refuses on, not just the errors: a warning marked\n // `gates: true` stops archive exactly as hard, and leaving it out of the\n // steps was the other half of leaving it out of the stage.\n const blocking = findings.filter(unshippable);\n if (blocking.length > 0) {\n const gating = blocking.filter((f) => f.gates === true && f.severity !== \"error\").length;\n steps.push({\n code: \"next.fix-coherence\",\n statement:\n `${id} has ${blocking.length} finding(s) that stop it, starting with ${blocking[0]!.code}` +\n (gating > 0\n ? ` — ${gating} of them ${gating === 1 ? \"is a warning that GATES\" : \"are warnings that GATE\"} archive, ` +\n \"which `validate` grades valid, so its exit code alone will not show you why archive refuses.\"\n : \" — the axes disagree, and archive refuses.\"),\n command: `loam validate ${id} --json`,\n });\n }\n\n // The implementation half of the forward flow, which next[] never named at\n // all: an agent read \"author the spec\" and then \"record the verification\",\n // with nothing in between saying where a test comes from — so the only way\n // left to answer a scenario claim was its own word, through `--record`.\n steps.push(...testStep(id, verification, { services, scans, boundService }));\n steps.push(...verifyStep(id, verification, { artifacts, services, boundService }));\n\n // Always last, and always present: a feature whose every artifact holds and\n // whose record is complete still has one thing left to do, and an empty\n // `next[]` would leave a caller unable to tell \"finished\" from \"this command\n // had nothing to say\".\n steps.push({\n code: \"next.archive\",\n statement:\n steps.length === 0\n ? `${id} is authored, coherent and verified — ship it.`\n : `${id} ships once everything above is done; the dry run writes nothing and lists every file the merge would touch.`,\n command: `loam archive ${id} --dry-run --json`,\n });\n return steps;\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One feature, fully graded — the record every question in this package asks
|
|
3
|
+
* about.
|
|
4
|
+
*
|
|
5
|
+
* It exists because eight functions took the same seven or nine values in
|
|
6
|
+
* hand-kept order: a feature, its services, its artifacts, its findings, its
|
|
7
|
+
* verification, its scans, what it is blocked by, and whether a commit was
|
|
8
|
+
* interrupted. Positional, `services` and `blockedBy` are both `string[]` and
|
|
9
|
+
* transposing them compiles.
|
|
10
|
+
*
|
|
11
|
+
* Note what is NOT in here: the `--service` lens. The whole feature is graded
|
|
12
|
+
* and the view is narrowed afterwards, never the other way round — a rollup
|
|
13
|
+
* that moved with the lens would report a feature `ready` because the one
|
|
14
|
+
* service you asked about happens to be written, while three others have
|
|
15
|
+
* nothing.
|
|
16
|
+
*/
|
|
17
|
+
import {} from "../../repo/entries.js";
|
|
18
|
+
import {} from "../../vocabulary/report.js";
|
|
19
|
+
import {} from "../scan.js";
|
|
20
|
+
import {} from "../report.js";
|
|
21
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../src/core/status/feature/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAqB,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAgB,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAkB,MAAM,YAAY,CAAC;AAC5C,OAAO,EAIN,MAAM,cAAc,CAAC","sourcesContent":["/**\n * One feature, fully graded — the record every question in this package asks\n * about.\n *\n * It exists because eight functions took the same seven or nine values in\n * hand-kept order: a feature, its services, its artifacts, its findings, its\n * verification, its scans, what it is blocked by, and whether a commit was\n * interrupted. Positional, `services` and `blockedBy` are both `string[]` and\n * transposing them compiles.\n *\n * Note what is NOT in here: the `--service` lens. The whole feature is graded\n * and the view is narrowed afterwards, never the other way round — a rollup\n * that moved with the lens would report a feature `ready` because the one\n * service you asked about happens to be written, while three others have\n * nothing.\n */\nimport { type FeatureEntry } from \"../../repo/entries.js\";\nimport { type Finding } from \"../../vocabulary/report.js\";\nimport { type DeltaScan } from \"../scan.js\";\nimport {\n type ArtifactState,\n type InterruptedCommit,\n type VerificationState,\n} from \"../report.js\";\n\nexport interface FeatureState {\n feature: FeatureEntry;\n /** Every service the feature touches — not the narrowed view. */\n services: string[];\n artifacts: ArtifactState[];\n findings: Finding[];\n /** Features that have to archive before this one can. */\n blockedBy: string[];\n verification: VerificationState;\n scans: DeltaScan[];\n interrupted: InterruptedCommit | null;\n}\n"]}
|