Doctrine written for one surface leaks to every request, because inline prose carries no scope #1049

Open
opened 2026-08-19 04:31:02 +00:00 by coilyco-ops · 0 comments
Member

Generalised from the #935 root cause, which was a specific instance of something the skill format allows everywhere.

The instance

site-work.md is inline: always, so it is in the prompt on every turn regardless of subject. It says, correctly and emphatically:

Never decline a change as another role's to make... Never wait for approval, a review, a window, or a go-ahead... Size is not a reason to defer. "Too small to be worth a write" and "too live to touch" are the same refusal wearing different clothes.

Every word of that is right about the site verbs. But nothing in the prompt scopes it to them. A model meeting a request no tool can serve reads a strongly worded, unqualified instruction not to decline, and #935 measured what happens next: fifteen rounds of unrelated tools and a confabulated answer.

2b4305e patched this instance by adding an explicit scoping paragraph to the new bounded-refusal rule. That fixes one collision and not the mechanism.

The mechanism

An inline: always reference is written by an author thinking about one subject and read by a model on every subject. The format has no way to say "this applies when the request is about X". So a file gets more emphatic to be effective within its topic, and that emphasis is what travels furthest outside it.

The emphasis is the tell. Prose written as never and always to overcome a specific hesitancy is exactly the prose that overrides an unrelated rule two files away.

Other candidates on the same lane

Not measured, listed as the places to look next:

  • moxn-knowledge-base.md says any question about the shared work is answered from a call made this turn rather than from memory. Strong, correct for the knowledge base, and a nudge toward calling moxn on questions that are not about glass at all. The Dowel probe in #935's comment shows a stray moxn.search on a question about host metrics, which is consistent with exactly this.
  • site-work.md's "never end a turn having described an edit instead of having made it", against a lane whose write surface is currently unreachable.
  • coilyco-suite.md names three projects and how to talk about them, which is one bad generalisation away from a product mention in an unrelated answer. It carries its own "answer the question asked" bound, which is the pattern that works.

What would actually fix it

Roughly in order of cost.

  • Scope in the prose, as a convention. Every strongly worded rule states what it applies to, the way the new bounded-refusal section ends by naming what it does not bound. Cheap, no code, and reviewable by reading.
  • A conditional inline tier. A reference that is always loaded but declares its subject, so the prompt can carry "when the request concerns the site: ..." rather than an unqualified imperative. This is a skill-contract change and belongs with #971 and #1004.
  • Test for the collision rather than the rule. The pairing rule already catches "refuses everything" as a degenerate pass. The same shape would catch a rule bleeding: an out-half on a different subject that the strong rule would wrongly capture. That is a boundary-authoring convention rather than a code change.

Why now

The Dowel lane carries six inline: always references and #993 measures that at 24KB every turn. That is six authors' worth of emphatic prose in one prompt, and the number of pairs that can collide grows faster than the file count.

Refs #935, #993, #971, #1004, #1011

Generalised from the #935 root cause, which was a specific instance of something the skill format allows everywhere. ## The instance `site-work.md` is `inline: always`, so it is in the prompt on every turn regardless of subject. It says, correctly and emphatically: > Never decline a change as another role's to make... Never wait for approval, a review, a window, or a go-ahead... **Size is not a reason to defer.** "Too small to be worth a write" and "too live to touch" are the same refusal wearing different clothes. Every word of that is right **about the site verbs**. But nothing in the prompt scopes it to them. A model meeting a request no tool can serve reads a strongly worded, unqualified instruction not to decline, and #935 measured what happens next: fifteen rounds of unrelated tools and a confabulated answer. `2b4305e` patched this instance by adding an explicit scoping paragraph to the new bounded-refusal rule. **That fixes one collision and not the mechanism.** ## The mechanism An `inline: always` reference is written by an author thinking about one subject and read by a model on every subject. The format has no way to say "this applies when the request is about X". So a file gets more emphatic to be effective within its topic, and that emphasis is what travels furthest outside it. The emphasis is the tell. Prose written as **never** and **always** to overcome a specific hesitancy is exactly the prose that overrides an unrelated rule two files away. ## Other candidates on the same lane Not measured, listed as the places to look next: * `moxn-knowledge-base.md` says any question about the shared work is answered from a call made this turn rather than from memory. Strong, correct for the knowledge base, and a nudge toward calling `moxn` on questions that are not about `glass` at all. **The Dowel probe in #935's comment shows a stray `moxn.search` on a question about host metrics**, which is consistent with exactly this. * `site-work.md`'s "never end a turn having described an edit instead of having made it", against a lane whose write surface is currently unreachable. * `coilyco-suite.md` names three projects and how to talk about them, which is one bad generalisation away from a product mention in an unrelated answer. It carries its own "answer the question asked" bound, which is the pattern that works. ## What would actually fix it Roughly in order of cost. * **Scope in the prose, as a convention.** Every strongly worded rule states what it applies to, the way the new bounded-refusal section ends by naming what it does not bound. Cheap, no code, and reviewable by reading. * **A conditional inline tier.** A reference that is always loaded but declares its subject, so the prompt can carry "when the request concerns the site: ..." rather than an unqualified imperative. This is a skill-contract change and belongs with #971 and #1004. * **Test for the collision rather than the rule.** The pairing rule already catches "refuses everything" as a degenerate pass. The same shape would catch a rule bleeding: an out-half on a *different* subject that the strong rule would wrongly capture. That is a boundary-authoring convention rather than a code change. ## Why now The Dowel lane carries **six** `inline: always` references and #993 measures that at 24KB every turn. That is six authors' worth of emphatic prose in one prompt, and the number of pairs that can collide grows faster than the file count. Refs #935, #993, #971, #1004, #1011
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-gaming/sirens-echo#1049
No description provided.