-
Notifications
You must be signed in to change notification settings - Fork 2
Lesson Template Contribution Discipline
type: synthesis up: "Home_llm-wiki-memory-template" extends: "Discipline-Gates" related:
- "Lesson-Parallel-File-Drift"
- "Lesson-Validation-Methodology"
- "Multi-Agent-Write-Protocol" tags: [lesson, contribution-discipline, ai-agent, pr-drafting]
Discipline-Gates names "Universal Rationalizations (Always Wrong)" for wiki-write work. A parallel set of rationalizations applies to AI agents (and humans) contributing PRs to this template repository itself. Each one has an empirical incident attached. This page is the record so the same drift does not have to be discovered four times by four different sessions.
This lesson is for template contributors, not derived-project users. Derived projects ingest the wiki and run skills; they do not draft PRs against the template. The rationalizations below are about the latter activity.
Empirical: On 2026-06-12 I wrote, while reasoning about whether to wire the multi-agent write protocol's reference implementation into the agent overlay, "the wiki is effectively single-writer most of the time." Csweet1 corrected me immediately: the web_forager wiki at PaperAnalyticalDeviceND/web_forager has 3-4 human+agent teams writing concurrently, and a real collision had happened that same day (Omegaice's agent advanced remote by 20 commits in the interim; Csweet1 had to manually reconcile a log_web_forager.md union conflict). The full incident is documented at Analysis-of-Wiki-Push-Race-Pattern.
Why it's wrong: "Most of the time" is a probability claim with no evidentiary basis. The architectural assumption that an llm-wiki-memory-template-derived wiki might be multi-writer is empirically grounded; defaulting to single-writer in reasoning leads to underwiring the write path and misclassifying the Multi-Agent-Write-Protocol prototype as "aspirational" rather than "empirically needed but unwired."
The fix: Default to multi-writer for any llm-wiki-template-derived wiki when reasoning about push paths, the protocol's value, or the priority of related work. Single-writer is the exception worth flagging; multi-writer is the assumption.
Empirical: My first draft of PR7's plan introduced an MCP-tool-based content-conflict resolver as "Option C" alongside the defer-to-agent-turn approach Csweet1 and I had discussed. MCP had never been mentioned in any prior turn of the conversation. Csweet1 pushed back: "MCP which seems outside anything proposed before?" The MCP suggestion was pure speculation; the broader pre-push hook expansion in the same draft was a misreading of "tidy" as "tidy + safety net."
Why it's wrong: The user has context an AI agent does not about what integrations are realistic for their stack, what dependencies they want, and what scope is appropriate for a given PR. Options the user did not propose pollute plans, read as scope creep, and force the user to do work disambiguating which parts of the plan are agreed versus speculative. The cleaner version of the same idea is to ask before including, not to include then offer to remove.
The fix: Mirror the scope of the most recent exchange that defined the PR's purpose. If a new integration path occurs while drafting, ask the user before folding it in. "Tidy" means no behaviour change in the affected systems; "wire it in" means connect existing pieces; "ship the feature" means new functionality. Treat the verbs as load-bearing.
Empirical: PR #28 (Memory boundary subsection) shipped with four code comments and prose references using "PR #26." The actual number was 28; 26 turned out to be an unrelated PR. Priscila (psaboia) filed follow-up commit e48f7d4 to fix all four stale references so future readers would not chase the wrong PR. The same near-mistake recurred in PR4's init-wiki.sh draft ("introduced in PR #29: analysis + decision") — caught and corrected before commit only because I noticed it myself.
Why it's wrong: GitHub PR numbers are not deterministic until the PR is opened. Speculating from the count assumes no other contributor opened a PR in between, which is an assumption that fails the moment the repo has more than one active contributor (which it does — see lesson #1). Stale PR references are silent debt; they don't fail any test but mislead the next reader.
The fix: Use a conceptual label (e.g., "PR6 of this cluster", "the rename PR", "the wiring PR") in code comments and prose until the real number is known from gh pr create output. If a number is required (e.g., for a CI workflow trigger), add it as a follow-up commit after the PR is open. Same rule for commit messages, PR bodies, and wiki pages.
Empirical: PR6 (the multi-agent-write-protocol-proto/ → wiki-write-protocol/ rename) added three smoke assertions to scripts/test-mvp/tests/smoke/template-bootstrap/assertions.sh: "renamed dir exists at new path", "old path absent", "README contains new path". Csweet1 flagged this on 2026-06-13: "what sense did it make to add this to the test harness?" The integration test that drives the 9 scenarios via PROTO_DIR already fails catastrophically if the dir vanishes; "old path absent" is paranoia (no realistic regression scenario); "README contains new path" is documentation policing.
Why it's wrong: The test harness exists to catch regressions in behaviour, not to lock in historical state. Assertions that test state add friction for future contributors (anyone modifying the layout must also update the test) without adding safety (no realistic regression they catch). The pattern accumulates noise that masks the real signal when something genuinely breaks.
The fix: Before adding a structural assertion, articulate the specific regression scenario it catches. Frame it as a question: "What realistic edit, by a future contributor, would cause this assertion to fire and nothing else?" If the answer is "no realistic edit" or "the integration test would fail first," do not add the assertion. Good assertions catch DRY-link decay (a skill file losing a reference the agent depends on), parallel-file drift (one of two byte-identical copies diverging), or sync-script gaps (a path missing from ALWAYS_FILES). State-locking assertions almost never qualify.
All four are forms of premature commitment: claiming knowledge the agent does not have (lesson #1, #3), generating options without consent (lesson #2), or freezing a state that has no functional importance (lesson #4). The fix in each case is the same shape: pause, name the realistic case the assumption is supposed to handle, and commit only to what the realistic case requires.
This is the same family as the Discipline-Gates "Universal Rationalizations" patterns for wiki writes, just applied one layer up: instead of rationalizing a bad wiki entry, the agent rationalizes a bad PR draft, a noisy test, or a stale reference. The check structure is the same: name the rationalization, name why it's wrong, name the fix.
- Before drafting a PR plan, re-read the most recent exchange that defined the PR's purpose. Mirror its scope; do not introduce options it did not name.
- Before adding a
PR #Nreference anywhere in code or prose, ask: do I have this number fromgh pr createoutput? If not, use a conceptual label until I do. - Before adding a test assertion, ask: what realistic edit fires this and nothing else? If no answer, do not add it.
- Before reasoning about wiki write paths, ask: what is the empirical writer count? Default to multi-writer for any llm-wiki-template-derived wiki unless told otherwise.
- Discipline-Gates — the wiki-write version of the same idea
- Lesson-Parallel-File-Drift — a related contribution-discipline lesson about byte-identical copies
- Lesson-Validation-Methodology — the structural + behavioural test discipline that frames how to think about what test assertions are for
- Analysis-of-Wiki-Push-Race-Pattern — the empirical record for lesson #1
- Multi-Agent-Write-Protocol — what lesson #1's default assumption implies for the protocol's classification
- Lesson-Gitignore-Anchor-Propagation — a related sync-time footgun surfaced by an external bug report rather than an internal review