@ybotok/loam 0.2.0-alpha.4 → 0.2.0-alpha.6
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 +947 -0
- package/MIGRATING-from-OpenSpec.md +7 -1
- package/QUICKSTART.md +8 -3
- package/README.md +20 -13
- package/ROADMAP.md +329 -22
- package/SCHEMA.md +472 -24
- package/WORKFLOW.md +23 -10
- package/dist/commands/adopt/render.js +47 -8
- package/dist/commands/adopt/render.js.map +1 -1
- package/dist/commands/archive/plan/landscape.js +45 -1
- package/dist/commands/archive/plan/landscape.js.map +1 -1
- package/dist/commands/archive/plan/model/extending.js +85 -0
- package/dist/commands/archive/plan/model/extending.js.map +1 -0
- package/dist/commands/archive/run.js +5 -2
- package/dist/commands/archive/run.js.map +1 -1
- package/dist/commands/context/print.js +11 -1
- package/dist/commands/context/print.js.map +1 -1
- package/dist/commands/doctor.js +46 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explore.js +12 -2
- package/dist/commands/explore.js.map +1 -1
- package/dist/commands/list/views.js +5 -1
- package/dist/commands/list/views.js.map +1 -1
- package/dist/commands/seed/plan.js +97 -3
- package/dist/commands/seed/plan.js.map +1 -1
- package/dist/commands/seed/seed.js +7 -2
- package/dist/commands/seed/seed.js.map +1 -1
- package/dist/commands/show/feature.js +2 -1
- package/dist/commands/show/feature.js.map +1 -1
- package/dist/commands/show/marks.js +3 -5
- package/dist/commands/show/marks.js.map +1 -1
- package/dist/commands/show/service.js +39 -18
- package/dist/commands/show/service.js.map +1 -1
- package/dist/commands/subsystem/sync.js +184 -39
- package/dist/commands/subsystem/sync.js.map +1 -1
- package/dist/commands/subsystem/txn/exclude.js +132 -0
- package/dist/commands/subsystem/txn/exclude.js.map +1 -0
- package/dist/commands/subsystem/txn/report.js +124 -0
- package/dist/commands/subsystem/txn/report.js.map +1 -0
- package/dist/commands/subsystem/txn/txn.js +29 -3
- package/dist/commands/subsystem/txn/txn.js.map +1 -1
- package/dist/commands/subsystem/txn/views.js +113 -16
- package/dist/commands/subsystem/txn/views.js.map +1 -1
- package/dist/commands/validate/arch-coverage.js +16 -9
- package/dist/commands/validate/arch-coverage.js.map +1 -1
- package/dist/commands/validate/checks/fleet-shape.js +30 -77
- package/dist/commands/validate/checks/fleet-shape.js.map +1 -1
- package/dist/commands/validate/checks/vocabulary.js +4 -19
- package/dist/commands/validate/checks/vocabulary.js.map +1 -1
- package/dist/commands/validate/feature.js +1 -1
- package/dist/commands/validate/feature.js.map +1 -1
- package/dist/commands/validate/fleet/census.js +11 -10
- package/dist/commands/validate/fleet/census.js.map +1 -1
- package/dist/commands/validate/fleet/landscape.js +128 -114
- package/dist/commands/validate/fleet/landscape.js.map +1 -1
- package/dist/commands/validate/fleet/load.js +66 -0
- package/dist/commands/validate/fleet/load.js.map +1 -1
- package/dist/commands/validate/fleet/map/attest.js +103 -0
- package/dist/commands/validate/fleet/map/attest.js.map +1 -0
- package/dist/commands/validate/fleet/map/bindings.js +96 -0
- package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
- package/dist/commands/validate/fleet/map/consumers.js +298 -0
- package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
- package/dist/commands/validate/fleet/map/isolation.js +116 -0
- package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
- package/dist/commands/validate/fleet/map/usecases.js +56 -0
- package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
- package/dist/commands/validate/fleet/usecases/steps.js +49 -17
- package/dist/commands/validate/fleet/usecases/steps.js.map +1 -1
- package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
- package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
- package/dist/commands/validate/fleet/views/ids.js +13 -9
- package/dist/commands/validate/fleet/views/ids.js.map +1 -1
- package/dist/commands/validate/fleet/views/projects.js +278 -0
- package/dist/commands/validate/fleet/views/projects.js.map +1 -0
- package/dist/commands/validate/fleet/views/root-documents.js +97 -0
- package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
- package/dist/commands/validate/fleet/views/stale.js +2 -2
- package/dist/commands/validate/fleet/views/stale.js.map +1 -1
- package/dist/commands/validate/service/model/diverged.js +226 -0
- package/dist/commands/validate/service/model/diverged.js.map +1 -0
- package/dist/commands/validate/service/model/grade.js +163 -0
- package/dist/commands/validate/service/model/grade.js.map +1 -0
- package/dist/commands/validate/service/service.js +110 -34
- package/dist/commands/validate/service/service.js.map +1 -1
- package/dist/commands/validate/service/specs.js +39 -5
- package/dist/commands/validate/service/specs.js.map +1 -1
- package/dist/commands/validate/service/spine.js +41 -3
- package/dist/commands/validate/service/spine.js.map +1 -1
- package/dist/commands/validate/service/usecases/tags.js +113 -0
- package/dist/commands/validate/service/usecases/tags.js.map +1 -0
- package/dist/commands/validate/service/usecases/usecases.js +209 -0
- package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
- package/dist/commands/validate/validate.js +10 -24
- package/dist/commands/validate/validate.js.map +1 -1
- package/dist/core/agent/agents-md/artifacts.js +1 -0
- package/dist/core/agent/agents-md/artifacts.js.map +1 -1
- package/dist/core/agent/agents-md/command-map.js +18 -2
- package/dist/core/agent/agents-md/command-map.js.map +1 -1
- package/dist/core/agent/agents-md/cycle.js +24 -9
- package/dist/core/agent/agents-md/cycle.js.map +1 -1
- package/dist/core/agent/agents-md/map/lenses/context.js +4 -3
- package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -1
- package/dist/core/agent/agents-md/map/subsystem.js +51 -2
- package/dist/core/agent/agents-md/map/subsystem.js.map +1 -1
- package/dist/core/agent/agents-md/map/usecases.js +45 -3
- package/dist/core/agent/agents-md/map/usecases.js.map +1 -1
- package/dist/core/agent/agents-md.js +14 -4
- package/dist/core/agent/agents-md.js.map +1 -1
- package/dist/core/agent/support/report.js +39 -5
- package/dist/core/agent/support/report.js.map +1 -1
- package/dist/core/agent/workflows/adopt.js +125 -6
- package/dist/core/agent/workflows/adopt.js.map +1 -1
- package/dist/core/agent/workflows/check.js +35 -19
- package/dist/core/agent/workflows/check.js.map +1 -1
- package/dist/core/agent/workflows/closing.js +3 -1
- package/dist/core/agent/workflows/closing.js.map +1 -1
- package/dist/core/brief/brief.js +63 -11
- package/dist/core/brief/brief.js.map +1 -1
- package/dist/core/brief/checks.js +138 -3
- package/dist/core/brief/checks.js.map +1 -1
- package/dist/core/brief/landscape.js +212 -129
- package/dist/core/brief/landscape.js.map +1 -1
- package/dist/core/brief/map/extend.js +81 -0
- package/dist/core/brief/map/extend.js.map +1 -0
- package/dist/core/brief/map/owed.js +284 -0
- package/dist/core/brief/map/owed.js.map +1 -0
- package/dist/core/brief/targets.js +30 -26
- package/dist/core/brief/targets.js.map +1 -1
- package/dist/core/brief/unchecked.js +12 -2
- package/dist/core/brief/unchecked.js.map +1 -1
- package/dist/core/c4/likec4.js +23 -1
- package/dist/core/c4/likec4.js.map +1 -1
- package/dist/core/c4/parsed/deployment.js +5 -3
- package/dist/core/c4/parsed/deployment.js.map +1 -1
- package/dist/core/c4/parsed/view-ids.js +39 -1
- package/dist/core/c4/parsed/view-ids.js.map +1 -1
- package/dist/core/c4/prefetch/fleet.js +142 -0
- package/dist/core/c4/prefetch/fleet.js.map +1 -0
- package/dist/core/c4/project/architecture.js +52 -4
- package/dist/core/c4/project/architecture.js.map +1 -1
- package/dist/core/c4/project/batch.js +140 -0
- package/dist/core/c4/project/batch.js.map +1 -0
- package/dist/core/c4/project/documents.js +9 -4
- package/dist/core/c4/project/documents.js.map +1 -1
- package/dist/core/c4/project/load.js +77 -38
- package/dist/core/c4/project/load.js.map +1 -1
- package/dist/core/c4/project/staged.js +46 -12
- package/dist/core/c4/project/staged.js.map +1 -1
- package/dist/core/c4/resolve/attested.js +0 -0
- package/dist/core/c4/resolve/attested.js.map +1 -0
- package/dist/core/c4/resolve/service.js +8 -17
- package/dist/core/c4/resolve/service.js.map +1 -1
- package/dist/core/c4/resolve/steps.js +18 -0
- package/dist/core/c4/resolve/steps.js.map +1 -1
- package/dist/core/c4/root-project/exclude.js +352 -0
- package/dist/core/c4/root-project/exclude.js.map +1 -0
- package/dist/core/c4/service-model/documents.js +47 -0
- package/dist/core/c4/service-model/documents.js.map +1 -0
- package/dist/core/c4/service-model/fleet/extending.js +82 -0
- package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
- package/dist/core/c4/service-model/load.js +165 -0
- package/dist/core/c4/service-model/load.js.map +1 -0
- package/dist/core/c4/service-model/renderer.js +128 -0
- package/dist/core/c4/service-model/renderer.js.map +1 -0
- package/dist/core/c4/service-model/shape.js +126 -0
- package/dist/core/c4/service-model/shape.js.map +1 -0
- package/dist/core/c4/service-model/slice.js +188 -0
- package/dist/core/c4/service-model/slice.js.map +1 -0
- package/dist/core/c4/source-scan.js +26 -0
- package/dist/core/c4/source-scan.js.map +1 -1
- package/dist/core/c4/splice/authored-source.js +60 -13
- package/dist/core/c4/splice/authored-source.js.map +1 -1
- package/dist/core/c4/splice/contract.js.map +1 -1
- package/dist/core/c4/splice/identity/declared.js +87 -0
- package/dist/core/c4/splice/identity/declared.js.map +1 -0
- package/dist/core/c4/splice/identity/edges.js +17 -0
- package/dist/core/c4/splice/identity/edges.js.map +1 -1
- package/dist/core/c4/splice/identity/existing.js +80 -0
- package/dist/core/c4/splice/identity/existing.js.map +1 -0
- package/dist/core/c4/splice/identity/interior.js +80 -0
- package/dist/core/c4/splice/identity/interior.js.map +1 -0
- package/dist/core/c4/splice/identity/owner.js +50 -0
- package/dist/core/c4/splice/identity/owner.js.map +1 -0
- package/dist/core/c4/splice/landscape-merge.js +154 -100
- package/dist/core/c4/splice/landscape-merge.js.map +1 -1
- package/dist/core/c4/splice/model/merge.js +140 -0
- package/dist/core/c4/splice/model/merge.js.map +1 -0
- package/dist/core/c4/splice/placement.js +14 -4
- package/dist/core/c4/splice/placement.js.map +1 -1
- package/dist/core/c4/workspace.js +2 -1
- package/dist/core/c4/workspace.js.map +1 -1
- package/dist/core/coherence/coherence.js +7 -0
- package/dist/core/coherence/coherence.js.map +1 -1
- package/dist/core/delta/delta.js +9 -0
- package/dist/core/delta/delta.js.map +1 -1
- package/dist/core/deployment/delta.js +4 -0
- package/dist/core/deployment/delta.js.map +1 -1
- package/dist/core/diff/base-state.js +21 -5
- package/dist/core/diff/base-state.js.map +1 -1
- package/dist/core/diff/victims.js +10 -1
- package/dist/core/diff/victims.js.map +1 -1
- package/dist/core/docs.js +31 -22
- package/dist/core/docs.js.map +1 -1
- package/dist/core/doctor/config.js +7 -3
- package/dist/core/doctor/config.js.map +1 -1
- package/dist/core/doctor/doctor.js +48 -9
- package/dist/core/doctor/doctor.js.map +1 -1
- package/dist/core/doctor/report.js.map +1 -1
- package/dist/core/doctor/reports/scan.js +242 -0
- package/dist/core/doctor/reports/scan.js.map +1 -0
- package/dist/core/explain/families.js +1 -1
- package/dist/core/explain/families.js.map +1 -1
- package/dist/core/explain/refusals.js +1 -1
- package/dist/core/explain/refusals.js.map +1 -1
- package/dist/core/explore/explore.js +44 -9
- package/dist/core/explore/explore.js.map +1 -1
- package/dist/core/fleet-context.js +47 -0
- package/dist/core/fleet-context.js.map +1 -1
- package/dist/core/gate/partners.js +5 -9
- package/dist/core/gate/partners.js.map +1 -1
- package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
- package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
- package/dist/core/pack/living.js +47 -13
- package/dist/core/pack/living.js.map +1 -1
- package/dist/core/pack/pack.js +9 -6
- package/dist/core/pack/pack.js.map +1 -1
- package/dist/core/projection/arch-slice.js +2 -2
- package/dist/core/projection/arch-slice.js.map +1 -1
- package/dist/core/repo/paths.js +40 -0
- package/dist/core/repo/paths.js.map +1 -1
- package/dist/core/repo/tree/render/projects.js +182 -0
- package/dist/core/repo/tree/render/projects.js.map +1 -0
- package/dist/core/repo/tree/render/stale.js +2 -3
- package/dist/core/repo/tree/render/stale.js.map +1 -1
- package/dist/core/repo/tree/render/views.js +51 -3
- package/dist/core/repo/tree/render/views.js.map +1 -1
- package/dist/core/repo/tree/walk.js +45 -2
- package/dist/core/repo/tree/walk.js.map +1 -1
- package/dist/core/scaffold/landscape.js +219 -9
- package/dist/core/scaffold/landscape.js.map +1 -1
- package/dist/core/staging/writes.js.map +1 -1
- package/dist/core/usecases/delta/claims.js +1 -0
- package/dist/core/usecases/delta/claims.js.map +1 -1
- package/dist/core/usecases/delta/overlay.js +4 -0
- package/dist/core/usecases/delta/overlay.js.map +1 -1
- package/dist/core/usecases/fleet.js +18 -6
- package/dist/core/usecases/fleet.js.map +1 -1
- package/dist/core/usecases/operations.js +7 -0
- package/dist/core/usecases/operations.js.map +1 -1
- package/dist/core/usecases/service/exclude.js +119 -0
- package/dist/core/usecases/service/exclude.js.map +1 -0
- package/dist/core/usecases/service/flows.js +161 -0
- package/dist/core/usecases/service/flows.js.map +1 -0
- package/dist/core/vocabulary/maturity.js +10 -0
- package/dist/core/vocabulary/maturity.js.map +1 -1
- package/examples/README.md +23 -0
- package/examples/docs/architecture/landscape.likec4 +41 -0
- package/examples/docs/architecture/usecases/order-notification.likec4 +5 -2
- package/examples/docs/likec4.config.json +0 -1
- package/examples/docs/services/checkout-web/model.likec4 +39 -56
- package/examples/docs/services/order-service/arch.spec.md +13 -6
- package/examples/docs/services/order-service/model.likec4 +53 -67
- package/examples/docs/services/payment-service/arch.spec.md +7 -4
- package/examples/docs/services/payment-service/model.likec4 +32 -33
- package/examples/docs/services/platform/identity-service/arch.spec.md +7 -4
- package/examples/docs/services/platform/identity-service/model.likec4 +29 -33
- package/examples/docs/services/platform/notification-service/health.yaml +8 -3
- package/examples/docs/services/platform/notification-service/model.likec4 +39 -59
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-map.js","sourceRoot":"","sources":["../../../../src/core/agent/agents-md/command-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuB7B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B9B,CAAC;AAEF;;;GAGG;AACH,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BjB,CAAC;AAEF,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyJhB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,GAAG,cAAc,GAAG,QAAQ,CAAC","sourcesContent":["/**\n * Reading loam's output, in its two deliveries.\n *\n * {@link READING_OUTPUT} and {@link REFERENCE_PAGES} are what AGENTS.md keeps:\n * the `--json` envelope, the rule to branch on codes rather than prose, and the\n * index of the pages this file no longer carries. {@link CODE_MAP} is the\n * code-by-code map of `status`, `validate`, `doctor`, `rebase`, `dependencies`,\n * `explore`, `seed` and `instructions` — the part `loam instructions loam-codes`\n * prints. ../workflows/reference/codes.ts composes it with `./map/`,\n * `./map/lenses/` and `./refusals.ts`, in exactly the order ../agents-md.ts used\n * to concatenate them, so the assembled page is the section byte for byte.\n *\n * WHY THE MAP LEFT THE FILE, given that this package's whole subject is a file.\n * AGENTS.md is auto-loaded from the working directory by every agents.md-aware\n * host, on every session, and `loam init` writes it once and never refreshes it.\n * It reached 109,399 bytes; Codex truncates the AGENTS.md chain at 32,768 bytes\n * and Windsurf caps a workspace rule file at 12,000 characters, both silently.\n * Roughly seventy percent of the document was being dropped with no error and no\n * way for the reader to tell which half it held — and this section alone was\n * 44,433 of those bytes, 41% of the file. It is also the half a reader consults\n * at a moment it can name (a run reported something) rather than the half it\n * needs to form a question at all, which is what decided which side of the split\n * it went. ../workflows/reference/reference.ts carries the rest of that argument.\n *\n * The move is a move and not a deletion: every byte is still shipped, still in\n * the same corpus test/codes-drift.test.ts reads (AGENTS_MD + PROTOCOLS), and\n * still one command away rather than one file away.\n *\n * WHAT THE MAP IS, AND WHAT IT DELIBERATELY IS NOT. The unique content is which\n * codes which INVOCATION can raise: nothing else in the corpus says that, and an\n * agent choosing what to run needs it. What it does not carry is a per-code\n * gloss of what each code MEANS. That half used to be written twice — once here,\n * once in the /loam-check fix tables — in two independently worded places, in a\n * file `loam init` writes once and never refreshes, so the two drifted with\n * nothing able to say which had rotted. `loam explain <code>` now answers\n * meaning, severity and fix for every code named below, out of the running\n * binary. test/agent-contract.test.ts holds that pointer honest: every code\n * backticked in the corpus must resolve through `explainSubject`, so a family\n * added here without an explanation fails by name. Keep the code list; add the\n * gloss only where it says something `explain` cannot — a condition on when the\n * invocation raises it at all, or a cross-reference between two codes.\n *\n * ONE PARAGRAPH THE MOVE MADE FALSE, and the reason to look for others like it.\n * The `agents.stale` entry read \"one check on this very file … the reason to\n * distrust what you are reading\", which was true while these bytes WERE the\n * scaffolded AGENTS.md. On a page printed by the binary it is exactly backwards\n * — this page cannot be stale, and the file it warns about is somewhere else —\n * so the entry names AGENTS.md instead. A section that talks about its own\n * document does not survive being moved to another one; that is the class to\n * check for whenever anything else leaves this file.\n *\n * READING_OUTPUT and REFERENCE_PAGES are sections of the AGENTS.md template.\n * ../agents-md.ts assembles the document by PLAIN CONCATENATION — no join\n * separator — so every section starts at the first character of its opening line\n * and ends with the newline that closes its last one. Keep that shape when\n * editing, or two sections glue onto one line in every docs repo loam scaffolds\n * from now on. CODE_MAP owes the same shape for the same reason, one level up:\n * reference/codes.ts concatenates it with the modules listed above.\n */\nimport { STATUS_COMMAND } from \"./map/status.js\";\n\n/**\n * The section AGENTS.md keeps. Three facts an agent needs BEFORE it can form a\n * question — that every command speaks JSON, that the envelope survives a bad\n * invocation, and that codes are the contract and prose is not — plus the two\n * places the detail went.\n */\nexport const READING_OUTPUT = `## Reading loam's output\n\nEvery command takes \\`--json\\`, and the envelope holds even when the INVOCATION\nis wrong: with \\`--json\\` anywhere in the arguments, an unknown flag, unknown\ncommand or missing argument still yields \\`{ ok: false, error: { code:\n\"invalid-option\" } }\\` on stdout with exit 1 (commander's own diagnostic goes\nto stderr; \\`--help\\` and \\`--version\\` output pass through untouched). Without\n\\`--json\\` the same refusal is plain text on stderr with nothing on stdout.\n\nBranch on \\`findings[].code\\`, never on the prose — the wording changes, the codes do\nnot.\n\n**What a code MEANS is one command away**, and the answer describes the loam you\nare running rather than the one that scaffolded this repo. \\`loam explain <code>\\`\ngives one code's meaning, its severity in each scope that grades it, and its fix;\n\\`loam explain --codes\\` lists the whole vocabulary and \\`loam explain --codes --json\\`\nis the machine-readable form. Reach for it rather than for a generated pointer:\nthis page is printed by the binary that defines the codes.\n\n**Which codes an INVOCATION can raise** is the other half, and it is the one\nthing nothing else carries. It is a reference page rather than a section here:\n\\`loam instructions loam-codes\\`.\n\n`;\n\n/**\n * The index. A reference nobody can find is content deleted with extra steps,\n * so the exact command is spelled per page rather than described — and\n * test/agents.test.ts asserts that every name in REFERENCES appears here inside\n * its own `loam instructions` line, which is what makes a renamed page fail\n * loudly instead of leaving a pointer at nothing.\n */\nexport const REFERENCE_PAGES = `## The reference pages\n\nThis file is the orientation: the layout, the cycle, what gates and what only\nadvises, and what the words mean. Four things it does NOT carry — the grammars\nyou consult while writing ONE document, and the inventory of what each command\ncan report — are **reference pages**, printed by the binary rather than written\nhere. That is why: this file is auto-loaded on every session and never\nrefreshed, while a page out of the binary describes the loam you are actually\nrunning, and is read at the one moment it is needed.\n\n- \\`loam instructions loam-codes\\` — which codes each invocation can raise:\n \\`validate --service\\` / \\`--feature\\` / \\`--all\\`, \\`status\\`, \\`doctor\\`, \\`gate\\`,\n \\`context\\`, \\`diff\\`, \\`explore\\`, \\`dependencies\\`, \\`rebase\\`, \\`seed\\`, \\`subsystem\\`,\n \\`mcp\\`, the use-case views, the containment refusals, the error envelope, and\n the OpenSpec migration surface.\n- \\`loam instructions loam-spine\\` — the ID spine: every join between the\n artifacts (\\`operationId\\`, message name, \\`Covers:\\`, \\`Requires:\\`,\n \\`Capability:\\`, \\`Realizes:\\`), the \\`Based-On:\\` baseline pins on both the\n requirement and the contract axis, how to draw a shared broker, and how to\n declare a message produced outside the fleet.\n- \\`loam instructions loam-authoring\\` — the grammars you author against:\n the architecture spec axis (\\`arch.spec.md\\` and its \\`Covers:\\` line), the\n generated Gherkin suite, and frontmatter with the vouch chain behind it.\n- \\`loam instructions loam-done-check\\` — the done-check: how \\`loam verify\\`\n derives its claims, the three channels that may answer them, the federated\n recording form, and what separates **verified** from **attested**.\n\nEach takes no arguments and prints whole. \\`loam instructions\\` with no argument\nlists them beside the six workflow protocols; \\`loam explain <code>\\` answers any\nsingle code without opening a page at all.\n\n`;\n\n/**\n * The reference page's own opening: what the map is, where the /loam-check fix\n * tables sit beside it, and the one family `loam explain` cannot answer.\n */\nconst MAP_INTRO = `**What this page is.** It says which codes an INVOCATION can raise. It does\nNOT say what they mean: that half is one command away and describes the loam you\nare running rather than the one that scaffolded this repo. \\`loam explain <code>\\`\ngives one code's meaning, its severity in each scope that grades it, and its fix;\n\\`loam explain --codes\\` lists the whole vocabulary and \\`loam explain --codes --json\\`\nis the machine-readable form. The one family \\`explain\\` does not answer\nis the OpenSpec migration surface (\\`openspec.*\\`, \\`mapping.*\\`) — those commands run\nbefore a repository has a governed loop to look a code up from — so those entries\nalone keep their notes here.\n\nThe code-by-code fix table is a different document again: it lives in the\n\\`/loam-check\\` command \\`loam init\\` lays\ndown. \\`init\\` writes that body twice for every tool it configures: once as a slash\ncommand in the tool's own command directory (you type it), and once as an Agent\nSkill at \\`<tool-dir>/skills/loam-check/SKILL.md\\` (the model loads it by itself when\nthe task matches the skill's description). Same body, two ways in.\n\nWhich tools get them is detected from the repo: \\`loam init\\` scans for the\ndot-directories of the tools it knows (\\`.claude\\`, \\`.cursor\\`, \\`.gemini\\`, …) and\nwrites for the ones it finds, falling back to Claude Code when it finds none.\n\\`loam init --tools <ids|all>\\` overrides the scan — an unknown id is refused\n(\\`invalid-option\\`) rather than skipped — and \\`--no-commands\\` / \\`--no-skills\\`\neach suppress one delivery. The tools written for are recorded in\n\\`loam.json\\` as \\`agentTools\\`, which is how \\`loam doctor\\` tells a file missing\nbecause the binary grew a new command from one missing because nobody ever\nselected that tool.\n\nThe map:\n\n`;\n\nconst MAP_REST = `- \\`loam validate --service <id>\\` grades one service's own axes: \\`service.unknown\\`,\n \\`service.no-model\\`, \\`service.no-spec\\`, \\`service.no-openapi\\`, \\`c4.invalid\\`,\n \\`c4.no-relationships\\`, \\`requirements.missing-scenarios\\`,\n \\`requirements.stepless-scenario\\`, \\`requirements.assertionless-scenario\\`,\n \\`requirements.examples-unbound\\`, \\`requirements.examples-unreferenced\\`,\n \\`spec.merge-conflict\\`, \\`spec.duplicate-requirement\\`, \\`spec.no-requirements\\`,\n \\`spec.repeated-operations\\`, \\`spec.repeated-covers\\`, \\`openapi.invalid\\`,\n \\`openapi.duplicate-operationid\\`, \\`openapi.response-undescribed\\`,\n \\`openapi.ref-unresolved\\`, \\`api.ungoverned\\`, \\`api.ops-unlinked\\`,\n \\`api.requirement-deprecated\\`, \\`spec-api.op-undefined\\`,\n \\`spine.landscape-invalid\\`, \\`spine.op-undefined\\`, \\`spine.op-link-missing\\`,\n \\`spine.op-deprecated\\`; the async contract axis (AsyncAPI 3):\n \\`service.no-asyncapi\\`, \\`asyncapi.invalid\\`, \\`asyncapi.duplicate-message\\`,\n \\`asyncapi.payload-undescribed\\`, \\`asyncapi.ref-unresolved\\`,\n \\`spine.message-undefined\\`, \\`spec-event.message-undefined\\`,\n \\`spine.message-unproduced\\`, \\`spine.message-external\\`,\n \\`asyncapi.message-contested\\`, \\`event.messages-unlinked\\`, \\`event.ungoverned\\`,\n \\`event.covered\\`; and the architecture spec axis: \\`covers.unknown\\`,\n \\`health.invalid\\`, \\`health.uncovered\\`, \\`health.dependency-unmodelled\\`.\n Run inside the service's own repo, once a generated suite exists under\n \\`<gherkinDir>/loam/\\`, it also grades that suite against the living specs:\n \\`gherkin.missing\\`, \\`gherkin.stale\\`, \\`gherkin.orphaned\\`. A service that never\n ran \\`loam gherkin\\` stays quiet — that whole trio is conditional on the suite\n existing here — and a file tagged with a feature still in flight answers to\n that feature, not to the living spec it has not merged into yet.\n- \\`loam validate --feature <id>\\` grades a change's three axes against each other and\n against the fleet in flight: \\`delta.invalid\\`, \\`delta.nothing-tagged\\`,\n \\`delta.service-unknown\\`, \\`delta.service-id-invalid\\`, \\`spec-api.op-undefined\\`,\n \\`spec-api.op-pending\\`, \\`c4-api.op-undefined\\`, \\`c4-api.op-pending\\`,\n \\`c4-api.op-deprecated\\`, \\`c4.op-ungoverned\\`, \\`c4.op-link-missing\\`,\n \\`c4.service-binding-invalid\\`, \\`api.op-unconsumed\\`,\n \\`service.no-requirement-delta\\`, \\`archedge.uncovered\\`, and — the same four\n codes service scope raises, graded here on the feature's own spec.md and\n arch.spec.md deltas, because every one of those breaches merges into the\n living document — \\`spec.repeated-operations\\`, \\`spec.repeated-covers\\`,\n \\`spec.merge-conflict\\` and \\`requirements.stepless-scenario\\`. Then the\n architecture spec axis (\\`c4.uncovered\\`, plus \\`covers.unknown\\` on the\n feature's arch.spec.md deltas), the delta-shape group:\n \\`delta.unknown-section\\`, \\`delta.no-delta-sections\\`,\n \\`delta.requirement-not-merged\\`, \\`delta.modified-unknown\\`, \\`delta.removed-unknown\\`,\n \\`delta.added-duplicate\\`, \\`delta.added-near-duplicate\\`, \\`delta.modified-pending\\`,\n \\`delta.removed-pending\\`, \\`delta.added-conflict\\`, \\`delta.modified-conflict\\`,\n \\`delta.living-duplicate-requirement\\`, and the API-removal group:\n \\`openapi.remove-marker-anonymous\\`, \\`openapi.remove-op-consumed\\`.\n The event axis is graded in feature scope too — the \\`asyncapi.*\\`\n baseline/removal/conflict codes plus \\`c4-event.*\\` and \\`spec-event.*\\`.\n Where a finding names another feature in flight (\\`delta.*-pending\\`,\n \\`delta.added-conflict\\`, \\`delta.modified-conflict\\`, \\`spec-api.op-pending\\`,\n \\`c4-api.op-pending\\`) the ORDER is the answer, and \\`loam dependencies --json\\`\n is what computes it: \\`order\\` is a dependency-first sequence, \\`conflicts\\`\n the pairs no ordering fixes, \\`cycles\\` the ones that need a human.\n- \\`loam validate --all\\` runs both of those for everything and adds the fleet\n cross-check: \\`landscape.missing\\`, \\`landscape.invalid\\`,\n \\`landscape.merge-conflict\\`, \\`landscape.service-unmodelled\\`,\n \\`landscape.service-undocumented\\`, \\`landscape.binding-unknown\\`,\n \\`landscape.binding-duplicate\\`, the fleet-shape advisories\n \\`landscape.platform-candidate\\`, \\`landscape.datastore-private\\` and\n \\`landscape.datastore-shared\\`, \\`service.id-invalid\\` (fleet scope only, and\n graded before the map is opened, so it stands even when the landscape is\n missing or unreadable), a per-service \\`sources.unverifiable-from-here\\`, and\n one check on the docs repo's own AGENTS.md, \\`agents.stale\\`. That last one is\n the reason to distrust THAT file rather than this page: it fires when its\n version stamp on line 1 (\\`<!-- generated by loam vX.Y.Z -->\\`) is missing or\n older than the running binary, which is exactly when what it says may name a\n loam that no longer exists. It is never refreshed automatically — your edits\n outrank the template, so detection is all loam does, and a hand-curated file\n silences it the same way, by keeping the stamp current. This page has no such\n failure mode: it is printed by the binary it describes.\n \\`loam validate --all\\`'s \\`--json\\` payload also carries the additive \\`scorecard\\` key — per-axis ceiling-vs-actual fleet\n aggregates, the text report appending the same table; derived per run and never stored, so week-over-week is the pipeline's job: capture the key per run into a metrics store.\n \\`scorecard.adoption\\` counts the services PARTICIPATING in each contract axis\n (requirements, arch, openapi, asyncapi, permissions, capabilities; the\n denominator is \\`scorecard.services\\`) — an axis at 0 of N reads \"not started\",\n which is expected during staged adoption and distinct from partially adopted.\n Text mode folds the warnings such an axis alone causes under one banner per\n axis and says so; \\`--json\\` carries every finding unchanged, and the summary\n counts, exit codes and \\`--strict\\` are identical either way.\n- \\`loam doctor\\` is read-only local/fleet preflight — the first thing to run in a\n repo that behaves as though the fleet were empty. Every finding carries a\n \\`fix\\` field naming the exact command or edit, so this is the one family you\n rarely need \\`loam explain\\` for. Its blockers are \\`doctor.config-missing\\`,\n \\`doctor.config-invalid\\`, \\`doctor.docs-missing\\`, \\`doctor.services-missing\\`, and\n the three that say the fleet map cannot be read at all —\n \\`doctor.landscape-merge-conflict\\`, \\`doctor.landscape-invalid\\` and\n \\`doctor.landscape-unreadable\\`. It also grades what a WRITE that did not finish\n left in the docs repo, reported as \\`writePath\\` beside the findings:\n \\`doctor.docs-locked\\`, \\`doctor.commit-interrupted\\`, \\`doctor.commit-unreadable\\`\n and \\`doctor.staging-temps\\`. When this repo is a service repo that same scan\n covers \\`<gherkinDir>/loam/\\`, the root \\`loam gherkin\\` commits into.\n Accessibility, portability and incomplete binding stay warnings:\n \\`doctor.docs-unreadable\\`, \\`doctor.docs-readonly\\`, \\`doctor.docs-absolute\\`,\n \\`doctor.inventory-unreadable\\`, \\`doctor.landscape-missing\\`,\n \\`doctor.service-unbound\\` (never raised inside the docs repo itself, where\n having no service binding is the correct state), \\`doctor.service-unknown\\`\n (the same state \\`loam status\\` reports as \\`next.adopt-bound\\`),\n \\`doctor.likec4-config-missing\\`, and the two about this repo's own generated\n command and skill files: \\`doctor.agent-files-missing\\` and\n \\`doctor.agent-files-stale\\`.\n EXPECT the second one on the first \\`loam doctor\\` after an upgrade. It is not\n evidence that anything was edited or broken: staleness reads the version\n stamp only. Re-running \\`loam init\\` refreshes an unchanged pointer only when\n its current bytes still match the digest recorded in \\`loam.json\\`; an\n unrecorded or customized file stays in place for a human to review.\n- \\`loam rebase <FEAT>\\` writes the baseline pins: \\`Based-On:\\` under every\n MODIFIED/REMOVED requirement in the feature's spec deltas, and\n \\`x-loam-based-on\\` on every operation in its openapi.yaml, from the living text\n as it stands right now. Run it when you finish authoring a delta and again\n after you resolve a collision — it is the one mechanism standing between two\n features in flight and silently reverting each other's landed work. It refuses\n rather than inventing a pin, and re-pinning is not resolving: see\n \"The requirement baseline\".\n- \\`loam dependencies [<FEAT>]\\` derives the ordering of the features in flight\n from the artifacts themselves — requirement identities and OpenAPI\n operationIds, never from validator prose. It is the answer to every\n \"another feature in flight does this first\" finding, and to\n \\`delta.added-conflict\\` / \\`delta.modified-conflict\\`, which no ordering fixes.\n- \\`loam explore [<service>...]\\` reads the fleet around a change nobody has\n written down yet, and writes nothing. It exists because \\`loam new\\`'s\n \\`--touches\\` list is the hardest call in the cycle and the only one nothing\n downstream catches: a list short by one service produces a feature that\n validates, archives and ships with a consumer nobody updated. What it derives\n is mechanical — the one-hop ring, each service's rung, its living operations,\n who already calls whom, and which active features cover the same services. It\n does NOT decide which of those neighbours you actually change; that is a\n judgement about intent, and loam does not make those. \\`--op <operationId>\\`\n seeds from the operation's defining service; \\`--capability <id>\\` (repeatable)\n seeds from a declared capability's realizing services, and an id that seeds\n nothing lands in the additive \\`unresolvedCapabilities\\` — beside\n \\`loam list capabilities\\`, the rollup those seeds are read from.\n- \\`loam seed --from fleet.yaml\\` is the onboarding entry point for an empty\n fleet: a tiny human-authored YAML — a \\`services:\\` list of ids, optional\n \\`subsystems:\\`, \\`externals:\\` and \\`calls:\\` lines like\n \\`checkout -> payments\\` — templated mechanically into\n architecture/landscape.likec4 (one bound element per service, plain edges, no\n guessed operationIds) plus one services/<id>/ directory per service, in one\n journaled transaction. Not an extractor: the human stated every fact, and\n \"who calls whom\" is the one thing no generator can read off a repository.\n The seeded landscape carries a line-1 stamp; while it stands unedited,\n editing fleet.yaml and re-running regenerates the map, and the first hand\n edit makes the file yours — seed then refuses \\`seed-landscape-edited\\`\n rather than overwrite. Then adopt each service: \\`loam adopt --service <id>\\`.\n- \\`loam instructions [<page>] [args...]\\` prints one of the six workflow\n protocols — \\`loam-adopt\\`, \\`loam-feature\\`, \\`loam-implement\\`, \\`loam-check\\`,\n \\`loam-verify\\`, \\`loam-ship\\` — with \\`$1\\`, \\`$2\\` filled in from the arguments you\n pass, or one of the four reference pages — \\`loam-codes\\`, \\`loam-spine\\`,\n \\`loam-authoring\\`, \\`loam-done-check\\` — which take no arguments. With no\n argument at all it lists both sets. The pages ship inside the binary, so they\n describe the loam you are about to run rather than the one that scaffolded the\n repository; the command and skill files \\`loam init\\` writes are pointers at it,\n and so is AGENTS.md's own \"The reference pages\" section. It reads no\n \\`loam.json\\` and no docs repo, deliberately: \\`loam-adopt\\`'s own first step is\n to run \\`loam init\\` when there is no config, so it cannot be the step that\n requires one.\n`;\n\n/**\n * The reference page's body, up to the modules that continue it. The bullets\n * are ordered so `status` — the orientation command, the one to run when you\n * have lost the session — is read first.\n */\nexport const CODE_MAP = MAP_INTRO + STATUS_COMMAND + MAP_REST;\n"]}
|
|
1
|
+
{"version":3,"file":"command-map.js","sourceRoot":"","sources":["../../../../src/core/agent/agents-md/command-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;CAuB7B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B9B,CAAC;AAEF;;;GAGG;AACH,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BjB,CAAC;AAEF,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyKhB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,GAAG,cAAc,GAAG,QAAQ,CAAC","sourcesContent":["/**\n * Reading loam's output, in its two deliveries.\n *\n * {@link READING_OUTPUT} and {@link REFERENCE_PAGES} are what AGENTS.md keeps:\n * the `--json` envelope, the rule to branch on codes rather than prose, and the\n * index of the pages this file no longer carries. {@link CODE_MAP} is the\n * code-by-code map of `status`, `validate`, `doctor`, `rebase`, `dependencies`,\n * `explore`, `seed` and `instructions` — the part `loam instructions loam-codes`\n * prints. ../workflows/reference/codes.ts composes it with `./map/`,\n * `./map/lenses/` and `./refusals.ts`, in exactly the order ../agents-md.ts used\n * to concatenate them, so the assembled page is the section byte for byte.\n *\n * WHY THE MAP LEFT THE FILE, given that this package's whole subject is a file.\n * AGENTS.md is auto-loaded from the working directory by every agents.md-aware\n * host, on every session, and `loam init` writes it once and never refreshes it.\n * It reached 109,399 bytes; Codex truncates the AGENTS.md chain at 32,768 bytes\n * and Windsurf caps a workspace rule file at 12,000 characters, both silently.\n * Roughly seventy percent of the document was being dropped with no error and no\n * way for the reader to tell which half it held — and this section alone was\n * 44,433 of those bytes, 41% of the file. It is also the half a reader consults\n * at a moment it can name (a run reported something) rather than the half it\n * needs to form a question at all, which is what decided which side of the split\n * it went. ../workflows/reference/reference.ts carries the rest of that argument.\n *\n * The move is a move and not a deletion: every byte is still shipped, still in\n * the same corpus test/codes-drift.test.ts reads (AGENTS_MD + PROTOCOLS), and\n * still one command away rather than one file away.\n *\n * WHAT THE MAP IS, AND WHAT IT DELIBERATELY IS NOT. The unique content is which\n * codes which INVOCATION can raise: nothing else in the corpus says that, and an\n * agent choosing what to run needs it. What it does not carry is a per-code\n * gloss of what each code MEANS. That half used to be written twice — once here,\n * once in the /loam-check fix tables — in two independently worded places, in a\n * file `loam init` writes once and never refreshes, so the two drifted with\n * nothing able to say which had rotted. `loam explain <code>` now answers\n * meaning, severity and fix for every code named below, out of the running\n * binary. test/agent-contract.test.ts holds that pointer honest: every code\n * backticked in the corpus must resolve through `explainSubject`, so a family\n * added here without an explanation fails by name. Keep the code list; add the\n * gloss only where it says something `explain` cannot — a condition on when the\n * invocation raises it at all, or a cross-reference between two codes.\n *\n * ONE PARAGRAPH THE MOVE MADE FALSE, and the reason to look for others like it.\n * The `agents.stale` entry read \"one check on this very file … the reason to\n * distrust what you are reading\", which was true while these bytes WERE the\n * scaffolded AGENTS.md. On a page printed by the binary it is exactly backwards\n * — this page cannot be stale, and the file it warns about is somewhere else —\n * so the entry names AGENTS.md instead. A section that talks about its own\n * document does not survive being moved to another one; that is the class to\n * check for whenever anything else leaves this file.\n *\n * READING_OUTPUT and REFERENCE_PAGES are sections of the AGENTS.md template.\n * ../agents-md.ts assembles the document by PLAIN CONCATENATION — no join\n * separator — so every section starts at the first character of its opening line\n * and ends with the newline that closes its last one. Keep that shape when\n * editing, or two sections glue onto one line in every docs repo loam scaffolds\n * from now on. CODE_MAP owes the same shape for the same reason, one level up:\n * reference/codes.ts concatenates it with the modules listed above.\n */\nimport { STATUS_COMMAND } from \"./map/status.js\";\n\n/**\n * The section AGENTS.md keeps. Three facts an agent needs BEFORE it can form a\n * question — that every command speaks JSON, that the envelope survives a bad\n * invocation, and that codes are the contract and prose is not — plus the two\n * places the detail went.\n */\nexport const READING_OUTPUT = `## Reading loam's output\n\nEvery command takes \\`--json\\`, and the envelope holds even when the INVOCATION\nis wrong: with \\`--json\\` anywhere in the arguments, an unknown flag, unknown\ncommand or missing argument still yields \\`{ ok: false, error: { code:\n\"invalid-option\" } }\\` on stdout with exit 1 (commander's own diagnostic goes\nto stderr; \\`--help\\` and \\`--version\\` output pass through untouched). Without\n\\`--json\\` the same refusal is plain text on stderr with nothing on stdout.\n\nBranch on \\`findings[].code\\`, never on the prose — the wording changes, the codes do\nnot.\n\n**What a code MEANS is one command away**, and the answer describes the loam you\nare running rather than the one that scaffolded this repo. \\`loam explain <code>\\`\ngives one code's meaning, its severity in each scope that grades it, and its fix;\n\\`loam explain --codes\\` lists the whole vocabulary and \\`loam explain --codes --json\\`\nis the machine-readable form. Reach for it rather than for a generated pointer:\nthis page is printed by the binary that defines the codes.\n\n**Which codes an INVOCATION can raise** is the other half, and it is the one\nthing nothing else carries. It is a reference page rather than a section here:\n\\`loam instructions loam-codes\\`.\n\n`;\n\n/**\n * The index. A reference nobody can find is content deleted with extra steps,\n * so the exact command is spelled per page rather than described — and\n * test/agents.test.ts asserts that every name in REFERENCES appears here inside\n * its own `loam instructions` line, which is what makes a renamed page fail\n * loudly instead of leaving a pointer at nothing.\n */\nexport const REFERENCE_PAGES = `## The reference pages\n\nThis file is the orientation: the layout, the cycle, what gates and what only\nadvises, and what the words mean. Four things it does NOT carry — the grammars\nyou consult while writing ONE document, and the inventory of what each command\ncan report — are **reference pages**, printed by the binary rather than written\nhere. That is why: this file is auto-loaded on every session and never\nrefreshed, while a page out of the binary describes the loam you are actually\nrunning, and is read at the one moment it is needed.\n\n- \\`loam instructions loam-codes\\` — which codes each invocation can raise:\n \\`validate --service\\` / \\`--feature\\` / \\`--all\\`, \\`status\\`, \\`doctor\\`, \\`gate\\`,\n \\`context\\`, \\`diff\\`, \\`explore\\`, \\`dependencies\\`, \\`rebase\\`, \\`seed\\`, \\`subsystem\\`,\n \\`mcp\\`, the use-case views, the containment refusals, the error envelope, and\n the OpenSpec migration surface.\n- \\`loam instructions loam-spine\\` — the ID spine: every join between the\n artifacts (\\`operationId\\`, message name, \\`Covers:\\`, \\`Requires:\\`,\n \\`Capability:\\`, \\`Realizes:\\`), the \\`Based-On:\\` baseline pins on both the\n requirement and the contract axis, how to draw a shared broker, and how to\n declare a message produced outside the fleet.\n- \\`loam instructions loam-authoring\\` — the grammars you author against:\n the architecture spec axis (\\`arch.spec.md\\` and its \\`Covers:\\` line), the\n generated Gherkin suite, and frontmatter with the vouch chain behind it.\n- \\`loam instructions loam-done-check\\` — the done-check: how \\`loam verify\\`\n derives its claims, the three channels that may answer them, the federated\n recording form, and what separates **verified** from **attested**.\n\nEach takes no arguments and prints whole. \\`loam instructions\\` with no argument\nlists them beside the six workflow protocols; \\`loam explain <code>\\` answers any\nsingle code without opening a page at all.\n\n`;\n\n/**\n * The reference page's own opening: what the map is, where the /loam-check fix\n * tables sit beside it, and the one family `loam explain` cannot answer.\n */\nconst MAP_INTRO = `**What this page is.** It says which codes an INVOCATION can raise. It does\nNOT say what they mean: that half is one command away and describes the loam you\nare running rather than the one that scaffolded this repo. \\`loam explain <code>\\`\ngives one code's meaning, its severity in each scope that grades it, and its fix;\n\\`loam explain --codes\\` lists the whole vocabulary and \\`loam explain --codes --json\\`\nis the machine-readable form. The one family \\`explain\\` does not answer\nis the OpenSpec migration surface (\\`openspec.*\\`, \\`mapping.*\\`) — those commands run\nbefore a repository has a governed loop to look a code up from — so those entries\nalone keep their notes here.\n\nThe code-by-code fix table is a different document again: it lives in the\n\\`/loam-check\\` command \\`loam init\\` lays\ndown. \\`init\\` writes that body twice for every tool it configures: once as a slash\ncommand in the tool's own command directory (you type it), and once as an Agent\nSkill at \\`<tool-dir>/skills/loam-check/SKILL.md\\` (the model loads it by itself when\nthe task matches the skill's description). Same body, two ways in.\n\nWhich tools get them is detected from the repo: \\`loam init\\` scans for the\ndot-directories of the tools it knows (\\`.claude\\`, \\`.cursor\\`, \\`.gemini\\`, …) and\nwrites for the ones it finds, falling back to Claude Code when it finds none.\n\\`loam init --tools <ids|all>\\` overrides the scan — an unknown id is refused\n(\\`invalid-option\\`) rather than skipped — and \\`--no-commands\\` / \\`--no-skills\\`\neach suppress one delivery. The tools written for are recorded in\n\\`loam.json\\` as \\`agentTools\\`, which is how \\`loam doctor\\` tells a file missing\nbecause the binary grew a new command from one missing because nobody ever\nselected that tool.\n\nThe map:\n\n`;\n\nconst MAP_REST = `- \\`loam validate --service <id>\\` grades one service's own axes: \\`service.unknown\\`,\n \\`service.no-model\\`, \\`service.no-spec\\`, \\`service.no-openapi\\`, \\`c4.invalid\\`,\n \\`c4.declaration-diverged\\`, \\`c4.element-unowned\\`,\n \\`c4.no-relationships\\`, \\`requirements.missing-scenarios\\`,\n \\`requirements.stepless-scenario\\`, \\`requirements.assertionless-scenario\\`,\n \\`requirements.examples-unbound\\`, \\`requirements.examples-unreferenced\\`,\n \\`spec.merge-conflict\\`, \\`spec.duplicate-requirement\\`, \\`spec.no-requirements\\`,\n \\`spec.repeated-operations\\`, \\`spec.repeated-covers\\`, \\`openapi.invalid\\`,\n \\`openapi.duplicate-operationid\\`, \\`openapi.response-undescribed\\`,\n \\`openapi.ref-unresolved\\`, \\`api.ungoverned\\`, \\`api.ops-unlinked\\`,\n \\`api.requirement-deprecated\\`, \\`spec-api.op-undefined\\`,\n \\`spine.landscape-invalid\\`, \\`spine.op-undefined\\`, \\`spine.op-link-missing\\`,\n \\`spine.op-deprecated\\`; the async contract axis (AsyncAPI 3):\n \\`service.no-asyncapi\\`, \\`asyncapi.invalid\\`, \\`asyncapi.duplicate-message\\`,\n \\`asyncapi.payload-undescribed\\`, \\`asyncapi.ref-unresolved\\`,\n \\`spine.message-undefined\\`, \\`spec-event.message-undefined\\`,\n \\`spine.message-unproduced\\`, \\`spine.message-external\\`,\n \\`asyncapi.message-contested\\`, \\`event.messages-unlinked\\`, \\`event.ungoverned\\`,\n \\`event.covered\\`; and the architecture spec axis: \\`covers.unknown\\`,\n \\`health.invalid\\`, \\`health.uncovered\\`, \\`health.dependency-unmodelled\\`.\n Run inside the service's own repo, once a generated suite exists under\n \\`<gherkinDir>/loam/\\`, it also grades that suite against the living specs:\n \\`gherkin.missing\\`, \\`gherkin.stale\\`, \\`gherkin.orphaned\\`. A service that never\n ran \\`loam gherkin\\` stays quiet — that whole trio is conditional on the suite\n existing here — and a file tagged with a feature still in flight answers to\n that feature, not to the living spec it has not merged into yet.\n- \\`loam validate --feature <id>\\` grades a change's three axes against each other and\n against the fleet in flight: \\`delta.invalid\\`, \\`delta.nothing-tagged\\`,\n \\`delta.service-unknown\\`, \\`delta.service-id-invalid\\`, \\`spec-api.op-undefined\\`,\n \\`spec-api.op-pending\\`, \\`c4-api.op-undefined\\`, \\`c4-api.op-pending\\`,\n \\`c4-api.op-deprecated\\`, \\`c4.op-ungoverned\\`, \\`c4.op-link-missing\\`,\n \\`c4.service-binding-invalid\\`, \\`api.op-unconsumed\\`,\n \\`service.no-requirement-delta\\`, \\`archedge.uncovered\\`, and — the same four\n codes service scope raises, graded here on the feature's own spec.md and\n arch.spec.md deltas, because every one of those breaches merges into the\n living document — \\`spec.repeated-operations\\`, \\`spec.repeated-covers\\`,\n \\`spec.merge-conflict\\` and \\`requirements.stepless-scenario\\`. Then the\n architecture spec axis (\\`c4.uncovered\\`, plus \\`covers.unknown\\` on the\n feature's arch.spec.md deltas), the delta-shape group:\n \\`delta.unknown-section\\`, \\`delta.no-delta-sections\\`,\n \\`delta.requirement-not-merged\\`, \\`delta.modified-unknown\\`, \\`delta.removed-unknown\\`,\n \\`delta.added-duplicate\\`, \\`delta.added-near-duplicate\\`, \\`delta.modified-pending\\`,\n \\`delta.removed-pending\\`, \\`delta.added-conflict\\`, \\`delta.modified-conflict\\`,\n \\`delta.living-duplicate-requirement\\`, and the API-removal group:\n \\`openapi.remove-marker-anonymous\\`, \\`openapi.remove-op-consumed\\`.\n The event axis is graded in feature scope too — the \\`asyncapi.*\\`\n baseline/removal/conflict codes plus \\`c4-event.*\\` and \\`spec-event.*\\`.\n Where a finding names another feature in flight (\\`delta.*-pending\\`,\n \\`delta.added-conflict\\`, \\`delta.modified-conflict\\`, \\`spec-api.op-pending\\`,\n \\`c4-api.op-pending\\`) the ORDER is the answer, and \\`loam dependencies --json\\`\n is what computes it: \\`order\\` is a dependency-first sequence, \\`conflicts\\`\n the pairs no ordering fixes, \\`cycles\\` the ones that need a human.\n- \\`loam validate --all\\` runs both of those for everything and adds the fleet\n cross-check: \\`landscape.missing\\`, \\`landscape.invalid\\`,\n \\`landscape.merge-conflict\\`, \\`landscape.service-unmodelled\\`,\n \\`landscape.service-undocumented\\`, \\`landscape.binding-unknown\\`,\n \\`landscape.binding-duplicate\\`, the fleet-shape advisories\n \\`landscape.platform-candidate\\`, \\`landscape.datastore-private\\` and\n \\`landscape.datastore-shared\\`, \\`service.id-invalid\\` (fleet scope only, and\n graded before the map is opened, so it stands even when the landscape is\n missing or unreadable), the four renderer-wiring warnings a\n \\`loam subsystem sync\\` repairs — \\`service.likec4-config-missing\\` (a model that\n STANDS ALONE, declaring its own \\`specification\\`, with no\n \\`likec4.config.json\\` beside it: it renders nowhere from the docs root),\n \\`service.likec4-config-stray\\` (that file beside a model that EXTENDS the map,\n where it registers a project that CLAIMS the model, out of the root project\n where the map's kinds are),\n \\`service.model-excluded\\` (the root \\`likec4.config.json\\` excludes an extending\n model's directory, so the renderer never loads it) and\n \\`service.model-unexcluded\\` (it does NOT exclude a standalone model's, so the\n renderer merges that model into the map and calls every declaration a\n duplicate) — plus \\`c4.fleet-project-invalid\\` (warn: every document reads clean\n where loam grades it and the ONE project the renderer builds out of the map and\n every extending model does not, because something is declared in two of them),\n a per-service \\`sources.unverifiable-from-here\\`, and\n one check on the docs repo's own AGENTS.md, \\`agents.stale\\`. That last one is\n the reason to distrust THAT file rather than this page: it fires when its\n version stamp on line 1 (\\`<!-- generated by loam vX.Y.Z -->\\`) is missing or\n older than the running binary, which is exactly when what it says may name a\n loam that no longer exists. It is never refreshed automatically — your edits\n outrank the template, so detection is all loam does, and a hand-curated file\n silences it the same way, by keeping the stamp current. This page has no such\n failure mode: it is printed by the binary it describes.\n \\`loam validate --all\\`'s \\`--json\\` payload also carries the additive \\`scorecard\\` key — per-axis ceiling-vs-actual fleet\n aggregates, the text report appending the same table; derived per run and never stored, so week-over-week is the pipeline's job: capture the key per run into a metrics store.\n \\`scorecard.adoption\\` counts the services PARTICIPATING in each contract axis\n (requirements, arch, openapi, asyncapi, permissions, capabilities; the\n denominator is \\`scorecard.services\\`) — an axis at 0 of N reads \"not started\",\n which is expected during staged adoption and distinct from partially adopted.\n Text mode folds the warnings such an axis alone causes under one banner per\n axis and says so; \\`--json\\` carries every finding unchanged, and the summary\n counts, exit codes and \\`--strict\\` are identical either way.\n- \\`loam doctor\\` is read-only local/fleet preflight — the first thing to run in a\n repo that behaves as though the fleet were empty. Every finding carries a\n \\`fix\\` field naming the exact command or edit, so this is the one family you\n rarely need \\`loam explain\\` for. Its blockers are \\`doctor.config-missing\\`,\n \\`doctor.config-invalid\\`, \\`doctor.docs-missing\\`, \\`doctor.services-missing\\`, and\n the three that say the fleet map cannot be read at all —\n \\`doctor.landscape-merge-conflict\\`, \\`doctor.landscape-invalid\\` and\n \\`doctor.landscape-unreadable\\`. It also grades what a WRITE that did not finish\n left in the docs repo, reported as \\`writePath\\` beside the findings:\n \\`doctor.docs-locked\\`, \\`doctor.commit-interrupted\\`, \\`doctor.commit-unreadable\\`\n and \\`doctor.staging-temps\\`. When this repo is a service repo that same scan\n covers \\`<gherkinDir>/loam/\\`, the root \\`loam gherkin\\` commits into.\n Accessibility, portability and incomplete binding stay warnings:\n \\`doctor.docs-unreadable\\`, \\`doctor.docs-readonly\\`, \\`doctor.docs-absolute\\`,\n \\`doctor.inventory-unreadable\\`, \\`doctor.landscape-missing\\`,\n \\`doctor.service-unbound\\` (never raised inside the docs repo itself, where\n having no service binding is the correct state), \\`doctor.service-unknown\\`\n (the same state \\`loam status\\` reports as \\`next.adopt-bound\\`),\n \\`doctor.likec4-config-missing\\`, and the two about this repo's own generated\n command and skill files: \\`doctor.agent-files-missing\\` and\n \\`doctor.agent-files-stale\\`.\n EXPECT the second one on the first \\`loam doctor\\` after an upgrade. It is not\n evidence that anything was edited or broken: staleness reads the version\n stamp only. Re-running \\`loam init\\` refreshes an unchanged pointer only when\n its current bytes still match the digest recorded in \\`loam.json\\`; an\n unrecorded or customized file stays in place for a human to review.\n- \\`loam rebase <FEAT>\\` writes the baseline pins: \\`Based-On:\\` under every\n MODIFIED/REMOVED requirement in the feature's spec deltas, and\n \\`x-loam-based-on\\` on every operation in its openapi.yaml, from the living text\n as it stands right now. Run it when you finish authoring a delta and again\n after you resolve a collision — it is the one mechanism standing between two\n features in flight and silently reverting each other's landed work. It refuses\n rather than inventing a pin, and re-pinning is not resolving: see\n \"The requirement baseline\".\n- \\`loam dependencies [<FEAT>]\\` derives the ordering of the features in flight\n from the artifacts themselves — requirement identities and OpenAPI\n operationIds, never from validator prose. It is the answer to every\n \"another feature in flight does this first\" finding, and to\n \\`delta.added-conflict\\` / \\`delta.modified-conflict\\`, which no ordering fixes.\n- \\`loam explore [<service>...]\\` reads the fleet around a change nobody has\n written down yet, and writes nothing. It exists because \\`loam new\\`'s\n \\`--touches\\` list is the hardest call in the cycle and the only one nothing\n downstream catches: a list short by one service produces a feature that\n validates, archives and ships with a consumer nobody updated. What it derives\n is mechanical — the one-hop ring, each service's rung, its living operations,\n who already calls whom, and which active features cover the same services. It\n does NOT decide which of those neighbours you actually change; that is a\n judgement about intent, and loam does not make those. \\`--op <operationId>\\`\n seeds from the operation's defining service; \\`--capability <id>\\` (repeatable)\n seeds from a declared capability's realizing services, and an id that seeds\n nothing lands in the additive \\`unresolvedCapabilities\\` — beside\n \\`loam list capabilities\\`, the rollup those seeds are read from.\n- \\`loam seed --from fleet.yaml\\` is the onboarding entry point for an empty\n fleet: a tiny human-authored YAML — a \\`services:\\` list of ids, optional\n \\`subsystems:\\`, \\`externals:\\` and \\`calls:\\` lines like\n \\`checkout -> payments\\` — templated mechanically into\n architecture/landscape.likec4 (one bound element per service, plain edges, no\n guessed operationIds) plus one services/<id>/ directory per service, in one\n journaled transaction. Not an extractor: the human stated every fact, and\n \"who calls whom\" is the one thing no generator can read off a repository.\n The seeded landscape carries a line-1 stamp; while it stands unedited,\n editing fleet.yaml and re-running regenerates the map, and the first hand\n edit anywhere in the file, including above the stub, makes it yours — seed\n then refuses \\`seed-landscape-edited\\`\n rather than overwrite. Then adopt each service: \\`loam adopt --service <id>\\`.\n- \\`loam instructions [<page>] [args...]\\` prints one of the six workflow\n protocols — \\`loam-adopt\\`, \\`loam-feature\\`, \\`loam-implement\\`, \\`loam-check\\`,\n \\`loam-verify\\`, \\`loam-ship\\` — with \\`$1\\`, \\`$2\\` filled in from the arguments you\n pass, or one of the four reference pages — \\`loam-codes\\`, \\`loam-spine\\`,\n \\`loam-authoring\\`, \\`loam-done-check\\` — which take no arguments. With no\n argument at all it lists both sets. The pages ship inside the binary, so they\n describe the loam you are about to run rather than the one that scaffolded the\n repository; the command and skill files \\`loam init\\` writes are pointers at it,\n and so is AGENTS.md's own \"The reference pages\" section. It reads no\n \\`loam.json\\` and no docs repo, deliberately: \\`loam-adopt\\`'s own first step is\n to run \\`loam init\\` when there is no config, so it cannot be the step that\n requires one.\n`;\n\n/**\n * The reference page's body, up to the modules that continue it. The bullets\n * are ordered so `status` — the orientation command, the one to run when you\n * have lost the session — is read first.\n */\nexport const CODE_MAP = MAP_INTRO + STATUS_COMMAND + MAP_REST;\n"]}
|
|
@@ -11,11 +11,15 @@
|
|
|
11
11
|
* scrolls looking for it concludes the file is truncated — which, on the two
|
|
12
12
|
* hosts that truncate silently, is a conclusion they cannot check.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* Not a section of the scaffolded AGENTS.md any more: that document carries a
|
|
15
|
+
* condensed cycle of its own (../agents-md.ts), sized for a host that loads it
|
|
16
|
+
* on every turn. This constant is the long teaching, and it is DELIVERED
|
|
17
|
+
* through `loam explain`'s term paragraphs — ../../explain/terms.ts pins
|
|
18
|
+
* verbatim phrases of it, so rewording a sentence here breaks the pairing
|
|
19
|
+
* loudly instead of letting a term drift away from what loam ships. Two
|
|
20
|
+
* consequences for an editor: a claim written here is read by an agent through
|
|
21
|
+
* `loam explain <term>` and must stay true, and a phrase a pin names cannot be
|
|
22
|
+
* reworded on one side alone.
|
|
19
23
|
*/
|
|
20
24
|
export const CYCLE = `## The cycle
|
|
21
25
|
|
|
@@ -91,12 +95,23 @@ wrong quietly, and \`loam validate\` passing means nothing about any of it.
|
|
|
91
95
|
|
|
92
96
|
One of the targets is not under \`services/<id>/\`: \`architecture/landscape.likec4\`,
|
|
93
97
|
the fleet map, carried with \`action: "edit"\` and a \`landscape.instruction\`
|
|
94
|
-
spelling out the
|
|
95
|
-
|
|
96
|
-
it
|
|
98
|
+
spelling out the write this service owes it. That target appears while nothing
|
|
99
|
+
in the map resolves to the service, and again while the element that does has
|
|
100
|
+
no edge touching it — \`landscape.touched\` says which, and \`landscape.attested\`
|
|
101
|
+
lists the calls the service's own model.likec4 declares across its boundary,
|
|
102
|
+
which are the edges the map owes. **Add to that file; never rewrite it** —
|
|
103
|
+
every other service's elements and edges are in there. A service that is
|
|
97
104
|
fully documented and undrawn is \`landscape.service-unmodelled\` (error) and is
|
|
98
105
|
invisible to every cross-service check: no edge into it can be graded against
|
|
99
|
-
its openapi.yaml, and no feature can draw a call to it.
|
|
106
|
+
its openapi.yaml, and no feature can draw a call to it. A drawn, bound,
|
|
107
|
+
edgeless service whose model reaches other systems is
|
|
108
|
+
\`landscape.service-isolated\` (warn): drawn, and invisible to every
|
|
109
|
+
cross-service check all the same. One whose model attests no such call is
|
|
110
|
+
silent there — the brief's \`landscape.touched: false\` is the only place that
|
|
111
|
+
state is named, so read it before the fleet run rather than hoping for it in it.
|
|
112
|
+
And one edge closes the state; the check is touched/untouched, not a set
|
|
113
|
+
difference, so draw every attested call in one pass — nothing names the ones
|
|
114
|
+
left out.
|
|
100
115
|
|
|
101
116
|
An adoption ends with two runs, not one: \`loam validate --service <id> --json\`
|
|
102
117
|
for the baseline, then \`loam validate --all --json\` in the docs repo — the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cycle.js","sourceRoot":"","sources":["../../../../src/core/agent/agents-md/cycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgJpB,CAAC","sourcesContent":["/**\n * What an agent DOES: the cycle step by step, adopting a service, what is\n * authored versus derived, and the rules the validator enforces.\n *\n * The done-check itself is no longer here — it is `loam instructions\n * loam-done-check` (../workflows/reference/done-check.ts). Steps 4 and 7 used\n * to end `See \"The requirement baseline\"` and `See \"The done-check\"`, naming\n * headings that were further down this same file; they now name the COMMAND\n * that prints them. That is not a rewording for its own sake: a section\n * reference to a section that left is a pointer at nothing, and a reader who\n * scrolls looking for it concludes the file is truncated — which, on the two\n * hosts that truncate silently, is a conclusion they cannot check.\n *\n * One section of the AGENTS.md template. ../agents-md.ts assembles the\n * document by PLAIN CONCATENATION — no join separator — so every section\n * starts at the first character of its opening line and ends with the newline\n * that closes its last one. Keep that shape when editing, or two sections glue\n * onto one line in every docs repo loam scaffolds from now on.\n */\nexport const CYCLE = `## The cycle\n\n0. **Wire the repo** — \\`loam init --docs <path-to-docs-repo> --service <id>\\` in\n each service repo, then \\`loam doctor\\`. Once per repository, before anything\n else; see \"\\`loam.json\\` — the wiring\" above. Every step below runs in a repo\n that has been through this one.\n1. **Adopt** — a service with no documentation at all starts at\n \\`loam adopt --service <id> --json\\`, which briefs you on the baseline to write.\n See \"Adopting a service\" below. Once per service, not once per feature.\n2. **Understand** — \\`loam status --json\\` first if you joined halfway or lost the\n session: it says what is in flight and what the next step is, for the fleet or\n for one feature (\\`loam status FEAT-101 --json\\`). Then \\`loam list --json\\` and\n \\`loam show <service> --json\\`.\n Then \\`loam explore <service> --json\\` around the services you believe are\n involved — it writes nothing and answers the one question the next step takes\n as an argument: which services this change actually touches. It reports the\n ring one hop out in the fleet map (\\`neighbours\\`), how far each service's\n documentation has got (\\`maturity\\`), what each already exposes, the features\n already in flight over the same ground (\\`overlaps\\`), and the \\`loam new\\` line\n the seeds imply (\\`scaffold\\`). \\`--op <operationId>\\` seeds from an operation\n when you know the call but not who owns it.\n Never propose a change to a service you have not read.\n3. **Scaffold** — \\`loam new FEAT-101 --title \"...\" --touches <existing> --new-service <new>\\`.\n The scaffold leaves a \\`delta.likec4\\` whose context elements are commented out —\n a requirements-only feature should DELETE that file rather than ship an empty\n one — and gives every \\`--new-service\\` a \\`specs/<svc>/arch.spec.md\\` alongside.\n \\`--capability <id>\\` (repeatable, and it composes with \\`--touches\\`) scaffolds a\n capability delta instead of a service one — the inversion of this step, for a\n change whose BUSINESS side is what is known: open the promise that changes and\n derive the service work from it. An id the fleet has never named is scaffolded\n rather than refused, with the close spellings printed beside it; the archive\n is what creates the living \\`capabilities/<id>/spec.md\\`.\n4. **Author** the four files the scaffold left as TODO: intent, delta.likec4,\n a spec.md per service, an openapi.yaml per new service. Finish with\n \\`loam rebase FEAT-101\\`: it pins every MODIFIED/REMOVED requirement and every\n operation in the contract delta to the living version you wrote it against.\n On the contract axis run it even when you changed nothing but one endpoint —\n that is exactly what marks the REST of the document as quotation the merge\n must not write. See \\`loam instructions loam-spine\\` — \"The requirement baseline\".\n5. **Check** — \\`loam validate FEAT-101 --json\\`. Fix every error before writing code.\n \\`loam dependencies --json\\` says whether another feature in flight has to\n archive first.\n6. **Build** — \\`loam delta FEAT-101 --service <svc> --json\\` is the task for one service:\n intent, its requirement delta with scenarios verbatim, and the edges around it.\n In the service's own repo, \\`loam gherkin FEAT-101\\` then emits those scenarios as\n \\`.feature\\` files under \\`<gherkinDir>/loam/\\` — write step definitions against them\n **first**, outside \\`loam/\\`, and implement until they pass.\n If \\`architecture.errors\\` is non-empty the payload keeps \\`ok: true\\` (the command\n ran) but the exit code is 1: the C4 slice is empty because delta.likec4 did not\n parse, not because the feature changes no architecture — do not build on it.\n7. **Verify** — \\`loam verify FEAT-101 --json\\` turns the feature's own promises into a\n checklist. The scenario claims are answered by the cucumber report\n (\\`--results report.json\\`); answer the rest with evidence and record them\n (\\`--record answers.json --service <id>\\`), **from each affected service's own\n repo**. See \\`loam instructions loam-done-check\\`.\n8. **Ship** — \\`loam archive FEAT-101\\` once the code is merged. \\`--dry-run\\` shows\n every file the merge would write, and writes none of them.\n\n## Adopting a service\n\n\\`loam adopt --service <id>\\` does not read code and never will. Nothing\ndeterministic can look at a legacy service and say what its architecture MEANS,\nand a guessed model is worse than none: everybody downstream has to re-derive it\nto know whether to believe it. So loam takes the half of the job that is\nmechanical — stating the work, and checking the result — and you do the reading.\n\nThe brief names every file to write, the grammar each must be in, what the\nlandscape already says about the service (bind to those elements, do not draw a\nparallel fleet), the frontmatter, and the checks that follow. It also lists what\n**no** check will ever catch. Read that list: everything on it is a way to be\nwrong quietly, and \\`loam validate\\` passing means nothing about any of it.\n\nOne of the targets is not under \\`services/<id>/\\`: \\`architecture/landscape.likec4\\`,\nthe fleet map, carried with \\`action: \"edit\"\\` and a \\`landscape.instruction\\`\nspelling out the block this service owes it. That target appears only while\nnothing in the map resolves to the service. **Add to that file; never rewrite\nit** — every other service's elements and edges are in there. A service that is\nfully documented and undrawn is \\`landscape.service-unmodelled\\` (error) and is\ninvisible to every cross-service check: no edge into it can be graded against\nits openapi.yaml, and no feature can draw a call to it.\n\nAn adoption ends with two runs, not one: \\`loam validate --service <id> --json\\`\nfor the baseline, then \\`loam validate --all --json\\` in the docs repo — the\nfleet cross-check the first invocation does not perform is exactly where a\nlandscape edit that did not land shows up. Done, stated once: \\`--service\\`\nclean when run from inside the service's own repo, and \\`--all\\` reporting no\n\\`landscape.*\\` finding. The fleet run is never SILENT — \\`sources.unverifiable-from-here\\`\n(severity ok) appears per service as a confirmation, not work — so \"keep going\nuntil validation is quiet\" is the wrong loop; the two runs above are the test.\n\nTwo rules the brief repeats and this file will too. An artifact that already\nexists is reported as \\`action: \"diff\"\\` — read it and report what disagrees;\nnever replace it, because a document somebody wrote is evidence. And everything\nyou write is \\`status: draft\\`: promotion is \\`loam vouch\\`, run by a person in the\nservice's own repo — \\`loam vouch --pack --service <id>\\` (read-only) preps that read.\n\n## What you author, what loam derives\n\nAuthored by hand: \\`intent.md\\`, \\`delta.likec4\\`, \\`specs/<svc>/spec.md\\`,\n\\`specs/<svc>/arch.spec.md\\`, \\`specs/<svc>/openapi.yaml\\`, ADRs, runbooks, health.\n\nWritten by loam: the merge into \\`services/<svc>/spec.md\\`, \\`services/<svc>/arch.spec.md\\`,\n\\`services/<svc>/openapi.yaml\\` and \\`architecture/landscape.likec4\\` at archive time.\n\n**Do not hand-edit the living landscape to add a feature's changes.** Put them in a\ndelta and archive it — otherwise the change has no intent, no requirement and no\nhistory behind it.\n\n## Rules the validator enforces\n\n- every requirement has at least one \\`#### Scenario:\\` — scenarios are the acceptance\n criteria and the source for tests;\n- every operationId a requirement governs exists in that service's OpenAPI;\n- every C4 edge's \\`op\\` resolves to an operation the target actually exposes;\n- every operation is governed by some requirement (warning);\n- a \"Calls\" edge with no \\`metadata { op }\\` is unlinked (warning);\n- **the map is complete**: every \\`services/<svc>/\\` has an element in the landscape,\n and every element that looks like a service has a directory (warning) or is\n tagged \\`#external\\`;\n- **the diff applies**: a \\`MODIFIED\\` or \\`REMOVED\\` requirement exists in the living\n spec, an \\`ADDED\\` one does not, and a section heading matches the grammar exactly;\n- a \\`Requirement-ID: <id>\\` is optional, but when present it is valid and unique;\n archive selects by it, so carry the same ID through \\`MODIFIED\\` to rename a heading;\n- **every requirement in a delta is under a delta section**: one under a prose heading\n (\\`## Behavior\\`) is documentation as far as the merge is concerned and is dropped\n (warning). \\`## Requirements\\` is exempt — quoting the living state is legal.\n\nThat last pair of rules exists because each of its failures used to be silent.\n\\`MODIFIED\\` of a requirement that does not exist merged as a creation; \\`ADDED\\` of one\nthat does exist REPLACED it, scenarios and all; a near-miss heading like\n\\`## ADDED Requirement\\` (singular) parses as plain prose, so archive merged nothing and\nsaid nothing; and a requirement under \\`## Behavior\\` vanished the same way.\n\nWrite the delta section heading on its own line exactly as \\`## ADDED Requirements\\`.\nThe heading is the only thing that gives a requirement its kind: without a matching\none, archive merges the requirement as nothing.\n\nSeverity and gating are two different questions. An ERROR means the document is\ninvalid — \\`loam validate\\` fails. A finding with \\`gates: true\\` means \\`loam archive\\`\nwill refuse — the merge is unsafe. They usually agree (errors gate, warnings do\nnot), and where they diverge the \\`--json\\` output says so: \\`delta.requirement-not-merged\\`\nis a warning (the shape is legal OpenSpec) that gates (the merge would drop the\nrequirement). Leave a warning standing only deliberately.\n\n`;\n"]}
|
|
1
|
+
{"version":3,"file":"cycle.js","sourceRoot":"","sources":["../../../../src/core/agent/agents-md/cycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2JpB,CAAC","sourcesContent":["/**\n * What an agent DOES: the cycle step by step, adopting a service, what is\n * authored versus derived, and the rules the validator enforces.\n *\n * The done-check itself is no longer here — it is `loam instructions\n * loam-done-check` (../workflows/reference/done-check.ts). Steps 4 and 7 used\n * to end `See \"The requirement baseline\"` and `See \"The done-check\"`, naming\n * headings that were further down this same file; they now name the COMMAND\n * that prints them. That is not a rewording for its own sake: a section\n * reference to a section that left is a pointer at nothing, and a reader who\n * scrolls looking for it concludes the file is truncated — which, on the two\n * hosts that truncate silently, is a conclusion they cannot check.\n *\n * Not a section of the scaffolded AGENTS.md any more: that document carries a\n * condensed cycle of its own (../agents-md.ts), sized for a host that loads it\n * on every turn. This constant is the long teaching, and it is DELIVERED\n * through `loam explain`'s term paragraphs — ../../explain/terms.ts pins\n * verbatim phrases of it, so rewording a sentence here breaks the pairing\n * loudly instead of letting a term drift away from what loam ships. Two\n * consequences for an editor: a claim written here is read by an agent through\n * `loam explain <term>` and must stay true, and a phrase a pin names cannot be\n * reworded on one side alone.\n */\nexport const CYCLE = `## The cycle\n\n0. **Wire the repo** — \\`loam init --docs <path-to-docs-repo> --service <id>\\` in\n each service repo, then \\`loam doctor\\`. Once per repository, before anything\n else; see \"\\`loam.json\\` — the wiring\" above. Every step below runs in a repo\n that has been through this one.\n1. **Adopt** — a service with no documentation at all starts at\n \\`loam adopt --service <id> --json\\`, which briefs you on the baseline to write.\n See \"Adopting a service\" below. Once per service, not once per feature.\n2. **Understand** — \\`loam status --json\\` first if you joined halfway or lost the\n session: it says what is in flight and what the next step is, for the fleet or\n for one feature (\\`loam status FEAT-101 --json\\`). Then \\`loam list --json\\` and\n \\`loam show <service> --json\\`.\n Then \\`loam explore <service> --json\\` around the services you believe are\n involved — it writes nothing and answers the one question the next step takes\n as an argument: which services this change actually touches. It reports the\n ring one hop out in the fleet map (\\`neighbours\\`), how far each service's\n documentation has got (\\`maturity\\`), what each already exposes, the features\n already in flight over the same ground (\\`overlaps\\`), and the \\`loam new\\` line\n the seeds imply (\\`scaffold\\`). \\`--op <operationId>\\` seeds from an operation\n when you know the call but not who owns it.\n Never propose a change to a service you have not read.\n3. **Scaffold** — \\`loam new FEAT-101 --title \"...\" --touches <existing> --new-service <new>\\`.\n The scaffold leaves a \\`delta.likec4\\` whose context elements are commented out —\n a requirements-only feature should DELETE that file rather than ship an empty\n one — and gives every \\`--new-service\\` a \\`specs/<svc>/arch.spec.md\\` alongside.\n \\`--capability <id>\\` (repeatable, and it composes with \\`--touches\\`) scaffolds a\n capability delta instead of a service one — the inversion of this step, for a\n change whose BUSINESS side is what is known: open the promise that changes and\n derive the service work from it. An id the fleet has never named is scaffolded\n rather than refused, with the close spellings printed beside it; the archive\n is what creates the living \\`capabilities/<id>/spec.md\\`.\n4. **Author** the four files the scaffold left as TODO: intent, delta.likec4,\n a spec.md per service, an openapi.yaml per new service. Finish with\n \\`loam rebase FEAT-101\\`: it pins every MODIFIED/REMOVED requirement and every\n operation in the contract delta to the living version you wrote it against.\n On the contract axis run it even when you changed nothing but one endpoint —\n that is exactly what marks the REST of the document as quotation the merge\n must not write. See \\`loam instructions loam-spine\\` — \"The requirement baseline\".\n5. **Check** — \\`loam validate FEAT-101 --json\\`. Fix every error before writing code.\n \\`loam dependencies --json\\` says whether another feature in flight has to\n archive first.\n6. **Build** — \\`loam delta FEAT-101 --service <svc> --json\\` is the task for one service:\n intent, its requirement delta with scenarios verbatim, and the edges around it.\n In the service's own repo, \\`loam gherkin FEAT-101\\` then emits those scenarios as\n \\`.feature\\` files under \\`<gherkinDir>/loam/\\` — write step definitions against them\n **first**, outside \\`loam/\\`, and implement until they pass.\n If \\`architecture.errors\\` is non-empty the payload keeps \\`ok: true\\` (the command\n ran) but the exit code is 1: the C4 slice is empty because delta.likec4 did not\n parse, not because the feature changes no architecture — do not build on it.\n7. **Verify** — \\`loam verify FEAT-101 --json\\` turns the feature's own promises into a\n checklist. The scenario claims are answered by the cucumber report\n (\\`--results report.json\\`); answer the rest with evidence and record them\n (\\`--record answers.json --service <id>\\`), **from each affected service's own\n repo**. See \\`loam instructions loam-done-check\\`.\n8. **Ship** — \\`loam archive FEAT-101\\` once the code is merged. \\`--dry-run\\` shows\n every file the merge would write, and writes none of them.\n\n## Adopting a service\n\n\\`loam adopt --service <id>\\` does not read code and never will. Nothing\ndeterministic can look at a legacy service and say what its architecture MEANS,\nand a guessed model is worse than none: everybody downstream has to re-derive it\nto know whether to believe it. So loam takes the half of the job that is\nmechanical — stating the work, and checking the result — and you do the reading.\n\nThe brief names every file to write, the grammar each must be in, what the\nlandscape already says about the service (bind to those elements, do not draw a\nparallel fleet), the frontmatter, and the checks that follow. It also lists what\n**no** check will ever catch. Read that list: everything on it is a way to be\nwrong quietly, and \\`loam validate\\` passing means nothing about any of it.\n\nOne of the targets is not under \\`services/<id>/\\`: \\`architecture/landscape.likec4\\`,\nthe fleet map, carried with \\`action: \"edit\"\\` and a \\`landscape.instruction\\`\nspelling out the write this service owes it. That target appears while nothing\nin the map resolves to the service, and again while the element that does has\nno edge touching it — \\`landscape.touched\\` says which, and \\`landscape.attested\\`\nlists the calls the service's own model.likec4 declares across its boundary,\nwhich are the edges the map owes. **Add to that file; never rewrite it** —\nevery other service's elements and edges are in there. A service that is\nfully documented and undrawn is \\`landscape.service-unmodelled\\` (error) and is\ninvisible to every cross-service check: no edge into it can be graded against\nits openapi.yaml, and no feature can draw a call to it. A drawn, bound,\nedgeless service whose model reaches other systems is\n\\`landscape.service-isolated\\` (warn): drawn, and invisible to every\ncross-service check all the same. One whose model attests no such call is\nsilent there — the brief's \\`landscape.touched: false\\` is the only place that\nstate is named, so read it before the fleet run rather than hoping for it in it.\nAnd one edge closes the state; the check is touched/untouched, not a set\ndifference, so draw every attested call in one pass — nothing names the ones\nleft out.\n\nAn adoption ends with two runs, not one: \\`loam validate --service <id> --json\\`\nfor the baseline, then \\`loam validate --all --json\\` in the docs repo — the\nfleet cross-check the first invocation does not perform is exactly where a\nlandscape edit that did not land shows up. Done, stated once: \\`--service\\`\nclean when run from inside the service's own repo, and \\`--all\\` reporting no\n\\`landscape.*\\` finding. The fleet run is never SILENT — \\`sources.unverifiable-from-here\\`\n(severity ok) appears per service as a confirmation, not work — so \"keep going\nuntil validation is quiet\" is the wrong loop; the two runs above are the test.\n\nTwo rules the brief repeats and this file will too. An artifact that already\nexists is reported as \\`action: \"diff\"\\` — read it and report what disagrees;\nnever replace it, because a document somebody wrote is evidence. And everything\nyou write is \\`status: draft\\`: promotion is \\`loam vouch\\`, run by a person in the\nservice's own repo — \\`loam vouch --pack --service <id>\\` (read-only) preps that read.\n\n## What you author, what loam derives\n\nAuthored by hand: \\`intent.md\\`, \\`delta.likec4\\`, \\`specs/<svc>/spec.md\\`,\n\\`specs/<svc>/arch.spec.md\\`, \\`specs/<svc>/openapi.yaml\\`, ADRs, runbooks, health.\n\nWritten by loam: the merge into \\`services/<svc>/spec.md\\`, \\`services/<svc>/arch.spec.md\\`,\n\\`services/<svc>/openapi.yaml\\` and \\`architecture/landscape.likec4\\` at archive time.\n\n**Do not hand-edit the living landscape to add a feature's changes.** Put them in a\ndelta and archive it — otherwise the change has no intent, no requirement and no\nhistory behind it.\n\n## Rules the validator enforces\n\n- every requirement has at least one \\`#### Scenario:\\` — scenarios are the acceptance\n criteria and the source for tests;\n- every operationId a requirement governs exists in that service's OpenAPI;\n- every C4 edge's \\`op\\` resolves to an operation the target actually exposes;\n- every operation is governed by some requirement (warning);\n- a \"Calls\" edge with no \\`metadata { op }\\` is unlinked (warning);\n- **the map is complete**: every \\`services/<svc>/\\` has an element in the landscape,\n and every element that looks like a service has a directory (warning) or is\n tagged \\`#external\\`;\n- **the diff applies**: a \\`MODIFIED\\` or \\`REMOVED\\` requirement exists in the living\n spec, an \\`ADDED\\` one does not, and a section heading matches the grammar exactly;\n- a \\`Requirement-ID: <id>\\` is optional, but when present it is valid and unique;\n archive selects by it, so carry the same ID through \\`MODIFIED\\` to rename a heading;\n- **every requirement in a delta is under a delta section**: one under a prose heading\n (\\`## Behavior\\`) is documentation as far as the merge is concerned and is dropped\n (warning). \\`## Requirements\\` is exempt — quoting the living state is legal.\n\nThat last pair of rules exists because each of its failures used to be silent.\n\\`MODIFIED\\` of a requirement that does not exist merged as a creation; \\`ADDED\\` of one\nthat does exist REPLACED it, scenarios and all; a near-miss heading like\n\\`## ADDED Requirement\\` (singular) parses as plain prose, so archive merged nothing and\nsaid nothing; and a requirement under \\`## Behavior\\` vanished the same way.\n\nWrite the delta section heading on its own line exactly as \\`## ADDED Requirements\\`.\nThe heading is the only thing that gives a requirement its kind: without a matching\none, archive merges the requirement as nothing.\n\nSeverity and gating are two different questions. An ERROR means the document is\ninvalid — \\`loam validate\\` fails. A finding with \\`gates: true\\` means \\`loam archive\\`\nwill refuse — the merge is unsafe. They usually agree (errors gate, warnings do\nnot), and where they diverge the \\`--json\\` output says so: \\`delta.requirement-not-merged\\`\nis a warning (the shape is legal OpenSpec) that gates (the merge would drop the\nrequirement). Leave a warning standing only deliberately.\n\n`;\n"]}
|
|
@@ -16,9 +16,10 @@ export const CONTEXT_COMMAND = `- \`loam context <service>\` assembles the docs
|
|
|
16
16
|
requirements and arch requirements VERBATIM (bodies and scenarios included),
|
|
17
17
|
the OpenAPI operations with the requirements governing each, the AsyncAPI
|
|
18
18
|
messages with their send/receive direction, the fleet edges one hop out with
|
|
19
|
-
the map's own health beside them (\`landscape.present
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
the map's own health beside them (\`landscape.present\` is the FILE,
|
|
20
|
+
\`landscape.parses\` is the whole \`architecture/\` project the renderer loads,
|
|
21
|
+
as \`loam adopt\` reads it — an empty edge list under a map that does not parse
|
|
22
|
+
is "nobody could look", never "nobody calls this"), the \`Requires:\` permissions resolved against the
|
|
22
23
|
vocabulary (an undeclared entry is carried with \`declared: false\`, never
|
|
23
24
|
refused — and when the vocabulary ITSELF does not read, its parse failure
|
|
24
25
|
rides beside them, so \`declared: false\` there means nobody could look, not
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../../../src/core/agent/agents-md/map/lenses/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../../../src/core/agent/agents-md/map/lenses/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4B9B,CAAC","sourcesContent":["/**\n * The `loam context` entry of the command map — one of the three consumer\n * LENSES this package holds (the agent briefing here, `./gate.ts`'s deploy\n * pipeline, `./diff.ts`'s PR review), the family carved out of `../` when the\n * map package hit its own five-file cap: command-map.ts sits against the\n * file-line limit, so the pack's documentation lives down here and is\n * concatenated after the map.\n *\n * Same assembly contract as every section: ../../../agents-md.ts concatenates\n * with NO join separator, so this string starts at the first character of its\n * opening line and ends with the newline that closes its last one.\n */\nexport const CONTEXT_COMMAND = `- \\`loam context <service>\\` assembles the docs slice bound to one service as a\n single deterministic briefing — the pack an agent loads before working in\n that service's repository. It writes nothing. One payload carries the living\n requirements and arch requirements VERBATIM (bodies and scenarios included),\n the OpenAPI operations with the requirements governing each, the AsyncAPI\n messages with their send/receive direction, the fleet edges one hop out with\n the map's own health beside them (\\`landscape.present\\` is the FILE,\n \\`landscape.parses\\` is the whole \\`architecture/\\` project the renderer loads,\n as \\`loam adopt\\` reads it — an empty edge list under a map that does not parse\n is \"nobody could look\", never \"nobody calls this\"), the \\`Requires:\\` permissions resolved against the\n vocabulary (an undeclared entry is carried with \\`declared: false\\`, never\n refused — and when the vocabulary ITSELF does not read, its parse failure\n rides beside them, so \\`declared: false\\` there means nobody could look, not\n that the claim is wrong), the capabilities this service realizes with the\n capability vocabulary's own health beside them, maturity and provenance,\n presence pointers for the runbook/health/ADRs, and every ACTIVE feature's\n delta over this service in \\`loam delta\\`'s own shapes. \\`--feature <FEAT>\\`\n narrows the in-flight section to that one feature and is echoed back as the\n \\`feature\\` key, so a narrowed pack says it is one; a known feature that does\n not touch the service still projects, with empty sections and its own\n services list. Exit 1 with \\`ok: true\\` means a document behind the pack did\n not parse — the fleet map, a living contract, a fleet vocabulary, another\n service's spec during the capability join, or an included feature's document\n (a feature whose delta.likec4 does not parse is still INCLUDED, its errors\n in the payload, because a change nobody can read is in flight, not absent)\n — and the empty section beside the flag IS the parse failure, not \"nothing\n here\". Identical state yields identical bytes, so packs are diffable across\n runs.\n`;\n"]}
|
|
@@ -25,13 +25,62 @@ export const SUBSYSTEM_COMMANDS = `- \`loam subsystem <verb>\` manages the group
|
|
|
25
25
|
\`unfiledServices\`); \`history <name>\` asks git how a service or subsystem
|
|
26
26
|
moved and answers nothing — exit 0, no finding — when git will not say;
|
|
27
27
|
\`sync\` regenerates \`architecture/subsystems.likec4\`, the one repair for
|
|
28
|
-
\`subsystem.views-stale
|
|
28
|
+
\`subsystem.views-stale\`, and also maintains the RENDERER's wiring for the
|
|
29
|
+
service models. Which wiring a model needs is decided by the file's own
|
|
30
|
+
grammar, never by a config key: a model that declares its own
|
|
31
|
+
\`specification { element … }\` block STANDS ALONE — it cannot share a project
|
|
32
|
+
with the fleet map, since every kind it declares would be a duplicate there —
|
|
33
|
+
and a model with no such block EXTENDS the map with
|
|
34
|
+
\`extend <fully-qualified id> { … }\` and parses only INSIDE the root project.
|
|
35
|
+
So \`sync\` writes one create-only \`services/<…>/<id>/likec4.config.json\` per
|
|
36
|
+
STANDALONE model (never rewritten; the team may edit it; commit
|
|
37
|
+
the new files before a \`move\`, which refuses over untracked paths), DELETES one
|
|
38
|
+
sitting beside an EXTENDING model (that nested project claims the model out of
|
|
39
|
+
the root project, so \`likec4 validate .\` refuses without \`--project\` and,
|
|
40
|
+
wherever that project claims the model, \`export json --project fleet\` loses
|
|
41
|
+
the service's containers; \`--json\` lists what it removed as \`projects.removed\`), and rewrites
|
|
42
|
+
the root \`likec4.config.json\`'s \`exclude\` to hold \`services/<tree>/**\` for
|
|
43
|
+
exactly those models, keeping every entry that is not about \`services/\` in the
|
|
44
|
+
order the team wrote it. It rewrites that list when at least one extending model
|
|
45
|
+
exists, or when a standalone model's directory is not covered — an older repo
|
|
46
|
+
whose models all stand alone behind \`services/**\` is never touched. \`--json\`
|
|
47
|
+
carries the result as \`projects.exclude\`, and the text view prints one line when
|
|
48
|
+
it rewrote. Between them these repair four warnings:
|
|
49
|
+
\`service.likec4-config-missing\` (a standalone model with no project file),
|
|
50
|
+
\`service.likec4-config-stray\` (a project file beside an extending model),
|
|
51
|
+
\`service.model-excluded\` (an extending model the root \`exclude\` hides from the
|
|
52
|
+
renderer) and \`service.model-unexcluded\` (a standalone model it does not hide,
|
|
53
|
+
which blanks the whole root project). A flat fleet with no subsystems still owes
|
|
54
|
+
this run: the verb is the tree's, the files are the renderer's. A fleet whose
|
|
55
|
+
models all extend the map ends with ONE project and one picker entry, and
|
|
56
|
+
\`likec4 validate\` at the docs root needs no flag; each standalone model adds a
|
|
57
|
+
project, and with more than one \`likec4 validate\` needs \`--project <name>\`
|
|
58
|
+
(\`build\` and \`export\` take every project). A view id claimed twice inside one
|
|
59
|
+
project — the landscape and an extending model both minting it, or either
|
|
60
|
+
claiming a generated one — is
|
|
29
61
|
\`subsystem.view-id-collision\`. Each generated view is titled by its PATH —
|
|
30
62
|
every marked ancestor's label and its own, which the renderer reads as
|
|
31
63
|
folders — where a label is the marker's \`title\` or the directory name; the
|
|
32
64
|
marker's \`description\` rides along. So editing \`subsystem.yaml\` changes
|
|
33
65
|
what the renderer LABELS the group, a parent's title changes every view
|
|
34
|
-
beneath it, and either makes the file stale until the next \`sync\`.
|
|
66
|
+
beneath it, and either makes the file stale until the next \`sync\`. The
|
|
67
|
+
generated file is NEVER part of the fleet-project load
|
|
68
|
+
(\`c4.fleet-project-invalid\` reads every other \`.likec4\` the root project holds);
|
|
69
|
+
\`subsystem.views-stale\` is the only check that reads it, by byte comparison.
|
|
70
|
+
Each view
|
|
71
|
+
carries \`global style subsystems\` — written after its title, the one line
|
|
72
|
+
LikeC4 gives a view for borrowing a palette — exactly when the \`architecture/\`
|
|
73
|
+
project declares a global style with that id (\`global { styleGroup subsystems
|
|
74
|
+
{ style element.tag = #external { color gray } } }\`, in the landscape or in
|
|
75
|
+
ANY \`.likec4\` under \`architecture/\` the root \`exclude\` does not cover — a
|
|
76
|
+
\`palette.likec4\` beside the map counts); nothing otherwise, and loam never reads
|
|
77
|
+
what the group says. Declaring it is the whole opt-in and makes the file stale
|
|
78
|
+
once, until the next \`sync\`. When the project declares style groups under other
|
|
79
|
+
names only, the file opens with one comment line naming them and saying none is
|
|
80
|
+
\`subsystems\`, and the views carry the renderer's defaults — so declaring a group
|
|
81
|
+
under ANY name restales the file, because that comment is part of the bytes.
|
|
82
|
+
\`sync\` refuses to rewrite it at all while \`architecture/\` does not parse
|
|
83
|
+
(\`action: "blocked"\`): fix the map first. It is generated wholesale:
|
|
35
84
|
an authored diagram of the same services belongs in the landscape or in a
|
|
36
85
|
file of your own name, never here. \`loam adopt --subsystem <name>\` briefs a new
|
|
37
86
|
service's baseline directly into a group, so adoption need not land unfiled.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subsystem.js","sourceRoot":"","sources":["../../../../../src/core/agent/agents-md/map/subsystem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG
|
|
1
|
+
{"version":3,"file":"subsystem.js","sourceRoot":"","sources":["../../../../../src/core/agent/agents-md/map/subsystem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4EjC,CAAC","sourcesContent":["/**\n * The `loam subsystem` half of the command map — its own section module\n * because command-map.ts sat against the file-line limit and the agents-md\n * package against the five-file cap, so the tree surface's documentation\n * lives one package down and is concatenated after the map.\n *\n * Same assembly contract as every section: ../agents-md.ts concatenates with\n * NO join separator, so this string starts at the first character of its\n * opening line and ends with the newline that closes its last one.\n */\nexport const SUBSYSTEM_COMMANDS = `- \\`loam subsystem <verb>\\` manages the grouping tree under \\`services/\\` — the\n navigable tree no identity depends on: a service id stays its leaf directory\n name, every join key is byte-identical before and after a move, and the tree\n carries no policy. Verbs: \\`new <name> [--under <sub>] [--title] [--description]\n [--owner]\\` creates a group (an empty one is legal — its \\`subsystem.yaml\\` is a\n marker, never a member list); \\`move <name>... --into <sub|.>\\` relocates\n services and whole subtrees in ONE journaled transaction over the renames\n plus the regenerated views file (\\`--into .\\` unfiles; the renames and the\n regenerated views file are staged in git without committing, where git answers); \\`rename <old> <new>\\` renames a\n group through the same transaction (services are never renamed — the id is\n the identity); \\`rm <name>\\` removes an EMPTY group; \\`list\\` shows the tree\n with member counts and the unfiled count (unfiled is permanent and normal —\n a count, never a finding; \\`loam list --json\\` carries the same facts as\n additive keys \\`services[].subsystem\\`, \\`subsystems[]\\` and\n \\`unfiledServices\\`); \\`history <name>\\` asks git how a service or subsystem\n moved and answers nothing — exit 0, no finding — when git will not say;\n \\`sync\\` regenerates \\`architecture/subsystems.likec4\\`, the one repair for\n \\`subsystem.views-stale\\`, and also maintains the RENDERER's wiring for the\n service models. Which wiring a model needs is decided by the file's own\n grammar, never by a config key: a model that declares its own\n \\`specification { element … }\\` block STANDS ALONE — it cannot share a project\n with the fleet map, since every kind it declares would be a duplicate there —\n and a model with no such block EXTENDS the map with\n \\`extend <fully-qualified id> { … }\\` and parses only INSIDE the root project.\n So \\`sync\\` writes one create-only \\`services/<…>/<id>/likec4.config.json\\` per\n STANDALONE model (never rewritten; the team may edit it; commit\n the new files before a \\`move\\`, which refuses over untracked paths), DELETES one\n sitting beside an EXTENDING model (that nested project claims the model out of\n the root project, so \\`likec4 validate .\\` refuses without \\`--project\\` and,\n wherever that project claims the model, \\`export json --project fleet\\` loses\n the service's containers; \\`--json\\` lists what it removed as \\`projects.removed\\`), and rewrites\n the root \\`likec4.config.json\\`'s \\`exclude\\` to hold \\`services/<tree>/**\\` for\n exactly those models, keeping every entry that is not about \\`services/\\` in the\n order the team wrote it. It rewrites that list when at least one extending model\n exists, or when a standalone model's directory is not covered — an older repo\n whose models all stand alone behind \\`services/**\\` is never touched. \\`--json\\`\n carries the result as \\`projects.exclude\\`, and the text view prints one line when\n it rewrote. Between them these repair four warnings:\n \\`service.likec4-config-missing\\` (a standalone model with no project file),\n \\`service.likec4-config-stray\\` (a project file beside an extending model),\n \\`service.model-excluded\\` (an extending model the root \\`exclude\\` hides from the\n renderer) and \\`service.model-unexcluded\\` (a standalone model it does not hide,\n which blanks the whole root project). A flat fleet with no subsystems still owes\n this run: the verb is the tree's, the files are the renderer's. A fleet whose\n models all extend the map ends with ONE project and one picker entry, and\n \\`likec4 validate\\` at the docs root needs no flag; each standalone model adds a\n project, and with more than one \\`likec4 validate\\` needs \\`--project <name>\\`\n (\\`build\\` and \\`export\\` take every project). A view id claimed twice inside one\n project — the landscape and an extending model both minting it, or either\n claiming a generated one — is\n \\`subsystem.view-id-collision\\`. Each generated view is titled by its PATH —\n every marked ancestor's label and its own, which the renderer reads as\n folders — where a label is the marker's \\`title\\` or the directory name; the\n marker's \\`description\\` rides along. So editing \\`subsystem.yaml\\` changes\n what the renderer LABELS the group, a parent's title changes every view\n beneath it, and either makes the file stale until the next \\`sync\\`. The\n generated file is NEVER part of the fleet-project load\n (\\`c4.fleet-project-invalid\\` reads every other \\`.likec4\\` the root project holds);\n \\`subsystem.views-stale\\` is the only check that reads it, by byte comparison.\n Each view\n carries \\`global style subsystems\\` — written after its title, the one line\n LikeC4 gives a view for borrowing a palette — exactly when the \\`architecture/\\`\n project declares a global style with that id (\\`global { styleGroup subsystems\n { style element.tag = #external { color gray } } }\\`, in the landscape or in\n ANY \\`.likec4\\` under \\`architecture/\\` the root \\`exclude\\` does not cover — a\n \\`palette.likec4\\` beside the map counts); nothing otherwise, and loam never reads\n what the group says. Declaring it is the whole opt-in and makes the file stale\n once, until the next \\`sync\\`. When the project declares style groups under other\n names only, the file opens with one comment line naming them and saying none is\n \\`subsystems\\`, and the views carry the renderer's defaults — so declaring a group\n under ANY name restales the file, because that comment is part of the bytes.\n \\`sync\\` refuses to rewrite it at all while \\`architecture/\\` does not parse\n (\\`action: \"blocked\"\\`): fix the map first. It is generated wholesale:\n an authored diagram of the same services belongs in the landscape or in a\n file of your own name, never here. \\`loam adopt --subsystem <name>\\` briefs a new\n service's baseline directly into a group, so adoption need not land unfiled.\n`;\n"]}
|
|
@@ -23,7 +23,13 @@ export const USECASE_VIEWS = `- Business use cases are \`dynamic view\`s, and \`
|
|
|
23
23
|
tag the view \`#cap-<capability>\` to have it graded. The tag spells a declared
|
|
24
24
|
capability id with every \`/\` flattened to \`-\` (a LikeC4 tag name cannot carry a
|
|
25
25
|
slash), and it must be declared as a \`tag\` in the one \`specification\` block the
|
|
26
|
-
project has, since LikeC4 refuses an undeclared tag.
|
|
26
|
+
\`architecture/\` project has, since LikeC4 refuses an undeclared tag. loam grades
|
|
27
|
+
the fleet map as THAT project and nothing else — the landscape plus its
|
|
28
|
+
siblings, never a service model — so a hop here names SERVICE elements: a step
|
|
29
|
+
naming a container that a service's extending model declares resolves in the
|
|
30
|
+
renderer's wider root project and is \`landscape.invalid\` for loam, which takes
|
|
31
|
+
the whole fleet map down. Container-level flows live beside the model that
|
|
32
|
+
declares them (below). EITHER reserved prefix
|
|
27
33
|
opts a view in — a view carrying only \`#req-<requirement>\` is graded too, and
|
|
28
34
|
earns \`usecase.requirement-unresolved\` for the \`#cap-\` tag it is missing
|
|
29
35
|
rather than silence. An UNTAGGED dynamic view is somebody's hand-drawn diagram
|
|
@@ -38,6 +44,37 @@ export const USECASE_VIEWS = `- Business use cases are \`dynamic view\`s, and \`
|
|
|
38
44
|
hop written \`a <- b\` is attributed to the call it answers, so spell replies
|
|
39
45
|
that way rather than as fresh hops. Every message names the file the view was
|
|
40
46
|
written in, never the landscape.
|
|
47
|
+
- A flow behind ONE service's own requirement — the hop sequence over its
|
|
48
|
+
containers that an arch.spec.md \`Covers:\` names — lives in that service's own
|
|
49
|
+
LikeC4 project: any \`.likec4\` beside \`services/<…>/<svc>/model.likec4\`
|
|
50
|
+
(\`usecases/<name>.likec4\` by convention, or \`views.likec4\`), or a \`dynamic view\`
|
|
51
|
+
inside model.likec4 itself; loam reads exactly what the renderer's per-service
|
|
52
|
+
project reads. Never \`architecture/usecases/\`, which cannot resolve a container
|
|
53
|
+
and turns the whole fleet \`landscape.invalid\`. Tag it \`#req-<Requirement-ID>\`
|
|
54
|
+
(the id flattened as above). The tag has to be DECLARED where that project can
|
|
55
|
+
see it: in model.likec4's own \`specification\` block when the model declares one
|
|
56
|
+
and therefore stands alone; in \`architecture/landscape.likec4\`'s block when the
|
|
57
|
+
model EXTENDS the map, or in a tags-only \`specification { tag req-… }\` beside
|
|
58
|
+
the \`extend\`, which is legal and lands the tag in the project's specification.
|
|
59
|
+
Declaring it in BOTH is a duplicate, and the code is the one that lands where
|
|
60
|
+
the second declaration's FILE is: \`c4.invalid\` (an error, and the model's
|
|
61
|
+
grading is suspended behind it) when the tags-only block is in model.likec4,
|
|
62
|
+
\`usecase.flow-invalid\` when it is in a sibling. \`c4.fleet-project-invalid\` is
|
|
63
|
+
the fleet-scope class one step out — two SERVICES each declaring the same tag
|
|
64
|
+
locally, which no per-service project sees.
|
|
65
|
+
Then \`loam validate --service <svc>\` grades it — under
|
|
66
|
+
\`--all\`, per service: \`usecase.step-unbacked\` and \`usecase.step-contested\`
|
|
67
|
+
against model.likec4, \`usecase.requirement-unresolved\` against THIS service's
|
|
68
|
+
spec.md and arch.spec.md ids, and \`usecase.flow-invalid\` when a sibling file
|
|
69
|
+
breaks the project (model.likec4 is still graded alone). \`usecase.step-unlinked\`
|
|
70
|
+
never fires on a hop whose caller and provider resolve to the same service — a
|
|
71
|
+
service owes no operationId to itself — while a hop from such a flow into another
|
|
72
|
+
service's element (a stand-in the model declares for a sibling, with no
|
|
73
|
+
\`metadata { op }\`) still warns, exactly as on the fleet map. A \`#cap-\` tag on
|
|
74
|
+
such a flow is \`usecase.capability-unresolved\`: a capability is claimed on the
|
|
75
|
+
fleet map, never inside one service. A resolved service-local \`#req-\` keeps its
|
|
76
|
+
own grade and nothing else — it is not \`keptBy\`, not \`Covers:\`, and no feature
|
|
77
|
+
carries one yet.
|
|
41
78
|
- A FEATURE brings a flow the way it brings every other axis: write it at
|
|
42
79
|
\`features/<FEAT>/usecases/<name>.likec4\` — the same views-only document, in the
|
|
43
80
|
feature's own directory — and \`loam archive\` copies it into
|
|
@@ -52,9 +89,14 @@ export const USECASE_VIEWS = `- Business use cases are \`dynamic view\`s, and \`
|
|
|
52
89
|
that file — the merge is a whole-file copy, so edit the living one directly
|
|
53
90
|
instead) and \`usecase.flow-invalid\` (loam could not read the flows against that
|
|
54
91
|
post-merge map — most often a hop naming an element neither the living
|
|
55
|
-
landscape nor the delta declares
|
|
92
|
+
landscape nor the delta declares; the merge preview stages no service model, so
|
|
93
|
+
a container an extending model declares is not among them either). Do NOT put a
|
|
94
|
+
\`dynamic view\` inside
|
|
56
95
|
\`delta.likec4\`: that document re-declares the landscape's own identifiers and
|
|
57
96
|
carries its own \`specification\` block, so it cannot be read beside the map, and
|
|
58
|
-
the archive refuses it by name.
|
|
97
|
+
the archive refuses it by name. A feature's \`delta.likec4\` keeps that shape
|
|
98
|
+
whatever shape the service models take — \`features/**\` stays excluded from the
|
|
99
|
+
root LikeC4 project, and the delta is pointed at alone
|
|
100
|
+
(\`npx likec4 start features/<FEAT>\`).
|
|
59
101
|
`;
|
|
60
102
|
//# sourceMappingURL=usecases.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usecases.js","sourceRoot":"","sources":["../../../../../src/core/agent/agents-md/map/usecases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG
|
|
1
|
+
{"version":3,"file":"usecases.js","sourceRoot":"","sources":["../../../../../src/core/agent/agents-md/map/usecases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkF5B,CAAC","sourcesContent":["/**\n * The use-case axis of the command map — its own section module for\n * `./subsystem.ts`'s exact reason: command-map.ts sat against the file-line\n * limit and the agents-md package against the five-file cap, so a family added\n * to the `validate --all` cross-check documents itself one package down and is\n * concatenated after the map. The four `usecase.*` codes are what\n * test/codes-drift.test.ts finds here.\n *\n * They are LISTED and not glossed: their fix rows live in the /loam-check\n * table and `loam explain usecase.step-unbacked` prints them, so writing the\n * meanings out again here is the duplication ../../command-map.ts's header\n * describes. What stays is what `explain` does not say — how to opt a view in,\n * and that an untagged dynamic view is never graded at all.\n *\n * Same assembly contract as every section: ../../agents-md.ts concatenates with\n * NO join separator, so this string starts at the first character of its opening\n * line and ends with the newline that closes its last one.\n */\nexport const USECASE_VIEWS = `- Business use cases are \\`dynamic view\\`s, and \\`loam validate --all\\` grades the\n ones that opt in. Write the flow in a file of its own —\n \\`architecture/usecases/<name>.likec4\\`, a \\`views { }\\` block over the landscape's\n elements, which loam reads as ONE LikeC4 project together with the map — and\n tag the view \\`#cap-<capability>\\` to have it graded. The tag spells a declared\n capability id with every \\`/\\` flattened to \\`-\\` (a LikeC4 tag name cannot carry a\n slash), and it must be declared as a \\`tag\\` in the one \\`specification\\` block the\n \\`architecture/\\` project has, since LikeC4 refuses an undeclared tag. loam grades\n the fleet map as THAT project and nothing else — the landscape plus its\n siblings, never a service model — so a hop here names SERVICE elements: a step\n naming a container that a service's extending model declares resolves in the\n renderer's wider root project and is \\`landscape.invalid\\` for loam, which takes\n the whole fleet map down. Container-level flows live beside the model that\n declares them (below). EITHER reserved prefix\n opts a view in — a view carrying only \\`#req-<requirement>\\` is graded too, and\n earns \\`usecase.requirement-unresolved\\` for the \\`#cap-\\` tag it is missing\n rather than silence. An UNTAGGED dynamic view is somebody's hand-drawn diagram\n and is never graded — that opt-in is what lets a fleet full of existing\n diagrams upgrade without turning red, and \\`loam validate\\`, \\`loam diff\\`,\n \\`loam delta\\`, \\`loam status\\`, \\`loam context\\` and \\`loam list capabilities\\` all\n read the same opt-in, so a flow one of them sees is a flow all of them see. On a tagged\n view: \\`usecase.capability-unresolved\\`, \\`usecase.step-unbacked\\`,\n \\`usecase.step-contested\\` and \\`usecase.step-unlinked\\`. The first is silent\n while architecture/capabilities.yaml is absent or unreadable, like the rest of\n the capability axis; the three step codes are about the model, and a return\n hop written \\`a <- b\\` is attributed to the call it answers, so spell replies\n that way rather than as fresh hops. Every message names the file the view was\n written in, never the landscape.\n- A flow behind ONE service's own requirement — the hop sequence over its\n containers that an arch.spec.md \\`Covers:\\` names — lives in that service's own\n LikeC4 project: any \\`.likec4\\` beside \\`services/<…>/<svc>/model.likec4\\`\n (\\`usecases/<name>.likec4\\` by convention, or \\`views.likec4\\`), or a \\`dynamic view\\`\n inside model.likec4 itself; loam reads exactly what the renderer's per-service\n project reads. Never \\`architecture/usecases/\\`, which cannot resolve a container\n and turns the whole fleet \\`landscape.invalid\\`. Tag it \\`#req-<Requirement-ID>\\`\n (the id flattened as above). The tag has to be DECLARED where that project can\n see it: in model.likec4's own \\`specification\\` block when the model declares one\n and therefore stands alone; in \\`architecture/landscape.likec4\\`'s block when the\n model EXTENDS the map, or in a tags-only \\`specification { tag req-… }\\` beside\n the \\`extend\\`, which is legal and lands the tag in the project's specification.\n Declaring it in BOTH is a duplicate, and the code is the one that lands where\n the second declaration's FILE is: \\`c4.invalid\\` (an error, and the model's\n grading is suspended behind it) when the tags-only block is in model.likec4,\n \\`usecase.flow-invalid\\` when it is in a sibling. \\`c4.fleet-project-invalid\\` is\n the fleet-scope class one step out — two SERVICES each declaring the same tag\n locally, which no per-service project sees.\n Then \\`loam validate --service <svc>\\` grades it — under\n \\`--all\\`, per service: \\`usecase.step-unbacked\\` and \\`usecase.step-contested\\`\n against model.likec4, \\`usecase.requirement-unresolved\\` against THIS service's\n spec.md and arch.spec.md ids, and \\`usecase.flow-invalid\\` when a sibling file\n breaks the project (model.likec4 is still graded alone). \\`usecase.step-unlinked\\`\n never fires on a hop whose caller and provider resolve to the same service — a\n service owes no operationId to itself — while a hop from such a flow into another\n service's element (a stand-in the model declares for a sibling, with no\n \\`metadata { op }\\`) still warns, exactly as on the fleet map. A \\`#cap-\\` tag on\n such a flow is \\`usecase.capability-unresolved\\`: a capability is claimed on the\n fleet map, never inside one service. A resolved service-local \\`#req-\\` keeps its\n own grade and nothing else — it is not \\`keptBy\\`, not \\`Covers:\\`, and no feature\n carries one yet.\n- A FEATURE brings a flow the way it brings every other axis: write it at\n \\`features/<FEAT>/usecases/<name>.likec4\\` — the same views-only document, in the\n feature's own directory — and \\`loam archive\\` copies it into\n \\`architecture/usecases/\\` while \\`loam unarchive\\` takes it back. That is what lets\n an analyst add a cross-service requirement and an architect answer it with the\n flow that keeps it IN ONE CHANGE: the \\`#req-\\` tag resolves against this\n feature's own \\`capabilities/<cap>/spec.md\\` delta as well as the living tree, and\n \\`capability.uncovered\\` counts the flow as cover. The flow is graded against the\n map the same merge would leave behind, so a hop may name a service this\n feature's \\`delta.likec4\\` adds. Two refusals guard it, and \\`--approve\\` moves\n neither: \\`usecase.flow-exists\\` (the living \\`architecture/usecases/\\` already has\n that file — the merge is a whole-file copy, so edit the living one directly\n instead) and \\`usecase.flow-invalid\\` (loam could not read the flows against that\n post-merge map — most often a hop naming an element neither the living\n landscape nor the delta declares; the merge preview stages no service model, so\n a container an extending model declares is not among them either). Do NOT put a\n \\`dynamic view\\` inside\n \\`delta.likec4\\`: that document re-declares the landscape's own identifiers and\n carries its own \\`specification\\` block, so it cannot be read beside the map, and\n the archive refuses it by name. A feature's \\`delta.likec4\\` keeps that shape\n whatever shape the service models take — \\`features/**\\` stays excluded from the\n root LikeC4 project, and the delta is pointed at alone\n (\\`npx likec4 start features/<FEAT>\\`).\n`;\n"]}
|
|
@@ -20,10 +20,15 @@ loam has no server or database. Delete it and the documents still make sense.
|
|
|
20
20
|
\`architecture/adrs/\` optional system-level decisions — only their links are graded.
|
|
21
21
|
\`architecture/subsystems.likec4\` is GENERATED by \`loam subsystem sync\` from the
|
|
22
22
|
directory tree under \`services/\` — one view per subsystem, a scoping aid, never
|
|
23
|
-
hand-edited and never a second fleet map
|
|
23
|
+
hand-edited and never a second fleet map; its one styling opt-in is a
|
|
24
|
+
\`global { styleGroup subsystems { … } }\` declared in any \`.likec4\` under
|
|
25
|
+
\`architecture/\`, which \`sync\` then references. A diagram you author belongs in the
|
|
24
26
|
landscape or in a file of your own name beside it.
|
|
25
27
|
\`services/<id>/\` holds a boundary's living \`model.likec4\`, \`spec.md\`,
|
|
26
|
-
\`arch.spec.md\`, OpenAPI, AsyncAPI, runbook and health facts
|
|
28
|
+
\`arch.spec.md\`, OpenAPI, AsyncAPI, runbook and health facts — and
|
|
29
|
+
\`services/<…>/<id>/usecases/*.likec4\`, the slot for a \`dynamic view\` over that
|
|
30
|
+
service's OWN containers, tagged \`#req-<Requirement-ID>\`; a flow that crosses
|
|
31
|
+
services lives in \`architecture/usecases/\` and is tagged \`#cap-\` instead.
|
|
27
32
|
\`features/<FEAT>/\` holds a change in flight: \`intent.md\`, \`delta.likec4\`,
|
|
28
33
|
per-service requirement and contract deltas, and \`verification.yaml\`.
|
|
29
34
|
\`features/archive/\` is shipped history.
|
|
@@ -78,7 +83,10 @@ decision or human-only act; the user does not have to type every loam command.
|
|
|
78
83
|
If loam or an agent integration behaves unexpectedly, invoke \`/loam-report\` (or
|
|
79
84
|
load \`$loam-report\` on a skills-only host). It collects a sanitized, reproducible
|
|
80
85
|
Markdown report under \`loam-reports/\` without repairing the repository, retrying a
|
|
81
|
-
writer or uploading anything.
|
|
86
|
+
writer or uploading anything. Reports are numbered — \`loam-reports/NNN-YYYY-MM-DD-<slug>.md\`,
|
|
87
|
+
cited by ordinal — and carry a \`Status:\` line, so \`loam doctor\` counts the
|
|
88
|
+
directory and says which ordinal the next report takes. This is support, not a
|
|
89
|
+
seventh lifecycle step.
|
|
82
90
|
|
|
83
91
|
## The cycle
|
|
84
92
|
|
|
@@ -86,7 +94,9 @@ writer or uploading anything. This is support, not a seventh lifecycle step.
|
|
|
86
94
|
\`loam init --docs <path-to-docs-repo> --service <id>\`, then \`loam doctor\`.
|
|
87
95
|
1. **Adopt** — for an undocumented boundary load \`loam instructions loam-adopt
|
|
88
96
|
<id>\`, then use \`loam adopt --service <id> --json\`. Write drafts; a person,
|
|
89
|
-
never an agent, later vouches for them.
|
|
97
|
+
never an agent, later vouches for them. Draw the map's edges in the same pass:
|
|
98
|
+
the brief's \`landscape.touched\` is the only place an edgeless element is named,
|
|
99
|
+
and \`landscape.service-isolated\` (fleet scope) goes quiet on the first edge.
|
|
90
100
|
2. **Understand** — start or resume with \`loam status --json\`; its ordered
|
|
91
101
|
\`next[]\` is the work queue. Read \`next[0].execution\`: run it only when
|
|
92
102
|
\`runnable\` is true; otherwise use \`kind\`, \`cwd\`, \`needs\` and \`after\`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../../../src/core/agent/agents-md.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiKnB,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,eAAe,CAAC,YAAY,CAAC,KAAK,WAAW,EAAE,CAAC","sourcesContent":["/**\n * The small, always-loaded orientation contract for a loam docs repository.\n *\n * Detailed grammars and workflows live behind `loam instructions`: those pages\n * describe the binary that is about to run, while this file is written once and\n * may be loaded into every agent turn for years. Keep only enough here to form\n * the next question, find the relevant page, and avoid an unsafe write.\n */\nimport { agentsStampLine } from \"./agents-stamp.js\";\nimport { LOAM_VERSION } from \"../envelope/version.js\";\n\nconst ORIENTATION = `# Working in this docs repo\n\nThis is a **loam** docs repo: plain files are the shared source of truth for a governed software\nfleet's architecture, requirements, contracts and verification evidence. A service may be a modular monolith, a network service, a CLI or a worker.\nloam has no server or database. Delete it and the documents still make sense.\n\n## What is where\n\n\\`architecture/landscape.likec4\\` is the fleet map, and\n\\`architecture/adrs/\\` optional system-level decisions — only their links are graded.\n\\`architecture/subsystems.likec4\\` is GENERATED by \\`loam subsystem sync\\` from the\ndirectory tree under \\`services/\\` — one view per subsystem, a scoping aid, never\nhand-edited and never a second fleet map. A diagram you author belongs in the\nlandscape or in a file of your own name beside it.\n\\`services/<id>/\\` holds a boundary's living \\`model.likec4\\`, \\`spec.md\\`,\n\\`arch.spec.md\\`, OpenAPI, AsyncAPI, runbook and health facts.\n\\`features/<FEAT>/\\` holds a change in flight: \\`intent.md\\`, \\`delta.likec4\\`,\nper-service requirement and contract deltas, and \\`verification.yaml\\`.\n\\`features/archive/\\` is shipped history.\n\nLiving documents are the complete current state. A feature document is a diff\nagainst them, reviewed as a diff; \\`loam archive\\` folds it into living state.\nDo not hand-edit the living landscape to add a feature change.\n\n## Linking between documents\n\nDocuments join with **standard markdown links** whose targets are real relative\npaths, for example \\`[decision](../adrs/ADR-001.md)\\`. They render in pull-request\nreview instead of showing literal brackets,\nand make “does this link resolve” a filesystem question; \\`[[Wikilinks]]\\` would\nrequire shortest-unique-path guessing.\nObsidian supports markdown links, autocomplete and rename-tracking when its\nwikilink setting is off. \\`link.unresolved\\` grades missing targets and CASE\n**is** graded; links outside this repository, \\`#section\\` targets, a fenced code\nblock or an inline code span are deliberately not graded.\n\n## \\`loam.json\\` — the wiring\n\nEvery repository commits its own \\`loam.json\\`:\n\n\\`{ \"docsDir\": \"../docs\", \"service\": \"payment-service\", \"gherkinDir\": \"features\" }\\`\n\n\\`docsDir\\` is stored exactly as it was passed and resolved against the directory\nholding the \\`loam.json\\`, so a relative path survives a clone; an absolute one\nraises \\`doctor.docs-absolute\\`. \\`service\\` binds a service checkout to the one boundary\nit may write evidence for. \\`gherkinDir\\` is optional. \\`agentTools\\` and\n\\`agentProfile\\` record which agent surfaces and workflow subset init manages;\n\\`agentFiles\\` records digests so unchanged generated pointers can refresh while\ncustomized ones remain untouched. With no config, loam refuses with \\`no-config\\`\nrather than guessing.\n\n\\`loam init --docs <dir>\\` **joins** an existing docs repo. Add \\`--create\\` only\nwhen creating a new one; a typo must not scaffold a second source of truth.\n\n## Starting from chat\n\nThere are two equivalent entry points into the same version-matched protocol.\nPrefer the explicit one when a user wants a predictable lifecycle: invoke\n\\`/loam-feature <FEAT> \"<title>\"\\` to propose, \\`/loam-implement <FEAT> [service]\\`\nto build, \\`/loam-check\\` and \\`/loam-verify <FEAT>\\` to grade it, and\n\\`/loam-ship <FEAT>\\` to finish. Most hosts use that flat slash\nspelling; Gemini uses \\`/loam:feature\\`, Amazon Q uses \\`@loam-feature\\`, and a\nskills-only host can invoke \\`$loam-feature\\`. Natural-language requests may load\nthe matching Agent Skill instead. Once either entry point is selected, the agent\ndrives the internal status/edit/validate loop and asks the user only for a real\ndecision or human-only act; the user does not have to type every loam command.\n\nIf loam or an agent integration behaves unexpectedly, invoke \\`/loam-report\\` (or\nload \\`$loam-report\\` on a skills-only host). It collects a sanitized, reproducible\nMarkdown report under \\`loam-reports/\\` without repairing the repository, retrying a\nwriter or uploading anything. This is support, not a seventh lifecycle step.\n\n## The cycle\n\n0. **Wire the repo** — in each service checkout run\n \\`loam init --docs <path-to-docs-repo> --service <id>\\`, then \\`loam doctor\\`.\n1. **Adopt** — for an undocumented boundary load \\`loam instructions loam-adopt\n <id>\\`, then use \\`loam adopt --service <id> --json\\`. Write drafts; a person,\n never an agent, later vouches for them.\n2. **Understand** — start or resume with \\`loam status --json\\`; its ordered\n \\`next[]\\` is the work queue. Read \\`next[0].execution\\`: run it only when\n \\`runnable\\` is true; otherwise use \\`kind\\`, \\`cwd\\`, \\`needs\\` and \\`after\\`\n to complete the edit or external-repo step. Use \\`loam list --json\\`, \\`loam show <id> --json\\`\n and \\`loam explore <id> --json\\` before proposing a change. Never propose a\n change to a service you have not read.\n3. **Scaffold** — load \\`loam instructions loam-feature <FEAT>\\`, then run\n \\`loam new <FEAT> --title \"...\" --touches <service>\\`.\n4. **Author** — fill the scaffolded TODOs and run \\`loam rebase <FEAT>\\` after\n reading the living baselines. The exact joins and authoring grammars are in\n the reference pages below.\n5. **Check** — load \\`loam instructions loam-check --no-fix-tables\\`, run\n \\`loam validate <FEAT> --json\\`, and use \\`loam explain <code>\\` for reported\n codes. \\`loam dependencies --json\\` names features that must archive first.\n6. **Build** — load \\`loam instructions loam-implement <FEAT>\\`.\n \\`loam delta <FEAT> --service <id> --json\\` is one service's task; in that\n service checkout, \\`loam gherkin <FEAT>\\` emits its executable scenarios.\n7. **Verify** — \\`loam verify <FEAT> --json\\` is the checklist. Record evidence\n from each affected service's own checkout. Read\n \\`loam instructions loam-done-check\\` before recording anything.\n8. **Ship** — load \\`loam instructions loam-ship <FEAT>\\`; begin with\n \\`loam archive <FEAT> --dry-run --json\\`, then archive only after the code is\n merged and the plan is the one reviewed.\n\n## Reading loam's output\n\nEvery command takes \\`--json\\`. The envelope has \\`contractVersion\\`, \\`ok\\` and,\non refusal, \\`error.code\\`. Unknown flags are \\`invalid-option\\`; \\`--help\\` and\n\\`--version\\` pass through. Branch on stable codes, never message prose.\n\nValidation \\`findings[]\\` carry \\`severity\\`; archive-related findings also carry\n\\`gates\\`. Severity and gating are two different questions: errors invalidate,\nwhile \\`gates: true\\` makes archive refuse — archive is gated on coherence, so a\ngating finding stops it whatever its severity. Advisory warnings never block.\n\\`--approve\\` overrides the gating issues — only those that are judgement calls —\nand never a mechanical loss. For example \\`delta.requirement-not-merged\\` warns but gates;\n\\`living.requirement-outside-requirements\\` cannot be approved, while\n\\`openapi.op-modified\\` is reviewable.\n\n\\`loam status --json\\` orders executable next actions. Findings include structured\n\\`locations[]\\`; use their paths instead of extracting filenames from prose.\n\\`loam show <FEAT> --json\\` includes a \\`review\\` pack with intent, architecture,\ncontracts, dependencies, verification, blockers and the same next actions.\n\\`loam explain <code> --json\\`\nreturns one code's meaning and fix; \\`loam explain --codes --json\\` lists them.\nWhich codes an INVOCATION can raise is in \\`loam instructions loam-codes\\`.\n\n## The identity rule\n\nA service is the element whose \\`metadata { service '<id>' }\\` matches its\n\\`services/<id>/\\` directory. An exact element id is the legacy fallback. Never\ninfer identity from display names or containment. Relationships join to contracts\nthrough exact ids: OpenAPI \\`operationId\\`, requirement \\`Operations:\\`, and C4\n\\`metadata { op '...' }\\`. Consult \\`loam instructions loam-spine\\` before editing\na join.\n\n## Reference pages — fetch when needed\n\n- \\`loam instructions loam-codes\\` — finding/refusal inventory and fixes.\n- \\`loam instructions loam-spine\\` — operation, message, coverage, permission,\n capability and baseline joins.\n- \\`loam instructions loam-authoring\\` — arch requirements, generated Gherkin\n and frontmatter/vouch grammar.\n- \\`loam instructions loam-done-check\\` — verification evidence and verdicts.\n\nBare \\`loam instructions\\` lists the six workflows, the separate \\`loam-report\\`\nsupport protocol and these references. Generated agent command/skill files are\nsmall pointers to them, so the runtime page wins if an old pointer disagrees with\nthe installed binary. MCP clients can read the same pages as\n\\`loam://orientation\\` and \\`loam://instructions/<name>\\` resources.\n\n## Safety and hand-back\n\nloam's writers are journaled, but the lifecycle still matters. Do not run\n\\`loam vouch\\` for a human, do not invent evidence, do not archive before code is\nmerged, and do not edit generated files under \\`<gherkinDir>/loam/\\` by hand.\n\\`loam unarchive <FEAT>\\` is the supported undo. To abandon a feature that was\nnever archived, review it and use \\`git rm -r features/<FEAT>\\`; loam deliberately\nhas no destructive drop command.\n\nFinish by reporting remaining warnings, unverifiable claims, files or directories\nyou did not inspect, and the exact human action still owed.\n`;\n\nexport const AGENTS_MD = `${agentsStampLine(LOAM_VERSION)}\\n${ORIENTATION}`;\n"]}
|
|
1
|
+
{"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../../../src/core/agent/agents-md.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2KnB,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,eAAe,CAAC,YAAY,CAAC,KAAK,WAAW,EAAE,CAAC","sourcesContent":["/**\n * The small, always-loaded orientation contract for a loam docs repository.\n *\n * Detailed grammars and workflows live behind `loam instructions`: those pages\n * describe the binary that is about to run, while this file is written once and\n * may be loaded into every agent turn for years. Keep only enough here to form\n * the next question, find the relevant page, and avoid an unsafe write.\n */\nimport { agentsStampLine } from \"./agents-stamp.js\";\nimport { LOAM_VERSION } from \"../envelope/version.js\";\n\nconst ORIENTATION = `# Working in this docs repo\n\nThis is a **loam** docs repo: plain files are the shared source of truth for a governed software\nfleet's architecture, requirements, contracts and verification evidence. A service may be a modular monolith, a network service, a CLI or a worker.\nloam has no server or database. Delete it and the documents still make sense.\n\n## What is where\n\n\\`architecture/landscape.likec4\\` is the fleet map, and\n\\`architecture/adrs/\\` optional system-level decisions — only their links are graded.\n\\`architecture/subsystems.likec4\\` is GENERATED by \\`loam subsystem sync\\` from the\ndirectory tree under \\`services/\\` — one view per subsystem, a scoping aid, never\nhand-edited and never a second fleet map; its one styling opt-in is a\n\\`global { styleGroup subsystems { … } }\\` declared in any \\`.likec4\\` under\n\\`architecture/\\`, which \\`sync\\` then references. A diagram you author belongs in the\nlandscape or in a file of your own name beside it.\n\\`services/<id>/\\` holds a boundary's living \\`model.likec4\\`, \\`spec.md\\`,\n\\`arch.spec.md\\`, OpenAPI, AsyncAPI, runbook and health facts — and\n\\`services/<…>/<id>/usecases/*.likec4\\`, the slot for a \\`dynamic view\\` over that\nservice's OWN containers, tagged \\`#req-<Requirement-ID>\\`; a flow that crosses\nservices lives in \\`architecture/usecases/\\` and is tagged \\`#cap-\\` instead.\n\\`features/<FEAT>/\\` holds a change in flight: \\`intent.md\\`, \\`delta.likec4\\`,\nper-service requirement and contract deltas, and \\`verification.yaml\\`.\n\\`features/archive/\\` is shipped history.\n\nLiving documents are the complete current state. A feature document is a diff\nagainst them, reviewed as a diff; \\`loam archive\\` folds it into living state.\nDo not hand-edit the living landscape to add a feature change.\n\n## Linking between documents\n\nDocuments join with **standard markdown links** whose targets are real relative\npaths, for example \\`[decision](../adrs/ADR-001.md)\\`. They render in pull-request\nreview instead of showing literal brackets,\nand make “does this link resolve” a filesystem question; \\`[[Wikilinks]]\\` would\nrequire shortest-unique-path guessing.\nObsidian supports markdown links, autocomplete and rename-tracking when its\nwikilink setting is off. \\`link.unresolved\\` grades missing targets and CASE\n**is** graded; links outside this repository, \\`#section\\` targets, a fenced code\nblock or an inline code span are deliberately not graded.\n\n## \\`loam.json\\` — the wiring\n\nEvery repository commits its own \\`loam.json\\`:\n\n\\`{ \"docsDir\": \"../docs\", \"service\": \"payment-service\", \"gherkinDir\": \"features\" }\\`\n\n\\`docsDir\\` is stored exactly as it was passed and resolved against the directory\nholding the \\`loam.json\\`, so a relative path survives a clone; an absolute one\nraises \\`doctor.docs-absolute\\`. \\`service\\` binds a service checkout to the one boundary\nit may write evidence for. \\`gherkinDir\\` is optional. \\`agentTools\\` and\n\\`agentProfile\\` record which agent surfaces and workflow subset init manages;\n\\`agentFiles\\` records digests so unchanged generated pointers can refresh while\ncustomized ones remain untouched. With no config, loam refuses with \\`no-config\\`\nrather than guessing.\n\n\\`loam init --docs <dir>\\` **joins** an existing docs repo. Add \\`--create\\` only\nwhen creating a new one; a typo must not scaffold a second source of truth.\n\n## Starting from chat\n\nThere are two equivalent entry points into the same version-matched protocol.\nPrefer the explicit one when a user wants a predictable lifecycle: invoke\n\\`/loam-feature <FEAT> \"<title>\"\\` to propose, \\`/loam-implement <FEAT> [service]\\`\nto build, \\`/loam-check\\` and \\`/loam-verify <FEAT>\\` to grade it, and\n\\`/loam-ship <FEAT>\\` to finish. Most hosts use that flat slash\nspelling; Gemini uses \\`/loam:feature\\`, Amazon Q uses \\`@loam-feature\\`, and a\nskills-only host can invoke \\`$loam-feature\\`. Natural-language requests may load\nthe matching Agent Skill instead. Once either entry point is selected, the agent\ndrives the internal status/edit/validate loop and asks the user only for a real\ndecision or human-only act; the user does not have to type every loam command.\n\nIf loam or an agent integration behaves unexpectedly, invoke \\`/loam-report\\` (or\nload \\`$loam-report\\` on a skills-only host). It collects a sanitized, reproducible\nMarkdown report under \\`loam-reports/\\` without repairing the repository, retrying a\nwriter or uploading anything. Reports are numbered — \\`loam-reports/NNN-YYYY-MM-DD-<slug>.md\\`,\ncited by ordinal — and carry a \\`Status:\\` line, so \\`loam doctor\\` counts the\ndirectory and says which ordinal the next report takes. This is support, not a\nseventh lifecycle step.\n\n## The cycle\n\n0. **Wire the repo** — in each service checkout run\n \\`loam init --docs <path-to-docs-repo> --service <id>\\`, then \\`loam doctor\\`.\n1. **Adopt** — for an undocumented boundary load \\`loam instructions loam-adopt\n <id>\\`, then use \\`loam adopt --service <id> --json\\`. Write drafts; a person,\n never an agent, later vouches for them. Draw the map's edges in the same pass:\n the brief's \\`landscape.touched\\` is the only place an edgeless element is named,\n and \\`landscape.service-isolated\\` (fleet scope) goes quiet on the first edge.\n2. **Understand** — start or resume with \\`loam status --json\\`; its ordered\n \\`next[]\\` is the work queue. Read \\`next[0].execution\\`: run it only when\n \\`runnable\\` is true; otherwise use \\`kind\\`, \\`cwd\\`, \\`needs\\` and \\`after\\`\n to complete the edit or external-repo step. Use \\`loam list --json\\`, \\`loam show <id> --json\\`\n and \\`loam explore <id> --json\\` before proposing a change. Never propose a\n change to a service you have not read.\n3. **Scaffold** — load \\`loam instructions loam-feature <FEAT>\\`, then run\n \\`loam new <FEAT> --title \"...\" --touches <service>\\`.\n4. **Author** — fill the scaffolded TODOs and run \\`loam rebase <FEAT>\\` after\n reading the living baselines. The exact joins and authoring grammars are in\n the reference pages below.\n5. **Check** — load \\`loam instructions loam-check --no-fix-tables\\`, run\n \\`loam validate <FEAT> --json\\`, and use \\`loam explain <code>\\` for reported\n codes. \\`loam dependencies --json\\` names features that must archive first.\n6. **Build** — load \\`loam instructions loam-implement <FEAT>\\`.\n \\`loam delta <FEAT> --service <id> --json\\` is one service's task; in that\n service checkout, \\`loam gherkin <FEAT>\\` emits its executable scenarios.\n7. **Verify** — \\`loam verify <FEAT> --json\\` is the checklist. Record evidence\n from each affected service's own checkout. Read\n \\`loam instructions loam-done-check\\` before recording anything.\n8. **Ship** — load \\`loam instructions loam-ship <FEAT>\\`; begin with\n \\`loam archive <FEAT> --dry-run --json\\`, then archive only after the code is\n merged and the plan is the one reviewed.\n\n## Reading loam's output\n\nEvery command takes \\`--json\\`. The envelope has \\`contractVersion\\`, \\`ok\\` and,\non refusal, \\`error.code\\`. Unknown flags are \\`invalid-option\\`; \\`--help\\` and\n\\`--version\\` pass through. Branch on stable codes, never message prose.\n\nValidation \\`findings[]\\` carry \\`severity\\`; archive-related findings also carry\n\\`gates\\`. Severity and gating are two different questions: errors invalidate,\nwhile \\`gates: true\\` makes archive refuse — archive is gated on coherence, so a\ngating finding stops it whatever its severity. Advisory warnings never block.\n\\`--approve\\` overrides the gating issues — only those that are judgement calls —\nand never a mechanical loss. For example \\`delta.requirement-not-merged\\` warns but gates;\n\\`living.requirement-outside-requirements\\` cannot be approved, while\n\\`openapi.op-modified\\` is reviewable.\n\n\\`loam status --json\\` orders executable next actions. Findings include structured\n\\`locations[]\\`; use their paths instead of extracting filenames from prose.\n\\`loam show <FEAT> --json\\` includes a \\`review\\` pack with intent, architecture,\ncontracts, dependencies, verification, blockers and the same next actions.\n\\`loam explain <code> --json\\`\nreturns one code's meaning and fix; \\`loam explain --codes --json\\` lists them.\nWhich codes an INVOCATION can raise is in \\`loam instructions loam-codes\\`.\n\n## The identity rule\n\nA service is the element whose \\`metadata { service '<id>' }\\` matches its\n\\`services/<id>/\\` directory. An exact element id is the legacy fallback. Never\ninfer identity from display names or containment. Relationships join to contracts\nthrough exact ids: OpenAPI \\`operationId\\`, requirement \\`Operations:\\`, and C4\n\\`metadata { op '...' }\\`. Consult \\`loam instructions loam-spine\\` before editing\na join.\n\n## Reference pages — fetch when needed\n\n- \\`loam instructions loam-codes\\` — finding/refusal inventory and fixes.\n- \\`loam instructions loam-spine\\` — operation, message, coverage, permission,\n capability and baseline joins.\n- \\`loam instructions loam-authoring\\` — arch requirements, generated Gherkin\n and frontmatter/vouch grammar.\n- \\`loam instructions loam-done-check\\` — verification evidence and verdicts.\n\nBare \\`loam instructions\\` lists the six workflows, the separate \\`loam-report\\`\nsupport protocol and these references. Generated agent command/skill files are\nsmall pointers to them, so the runtime page wins if an old pointer disagrees with\nthe installed binary. MCP clients can read the same pages as\n\\`loam://orientation\\` and \\`loam://instructions/<name>\\` resources.\n\n## Safety and hand-back\n\nloam's writers are journaled, but the lifecycle still matters. Do not run\n\\`loam vouch\\` for a human, do not invent evidence, do not archive before code is\nmerged, and do not edit generated files under \\`<gherkinDir>/loam/\\` by hand.\n\\`loam unarchive <FEAT>\\` is the supported undo. To abandon a feature that was\nnever archived, review it and use \\`git rm -r features/<FEAT>\\`; loam deliberately\nhas no destructive drop command.\n\nFinish by reporting remaining warnings, unverifiable claims, files or directories\nyou did not inspect, and the exact human action still owed.\n`;\n\nexport const AGENTS_MD = `${agentsStampLine(LOAM_VERSION)}\\n${ORIENTATION}`;\n"]}
|