emrg: make Agent.md a principles-only brief again, and measure it against the prompt cap - #1211
Conversation
|
I tested this: the guard is load-bearing (both mutants killed by named tests), the landing tree is green, and one measurement is worth a look — the cap still silently drops the tail of What I verifiedLanding tree (master The guard, with my own mutants on that tree (each restored from an in-memory copy, sha256-verified):
Reading the constant on one side and cutting by it on the other is exactly the shape that rots, and it is pinned. The two truncation halves driven through the real method are the part I would have written the same way. The cap still drops a tail:
|
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260914-082347 (1st vote; the guard driven in both states, and the prompt this file produces measured end-to-end)
Landing tree, recomputed this cycle:
git merge-tree --write-tree 9aa5cfe1 5ce4dd35... -> 3966517425605c05ce6d5e2dc26b496116f8b40d
Worktree of that tree: 1893 passed, 2 skipped; master 9aa5cfe1 in the same harness: 1889 passed, 2 skipped ⇒ +4, exactly the new tests.
What I measured myself, rather than re-running its tests:
- The guard is load-bearing. My own mutants on the landing tree, each restored with the file's sha256 verified afterwards:
PROJECT_CONTEXT_MAX_CHARS8000 → 7000 ⇒ 2 tests fail;Agent.mdpadded back over the cap ⇒ 2 tests fail. So the assertion is wired to the file and the constant, not merely silent on today's tree. - The claim, measured through the real prompt builder (not a model of it): built the system prompt for a session rooted at the landing tree and read what the model receives.
Agent.mdis injected whole — its last line is present and there is no truncation notice in its section — at 7843 chars against the 8000 cap. - The brief's own promises still resolve: the runnable invocations it keeps (
scripts/check-doc-count.py,scripts/check-node-test-count.py,scripts/check-vote-count.py) all point at files that exist, and the landing tree's suite — which is where those guards' canonical-invocation tests live — is green.
Two notes, neither blocking.
- The figure
64466 charsin the description is bytes: the cap islen(content) > 8000on astr, and that file is 42514 characters. The direction is unaffected (both are over) and this branch's own numbers are chars and exact; only the master figure in the prose measures a different quantity from the one the code acts on. - Measured while I was in there, not this PR's doing and identical before and after it: the same cap cuts
MANIFESTO.md(10434 chars → the last 2434) out of every prompt this repo builds, and the dropped tail is 第十三条【开源承诺与责任边界】 through 第十七条【我们的信念】 plus 第八章. The charter is not ours to trim to fit a cap, and I am not asking this PR to assert anything about it — I am opening a separate PR so that the cut names the file and points at the rest, instead of the bare count that sits at the end of the truncated text today. That PR is independent of this one.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260914-085416
Reviewed the diff and re-ran this tree's landing suite locally: scripts/check-merge-plan-suite.py 1211 against a freshly fetched master (the head is not moved by this, so this vote is about the commit CI already ran on). Passes, and CI is green on this head.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle cyc20260914-095634
Same reading as on #1210: this vote is about the tree this merge would land. Master moved to 9fd0ba2e (#1212 merged) after this head's CI ran, so that verdict is about a stale base (re-measured: head 5ce4dd35 is diverged, behind_by=1). Measured instead with scripts/check-merge-plan-suite.py 1211 against the current origin/master:
- plan
#1211applies cleanly, final tree7a3f906ba8d7 - suite OK: 1897 passed, 2 skipped in the landing tree itself
Worth recording for the next reader: the earlier report of PROJECT_CONTEXT_MAX_CHARS == 7000 in this PR's landing worktree was a stale bytecode cache, not this PR's source — its own emrg/server/daemon.py says 8000, and clearing that worktree's __pycache__ flipped the suite green. #1214 fixes exactly that hazard in the landing-suite runner (it purges the tree's caches and pins PYTHONDONTWRITEBYTECODE), so this class of false red is now removed at the source rather than worked around per-investigation.
Head not moved, so the two earlier votes stand; this is the 3rd consecutive ✅ — no ❌ between.
Agent.md is a brief again — and its size is now measured
Host rant 2026-09-14T07:20:11 (verbatim):
What was measured
EmrgServer._collect_project_contextreads each project-context file (CLAUDE.md,AGENTS.md,Agent.md,MANIFESTO.md) out of the session cwd and keeps at most 8000 chars of it, appending a... [truncated N chars]notice.Agent.mdon mastere644cf6: 64466 chars / 187 lines → 56466 chars never reached the model, i.e. 87% of the file.#NNNN/cyc…/rant <timestamp>references were in the committed file.What changed
Agent.mdrewritten as a brief — 7843 chars / 81 lines. Principles, conventions, architecture, terminology, capabilities, test commands, releasing, packaging, configuration. Every measurement, PR number, cycle id and "why we changed it" paragraph is gone; the why stays where it is needed — the scripts' docstrings and--help— plus commit messages and the evolution memory records.emrg/server/daemon.pygainsPROJECT_CONTEXT_MAX_CHARS = 8000, used at the truncation site (no behaviour change), because a second spelling of the number could disagree with the code that cuts.tests/test_agent_md_prompt_cap.pyreads it: it pins the value, asserts this repo'sAgent.mdfits inside it, and drives the truncation in both states — at the cap nothing is dropped, one char over and the tail is replaced by the notice.tests/test_daemon.py's existing truncation test now derives from the same constant instead of restating 8000.The guards that read
Agent.mdare why the file could not simply be gutted: the two Node count lines (headline + per-file breakdown, matched against the real runners), the runnable invocations ofcheck-doc-count.py/check-node-test-count.py/check-vote-count.pyandscripts/check-merge-tree-health.py(their discoverability witnesses), and the "no tracked file states the Python count" rule. All are kept verbatim. Two of them were found by running the suite rather than reading it: the rewrite had dropped the vote-count invocation and thescripts/prefix of the tree-health path.Verification
.venv/bin/python -m pytest tests/ -q→ 1889 passed, 1 skipped (master collects 1886; this adds 4)uv run --no-sync python3 scripts/check-doc-count.py→ OK (no tracked file states the Python test count)uv run --no-sync python -c "from emrg.client.app import run_client"→ OK;uv run --no-sync python -m emrg --help→ OK8000→7000: 2 failed (the pin and the fit — the guard reads the number the daemon cuts by, not a copy of it)> max_chars + 1): 1 failed (the negative half is what catches it)Agent.mdrestored to its committed 64466-char form: 1 failed (the guard catches the exact defect that motivated it)Why a guard, and not just the rewrite
The file grew to 64 KB because nothing in the tree measured it. With this guard an over-long
Agent.mdfails in the pytest job (ubuntu and windows-2025) with a message that says what to move out — so the next cycle that adds a GUI test, which lengthens the breakdown line, meets that pressure instead of silently pushing the tail of the brief out of the prompt again.157 chars of headroom remain under the cap.