fix(retention): gate must target the git main worktree, not the twin holding main - #105
Conversation
…holding main canonicalMainWorktree resolved the canonical retention workspace as whichever worktree hosts refs/heads/main. When the repository's main worktree is detached, that is some other worktree — the closed twin — whose state roots may be empty and whose checkout may run ancient gate code. The Friday gate then passed on the stale empty twin while real client records sat untouched in the main worktree. The main worktree is always the first entry of 'git worktree list --porcelain'; resolve it from there and never substitute a twin. The gate additionally proves the canonical workspace itself is fresh when the script runs from a different checkout, and the regression suite now covers both the twin-hijack and the stale-canonical-workspace cases.
The Friday gate's canonical workspace is the git main worktree (first entry of git worktree list), never a twin that happens to hold the refs/heads/main branch while the main worktree is detached; a stale canonical workspace fails just like a stale checkout.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
|
Warning Review limit reached
Next review available in: 16 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (4)
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
nish3451 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ea3debc17e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // otherwise prove the canonical workspace directly. | ||
| const expectedRepo = normalizedPath(expectedCwd); | ||
| const canonicalFreshness = | ||
| normalizedPath(repoForFreshness) === expectedRepo ? preflight.freshness : proveFreshness(expectedCwd); |
There was a problem hiding this comment.
Reject workspace overrides that select a linked twin
When TINYSTUDIO_AUTOMATION_WORKSPACE is set to a linked twin, expectedCwd refers to that twin, so this freshness check validates the twin and the later workspace comparison also accepts an automation configured there. Meanwhile, stateRoot still defaults to the actual main worktree, allowing the gate to pass while Friday runs the twin's potentially stale gate code—the exact failure this change intends to prevent. Derive the canonical workspace independently of this override, or reject an override that differs from canonicalMainWorktree(repoForFreshness).
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
…le with main after PRs #135/#104/#99/#112/#100/#105) The PR #130 branch had already been reconciled with origin/main through c617364 (PRs #131 + #133/#134/#132/#116). Since then origin/main moved to d4f3ef4 with six more merges (#135 #104 #99 #112 #100 #105). Pull them in so PR #130 can be reviewed against current main without weakening the capture/rollback/reverification implementation or the PR #131 fail-closed missing-secret gate. The merge resolved cleanly: - PR #130 capture/rollback logic (publish-public-site.mjs canonical_deployment, rollbackTo, restored identity re-verify, accept-again) is intact. - PR #130 test file (scripts/test-pages-release.mjs) is intact and wired into the npm ci/test scripts. - PR #131 fail-loud missing-secret workflow step in .github/workflows/deploy-public-site.yml is preserved byte-for-byte. - The new origin/main changes touch operator surfaces and the deploy bundle prep; none of them modify the publish-public-site.mjs rollback contract or the Pages token gate, so there were no conflict markers.
What
The Friday retention gate still passed on a stale, empty workspace after the closed twin. Live reproduction on the current main (d898707), running the gate from the fresh main worktree:
{ "status": "pass", "clientCount": 0, "repo": "/home/nish/workspaces/products/tinystudio-in-autonomous-service", "failures": [] }The real main worktree holds 3 client records (
clients/ai-converter,five-to-nine-0509,siterep) — invisible to the gate.Root cause
canonicalMainWorktree()resolved "the repository's main worktree" as whichever worktree hostsrefs/heads/main. When the git main worktree is detached (the closed twin), that is some other worktree — hereproducts/tinystudio-in-autonomous-service, 45 commits behind at 24e516a with emptyclients/and no prospect directories. Both the canonical state inspection and the automation-workspace check followed the twin, so the gate inspected empty roots (0 clients) and considered the automation correctly pointed at the twin. The liveautomation.tomlalso points at that twin, so Friday additionally ran the twin's ancient gate-lesscheck-retention-automation.mjs.Fix
canonicalMainWorktree()now returns the first entry ofgit worktree list --porcelain— the git main worktree that owns.git— never a twin holding the main branch.refs/heads/mainmust not hijack the canonical workspace, and a stale canonical workspace must fail even when the gate runs from a fresh checkout.Verification
node scripts/test-retention-automation.mjspasses; the new assertions fail against the oldcanonicalMainWorktreelogic.products/tinystudio-in, reportsclientCount: 3, and fails loudly with the replacement prompt (previously a silent pass).npm testchain pass.npm teston the machine now exits 1 because the live gate correctly surfaces the true divergent state (3 clients,service-decisions0,runs/service-engine0) — the designed fail-closed contract; the parity repair is human-owned via the replacement prompt.Operational follow-up (outside the repo)
The live
~/.codex/automations/tinystudio-retention-checkups/automation.tomlwas re-pointed from the stale twin to/home/nish/workspaces/products/tinystudio-in, so Friday runs current gate code instead of the twin's gate-less version.