CANP-WP-0005: document and detect inclusion diamonds

Section 10.4 said nothing about inclusion being textual and repeated, so an
author met the behaviour only by reading rendered output carefully. That
silence was the defect.

Writing it up got the mechanism wrong at first. I documented a dependency
"reached by two paths" through two include chains, and wrote a detector that
counted composer calls to match. Tested it against the real case that motivated
the task — helix/repo-advance — and it did not fire, though the conventions
block still rendered twice.

The actual mechanism is subtler. helix/commit-sync declares its own
`conventions` input; when composed, resolution passes the including package's
already-resolved values down by name, so it *inherits* the outer text rather
than resolving its own include, and renders it again. Nothing was included
twice; the text appeared twice regardless.

Both mechanisms are now documented with worked diagrams. duplicate_inclusions
detects both — included values that are equal, and an included value contained
within another — and resolve, render and eval warn.

Nothing is deduplicated, as leaned. Deduplicating means choosing which
occurrence survives, since position in a prompt carries meaning, and deciding
what happens when two paths select different versions of the same dependency,
which section 10.3 permits. That is resolver behaviour and section 10.4 keeps
composition declarative.

Verified by reintroducing the diamond in a scratch copy of repo-advance, which
warns, and confirming the shipped factored collection stays silent.
Tests 90 -> 95.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bjefh8NUiEiahN4JLwoSKM

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 388925@bnt-lap001
Assistant-Session: 3507023f-e0fd-4a1e-9d90-a0d4217d1502
This commit is contained in:
tegwick 2026-09-06 19:23:16 +02:00
parent e16bf024d4
commit 75e0597019
5 changed files with 180 additions and 7 deletions

View file

@ -4,7 +4,7 @@ type: workplan
title: "Document and detect inclusion diamonds"
domain: agents
repo: canned-prompts
status: proposed
status: finished
owner: codex
topic_slug: practice
created: "2026-09-06"
@ -20,7 +20,7 @@ Residual from `CANP-WP-0004` (`origin: residual`, `origin_ref: CANP-WP-0004`).
```task
id: CANP-WP-0005-T01
status: todo
status: done
priority: medium
state_hub_task_id: "74234a7a-c3bd-5bf7-a40d-21ddf208cfb5"
```
@ -47,3 +47,28 @@ Two questions, and the second depends on the first:
purpose.
Leaning: document it now, warn at validation time, and do not deduplicate.
## Outcome
Done as leaned, with one correction found by testing.
**The documented mechanism was wrong at first.** § 10.4 was written describing a
dependency "reached by two paths" through two `include` chains, and the detector
counted composer calls to match. Tested against the real case that motivated the
task — `helix/repo-advance` — and it did not fire, even though the conventions
block still rendered twice.
The actual mechanism is different and more subtle. `helix/commit-sync` declares
its own `conventions` input; when composed, resolution passes the including
package's already-resolved values down by name (§ 10.4 inheritance), so it
*inherits* the outer text rather than resolving its own include — and renders it
a second time. Nothing was included twice. The text appeared twice regardless.
Both mechanisms are now documented with worked diagrams, and
`duplicate_inclusions` detects both: included values that are equal, and an
included value contained within another. `resolve`, `render` and `eval` warn;
nothing is deduplicated.
Verified by reintroducing the diamond in a scratch copy of `repo-advance` — it
warns — and confirming the shipped factored collection stays silent.
Tests 90 → 95.