Skip to content

Docs(refactor[agents]): Route instead of restate - #4

Merged
tony merged 8 commits into
masterfrom
house-style
Aug 22, 2026
Merged

Docs(refactor[agents]): Route instead of restate#4
tony merged 8 commits into
masterfrom
house-style

Conversation

@tony

@tony tony commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

AGENTS.md is read on every task, so anything in it that governs one class of change is context spent on every change that does not touch that class. This splits the policy in three and leaves the root file as a router.

Layout

  • AGENTS.md — universal constraints, then one pointer per class of change, and nothing else.
  • .github/WRITING.md — how we write: README prose, changelog, release notes, commit messages, API documentation, source comments, terminology, code blocks.
  • .github/CONTRIBUTING.md — how we work: build, tests, required checks, pull request structure, review, releases, compatibility.

The root CONTRIBUTING.md is gone; .github/CONTRIBUTING.md replaces it. GitHub still links a contributing guide from that location, so the new-issue and new-pull-request pages are unaffected.

CLAUDE.md is a symlink to AGENTS.md, so it follows with no separate change.

The routes are written as conditions — "for changes to X, follow Y" rather than a bare "read Y" — so an agent re-evaluates per change instead of treating the pointer as a one-time startup instruction.

What the policy says

Two things in .github/WRITING.md are worth calling out:

  • Commit format now has a single home. AGENTS.md on master mandated the Scope(type[detail]): prefix while CONTRIBUTING.md on master forbade prefixes outright. The repository's own history uses the prefix, so that is what is written down, and the contradiction is gone.
  • The documentation rules are Javadoc rules, not generic ones: contract over mechanism, the first sentence as the summary the tool generates, and JSpecify carrying nullability because NullAway already enforces it in JSpecify mode.

.github/CONTRIBUTING.md absorbs the socket-hygiene rule in full. That was forty lines of test hygiene living in AGENTS.md — exactly the always-on context cost this refactor exists to remove. AGENTS.md keeps one line naming the socket roots, as a constraint plus a route rather than a restatement.

Nothing claims a gate that does not exist. No japicmp, no SBOM, no release machinery beyond what release.yml already does. japicmp in particular would contradict the README's own alpha terms, which promise no compatibility at all.

Repairs

Moving CONTRIBUTING.md under .github/ left two links resolving to nothing, and moving the socket rule out of AGENTS.md left six files citing a file that no longer explains what they cite it for. Both sets are repointed. docs/parity/test-map.md is deliberately untouched: its "per AGENTS.md" quotes the Python repository's file inside a row describing a Python test.

The alpha terms were stated three different ways — the README blockquote, the README Status section, and the CHANGELOG.md preamble. They now agree, in the wording every port shares: releases carry an -alpha prerelease tag, the API is not settled, any release may change or remove exported identifiers without a deprecation period, pin an exact version, not recommended for production.

The README title is libtmux for Java, matching the other ports.

Verification

./gradlew check passes. docs-tests re-ran rather than resolving from cache, so the Java snippets in the edited README were compiled and run against a real tmux. Every relative link in the touched files resolves on disk, and no <placeholder> remains in the tree.

.github/*.md is not covered by docs-tests, so the code blocks in the two policy files are gated by review alone.

Not in this branch

The heading sets in both policy files are shared with five sibling ports and are unchanged. Filling those ports is separate work.

tony added 8 commits August 22, 2026 06:32
why: AGENTS.md is read on every task, so a policy that matters to
one class of change costs context on all the others. Splitting how
we work from how we write lets each be loaded when it applies, and
keeps both discoverable to humans rather than only to agents.

what:
- Replace the AGENTS.md body with a router: universal constraints,
  then one pointer per class of change
- Add .github/WRITING.md for prose policy: README, changelog,
  release notes, commit messages, API docs, source comments,
  terminology
- Move CONTRIBUTING.md under .github/ as workflow policy: build, test,
  required checks, pull requests, review, releases, compatibility
- Title the README "libtmux for <language>" and state the alpha
  terms the same way across the ports
- Section bodies are <placeholder>; a per-language pass fills them
  from what this branch replaced
why: The router promised a prose policy and pointed at a file whose
every section body was the literal string <placeholder>. An agent or
contributor following the route reached nothing, and the rules it was
meant to carry stayed only on master, in a file the branch replaced.

what:
- Fill README, changelog, release notes, commit messages, API
  documentation, source comments, terminology, and code blocks
- Keep the commit format as the single home for it, resolving master's
  contradiction between AGENTS.md, which mandated the Scope(type[detail])
  prefix, and CONTRIBUTING.md, which forbade prefixes outright; the
  repository's own history uses the prefix
- Recast the documentation rules for Javadoc: contract over mechanism,
  the first sentence as the generated summary, and JSpecify carrying
  nullability because NullAway already enforces it
- State the 80-column wrap for files and the no-wrap rule for pull
  request and issue bodies, which GitHub renders differently
why: Same empty route as the writing policy, and this file also has to
absorb the socket-hygiene rule. That rule was 40 lines of test hygiene
sitting in AGENTS.md, which is read on every task — exactly the
always-on cost the router refactor exists to remove.

what:
- Fill building, running the tests, checks, pull requests, review,
  releases, and compatibility
- Move the socket-hygiene rule here in full: the two roots, why a bare
  /tmp/libtmux- prefix collides with a sibling port, the failure modes
  that debris produces, and how to find whose servers are running
- Carry over the published-directory table and the libtmux-kotlin case
  that produced the platformCoversEveryPublishedModule gate
- Say that a green check reporting UP-TO-DATE verified nothing, and that
  the exit status is what to read rather than the last lines of output
- Describe review as what actually happens rather than inventing a
  process the project does not run
why: The root file is read on every task, so what it holds should be
what applies before the class of change is known. It had a placeholder
where those constraints belong, and no route to RELEASING.md.

what:
- State the constraints that bind every change: smallest coherent
  change, reuse before adding, package-private until a caller needs it,
  a new file only for a durable boundary, and a gate that has been shown
  capable of failing
- Name the socket roots as a constraint and route to CONTRIBUTING.md for
  why, rather than restating the reasoning here
- Add the release route
why: Moving CONTRIBUTING.md under .github/ left two links resolving to
nothing, and moving the socket-hygiene rule out of AGENTS.md left six
files pointing at a file that no longer explains what they cite it for.

what:
- Repoint README.md and scripts/README.md at .github/CONTRIBUTING.md
- Repoint the socket-hygiene referrers in gradle.properties,
  reap-stale-servers.sh, scripts/README.md, integration-tests/README.md,
  libtmux-junit5/README.md, and docs/spikes/22-abandoned-servers.md
- Leave docs/parity/test-map.md alone: its "per AGENTS.md" quotes the
  Python repository's file inside a row describing a Python test
why: Three places stated the same terms three ways. The README
blockquote had been updated to the wording every port now shares, while
the README's own Status section and the changelog preamble still carried
the older phrasing, so the file disagreed with itself.

what:
- Restate README Status and the CHANGELOG preamble in the shared terms:
  an -alpha prerelease tag, an unsettled API, identifiers that may change
  or be removed with no deprecation period, pin an exact version, not
  recommended for production
- Keep the point that tmux correctness is not alpha, being gated against
  every supported release on each push
- Drop the Maven comparator explanation from Status; gradle.properties
  already carries it beside the version it explains
why: The opening line said twelve subprojects where settings.gradle.kts
declares eleven, and a hardcoded count is what the upkeep gate and the
slop rule both forbid — it is false the first module that moves. The
branch also owed itself a changelog entry: it moves a file callers link
to, and the rule requiring one ships in this same branch.

what:
- Describe the build without counting it, as the published-artifact rule
  beneath it already does
- Add the Documented entry for the CONTRIBUTING.md move
- Present the changelog categories as the allowed set rather than the set
  already in use; Security has no entries yet
why: The module reads more than it compiles, and only the compiling half
was written down. DocumentationFactsTest holds the versions in install
blocks, the platform's own README and the parity citations to the build,
and nothing said so — the first anyone learns of it is a failure naming
a check no document mentions. The gate a contributor is told to run
before opening a pull request did not route to any of it either.

what:
- Add a section for the claims that are not code, one row per check and
  where it looks, including the two documents nothing takes snippets from
- Say a type-declaring block is compiled and never run, whatever its
  directive: a declaration has nothing to execute
- Say throws: matches the exception's simple name, and that the directive
  comment has to sit directly above the fence
- Add yamlString to the fixtures a snippet may assume, and stop counting
  them in prose; the count is the code's to own
- Scope the document list to snippets, since the other checks read wider
- Name :docs-tests:test in the checks that must pass and route to this
  README from there, beside the code that reads the directives
@tony
tony merged commit 05feb91 into master Aug 22, 2026
15 checks passed
@tony
tony deleted the house-style branch August 22, 2026 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant