Skip to content

docs: bound documentation and comment length in template AGENTS.md (port aeloop#434) - #14

Merged
mariushelf merged 2 commits into
mainfrom
feat/9-loop-docs-bound-documentation-and-comment-len
Aug 14, 2026
Merged

docs: bound documentation and comment length in template AGENTS.md (port aeloop#434)#14
mariushelf merged 2 commits into
mainfrom
feat/9-loop-docs-bound-documentation-and-comment-len

Conversation

@mariushelf

Copy link
Copy Markdown
Owner

Committed on feat/9-loop-docs-bound-documentation-and-comment-len as 5169fce. Working tree clean.

PR-ready summary

docs: bound documentation and comment length in template AGENTS.md (#9)

What changed

  • template/AGENTS.md.jinja — appended a Documentation and Comment Style section at the end of the file, verbatim from the spec. It ports the added-fact rule from agentic-engineering-loop#434: past the summary line, every line must tell the reader something the name, signature, type hints, or code cannot. It lists what earns more than a summary line (contracts, units/bounds, surprising caller-visible behaviour, pointers to the why) and what does not (restating the signature, narrating the implementation, history, obvious examples), and extends the same rule to prose and to edits (a docstring must not get longer unless behaviour was added). No Jinja expressions introduced.
  • tests/test_template.pytest_template_renders now asserts AGENTS.md and CLAUDE.md exist in the generated project, plus that the rendered AGENTS.md contains no unresolved {{ placeholders.

Behaviour

Generated projects now instruct their agents to bound documentation length. The template already enforced docstring presence via ruff D; this bounds length. Nothing executable changed.

Deviations from the spec (worth a reviewer's eye)

  1. The target file is template/AGENTS.md.jinja, not template/AGENTS.md. The spec was written against a state where it was a static file; on current main it is a Jinja template with {% if include_hexagonal %} blocks and Architecture / Testing & Linting sections after Git Conventions. I appended at the end of the file (after Testing & Linting) rather than immediately after Git Conventions, which is what "append at the end" implies now. The spec's "no Jinja" constraint is honoured for the added text; the file's pre-existing delimiters are untouched.
  2. Extra assertion. Because AGENTS.md is now rendered rather than copied verbatim, leftover-placeholder leakage became a real failure mode the spec didn't anticipate. I added one "{{" not in ... check, matching the pattern already used in test_docs_scaffold_renders.
  3. The spec's "deliberately not ported" rationale is outdated but the decision still holds. The template does now ship a Sphinx tree including docs/source/contributing/code_style.md — currently an unauthored scaffold stub. I left it alone, per the spec's explicit scope. If the reviewer wants the docs half of #434 too, that is a follow-up issue.
  4. No Co-Authored-By trailer, per the spec's acceptance criteria and the template's own Git Conventions.

Verification

uv run pytest tests -q20 passed (both hexagonal and flat parametrisations; includes the generated project's make lint, make test, make docs-strict, make test-docs, and pre-commit run --all-files). I also rendered both variants by hand and read the resulting AGENTS.md: section present, one blank line of separation, zero Jinja delimiters.

Impact / risk

Low. Documentation-only text in a template file plus three test assertions; nothing added is executable. Worst case is wording taste, fully reviewable in the diff. The one thing a reviewer should confirm is judgement call (1) — placement at end-of-file rather than after Git Conventions.

Fixes #9

~Written by Claude, run via the agentic engineering loop

Ports the added-fact rule from agentic-engineering-loop#434. The template
enforces docstring presence (ruff D, numpy convention) but nothing bounded
their length, so agents in a generated project produced Parameters/Returns
blocks that restate annotations and docstrings that only grow.

The new Documentation and Comment Style section states the rule: past the
summary line, a line must carry a fact the code cannot.

Also assert AGENTS.md and CLAUDE.md land in the generated project, and that
AGENTS.md has no unresolved Jinja placeholders.
@mariushelf mariushelf added the documentation Improvements or additions to documentation label Aug 14, 2026
@mariushelf

Copy link
Copy Markdown
Owner Author

Build complete.

~Written by Claude, run via the agentic engineering loop

@mariushelf mariushelf left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: intent vs behaviour

The added text is byte-identical to the spec's verbatim block (diff of the spec fence against template/AGENTS.md.jinja:74-109 → no differences), appended as a pure addition (37 insertions, 0 deletions) with Package Management and Git Conventions untouched.

Verified locally:

  • No Jinja introduced. No {{ or {% on any added line; rendered both include_hexagonal=true/false variants and grepped the output — zero delimiters, and exactly one blank line before the new heading in both (AGENTS.md:69-70 hexagonal, :28-29 flat).
  • Factual claim holds. "Docstring presence is enforced by ruff's D rules (numpy convention) in pyproject.toml" matches template/pyproject.toml.jinja:43 ("D" selected) and :68-69 (convention = "numpy").
  • Suite green. uv run pytest tests -q20 passed. Durations confirm the heavy tests really executed (make docs-strict 2.3s per variant, pre-commit run --all-files 0.46s); I re-ran uvx pre-commit run --all-files by hand in a rendered project to confirm the hooks (ruff, ruff format, yamllint, ty, import-linter) actually run and pass rather than the green being vacuous.
  • Commit hygiene. 5169fce uses the docs: prefix and carries no trailers at all (%(trailers) is empty) — no Co-Authored-By, no AI attribution.

All five acceptance criteria met. The template/AGENTS.mdtemplate/AGENTS.md.jinja filename shift is a stale-spec artefact, not a deviation: it is the same file (it renders to AGENTS.md in the generated project), it does end with the new section, and the deviation is disclosed in the PR body.

On the disclosed judgement call (placement at end-of-file rather than immediately after Git Conventions): appending after Testing & Linting reads better than wedging documentation style between git conventions and the architecture/testing material, and the AC says "ends with" — I'd keep it.

Findings

Nothing gating. Three non-blocking notes for the human reviewer, the first of which is the one worth a decision — see the inline comments. In short: the spec's premise that "the template ships no Sphinx docs/ tree and no contributing guide" is now false, and the ported prose paragraph contradicts the docs guide the template actually ships. The builder flagged the stale rationale in the PR body; the contradiction itself is a wording call that belongs to you, not to a fixer round overriding a signed-off spec.

Verdict: approve.

~Written by Claude, run via the agentic engineering loop

Comment thread template/AGENTS.md.jinja
run, and maintain the project; implementation detail belongs in the code.
Prefer a list, table, or short code example over paragraphs. When editing an
existing docstring, comment, or page, it must not get longer unless behaviour
was added.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor — the ported prose paragraph contradicts the docs tree the template now ships.

The spec justified dropping #434's docs/source/contributing/code_style.md half on the grounds that "the template ships no Sphinx docs/ tree and no contributing guide." That is no longer true on main: template/docs/source/contributing/ ships 10 pages, including a 184-line documentation_guide.md. The PR body flags the rationale as outdated; this is the concrete consequence.

Two specific collisions, both in a file that is always in an agent's context (template/CLAUDE.md is just @AGENTS.md):

  1. "implementation detail belongs in the code" vs documentation_guide.md, which routes How it is built to architecture/implementation/ pages covering "the internal types and how they collaborate" with file:line references.
  2. "a page … must not get longer unless behaviour was added" vs the scaffold's own stubs — docs/source/contributing/code_style.md says "This page is a scaffold stub. Author it from the repository." Authoring a stub makes a page much longer with no behaviour change.

Failure scenario: an agent in a generated project is asked to document a new subsystem, reads AGENTS.md, and concludes prose lives in the README while implementation detail stays in the code — so it never authors the architecture/implementation/ page the shipped docs guide requires, and declines to expand the stubs. The shipped Sphinx scaffold stays a scaffold.

Not filed as gating: the spec mandated this text verbatim and put the docs half explicitly out of scope, so a fixer would be overriding a signed-off spec. The call is whether to (a) ship as-is, (b) scope the paragraph to "the README and docs/" and carve out unauthored scaffold pages, or (c) open the follow-up issue for #434's code_style.md half and reconcile there. My preference is (c) with a one-clause tweak here — replacing "implementation detail belongs in the code" with a pointer to docs/source/contributing/documentation_guide.md would remove the contradiction without touching the added-fact rule.

~Written by Claude, run via the agentic engineering loop

Comment thread tests/test_template.py
assert (project.path / "AGENTS.md").is_file()
assert (project.path / "CLAUDE.md").is_file()
# AGENTS.md is rendered from a .jinja source, so placeholders must resolve.
assert "{{" not in (project.path / "AGENTS.md").read_text(encoding="utf-8")

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit — the guard covers {{ but not {%, and the acceptance criterion names both delimiters. A stray {%- if … %} that Jinja never consumes (e.g. mis-typed as {% -if … %}) would render literally and slip past this assertion.

Low value in practice — a genuinely malformed tag usually fails rendering outright, and this matches the existing test_docs_scaffold_renders pattern, so consistency is a fair reason to leave it. If you want it tight: assert not re.search(r"\{\{|\{%", text) (re is already imported at line 3).

~Written by Claude, run via the agentic engineering loop

Comment thread spec/issue-9.md
@@ -0,0 +1,133 @@
Port the *added-fact* documentation rule from

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit — this commit (3268278, "Materialize signed-off spec for #9") introduces a new top-level spec/ directory with no precedent in the repo (git log main -- spec/ is empty) and no .gitignore entry, which sits outside the ticket's "No other file changes."

It is loop mechanism rather than anything the builder chose, and it is isolated in its own commit, so it is trivially droppable. Worth a one-time decision: keep spec/ as a checked-in convention for this repo, or gitignore it. Also note the file records a premise that is already stale ("The template ships no Sphinx docs/ tree") — if it stays in the repo it will read as current documentation.

~Written by Claude, run via the agentic engineering loop

@mariushelf

Copy link
Copy Markdown
Owner Author

Review iteration 1: approve — The added section is byte-identical to the spec's verbatim block, appended as a pure addition (37 insertions, 0 deletions) with Package Management and Git Conventions untouched. Verified: no {{/{% on any added line; both include_hexagonal variants render with exactly one blank line before the new heading and zero Jinja delimiters in the output; the text's factual claim about ruff D + numpy convention matches template/pyproject.toml.jinja:43,68-69; uv run pytest tests -q → 20 passed, and per-test durations plus a hand-run of uvx pre-commit run --all-files in a rendered project confirm the heavy checks (make lint/test, docs-strict, pre-commit hooks) genuinely executed rather than passing vacuously; commit 5169fce uses the docs: prefix with no trailers at all. The template/AGENTS.mdAGENTS.md.jinja filename shift is a stale-spec artefact on the same file, disclosed in the PR body, and the end-of-file placement satisfies the AC's "ends with" wording. All five acceptance criteria met, nothing gating. One substantive note for the human: the spec's premise that the template ships no Sphinx docs tree is now false, and the ported prose paragraph contradicts the documentation_guide.md the template actually ships — filed minor because the spec mandated the text verbatim and put that half out of scope.

~Written by Claude, run via the agentic engineering loop

@mariushelf mariushelf added the loop:needs-human Reviewer approved; in human merge queue label Aug 14, 2026
@mariushelf

Copy link
Copy Markdown
Owner Author

Review verdict: approved (tier 1)
Could not verify: Whether the ported prose paragraph should be reworded to fit the Sphinx docs tree the template now ships, or left verbatim per the signed-off spec (which explicitly put #434's docs half out of scope). This is a wording/scope decision for the human, not something a fixer should override the spec to change.; Whether the loop's spec/issue-9.md commit should stay checked in as a repo convention or be gitignored — no precedent exists on main to infer the intent from.; Wording taste of the ported text generally (e.g. the list under "Does not:" uses gerunds while "Earns more than a summary line:" uses noun phrases — inherited verbatim from upstream #434, so mandated by the spec).

~Written by Claude, run via the agentic engineering loop

@mariushelf
mariushelf merged commit 6637764 into main Aug 14, 2026
4 checks passed
@mariushelf
mariushelf deleted the feat/9-loop-docs-bound-documentation-and-comment-len branch August 14, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation loop:needs-human Reviewer approved; in human merge queue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: bound documentation and comment length in template AGENTS.md (port aeloop#434)

1 participant