Skip to content

feat(miner): wire the Neon branch-per-attempt DB fork into runAttempt#8206

Merged
JSONbored merged 2 commits into
mainfrom
feat/attempt-db-fork-wiring
Jul 23, 2026
Merged

feat(miner): wire the Neon branch-per-attempt DB fork into runAttempt#8206
JSONbored merged 2 commits into
mainfrom
feat/attempt-db-fork-wiring

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Summary

Closes #7858 (self-host scope). Wires createAttemptDbFork/discardAttemptDbFork (#8205, already merged) into runAttempt's real lifecycle in attempt-cli.ts, mirroring the existing worktree allocator's acquire/finally-release shape exactly:

  • Fork created right after the worktree slot is acquired, only when LOOPOVER_MINER_NEON_API_KEY/LOOPOVER_MINER_NEON_PROJECT_ID/LOOPOVER_MINER_NEON_PARENT_BRANCH_ID are all configured (attempt-db-fork-config.ts — secrets stay in env vars, never .loopover-ams.yml, matching this repo's universal credential convention). Any one missing disables the feature entirely — zero behavior change for every operator who hasn't heard of it.
  • Fork discarded in the same top-level finally block on every terminal outcome, alongside allocator.release.
  • Creation failure aborts the attempt rather than proceeding without isolation — this feature exists specifically so the coding agent's writes never reach the tenant's real database; silently continuing on a fork failure would defeat that safety property entirely.
  • Discard failure is captured to Sentry but never blocks the rest of cleanup (claim release, ledger closes) — same discipline this file already applies to its kill-switch ledger append. Leaks one Neon branch rather than losing something more important in the same cleanup pass.

Boundary deliberately not crossed in this PR: the resulting connection string is not threaded into the coding agent's own subprocess environment (CODING_AGENT_ENV_ALLOWLIST in cli-subprocess-driver.ts). Widening what reaches the untrusted, attacker-content-processing subprocess is a separate, security-relevant interface change to the driver/spawn layer that deserves its own focused review, not a bolt-on here.

Test plan

  • npm run typecheck clean (repo-wide)
  • npm run build --workspace @loopover/engine and --workspace @loopover/miner clean
  • Zero regressions: the existing 84-test test/unit/miner-attempt-cli.test.ts suite passes completely unmodified (proves the default/no-Neon-configured path is a true no-op)
  • 8 new tests in the same file covering: no-op when unconfigured, create-then-discard on submit, discard-on-abandon (cleanup isn't conditional on success), creation-failure aborts with no discard call, discard survives a subsequent worktree-prep failure (no leaked branch on an early abort), a discard failure is captured but doesn't block cleanup, and the real (non-injected) fallback path against a mocked Neon API
  • New test/unit/miner-attempt-db-fork-config.test.ts — the env-var resolver's own edge cases (trimming, blank-as-unset, any-one-missing-disables-all)
  • 100% branch coverage on both new/touched files (scoped coverage run); the one remaining branch gap in attempt-cli.ts's file-wide number is pre-existing and outside this diff

Completes #7858's self-host scope: createAttemptDbFork/discardAttemptDbFork
(#8205) are now called from runAttempt's real lifecycle, mirroring the
worktree allocator's own acquire/finally-release shape exactly.

Config-gated via LOOPOVER_MINER_NEON_API_KEY/_PROJECT_ID/_PARENT_BRANCH_ID
(attempt-db-fork-config.ts) -- an operator who hasn't configured all three
sees zero behavior change, proven by running the existing 84-test
miner-attempt-cli.test.ts suite unmodified alongside the new tests.

Fork creation failure aborts the attempt rather than proceeding without
isolation, since this feature exists specifically so the coding agent's
writes never reach the tenant's real database -- silently continuing on a
fork failure would defeat that safety property. Discard failure is captured
to Sentry but never blocks the rest of cleanup (same discipline this file
already applies to its kill-switch ledger append).

Boundary explicitly not crossed here: the resulting connection string is not
threaded into the coding agent's own subprocess environment
(CODING_AGENT_ENV_ALLOWLIST in cli-subprocess-driver.ts). That's a separate,
security-relevant interface change to the driver/spawn layer -- widening what
reaches the untrusted, attacker-content-processing subprocess -- and deserves
its own focused review rather than a bolt-on here.
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@JSONbored JSONbored self-assigned this Jul 23, 2026
npm run test:miner-deployment-docs-audit failed CI: LOOPOVER_MINER_NEON_API_KEY/
_PROJECT_ID/_PARENT_BRANCH_ID (attempt-db-fork-config.ts) were read but
undocumented.
@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.58%. Comparing base (19273b3) to head (b976d5b).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8206      +/-   ##
==========================================
- Coverage   92.10%   91.58%   -0.53%     
==========================================
  Files         775      776       +1     
  Lines       78308    78328      +20     
  Branches    23661    23667       +6     
==========================================
- Hits        72127    71736     -391     
- Misses       5062     5524     +462     
+ Partials     1119     1068      -51     
Flag Coverage Δ
shard-1 56.26% <90.00%> (-0.84%) ⬇️
shard-2 51.46% <35.00%> (+1.51%) ⬆️
shard-3 51.45% <0.00%> (-3.63%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/loopover-miner/lib/attempt-cli.ts 100.00% <100.00%> (ø)
...kages/loopover-miner/lib/attempt-db-fork-config.ts 100.00% <100.00%> (ø)

... and 2 files with indirect coverage changes

@JSONbored
JSONbored merged commit c26fe94 into main Jul 23, 2026
14 checks passed
@JSONbored
JSONbored deleted the feat/attempt-db-fork-wiring branch July 23, 2026 12:48
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.

Neon branch-per-attempt disposable DB fork for APR execution (implements #7649)

1 participant