check_catalog_block and catalog-trifecta pin .ward/ward.yaml, so a repo that retires Ward still ships it #1081

Closed
opened 2026-08-16 01:23:21 +00:00 by coilyco-ops · 2 comments
Member

Two validators pin .ward/ward.yaml by path, so a repo that has retired Ward as its command runner still has to keep the file on disk purely to satisfy them.

Where it is pinned

  • agentic_os/pre_commit/check_catalog_block.py sets CONFIG_PATH = Path(".ward/ward.yaml") and fails with "no catalog config found. Every coilysiren/ repo needs .ward/ward.yaml."*
  • catalog-trifecta requires README, AGENTS, and docs/FEATURES.md to each carry a markdown link resolving to .ward/ward.yaml.

Why it came up

coilyco-gaming/sirens-echo moved its 30 dev verbs from Ward to a repo-root justfile (sirens-echo#853). The commands: block is gone and nothing in that repo reads Ward for dev verbs any more.

But .ward/ward.yaml cannot be deleted, because the catalog block has no other home and the trifecta hook wants three links to it. So the repo now ships a file whose only content is:

catalog:
  description: "..."
  dependsOn:
    - ...

and three See-also links pointing at it, which read as though Ward is still the command surface when it is not.

The mismatch

Catalog metadata is repository identity for the cross-repo knowledge graph. It has nothing to do with Ward. It lives at a Ward-shaped path for historical reasons, and now that a consumer has moved off Ward the coupling is visible.

Per the authoring-vs-rollout rule the consumer repo cannot fix this: both validators are authored here.

Options, not a recommendation

  • Accept an alternate path. Have check_catalog_block look for the block at a neutral location (.catalog.yaml, or [tool.agentic-os.catalog] in pyproject.toml) and fall back to .ward/ward.yaml so no repo has to move at once. catalog-trifecta learns whichever path resolved.
  • Leave it. The file is four lines and harmless. The cost is that every repo which retires Ward carries a misleading artifact and three links that misdescribe it.

Either is fine. Filing it so the coupling is recorded rather than rediscovered by the next repo that migrates.

Found while migrating sirens-echo to just.

Two validators pin `.ward/ward.yaml` by path, so a repo that has retired Ward as its command runner still has to keep the file on disk purely to satisfy them. ## Where it is pinned * `agentic_os/pre_commit/check_catalog_block.py` sets `CONFIG_PATH = Path(".ward/ward.yaml")` and fails with *"no catalog config found. Every coilysiren/* repo needs .ward/ward.yaml."* * `catalog-trifecta` requires README, AGENTS, and `docs/FEATURES.md` to each carry a markdown link resolving to `.ward/ward.yaml`. ## Why it came up `coilyco-gaming/sirens-echo` moved its 30 dev verbs from Ward to a repo-root `justfile` (sirens-echo#853). The `commands:` block is gone and nothing in that repo reads Ward for dev verbs any more. **But `.ward/ward.yaml` cannot be deleted**, because the catalog block has no other home and the trifecta hook wants three links to it. So the repo now ships a file whose only content is: ```yaml catalog: description: "..." dependsOn: - ... ``` and three See-also links pointing at it, which read as though Ward is still the command surface when it is not. ## The mismatch Catalog metadata is repository identity for the cross-repo knowledge graph. It has nothing to do with Ward. It lives at a Ward-shaped path for historical reasons, and now that a consumer has moved off Ward the coupling is visible. Per the authoring-vs-rollout rule the consumer repo cannot fix this: both validators are authored here. ## Options, not a recommendation * **Accept an alternate path.** Have `check_catalog_block` look for the block at a neutral location (`.catalog.yaml`, or `[tool.agentic-os.catalog]` in `pyproject.toml`) and fall back to `.ward/ward.yaml` so no repo has to move at once. `catalog-trifecta` learns whichever path resolved. * **Leave it.** The file is four lines and harmless. The cost is that every repo which retires Ward carries a misleading artifact and three links that misdescribe it. Either is fine. **Filing it so the coupling is recorded rather than rediscovered** by the next repo that migrates. Found while migrating sirens-echo to `just`.
Author
Member

Correcting my own framing. Kai recalled that catalog-trifecta had been updated for something like this, and she is right. Lucia (AI Engineer seat), 2026-08-15.

I wrote that these hooks "pin .ward/ward.yaml", which reads as a design choice. The truer statement is that both once accepted several paths, and the coily -> ward migration collapsed them. That migration is the precedent for this one.

What 6bbf7eda did

check_catalog_trifecta.py had a genuinely multi-entry tuple, commented "Existence-only fourth member; .coily for personal, .ward for external-facing." It became:

# Existence-only fourth member: the ward command spec.
CATALOG_YAMLS = (Path(".ward/ward.yaml"),)

The mechanism survived, the alternatives did not. resolve_catalog_yaml() still loops over the tuple and returns the first path that exists, so it is doing single-candidate work with multi-candidate machinery.

check_catalog_block.py fared worse. It had:

CONFIG_PATHS = (Path(".ward/ward.yaml"), Path(".coily/coily.yaml"))

with documented fallback behaviour. That became a bare CONFIG_PATH, so the multi-path support is gone rather than narrowed.

Why this makes the issue smaller

I framed the options as a real design question. It is mostly a restoration:

  • trifecta - add a path to the tuple that is already there. resolve_catalog_yaml() needs no change at all.
  • block - restore CONFIG_PATHS as a tuple with fallback, which is what it was until June.

The house has done this exact migration before, kept both spellings live through the transition, and dropped the old one afterwards. A ward-to-just move wants the same shape.

What it does not settle

Which path replaces it. A justfile carries no catalog block, so the block has to live somewhere: .catalog.yaml, [tool.agentic-os.catalog] in pyproject.toml, or something else. That is the actual open question, and it is a smaller one than "can these hooks move at all", which is what I implied.

Two repos are now carrying the artifact this describes: coilyco-gaming/sirens-echo #853 and coilyco-flight-deck/agent-compose #291, both keeping a .ward/ward.yaml that holds only a catalog block, plus three See-also links calling it a command manifest it no longer is.

**Correcting my own framing. Kai recalled that catalog-trifecta had been updated for something like this, and she is right.** Lucia (AI Engineer seat), 2026-08-15. I wrote that these hooks "pin `.ward/ward.yaml`", which reads as a design choice. **The truer statement is that both once accepted several paths, and the `coily -> ward` migration collapsed them.** That migration is the precedent for this one. ## What `6bbf7eda` did `check_catalog_trifecta.py` had a genuinely multi-entry tuple, commented *"Existence-only fourth member; .coily for personal, .ward for external-facing."* It became: ```python # Existence-only fourth member: the ward command spec. CATALOG_YAMLS = (Path(".ward/ward.yaml"),) ``` **The mechanism survived, the alternatives did not.** `resolve_catalog_yaml()` still loops over the tuple and returns the first path that exists, so it is doing single-candidate work with multi-candidate machinery. `check_catalog_block.py` fared worse. It had: ```python CONFIG_PATHS = (Path(".ward/ward.yaml"), Path(".coily/coily.yaml")) ``` with documented fallback behaviour. That became a bare `CONFIG_PATH`, so **the multi-path support is gone rather than narrowed.** ## Why this makes the issue smaller I framed the options as a real design question. It is mostly a restoration: * **trifecta** - add a path to the tuple that is already there. `resolve_catalog_yaml()` needs no change at all. * **block** - restore `CONFIG_PATHS` as a tuple with fallback, which is what it was until June. The house has done this exact migration before, kept both spellings live through the transition, and dropped the old one afterwards. A ward-to-just move wants the same shape. ## What it does not settle Which path replaces it. A `justfile` carries no catalog block, so the block has to live somewhere: `.catalog.yaml`, `[tool.agentic-os.catalog]` in `pyproject.toml`, or something else. **That is the actual open question**, and it is a smaller one than "can these hooks move at all", which is what I implied. Two repos are now carrying the artifact this describes: `coilyco-gaming/sirens-echo` #853 and `coilyco-flight-deck/agent-compose` #291, both keeping a `.ward/ward.yaml` that holds only a catalog block, plus three See-also links calling it a command manifest it no longer is.
Author
Member

This issue is superseded. Close it in favour of coilyco-flight-deck/ward #1660. Lucia (AI Engineer seat), 2026-08-15.

I filed this asking where the catalog block should move. It does not move. It is deleted, and this hook is deleted with it.

coilysiren/inbox #365 already ruled that .ward/ward.yaml leaves repos entirely: just takes over commands:, and every other key is deleted or relocated. ward#1660 carries the one key that is live, catalog.dependsOn, and says outright:

agentic_os/pre_commit/check_catalog_block.py in agentic-os exists solely to enforce that dependsOn is present and a list. It gets retired alongside this.

So both of my proposals here were wrong in the same direction. Adding a path to CATALOG_YAMLS, or restoring CONFIG_PATHS as a tuple, would be building a road to a demolished building. The right change is deletion, sequenced behind ward#1660, because the hook cannot retire while ward still reads the key at agent launch.

catalog-trifecta is the residue worth keeping in view. It requires README, AGENTS, and FEATURES to link .ward/ward.yaml, so when the file goes those three links become dead in every catalog repo. That is a trifecta change rather than a block-hook one, and it is real work this issue was right to notice even though it framed the cause wrongly.

One number for whoever schedules it. I swept all 33 repos: 12 declare a non-empty dependsOn, and 6 more ship the file with no dependsOn key at all, which this hook would reject today if it were wired in them. Full breakdown on ward#1660.

Recommend closing this as superseded rather than leaving two issues describing the same retirement from different ends.

**This issue is superseded. Close it in favour of `coilyco-flight-deck/ward` #1660.** Lucia (AI Engineer seat), 2026-08-15. I filed this asking where the catalog block should move. **It does not move. It is deleted**, and this hook is deleted with it. `coilysiren/inbox` #365 already ruled that `.ward/ward.yaml` leaves repos entirely: `just` takes over `commands:`, and every other key is deleted or relocated. ward#1660 carries the one key that is live, `catalog.dependsOn`, and says outright: > `agentic_os/pre_commit/check_catalog_block.py` in agentic-os exists solely to enforce that `dependsOn` is present and a list. **It gets retired alongside this.** So both of my proposals here were wrong in the same direction. Adding a path to `CATALOG_YAMLS`, or restoring `CONFIG_PATHS` as a tuple, would be building a road to a demolished building. **The right change is deletion, sequenced behind ward#1660**, because the hook cannot retire while ward still reads the key at agent launch. `catalog-trifecta` is the residue worth keeping in view. It requires README, AGENTS, and FEATURES to link `.ward/ward.yaml`, so when the file goes those three links become dead in every catalog repo. That is a trifecta change rather than a block-hook one, and it is real work this issue was right to notice even though it framed the cause wrongly. **One number for whoever schedules it.** I swept all 33 repos: 12 declare a non-empty `dependsOn`, and 6 more ship the file with no `dependsOn` key at all, which this hook would reject today if it were wired in them. Full breakdown on ward#1660. Recommend closing this as superseded rather than leaving two issues describing the same retirement from different ends.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/agentic-os#1081
No description provided.