Skip to content

nightly 2026-09-01: closeRepoTask ignored payload.dryRun and committed real writes - #17

Open
jaydubya818 wants to merge 1 commit into
mainfrom
nightly/2026-09-01-improvements
Open

nightly 2026-09-01: closeRepoTask ignored payload.dryRun and committed real writes#17
jaydubya818 wants to merge 1 commit into
mainfrom
nightly/2026-09-01-improvements

Conversation

@jaydubya818

Copy link
Copy Markdown
Owner

The finding, and how to reproduce it

lib/agent-runtime/writeback.mjs:296 short-circuits closeTask on payload.dryRun === true and touches nothing. Its repo twin lib/repo-runtime/writeback.mjs:247 had no such branch, so dryRun was simply an unrecognised payload key: the call took the per-repo lock and performed the entire real close. The two functions are deliberate twins — the repo file's own comments say so — so a caller that learned the convention from the agent runtime got irreversible writes from what it believed was a preview.

Reproduced on a throwaway fixture KB before the fix, passing { dryRun: true, taskLogEntry, hotUpdate, discoveries }:

returned keys : ok, trace, committed      <- no `dryRun` key at all
res.committed : true
progress.md written?  true                (and it contained the dry-run text)
hot.md written?       true
bus discovery items:  1

The caller had no way to tell from the return value that its plan request had written and published. After the fix:

returned keys : ok, dryRun, wouldSucceed, planned, rejected, summary
res.dryRun    : true
progress.md / hot.md written?  false
bus discovery items:  0

The fix is the five-line mirror of the agent-runtime branch, dispatching to dryRunCloseRepoTaskwhich already existed at line 358 and was simply never reachable through this entry point. ok tracks the plan (plan.wouldSucceed !== false), matching the twin. Closes the 2026-08-25 backlog item.

Commits

Hash Subject Tier Verification
171786f6 fix(repo-writeback): closeRepoTask silently ignored payload.dryRun B (runtime behaviour of a write path) V2 — full suite green

The other six commits from this run were Tier A and are already on main (8baa3376..f42213ee): three coverage commits (+31 tests), the backlog SHA correction, the backlog record, and a CONTRIBUTING count refresh.

Verification

npm test        # before, at clone:                   571 pass / 0 fail
npm test        # main after the 3 coverage commits:  602 pass / 0 fail
npm test        # this branch, rebased onto main:     604 pass / 0 fail

Regression tests were verified to fail against pre-fix source, not merely to pass after it: stashing the writeback.mjs change and running node --test --test-name-pattern='dryRun|dry run that violates' tests/repos/repo-runtime.test.mjs gives 2 fail / 2 pass; restoring gives 4 pass.

Verification is capped at V2. V3 (production build) was not attempted — nothing here touches web/. Node pin mismatch disclosed: .nvmrc says 20, the host runs v24.18.1, and no nvm/fnm/volta is installed, so everything here is verified on Node 24 only. There is no root eslint/tsconfig, so node --check + npm test are the only gates that exist.

The two new tests are placed near line 350 of tests/repos/repo-runtime.test.mjs specifically to avoid colliding with the ~line 665 hunk on nightly/2026-08-31-improvements.

Risk if this is wrong

Any caller that was passing dryRun: true and relying on the writes actually happening would stop getting them. That reliance would have to be accidental — it contradicts the key's name, the twin's behaviour and the repo's own comments — but it is the honest failure mode. Non-dry-run callers are on a byte-identical path; the branch only adds a guarded early return. Scope is one function.

Escalation that does not belong to this branch

The highest-severity thing found tonight is not here: web/package-lock.json on main resolves next == 16.3.1, which is below the 16.3.3 floor of the August 2026 Next.js release covering two critical unauthenticated RCEs (GHSA-2xp9-vwfh-vxw4, CVE-2026-75604). The brief for this run asserted 16.3.1 was clean by reasoning from the July batch. The fix already exists on nightly/2026-08-26-improvements; a PR is open for it and it is ranked first in the recommended merge order.


Standing facts, measured on this run (2026-09-01)

All eight pre-existing nightly branches were re-measured against main at commit f42213ee:

  • Merges cleanly: yes — git merge-tree --write-tree main <branch> reports zero conflicts for all eight. (The brief described all eight as diverged; that is a GitHub compare status meaning "both refs have unique commits", not a conflict prediction.)
  • Not superseded: git log --cherry-pick --right-only main...<branch> returns a non-empty commit list for every one of the eight, so no branch is closable without merging on supersession grounds.
  • Tests rebased: each branch was rebased onto current main and the full root suite run. All green (counts per-PR below). Root suite only — web/ has no test suite, so branches touching web/ are unverified on their actual subject matter.

Opened by the nightly maintenance run. Not auto-merged and not self-approved.

Closes the 2026-08-25 backlog item. lib/agent-runtime/writeback.mjs:296
short-circuits closeTask on `payload.dryRun === true` and touches nothing.
Its repo twin lib/repo-runtime/writeback.mjs:247 had no such branch, so
`dryRun` was just an unrecognised payload key: the call took the per-repo
lock and did the whole real close.

Reproduced before the fix on a throwaway fixture KB, passing
`{ dryRun: true, taskLogEntry, hotUpdate, discoveries }`:

  returned keys : ok, trace, committed     <- no `dryRun` key at all
  res.committed : true
  progress.md written?  true   (and it contained the dry-run text)
  hot.md written?       true
  bus discovery items:  1

So the caller had no way to tell from the return value that its "plan"
request had actually written and published. After:

  returned keys : ok, dryRun, wouldSucceed, planned, rejected, summary
  res.dryRun    : true
  progress.md / hot.md written? false ; bus discovery items: 0

The fix is the five-line mirror of the agent-runtime branch, dispatching to
dryRunCloseRepoTask -- which already existed at line 358 and was simply
never reachable through this entry point. `ok` tracks the plan
(`plan.wouldSucceed !== false`), matching the twin.

Two regression tests in tests/repos/repo-runtime.test.mjs, both verified to
FAIL against pre-fix source (stashed the source change, ran the pattern:
2 fail / 2 pass; restored: 4 pass). One pins that nothing lands on disk and
that a dry run does not consume the subsequent real close; one pins that a
close-policy violation reports ok:false. They are placed near line 350 to
avoid colliding with the ~line 665 hunk on nightly/2026-08-31-improvements.

Tier B: this changes runtime behaviour of a write path.
Verified: npm test -> 604 pass / 0 fail (602/0 before), Node v24.18.1.
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