Skip to content

fix(clean): reserve room for the stamp so the playbook body isn't truncated on load#5

Merged
sturlese merged 1 commit into
mainfrom
fix/bughunt-playbook-cap-truncation
Jul 12, 2026
Merged

fix(clean): reserve room for the stamp so the playbook body isn't truncated on load#5
sturlese merged 1 commit into
mainfrom
fix/bughunt-playbook-cap-truncation

Conversation

@sturlese

Copy link
Copy Markdown
Owner

Bug

The playbook is the supervisor's advisory memory, injected into every worker pass (ops → telemetry → supervisor → playbook → workers). save_playbook caps the body to PLAYBOOK_MAX_CHARS (1500) and then prepends a ~60-char provenance stamp, but load_playbook re-caps stamp + body to PLAYBOOK_MAX_CHARS:

# save: body capped to 1500, THEN stamp prepended  -> file is ~1560 chars
# load: f.read()[:PLAYBOOK_MAX_CHARS].strip()       -> keeps stamp + first ~1440 body chars

So a maxed-out playbook silently loses its last ~60 body characters before reaching the workers, and ops.update_playbook_impl reports updated playbook (1500 chars) while only ~1440 are ever delivered. The tail of the supervisor's learned guidance never arrives.

Fix

Build the stamp first and cap the body to PLAYBOOK_MAX_CHARS - len(stamp), so stamp + body fits the exact budget load_playbook re-applies on read. The whole stored body then survives the round-trip, and since save_playbook returns that body, ops' reported size now matches what workers receive. The read-side re-cap (a guardrail against a hand-edited oversized file — the playbook is human-editable) is preserved.

Test

test_full_size_playbook_body_is_not_truncated_on_load saves an over-max playbook and asserts the entire stored body survives load (tail included) while staying within the cap and keeping the stamp — verified to fail on the pre-fix code (the tail is dropped). Existing test_size_cap_enforced / test_roundtrip_and_stamp still pass (cap still enforced, stamp still present).

Full clean suite: 134 passed, coverage 92% (gate 75%). Offline evals: 8/8 green. ruff check pipeline evals clean.

Scope note: this is the playbook size-cap handling only — it does not touch the deliberately-deferred playbook prompt-injection trust-model concern.


Found by the autonomous bughunt loop (iteration 5), during a fresh sweep of pipeline/clean after merging PRs #2#4. Dry-run mode — human merges.

🤖 Generated with Claude Code

…ncated on load

save_playbook capped the body to PLAYBOOK_MAX_CHARS and THEN prepended a ~60-char
provenance stamp, but load_playbook re-caps stamp+body to PLAYBOOK_MAX_CHARS. A
maxed-out playbook therefore lost its last ~60 body chars on the way to the
workers, and ops reported the pre-truncation length. Cap the body to
PLAYBOOK_MAX_CHARS - len(stamp) so stamp+body fits the same budget load applies,
and the whole body survives (also fixing the over-reported size).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sturlese

Copy link
Copy Markdown
Owner Author

Gate: adversarial verify → clean (SAFE)

The verifier confirmed the fix is correct and regression-free across every angle:

  • Round-trip: short / exactly-at-budget / far-over-budget content all load back with the full stored body, never truncated, always ≤ PLAYBOOK_MAX_CHARS. len(stamp) is a fixed 60 (the %Y-%m-%d %H:%M field is always 16 chars), so the body budget is a stable 1440.
  • Budget 1500→1440 is not a new problem: the old load already re-capped stamp+body to 1500, so workers already only ever received ~1440 body chars — the fix just moves the truncation to save-time so the stored file equals the delivered content (and ops' reported size is now accurate).
  • No test/eval depends on the old truncation or an exact-1500 body; all assertions are <=. Full clean suite green.

The verifier noted one pre-existing, non-regression, whitespace-only nit: the read-side .strip() (unchanged by this diff) could trim a trailing space if the slice boundary lands on interior whitespace — immaterial for advisory Markdown and out of scope here.

Gate verdict: clean. Dry-run mode → open for human merge.

@sturlese
sturlese merged commit 5d5b26f into main Jul 12, 2026
7 checks passed
@sturlese
sturlese deleted the fix/bughunt-playbook-cap-truncation branch July 12, 2026 10:31
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