Skip to content

T3/factory deploy names shown build - #27501

Closed
tomkaczocha wants to merge 1303 commits into
pingdotgg:mainfrom
original-solutions:t3/factory-deploy-names-shown-build
Closed

tomkaczocha wants to merge 1303 commits into
pingdotgg:mainfrom
original-solutions:t3/factory-deploy-names-shown-build

Conversation

@tomkaczocha

Copy link
Copy Markdown

Problem

Change

Scope and approval

Verification

rawphp and others added 30 commits October 25, 2026 21:37
…tempt records its time

Red: regate posts "passed again" without reading the checks; the ledger
rejects gate_finished as an unknown event; no gate attempt ends with a
gate_finished line.

Issue: #222
Upstream v0.1.3-nightly.20261024.3643 brands SourceControlProviderKind,
so the fork's test now constructs it with SourceControlProviderKind.make
instead of a plain string. Typecheck was failing in the sync gate.

Issue: #221
…tempt records its time

A pull request that was ready and is re-gated after a push now stays as
it was until GitHub's required checks pass on the re-gated head. Pending
checks answer checks-pending with nothing written; a failed check starts
a new session from the branch with the check named, as a failed re-gate
does; a head that moves meanwhile is compared and gated as a push is,
with nothing of the undecided pass posted; checks_minutes after the pass
the issue goes stuck. The first gate's and the re-gate's checks decision
share one reader.

FactoryGate ends every attempt that ran with a gate_finished line
carrying the attempt and the wall-clock milliseconds from the start of
the checkout to the end of the last command or of the aborted merge, so
the run log shows how long a gate took. A line that cannot be written
leaves the attempt's result as it is.

Issue: #222
…0261024.3643

sync: v0.1.3-nightly.20261024.3643
…ged text and a reviewer's draft

Red at this commit: an issue closed during the wait is not abandoned, a
reviewer's draft is undone when the checks pass, a checks-failed relaunch
cut short before its send line launches a second session, and the
failed-check crash matrix relaunches twice. Also green coverage the review
asked for: retries used up on a re-gate, a check that fails after a pending
read, the issue text judged again on both branches, and the attempt's time
covering the checkout through a git that takes known time.

Issue: #222
…and re-asserts only after a cut-short call

A re-gate failure whose session is launched but whose gate_sent_back line
never went in is finished on the next call without a second launch. A
re-gate waiting for its checks abandons the run when a person closes the
issue. The ready state is set again only when the pass was recorded by a
call that resumed an earlier one (the gate-passed step's cause says so),
so a draft or an assignment a person made while the checks ran stands.
The check settlement and the failed re-gate's relaunch each have one home,
shared by the first gate and the re-gate.

Issue: #222
…t read stands, and a resumed pass repairs a cut-short draft

Red at this commit: the fresh gate on a pushed head still re-asserts the
ready state over a reviewer's draft, and a checks timeout whose stuck path
was cut short is judged again on the next call. Green coverage: the
reassert flag read back from the ledger makes a drafted pull request ready
again once a resumed pass's checks turn green.

Issue: #222
…ded timeout stands

A head that moves on while a re-gate waits for its checks starts a gate
that resumes nothing, so its pass sets nothing again. A checks_read line
with nothing failed and not everything passed is the recorded decision
that the wait ran out: the next call finishes that stuck decision instead
of reading the checks again, as it does for a recorded failure. The ready
mode's copy of the owed-send recovery was dead once regate recovered it
first, and is gone.

Issue: #222
…ept when a push arrives

Red at this commit: a timed-out stuck path cut short after the draft is
dropped once the head moved and the new head is gated fresh, and a resumed
pass that owes the ready state loses it when a push arrives before its
checks pass. Green coverage: a check that never appeared keeps its own
reason through every crash of the timeout path.

Issue: #222
…wed ready state survives a push

A wait that ran out is a stuck decision on record, and the call that wrote
it may have drafted the pull request before it died, so a resumed re-gate
finishes it before comparing heads. A pass recorded by a resumed call owes
the ready state; a push before its checks pass starts a fresh gate that
carries that debt. The reset of the check reads a new pass implies has one
name, withoutCheckReads, so the building gate's view of it cannot drift
from readProgress.

Issue: #222
…d even once the head moved

Red at this commit: with no retry left, a failed read's stuck path that
died after drafting the pull request is bypassed by a push, and the new
head is gated fresh over the factory's own draft.

Issue: #222
…ead holds

A failed read whose retries are used up is a stuck decision like a
timed-out one, and the call that wrote it may have drafted the pull
request before it died, so a push no longer bypasses it. The ready mode's
flag is named for what it means now, reassert, and the wait's doc says a
moved head reaches it only through a recorded read.

Issue: #222
…orded failure outrun by a push is pinned

The end-to-end scenarios list every ledger line and were red since the
gate began writing gate_finished after each attempt. A recorded failed
read with a retry left relaunches for the failure it names even once the
head moved, and the new head is not gated on its own; green at this
commit, pinned on purpose.

Issue: #222
Merges upstream's nightly tag into main by hand after the sync workflow
hit conflicts in six seams. Each seam takes upstream's side with the fork
hook re-added. Upstream turned the mobile Settings index into data, so the
fork's Factory row becomes useFactorySettingsSection, one appended section.
The route tree is regenerated, not merged by hand.

Issue: #225
… and a timeout is read from its recorded reason

- A re-gate pass is now recorded `gate-passed-clean` when nothing before it needs repair, and
  plain `gate-passed` otherwise. Ledgers written before this change carry `gate-passed` on every
  pass, so a pass in flight across the upgrade is finished as before, with the ready state set again.
- `Seen.checksTimedOut` is set only by a `checks_read` line whose cause says `checks-timed-out`
  (shared `CHECKS_TIMED_OUT`), not guessed from an unfinished read.
- `recordedChecks` is the one rule for "a read on record decided this pass", used by
  `decideChecks` and by `regate`'s moved-head test.
- Tests: the first gate's recorded timeout survives a crash before the stuck comment; an older
  build's pass with a draft is finished ready; both reason-keyed `readProgress` fields.
Local gate runs fast checks only; GitHub CI is the merge gate
…yout

Upstream moved every settings page from routes/settings.*.tsx to
routes/_chat.settings.*.tsx, where SettingsScopeProvider and the modal
chrome live. The fork's settings.factory.tsx did not conflict, so the merge
left it at the root, where FactorySettingsPanel throws on useSettingsScope.
Rename it to match and regenerate the route tree. The fork-owned glob in
check-seams.sh and the docs that quote it follow the file.

Issue: #225
Upstream made SidebarUtilityMenu local to SidebarChrome.tsx, which broke
the web typecheck on the fork test that imported it. The test wanted the
real footer; SidebarChromeFooter is the exported one and renders the menu.

Issue: #225
check-seams.sh now owns apps/web/src/routes/_chat.settings.factory*, so the
fixture that committed the old settings.factory.tsx tripped the script. The
allowed-changes case writes the new path, and the unlisted-change case writes
the old one and expects it named, pinning that the retired pattern is gone.

Issue: #225
Pins the generated tree so a future sync that moves the settings layout
again, or a file back at routes/settings.factory.tsx, fails here rather
than throwing in FactorySettingsPanel at runtime. Green at this tip.

Issue: #225
Upstream's v0.1.3-nightly.20261025.3669 turns on t3code/no-low-value-comments,
which rejects comments over four lines and bare issue numbers. 190 fork comments
broke it and failed the Lint job; each now keeps its constraint in four lines or
fewer. Only comment text changes.
…k are pinned

The section keeps its own title, since the Settings list keys an untitled
section as the overflow tabs, opens the Factory screen, is found by search
and stays the last section of the Settings index. isSidebarUtilityPage keeps
Factory pages out of the main app's back target.
…e-225

Sync to v0.1.3-nightly.20261025.3669 conflicts
Fails: process.test.ts expects T3FAC_LAUNCH_PATH entries ahead of the
server PATH, deduplicated and not passed on; installScripts.test.ts
expects the LaunchAgent to export T3FAC_LAUNCH_PATH before exec.

Issue: #228
…ll's

The server merges the login shell's PATH in front of the LaunchAgent's at
startup, so /usr/bin shadowed the interpreter ~/.config/t3fac/env named
and a Python 3.11+ repo's gate ran under Command Line Tools 3.9 on the
Trilogy Mac. The LaunchAgent now exports the PATH it launched with as
T3FAC_LAUNCH_PATH, and every factory child gets those entries first, then
the rest of the server PATH without duplicates. Unset, PATH is unchanged.
The variable itself is not passed on.

Issue: #228
Red: the launch request has no pull request URL yet and Sessions.launch dispatches no link.

Issue: #229
Green already: the assertion pins the plain-start path for the closed-PR
and needs-info fallbacks, which share the helper.

Issue: #229
rawphp and others added 24 commits October 30, 2026 15:20
No red phase: the checks already hold. Covers a runs directory that
cannot be listed, a planned resume and a relaunch naming the branch, a
sibling thread on the branch whose checkout is elsewhere, and archived
or worktree-less sibling threads, which let the run bind.

Issue: #260
The interruption line sets the run's last branch too, so it was never
the only source.

Issue: #260
Red: otherRunHas no longer reads the interruption's branch, and a later
session_launched moves the run's last branch away from it.

Issue: #260
A relaunch's session_launched moves the run's last branch, while the
interruption keeps the branch the interrupted thread was on.

Issue: #260
Red: otherRunHas reads only the newest value of each branch field, so a
run launched on the branch and relaunched twice no longer names it.

Issue: #260
earlierAttempts and otherRunHas now share one reader of a ledger's
branch- and pull-request-naming lines: launches (with the resumed-from
branch and T3's launch branch of the worktree), stuck lines,
interruptions, relaunches, bound branches and opened or left pull
requests. A run's older sessions can no longer drop out of the check.

Issue: #260
…po-observe-xcode26

fix: main's Factory mobile archives the iOS app again (expo-observe fails to compile under Xcode 26.3)
…oze-or-install

feat: the factory reports a waiting update, and a person can snooze it for an hour or install it now
Red: factoryApi has no snoozeDeploy or deployNow, and the belt shows no
banner, so the new api test and the ten "a waiting update" belt tests fail.

Issue: #269
… Update now

The belt shows a banner for the selected environment while a build waits:
which build, until when claims hold, and Snooze 1 hour and Update now.
Update now asks first when it would interrupt a run or a thread at work.
The Claimed post says claims are held for update, after a hand pause.

Issue: #269
…ks its build

Red: a null thread count posts with no dialog, an open dialog comes back
for a later build, and the updating note outlives a build autodeploy
dropped. The in-flight Update now and deploy_by-null cases already pass.

Issue: #269
…s its build

A thread count T3 could not read now opens the confirm, as autodeploy
waits on it. The banner is keyed to its build, so a dialog left open does
not return for a later one, and the updating note ends when autodeploy
drops the build it was for. The install guide says when Update now asks.

Issue: #269
…closes the dialog

No red phase: the behavior shipped in the previous fix; these cases pin
the uncounted-threads and unreadable-run branches apart, and the banner's
key when one build replaces another directly.

Issue: #269
…inished work as stuck

Review round 1 (review-gate):
- f1: a failed read of another issue's thread, worktree or ledger now fails the pass, so the next pass asks again; the run's own worktree read still refuses on failure (#260 AC3e). `worktreeCheckout` answers null for a path with no `.git`, which holds nothing.
- f3/f5: the other-run check reads every other issue's ledger, finished runs included, so the FACTORY-DONE row's "no other issue's run names" holds; tests pin a run finished a week before the claim.
- f2: drop the stale World.checkouts comment. f4: addNamed and runBranches point at each other.
…d one reader names a run's branches

Review round 2 (review-gate):
- f1: the own-worktree read now fails the pass on a git error, as the other-run reads do, so a timeout or lock does not end finished work as stuck before the worktree is removed. No `.git` at the path (null) is still no proof and stuck. This narrows #260 AC3(e): a failed read never binds, and waits a pass rather than going stuck.
- f4: `runNames` in progress.ts is the one reader of a run's named branches and pull requests; the other-run check, `earlierAttempts` and the branch prune's `runBranches` all use it. The prune now keeps every branch an unfinished run's ledger names, not only the newest.
…h-session-from-stuck

fix: a session that makes its own branch is not released as stuck pr-not-bound
… its environment

- The rule for what Update now interrupts moves to updateInterrupts.ts, with a
  test that fails when autodeploy.sh's state list or busy checks drift from it.
- A running factory pass opens the confirm, as autodeploy waits on it too.
- A refused snooze or Update now shows only under the environment that refused.
- The 202 of deploy/now always names its build, so the client types it as a
  string and the updating note always follows that build.
- Tests: a run with no state yet is asked about; Cancel leaves the update alone.
…date-snooze

feat: the Factory page shows a waiting update, with Snooze 1 hour and Update now
Snooze 1 hour and Update now posted no build, so a build that replaced
the waiting one between the last status read and the press was the one
snoozed or installed. Both now send the commit the banner showed, and
the deploy routes answer 409 deploy_changed when another build waits
now. A body that names no build takes the waiting one, as before.
@github-actions github-actions Bot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Oct 30, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Macroscope skipped reviewing this pull request. Per-review cost limit exceeded (workspace setting).

This review would cost an estimated $68.54, which exceeds your per-review limit of $15.00.

The top 3 files driving up this estimate:

File Diff Size Estimate
apps/server/src/factory/tracker/github.ts 96.88KB $3.87
apps/server/src/factory/pass.ts 95.25KB $3.81
apps/server/src/factory/runner/building.ts 85.36KB $3.41

Tip

To get this pull request reviewed, you can:

  1. Comment @macroscope-app on this PR to request a manual review (monthly spend limits still apply).
  2. Exclude the file(s) above from review by adding a pattern to your .macroscope/ignore.md — note that creating this file replaces Macroscope's built-in default ignores rather than extending them.
  3. Raise your cost limit in your workspace billing settings.

Turn off this reminder going forward

@github-actions github-actions Bot added the size:XXL 1,000+ changed lines (additions + deletions). label Oct 30, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This change replaces desktop identity defaults and broadens the raw-RPC-access lint exemption to mobile Factory sign-in. The diagnostic exemption and changed defaults require explicit human review.

Needs human approval because:

  • Per-review cost limit exceeded (workspace setting). Approvability relies on correctness review in order to determine eligibility

Review your spending limits in Billing settings, or comment @macroscope-app review this PR to bypass the limit and review now. You can add or adjust custom eligibility rules. Learn more.

@tomkaczocha
tomkaczocha deleted the t3/factory-deploy-names-shown-build branch October 31, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants