Repository navigation
Conversation
A `nestedMemoryFiles` entry may now be `{ "path", "budgetTokens" }` to hold
that file to its own cap; a plain path entry keeps `nestedBudgetTokens`, then
`budgetTokens`, exactly as before. Entries are split once at config load into
the path list every consumer reads plus per-path caps (re-keyed to the
normalized path by `applyNestedMemoryConfig`), and propose, status, run, and
apply all read the cap through `nestedBudget(config, path)`. A malformed
entry (missing path, non-positive-integer budgetTokens, unknown key) is a
named config error.
Fixes kunchenguid#190
Co-Authored-By: Claude Opus 5.5 <[email protected]>
[Low impact] The PR appears safe to merge; no actionable issues were found. Reviews (2) · Last reviewed commit: "Merge origin/main into feat/190-nested-p..." · Reviewed by Greptile |
|
Speaking as Kun's firstmate: Thanks @Pantoria, this one looks good. I reviewed the diff against main and it was ready to merge. It's now conflicting only because #210 just merged ( contract-class: opt-in. I checked the unconfigured path myself. VISION (per rule):
One thing to fix while you rebase (this is more than a text conflict): #210 added Please rebase onto main and push through no-mistakes again. The required "PR must be raised via no-mistakes" check is bound to the head SHA, so a maintainer-side conflict fix would invalidate your attestation anyway. Once it's green and clean, I'll take it from there. |
|
Speaking as Kun's firstmate: this is opt-in and was ready apart from the conflict with #210, so we're resolving that conflict ourselves on your branch, including passing the file path into |
Resolve conflicts with kunchenguid#210 so per-file nested budgets and apply's budgetMismatches gate both survive. budgetMismatches now passes the file path into nestedBudget so a file's own cap is checked instead of the shared nestedBudgetTokens. Co-authored-by: Kun Chen <[email protected]>
|
Speaking as Kun's firstmate: quick update so you know where this stands, @Pantoria. We merged current main into your branch ourselves (new head This is a captain-decision hold with Kun, not waiting on you. He's deciding how to handle the attestation after our own conflict fix. Please don't rebase or re-push; nothing is needed from you. Contract class is still opt-in, and the VISION verdict hasn't changed: it aligns on all seven rules (evidence, human owns the weights, nothing on faith, budget, reads what you have, failure is loud, scope). |
Intent
Implement issue #190: per-file budget for nested memory files. nestedBudgetTokens was one shared cap for every nestedMemoryFiles entry, which cannot fit files differing 5-10x in size. The user (issue author, Pantoria) asked to implement their own ready-for-pr backpass issues, each in its own worktree and PR. Follow AGENTS.md invariants and VISION.md. No live model calls were made while implementing.
Design, following the maintainer's stated preference for object entries over a path map: nestedMemoryFiles accepts plain strings (unchanged behavior: nestedBudgetTokens then budgetTokens) or { "path", "budgetTokens" } objects. Entries are normalized once at config load (splitNestedMemoryFiles in src/config.js) into a plain path list plus a derived nestedBudgetTokensByPath, so downstream string consumers are untouched; the derived key is always recomputed and ignored if set by hand. Propose and apply both read the cap through ONE helper, nestedBudget(config, relative) in src/nested.js (maintainer requirement, see #188); the apply change is deliberately a one-line call-site swap so the parallel #188 PR rebases cleanly. Malformed entries fail with named config errors (maintainer requirement). Deliberate choices: unknown keys in an entry are rejected (so a typo like 'budget' can't silently train under the wrong cap) even though other config objects are lenient; per-file budgetTokens must be a positive integer as the issue specified. --budget behavior is unchanged. contract-class opt-in: existing configs behave identically.
What Changed
nestedMemoryFilesentries can now be{ "path", "budgetTokens" }objects as well as plain path strings. At config load,splitNestedMemoryFiles(src/config.js) turns them into a plain path list plus a derivednestedBudgetTokensByPath.applyNestedMemoryConfigthen re-keys those caps to normalized paths. AnynestedBudgetTokensByPathset by hand is overwritten. Malformed entries fail with named config errors: a non-object, a missing or emptypath, an unknown key, or abudgetTokensthat isn't a positive integer.nestedBudget(config, relative)(src/nested.js) now takes the file path. It returns the entry's own cap if it has one, otherwisenestedBudgetTokens, otherwisebudgetTokens. Propose (nestedContext),runandstatusbudget displays, and the apply gate insrc/apply/writer.jsall read the cap through this one helper. Plain string entries and--budgetbehave the same as before.test/nested.test.jsadds tests for the new entry handling.🤖 Generated with Claude Code
Risk Assessment
✅ Low: This is a contained opt-in config extension. String entries keep their old behavior. Per-file caps are derived once at load, re-keyed to the normalized path in applyNestedMemoryConfig (any value set by hand is overwritten), and read through the single nestedBudget helper at every consumer (propose's nestedContext, run, status, and apply's writer). Malformed entries raise named errors.
Testing
I drove the real backpass CLI against throwaway monorepos with an isolated HOME and XDG config directory. The model and the browser review page were replaced by the repo's own stand-ins (fake acpx and fake lavish). -statusshowed each nested file's own cap. - String-only configs gave output identical to the base commit, both with and without--budget. - A hand-setnestedBudgetTokensByPathwas ignored. - Every malformed entry failed with a config error naming the problem. - A full run plus apply proposed and wrote under the entry's 8000-token cap. When I lowered that cap to 20 between propose and apply, apply refused the write with "8 over its 20-token budget" and wrote nothing. - A plain entry keptnestedBudgetTokens(2000). - The targetedtest/nested.test.jspassed (31/31). Everything passed. Temporary repos were removed.Evidence: CLI transcript: status caps, base-commit comparison, --budget, ignored hand-set key, malformed-entry errors
Evidence: CLI transcript: full backpass run + apply under per-file cap, apply refusing a lowered per-file cap, plain entry fallback
~/.no-mistakes/evidence/01M503TY2WM6YVASFNZNJAK556/driver)Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
backpass status(text and--json) on a repo with a string entry and an{path:'./apps/api/AGENTS.md', budgetTokens:8000}entry (driver: evidence/driver/scenarios.mjs)backpass status --jsonwith string-only configs, with and without--budget 3000, on this commit vs. agit archivecopy of base e6a030a, comparing the full output byte for bytebackpass status --json --budget 3000with a mixed configbackpass status --jsonwith a hand-setnestedBudgetTokensByPathbackpass statuswith 11 malformednestedMemoryFilesentriesfullbackpassrun (pi sessions plus the repo's stand-in acpx for the model) followed bybackpass apply(stand-in lavish accepting all edits), with the per-file entry, the per-file cap lowered before apply, and a plain string entry (driver: evidence/driver/run-apply.mjs)node --test test/nested.test.js✅ **Document** - passed
✅ No issues found.
🔧 **Lint** - 1 issue found → no changes applied ✅
pnpm install && pnpm run lint && pnpm run typecheckto finish the lint pass.🔧 No changes applied.
✅ Re-checked - no issues remain.
✅ **Push** - passed
✅ No issues found.