Brain-quality sweep, batch 1: brain_edit/brain_update correctness + close-session docs #124

Merged
mathias merged 4 commits from sweep/brain-quality-batch1 into main 2026-09-22 21:27:11 +00:00
Owner

Part of a brain-quality-and-structure sweep sprint (hyperguild + brain-gardener). Three atomic commits, each closing one issue, each independently tested and gated through task check.

Commits

  1. fix(mcp): name raw argument bytes when brain_edit refuses an empty old_str — closes #115. Live-reproduced first (a fresh brain_edit call from this session's client round-trips cleanly, so the server-side path itself isn't broken) before deciding the real, minimal fix was the diagnostic the issue itself asked for: the refusal now says how many raw argument bytes it received, so a future repro is a 30-second check instead of a dead end.
  2. fix(api): validate the claim envelope on supersede, same as on create — closes #111. writeHallNote validated half_life/applies/claim_provenance on note birth; UpdateNote (the brain_update supersede path) didn't. Fixed by extracting any frontmatter fence the caller leads Content with, validating it, and merging it into the restamped frontmatter — that merge closes a second, independent gap: a caller's supersede-time frontmatter was previously silently dropped as inert body text, never taking effect at all.
  3. docs(close-session): teach the skill the claim envelope, drop the stale tag-list hint — closes #112. Two documentation gaps: the skill never mentioned the envelope fields it should be using by default, and its "tagged internal today" repo list had drifted stale against classification.yaml (10 → ~39 repos since hyperguild#91) in the direction that misleads expensively.

Follow-up filed, not bundled here

#111's own acceptance criteria asked to check for other write paths with the same gap. Found several (brain_edit's raw byte-patch has zero envelope awareness; the claudewatcher ingest pipeline unaudited) — scoped as its own issue rather than expanding this PR: #123.

Verification

task check green on every commit (go test + vet + govulncheck + build + gitleaks), not just at the tip.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com


Created via git-mcp on behalf of @mathias

Part of a brain-quality-and-structure sweep sprint (hyperguild + brain-gardener). Three atomic commits, each closing one issue, each independently tested and gated through `task check`. ## Commits 1. **fix(mcp): name raw argument bytes when brain_edit refuses an empty old_str** — closes #115. Live-reproduced first (a fresh `brain_edit` call from this session's client round-trips cleanly, so the server-side path itself isn't broken) before deciding the real, minimal fix was the diagnostic the issue itself asked for: the refusal now says how many raw argument bytes it received, so a future repro is a 30-second check instead of a dead end. 2. **fix(api): validate the claim envelope on supersede, same as on create** — closes #111. `writeHallNote` validated `half_life`/`applies`/`claim_provenance` on note birth; `UpdateNote` (the `brain_update` supersede path) didn't. Fixed by extracting any frontmatter fence the caller leads `Content` with, validating it, and merging it into the restamped frontmatter — that merge closes a second, independent gap: a caller's supersede-time frontmatter was previously silently dropped as inert body text, never taking effect at all. 3. **docs(close-session): teach the skill the claim envelope, drop the stale tag-list hint** — closes #112. Two documentation gaps: the skill never mentioned the envelope fields it should be using by default, and its "tagged internal today" repo list had drifted stale against `classification.yaml` (10 → ~39 repos since hyperguild#91) in the direction that misleads expensively. ## Follow-up filed, not bundled here #111's own acceptance criteria asked to check for other write paths with the same gap. Found several (`brain_edit`'s raw byte-patch has zero envelope awareness; the claudewatcher ingest pipeline unaudited) — scoped as its own issue rather than expanding this PR: #123. ## Verification `task check` green on every commit (go test + vet + govulncheck + build + gitleaks), not just at the tip. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --- _Created via git-mcp on behalf of @mathias_
mathias added 3 commits 2026-09-22 21:21:05 +00:00
hyperguild#115: a session reported "old_str is empty" with old_str that
was never empty on their end. Server-side round-trip re-verified clean
(fresh brain_edit call, real content, succeeds) — the code path itself
isn't broken, but its error left no way to tell "client sent empty" apart
from "something between the client and here lost the field" without a
second investigation. The refusal now names the raw argument byte count.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
hyperguild#111: writeHallNote validates half_life/applies/claim_provenance
before a note is born; UpdateNote's supersede path didn't, so the fields
that need provenance most (a whole-note regenerate is more likely to carry
model-authored frontmatter than a fresh create) went unchecked.

Fixed by extracting any frontmatter fence the caller leads Content with,
validating it with the same claim.ValidateEnvelope, and merging its fields
into the restamped frontmatter instead of leaving it as a second, inert
`---`-fenced block in the body — that merge was a real gap independent of
validation: a caller's supersede-time frontmatter was previously silently
dropped, never taking effect at all.

Reject leaves the note byte-identical (fail-closed, nothing written).
Fence-less content (the common case today) is unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
docs(close-session): teach the skill the claim envelope, drop the stale tag-list hint
CI / Lint / Test / Vet (pull_request) Successful in 33s
CI / Mirror to GitHub (pull_request) Skipped
31ebc8afc4
hyperguild#112: two documentation gaps found checking the skill against
current state.

1. The skill never mentioned the claim envelope (half_life/applies/
   claim_provenance) capture's insight-write now validates — the natural
   place to say a close-session insight is usually exactly the durable,
   universal, human-decided kind it describes.
2. The "tagged internal today" repo list was a frozen snapshot next to a
   fail-safe gate — the expensive direction to mislead in. Replaced with
   the rule (untagged -> confidential) plus a pointer at classification.yaml
   as sole authority, since hyperguild#91 already moved the real count from
   10 to ~39 repos and it will keep moving.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mathias added 1 commit 2026-09-22 21:24:53 +00:00
fix(api): validate the merged envelope on supersede, not the caller's fragment
CI / Lint / Test / Vet (pull_request) Successful in 32s
CI / Mirror to GitHub (pull_request) Skipped
e2cb315b31
Review caught a real bypass in the #111 fix before merge: the previous
commit validated only the frontmatter fence the caller supplied, not the
merged result that actually reaches disk. A caller could blank
claim_provenance alone (absent per claim.present's "empty is unset" rule)
while half_life/applies survived untouched from the prior note — each side
individually looked fine, the merged envelope on disk was the
unprovenanced one the whole check exists to catch. That's the exact
laundering #111 named as the worse of its two gaps.

Fixed by computing the envelope from fm (post-merge, pre-write) instead of
contentFM (the caller's raw fragment). Flip-tested: reverting to
fragment-only validation turns the new adversarial test red; the merged
validation turns it green.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mathias merged commit 5a5d938e8e into main 2026-09-22 21:27:11 +00:00
Sign in to join this conversation.