spec: make endpoint authority an explicit, sourced decision in the contract - #30
Merged
Merged
Conversation
Workflow section 5 already requires the filled contract to identify whether commit, branch publication, PR updates and validation are authorized. The template had nowhere to record the answer: NORMAL STOP CONDITION is free text, and STOP CONDITION states the shipped endpoint as generic prose rather than as a filled decision. A requirement whose answer has no field is a requirement the filled artifact does not carry, which is how an agent came to write a contract that stopped after local tests and asked for a fresh approval to commit, push and open a PR -- work sections 14 and 21 authorize autonomously. ENDPOINT AUTHORITY lists the six endpoints as separate decisions, each with the shipped default and the section it comes from, so filling the block means choosing against a stated default rather than inventing one from scratch. Each line also records where its decision came from: an explicit operator instruction, an applicable repository restriction, or unresolved. Caution is named as not being a source, because that is the actual failure mode. An endpoint the agent narrowed on its own is unresolved and gets settled with the operator before freeze; it is not the operator's decision, and writing it as one misrepresents them to every later session. Merge is fixed on the line rather than left to a source value: explicit operator authorization only, per section 22. A planning-only or local-only request does restrict publication, and that restriction has a source -- the operator said it. The absence of any instruction is not that. The specification baseline refused this edit until it was updated deliberately, which is what pinning it is for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
"The project-specific contract overrides generic defaults below where it is more restrictive" was the mechanism behind the second incident in issue #25. An agent chose caution, wrote a narrower endpoint into the contract, and the rules then treated that as winning over sections 14 and 21 -- because nothing distinguished a restriction the operator asked for from one the agent invented. Adding the endpoint field alone would have left this sentence still legitimizing the invention. A more restrictive contract now overrides only when the restriction records a source. An unsourced restriction does not override anything and is resolved with the operator before freeze rather than acted on. The sentence names the consequence, since that is what makes a rule stick: presenting an agent's caution as the operator's decision misrepresents them to every later session that reads the contract correctly. The rule deliberately does not work in reverse. An unsourced line is resolved, not widened past the shipped defaults, and merge authority is never widened at all. Section 21 already said not to stop merely because local tests are green, and section 22 already reserved merge; rereading both confirmed this introduces no contradiction with either. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The invented restriction in issue #25's second incident did not stay in the contract. It propagated into the handoff, where a successor session that reads the handoff correctly inherits it as though the operator had set it. Two additions close that path. The handoff's minimum record list now includes endpoint authority with each line's source, next to approved scope and frozen invariants. A successor therefore inherits the sources too, so an unresolved line arrives visibly unresolved instead of arriving as a boundary. PR CONTEXT AUTHORITY ORDER gains the item it was missing. It ranked repository truth, design, parents, handoff and memory, but said nothing about the operator talking to the session right now -- so a stale recorded restriction outranked a fresh instruction by omission. An explicit instruction in the current session now outranks a recorded restriction, and the reconciliation is explicit: quote the instruction, record it as the source, and say that it replaces the earlier line. Neither side is silently dropped, and an instruction must be quotable from the current session rather than asserted. Merge authority is carved out of both: never inherited, never widened, always requiring explicit authorization for this merge. The workflow's fresh-session step and recovery step say the same thing in the reader's voice, in both languages: work to the contract's endpoint authority, raise an unresolved line instead of narrowing it further, and report a restriction that exists only in a handoff with no source rather than obeying it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…xists
Workflow section 5 already required the contract to identify whether
commit, branch publication, PR updates and validation are authorized.
Identifying is not reconciling, and the incident's contract satisfied the
letter of that sentence while contradicting the effort it was written for.
Freezing now requires comparing the filled endpoint block against what the
operator actually said. A block that stops at local documentation and
tests, in an effort whose agreed workflow runs to PR review readiness, is
a mismatch to raise rather than a cautious default to freeze. The converse
is stated in the same breath, because a rule that only ever unlocks things
is a rule that will eventually unlock the wrong one: a planning-only or
explicitly local-only request does not acquire publication permission
because the shipped default has one. Both languages carry this.
The human autonomy paragraph gains the part a user needs in order to
exercise the control at all: the contract records which endpoints they
authorized, merge is never one of them, and the agent may not quietly
narrow the list -- a stopping point they did not ask for is a question for
them, not a default the agent adopts on their behalf. Without that
sentence the feature exists only in a specification the user does not
read.
Edited in docs/content.{en,zh-CN}.json and regenerated into README,
TUTORIAL, both HTML pages and both packages.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 11, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses the second incident in #25 (the comment thread), which #29 did not touch. #25 stays open until this merges.
What went wrong
An agent had read the working rules — sections 14, 21 and 22 were in its context. It then wrote a contract and a fresh-session kickoff that stopped after local documentation and tests, requiring a new approval for commit, push and PR creation. The operator never asked for that endpoint. The restriction then propagated into the handoff, where a successor session that reads the handoff correctly inherits an agent-invented limitation as though the operator had set it.
So "make the agent read more" cannot fix this. It had read.
The actual mechanism, which is three facts together
NORMAL STOP CONDITIONis free text;STOP CONDITIONstates the shipped endpoint as generic prose, not as a filled decision. A §5 requirement whose answer has nowhere to live is one the filled artifact does not carry.implementation-working-rules.mdsaid: "The project-specific contract overrides generic defaults below where it is more restrictive." That is the loophole — an agent that chose caution wrote something the rules then treated as winning over §14 and §21, because nothing distinguished a restriction the operator asked for from one the agent invented.Adding the field alone would have left point 3 still legitimizing the invention. So this PR does both.
Four commits
ENDPOINT AUTHORITYin the contract template. Six endpoints as separate decisions — implementation + local validation, semantic commits, branch push, PR creation/update, CI repair to review readiness, merge — each with the shipped default and the section it comes from, so filling the block means choosing against a stated default rather than inventing one. Each line records a source: explicit operator instruction, applicable repository restriction, orunresolved. Caution is named as not being a source. Merge is fixed on the line: explicit operator authorization, no source value changes it.PR CONTEXT AUTHORITY ORDERgains the item it was missing — it ranked repository truth, design, parents, handoff and memory, but said nothing about the operator talking to the session right now, so a stale restriction outranked a fresh instruction by omission. An explicit instruction in the current session now outranks a recorded restriction, quoted and recorded as the new source, with neither side silently dropped. Merge is carved out of both.Validation
translations.jsonalone and seeingEstablished specification changed: .../implementation-working-rules.mddist/copies, not only from sourceRan 171 tests ... OK (skipped=1); all five--checkvalidations PASS; packages at codex 23 / claude-code 22 filesLimits, stated because #25 asks for them
No test asserts that an agent applied any of this, and none pretends to. What changed is the shape of the artifact: the decision now has a field, a default, a source, and a rule that an unsourced narrowing does not win. Whether a given session reconciles correctly stays a semantic judgement. The merge boundary is untouched in every direction, and nothing here grants blanket publication access.
🤖 Generated with Claude Code