Every gate on create_rule and create_project_rule was about SHAPE — rule vs process vs snippet, one-thing-you-could-violate, general-enough, not-a-dupe. All of them improve a rule someone has already decided to write. None asked the prior question: has the person this will bind agreed to be bound by it?
Both docstrings now carry the loop.
Propose readily. Noticing that something has hardened into a standing instruction is valuable work; a session that notices and says nothing has thrown the observation away. The single step that belongs between noticing and writing is the operator's yes.
State four things — what it would require in the words it would carry, its intent, why now, and how it would be enforced. The fourth is the one that decides it: "a test, a CI check, a hook, a schema constraint... or nothing" sometimes dissolves the rule rather than improving it, which is the point. What a test can assert should BE that test, and a rule is what remains when nothing mechanical can hold the thing.
Close with a question answerable in one word — approve it as written / let's talk about it / no. "As written" is what makes the first element load-bearing: the operator approved TEXT, so that text is stored verbatim. "Talk about it" is framed as the expected answer rather than a setback. "No" routes the observation to create_note: recorded, findable, binding on nobody. Named options where the interface offers them; three written-out options where it does not.
The argument for asking is better than consent. The operator's yes is the one moment the rule is certainly in front of them — afterwards a conditional rule is not read aloud at session start, and a project-scoped rule is absent from an unfiltered list_rules(). The proposal IS the review, which is also why create_project_rule says to reach for the loop more readily rather than less.
The two commits are a worked example
1a34363 opened with "NOT YOURS TO CALL UNPROMPTED", and that was the wrong instrument. A prohibition names the act it forbids and stays silent on the act it wants, so a caller stops NOTICING rule-shaped things rather than noticing them and asking — trading an occasional unapproved rule for a permanent loss of proposals, the quieter of the two failures. c3ecdf0 is the same guidance rewritten as a practice. The diff between them is the example, which is why both commits are kept.
Guard
tests/test_rule_creation_asks_first.py pins STRUCTURE, never wording — the same bargain the #3123 disambiguator guard strikes next door. Each element matches a family of synonyms so the prose stays free to be rewritten; only deleting one fails. It also asserts the loop precedes the Args: block, because a caller who has decided to make the call reads the parameters and not the prose beneath them. Its header records why the framing changed, so the prohibition is not reintroduced as a tidy-up.
Not in this PR
No provenance column, no new review surface, no back-catalogue audit, and nothing added to the static context or the skill — a per-tool contract belongs in the tool. #3557 stays open for the half of its title this does not address: the record still cannot say which existing rules were approved.
Issue #3557 · note #3565 · rule #165. CI 5605 and 5612 green.
Every gate on `create_rule` and `create_project_rule` was about SHAPE — rule vs process vs snippet, one-thing-you-could-violate, general-enough, not-a-dupe. All of them improve a rule someone has already decided to write. None asked the prior question: has the person this will bind agreed to be bound by it?
Both docstrings now carry the loop.
**Propose readily.** Noticing that something has hardened into a standing instruction is valuable work; a session that notices and says nothing has thrown the observation away. The single step that belongs between noticing and writing is the operator's yes.
**State four things** — what it would require in the words it would carry, its intent, why now, and how it would be enforced. The fourth is the one that decides it: "a test, a CI check, a hook, a schema constraint... or nothing" sometimes dissolves the rule rather than improving it, which is the point. What a test can assert should BE that test, and a rule is what remains when nothing mechanical can hold the thing.
**Close with a question answerable in one word** — *approve it as written* / *let's talk about it* / *no*. "As written" is what makes the first element load-bearing: the operator approved TEXT, so that text is stored verbatim. "Talk about it" is framed as the expected answer rather than a setback. "No" routes the observation to `create_note`: recorded, findable, binding on nobody. Named options where the interface offers them; three written-out options where it does not.
The argument for asking is better than consent. **The operator's yes is the one moment the rule is certainly in front of them** — afterwards a conditional rule is not read aloud at session start, and a project-scoped rule is absent from an unfiltered `list_rules()`. The proposal IS the review, which is also why `create_project_rule` says to reach for the loop more readily rather than less.
### The two commits are a worked example
`1a34363` opened with **"NOT YOURS TO CALL UNPROMPTED"**, and that was the wrong instrument. A prohibition names the act it forbids and stays silent on the act it wants, so a caller stops NOTICING rule-shaped things rather than noticing them and asking — trading an occasional unapproved rule for a permanent loss of proposals, the quieter of the two failures. `c3ecdf0` is the same guidance rewritten as a practice. The diff between them is the example, which is why both commits are kept.
### Guard
`tests/test_rule_creation_asks_first.py` pins STRUCTURE, never wording — the same bargain the #3123 disambiguator guard strikes next door. Each element matches a family of synonyms so the prose stays free to be rewritten; only deleting one fails. It also asserts the loop precedes the `Args:` block, because a caller who has decided to make the call reads the parameters and not the prose beneath them. Its header records why the framing changed, so the prohibition is not reintroduced as a tidy-up.
### Not in this PR
No provenance column, no new review surface, no back-catalogue audit, and nothing added to the static context or the skill — a per-tool contract belongs in the tool. #3557 stays open for the half of its title this does not address: the record still cannot say which existing rules were approved.
Issue #3557 · note #3565 · rule #165. CI 5605 and 5612 green.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ
Every gate on create_rule and create_project_rule was about SHAPE — rule vs
process vs snippet, one-thing-you-could-violate, general-enough, not-a-dupe.
All of them improve a rule someone has already decided to write. None asked
the prior question: has the person this will bind agreed to be bound by it?
Both docstrings now open with the gate, and with the four things a proposal
carries: what it would require in the words it would carry, its intent, why
now, and how it would be enforced.
The fourth is the one that decides it. "A test, a CI check, a hook, a schema
constraint... or nothing" is a question that sometimes dissolves the rule:
what a test can assert should BE that test, and a rule is what is left when
nothing mechanical can hold the thing. A rulebook grows by default and
shrinks only on purpose.
create_project_rule needs the gate more, not less, and says so: a project
rule is absent from an unfiltered list_rules(), and a conditional one is
absent from session start too, so one written there can bind for months
without ever having been in front of the person it binds.
test_rule_creation_asks_first pins structure, never wording — each element
matches a family of synonyms, and the gate must precede the Args: block,
because a caller who has decided to make the call reads the parameters and
not the prose under them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ
The first cut opened "NOT YOURS TO CALL UNPROMPTED", and that is the wrong
instrument. A caller reading a prohibition stops NOTICING rule-shaped things
rather than noticing them and asking — which trades a small failure for a
larger one. The wanted behaviour is more proposals, not fewer.
So both docstrings now describe the practice: propose readily, state the
four things, and close with a question the operator answers in one word —
approve it as written / let's talk about it / no. Named options where the
interface has them, three written-out options where it does not.
"Approve it as written" is what makes element 1 load-bearing: they approved
TEXT, so that text is stored verbatim. "Let's talk about it" is framed as
the expected answer rather than a setback. "No" routes the observation to
create_note, which records without binding.
The argument for asking is also better than consent. The operator's yes is
the one moment the rule is certainly in front of them: afterwards a
conditional rule is not read aloud at session start, and a project rule is
absent from an unfiltered list_rules(). The proposal IS the review.
Guard gains the answers-offered-back element and drops the wording that
forbade; its header records why the framing changed, so the prohibition does
not get reintroduced as a tidy-up.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Every gate on
create_ruleandcreate_project_rulewas about SHAPE — rule vs process vs snippet, one-thing-you-could-violate, general-enough, not-a-dupe. All of them improve a rule someone has already decided to write. None asked the prior question: has the person this will bind agreed to be bound by it?Both docstrings now carry the loop.
Propose readily. Noticing that something has hardened into a standing instruction is valuable work; a session that notices and says nothing has thrown the observation away. The single step that belongs between noticing and writing is the operator's yes.
State four things — what it would require in the words it would carry, its intent, why now, and how it would be enforced. The fourth is the one that decides it: "a test, a CI check, a hook, a schema constraint... or nothing" sometimes dissolves the rule rather than improving it, which is the point. What a test can assert should BE that test, and a rule is what remains when nothing mechanical can hold the thing.
Close with a question answerable in one word — approve it as written / let's talk about it / no. "As written" is what makes the first element load-bearing: the operator approved TEXT, so that text is stored verbatim. "Talk about it" is framed as the expected answer rather than a setback. "No" routes the observation to
create_note: recorded, findable, binding on nobody. Named options where the interface offers them; three written-out options where it does not.The argument for asking is better than consent. The operator's yes is the one moment the rule is certainly in front of them — afterwards a conditional rule is not read aloud at session start, and a project-scoped rule is absent from an unfiltered
list_rules(). The proposal IS the review, which is also whycreate_project_rulesays to reach for the loop more readily rather than less.The two commits are a worked example
1a34363opened with "NOT YOURS TO CALL UNPROMPTED", and that was the wrong instrument. A prohibition names the act it forbids and stays silent on the act it wants, so a caller stops NOTICING rule-shaped things rather than noticing them and asking — trading an occasional unapproved rule for a permanent loss of proposals, the quieter of the two failures.c3ecdf0is the same guidance rewritten as a practice. The diff between them is the example, which is why both commits are kept.Guard
tests/test_rule_creation_asks_first.pypins STRUCTURE, never wording — the same bargain the #3123 disambiguator guard strikes next door. Each element matches a family of synonyms so the prose stays free to be rewritten; only deleting one fails. It also asserts the loop precedes theArgs:block, because a caller who has decided to make the call reads the parameters and not the prose beneath them. Its header records why the framing changed, so the prohibition is not reintroduced as a tidy-up.Not in this PR
No provenance column, no new review surface, no back-catalogue audit, and nothing added to the static context or the skill — a per-tool contract belongs in the tool. #3557 stays open for the half of its title this does not address: the record still cannot say which existing rules were approved.
Issue #3557 · note #3565 · rule #165. CI 5605 and 5612 green.
🤖 Generated with Claude Code
https://claude.ai/code/session_011cPyzNnegXHr5iRMzzy5KJ