Skip to content

Fix batch: YAML round-trip + state self-heal, branch validation, lifecycle reload, committer extensions - #4

Merged
Whamp merged 3 commits into
mainfrom
fix/bugfix-batch
Aug 17, 2026
Merged

Fix batch: YAML round-trip + state self-heal, branch validation, lifecycle reload, committer extensions#4
Whamp merged 3 commits into
mainfrom
fix/bugfix-batch

Conversation

@Whamp

@Whamp Whamp commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Fixes all six findings from the Grok 4.6 adversarial review of #3 plus a whole-repo bug hunt. Every fix was reproduced before implementation and independently verified after (runtime probes + mutation checks) by the delivery owner.

1. YAML correctness + legacy state self-heal

  • serializeYaml escapes embedded " and \\ when quoting; parseYaml honors escaped quotes in double-quoted regions — all values round-trip (property tests now cover ", \\, #).
  • MemoryState.load() quotes legacy unquoted # scalars before parsing (old summary: Fixes #1 no longer truncates) and rewrites the file canonically on first load. Read-only/missing files never throw.

2. Branch name validation

  • /, \\, empty, and leading-. names rejected at create/switch/merge with a clear tool error. ../x previously wrote outside .memory/branches/; feat/auth corrupted listBranches().

3. Lifecycle reload

  • turn_end and session_before_compact call tryLoad(ctx): OTA logging works after mid-session brain-init, and a cwd change appends to the new project's log instead of the old one's.
  • Reloading on cwd change clears frozenStatusSnapshot (no cross-project status leak).

4. Committer extension passthrough

  • committer.extensions in .memory/config.yaml (list or comma string) → --extension args on the child, so custom-provider committer models work under --no-extensions. Session extensions deliberately not forwarded (isolation preserved). Documented in SKILL.md + init skeleton.

5. Space-safe module resolution

  • resolveAgentPrompt uses fileURLToPath; paths with spaces no longer fail every commit via %20.

6. README honesty

  • Documents the two registered tools (memory_commit, memory_branch) instead of five nonexistent ones.

Evidence: 214 tests / 14 files green, pnpm run check all green (lint, typecheck, format, knip, jscpd, gitleaks). Mutation spot-checks: removing the snapshot reset or branch validation turns the corresponding tests red. aislop clean; slop-scan flags adjudicated (pre-existing shifted catch blocks + two intentional commented catches).

Will Hampson added 3 commits August 17, 2026 14:41
serializeYaml now escapes embedded double quotes and backslashes
when quoting, and parseYaml honors escaped quotes inside
double-quoted regions, so every value round-trips — including
values with quotes, backslashes, and unquoted-hash content, now
all covered by the property tests.

MemoryState.load() migrates pre-comment-support state.yaml files:
unquoted scalars containing '#' are quoted before parsing, and the
file is rewritten in canonical form on first load. Unreadable or
read-only state files no longer throw out of load().

Found by a Grok 4.6 adversarial review (PR #3 follow-up bug hunt)
and independently reproduced.
Branch names are validated at create, switch, and merge: names
containing '/', '\', empty, or starting with '.' are rejected with
a clear tool error instead of escaping .memory/branches/ (e.g.
'../x' wrote outside the directory and 'feat/auth' corrupted
listBranches). The memory_branch handler catches thrown errors so
they surface as tool results, not raw exceptions.

turn_end and session_before_compact now call tryLoad(ctx), so OTA
logging works after a mid-session brain-init and appends to the
current project's log after a cwd change instead of the previous
project's. Reloading on cwd change also clears the frozen status
snapshot so one project's injected status cannot leak into another.

Found by a Grok 4.6 adversarial review and independently
reproduced.
.memory/config.yaml accepts committer.extensions as a list or
comma-separated string; each spec becomes an --extension arg on
the committer child so custom-provider models work under
--no-extensions (explicit -e paths bypass discovery disabling).
Session extensions are deliberately not forwarded, preserving
committer isolation.

resolveAgentPrompt uses fileURLToPath so checkout paths with
spaces no longer keep %20 and miss memory-committer.md. README
now documents the two registered tools (memory_commit,
memory_branch) instead of five tools that do not exist.
@Whamp
Whamp merged commit fce8c22 into main Aug 17, 2026
2 of 3 checks passed
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