Merge upstream/main: fork renewal (6 commits through f7a387f) - #12
Merged
Merged
Conversation
* fix(bin): bound remote worker supervisors * no-mistakes(review): release incumbent supervisor before starting its replacement * no-mistakes(review): wait out a healthy same-root supervisor instead of replacing it * no-mistakes(review): narrow remote worker change to restart accounting only * no-mistakes(document): clarify supervisor restart guard is a lifetime total
* feat(bin,pi): per-actor wake consume, silent success gating, merge-poll dedup Three related fixes to the shared wake-drain and Pi supervision-branch dispatch machinery so a routine success is never main-blocking and a mixed queue can safely split between actors. 1. Successful routine results no longer create main-blocking wake rows. fm-startup-network.sh only enqueues a check: startup-network wake when the deferred result is actionable (state is not "done", or the report carries a bootstrap-diagnostics actionable prefix); a clean success stays durable in the report file without ever waking the agent. 2. Per-actor wake-drain consume contract. bin/fm-wake-drain.sh now scopes presentation and --ack-through to the current actor (bin/fm-lease-lib.sh's fm_lease_actor): main keeps the original whole-queue cutoff behavior, unaffected. A branch actor (FM_SUPERVISION_ACTOR=branch, set only inside the Pi supervision branch's own bash tool calls) is scoped to an explicit eligible-row snapshot instead of a cutoff comparison, so it can never remove a row it was not granted - the fix for the swallow risk that used to force an all-or-nothing whole-queue fallback to main. .pi/extensions/lib/fm-branch-dispatch.ts's scopeForUnreadWake is the single owner of eligibility: a check-kind row (merge-confirmation polls, Relay mentions, credential/auth failures) is now excluded rather than vetoing the whole scan for a non-heartbeat wake, while a heartbeat review keeps its original all-or-nothing rule unchanged. writeEligibleRowsSnapshot publishes the exact eligible sequence numbers before every branch prompt; fm-primary-pi-watch.ts's offer still refuses a check-kind trigger outright so a main-only close is never itself routed to the branch. 3. A repeat identical merged-PR-poll result for an already-notified task is absorbed instead of enqueued again. A poll's own retirement state is scoped to one registration and cannot see a prior registration's outcome, so a task re-registered after its merge was already surfaced would otherwise wake main a second time for the same event. bin/fm-pr-lib.sh's new per-task pr-poll-merge-notified marker survives across re-registrations to catch that case; the first notification for a task still reaches main unchanged. Regression tests colocated in tests/fm-startup-network.test.sh, tests/fm-wake-queue.test.sh (including the mixed-queue no-swallow property), tests/fm-pi-branch-extension.test.sh, and tests/fm-pr-check-security.test.sh. docs/watcher-continuity.md and docs/pi-supervision-branch.md updated for the new contracts. * no-mistakes(review): Bind merge deduplication to canonical PR identity * no-mistakes(review): Serialize wake row ownership across main and branch * no-mistakes(review): Bind branch grants and deduplicate within actor claims * no-mistakes(review): Fallback main-owned wake claims to main delivery * no-mistakes(review): Clarify silent startup success guidance * no-mistakes(review): Release residual branch grants after settled prompts * no-mistakes(review): Reject truncated wake rows as corrupted * no-mistakes(document): Document per-actor routing and silent startup success * no-mistakes(lint): Fix ShellCheck findings in wake grant and startup test * no-mistakes: apply CI fixes
* Hide branch outcome tool in Pi Calm * no-mistakes(review): Preserve stock outcomes rendering and document tool audit * no-mistakes(review): Document branch read tool audit disposition * no-mistakes(review): Match stock outcomes output sanitization * no-mistakes(document): Document Calm custom-tool visibility
* fix: delegate no-mistakes PR gate to pinned action * no-mistakes(document): Document commit-bound no-mistakes attestations
…uid#3028) * feat(pi): let operators pin a cheaper supervision-branch model Supervision is an easier job than the captain's own conversation, so the Pi supervision branch does not need main's model. A new /supervision-model command opens Pi's own selector over Pi's own catalog of credentialed models, plus a "Follow main" entry, and persists the pick as one <provider>/<model-id> line in this home's gitignored config/supervision-branch-model. Firstmate keeps no model catalog of its own. The branch resolves the pin at every branch build - the first wake of a cold start and the reopen after /new, /resume, /fork, or reload - so the choice survives all of them, and picking also releases the live branch so the next wake reopens the same persistent branch conversation under the new model. An absent, unreadable, or unparseable file means no pin and keeps today's behavior byte for byte: no model option is passed and Pi picks the branch's model exactly as before. A pin naming a model Pi cannot hand back is never silently downgraded onto main's model: the branch refuses to build and the wake falls back to the captain-facing main path naming the unusable pin, which is the extension's existing failure direction. The choice is home-local and not part of secondmate inherited configuration, matching the Pi Calm preference precedent. docs/configuration.md owns the operator-facing schema. Portable regressions cover pin-present on create and reopen, pin-absent default, the command's persistence, cancellation, and live rebind, and both unusable and unparseable pins. The opt-in real-SDK guard proves the vendor surface the pin reads and that an explicit model wins over the model a reopened session recorded. * no-mistakes(review): Fix supervision model runtime and rebind races * no-mistakes(review): Restrict supervision picker to isolated runtime models * no-mistakes(document): Document supervision branch model selection * fix(pi): make the supervision model pin authoritative on every reopen Clearing the pin with "Follow main" removed the file but the next branch build reopened the persistent branch session with no explicit model override, so Pi restored the model that session had recorded - the old pinned model - while the command reported that the branch now follows main. The same gap meant an absent pin did not reliably mean same-model-as-main once a home had pinned once. The pin file's current state now decides the model on every branch build, create and reopen alike, overriding Pi's session-state restore. With a pin, that model. With no pin, main's own current model is applied explicitly, tracked from the contexts Pi already hands the extension plus its model_select event, since the branch is built at wake time with no context of its own. Only when main's model is unknown, or this home's stored credentials cannot run it in the isolated branch runtime, does a build fall back to passing no override at all, which is the behavior from before the pin existed; the branch is never refused over model choice. The command's notification now reports the model actually applied, and says plainly when clearing the pin could not apply main's model instead of claiming a change that did not take effect. No credential handling changes: the branch still relies entirely on the stored credentials its own runtime already holds, and the picker stays restricted to models that runtime can resolve. Colocated regressions cover pin present on create and reopen, clearing the pin returning a reopened branch to main's model and specifically not the old pinned one, an unparseable pin behaving as no pin, and the unknown-main-model fallback to no override. * no-mistakes(review): Make unpinned supervision follow main model changes * no-mistakes(document): Correct supervision model documentation
…nguid#3079) * feat(pi): let /supervision-model pick the branch's reasoning effort Supervision is an easier job than the captain's own conversation, so the Pi supervision branch does not need main's reasoning effort any more than it needs main's model. /supervision-model now settles both in one flow: the existing model picker, then a follow-up effort picker built from Pi's own supported thinking levels for the model just chosen. Firstmate keeps no effort catalog of its own; the menu, the clamp, and the vocabulary all come from Pi. The pick persists as one line in this home's gitignored config/supervision-branch-effort, independent of the model pin: a captain may pin a model, an effort, both, or neither. The effort pin's current state decides the branch effort on every branch build - the first wake of a cold start and the reopen after /new, /resume, /fork, or reload - and overrides Pi's restore of whatever level a reopened branch session recorded, which is what keeps "Follow main" honest. With no pin, main's own current effort is applied explicitly and followed live through Pi's thinking_level_select event, the same way an unpinned branch already follows main's model, and the two selections now share one build revision so either change invalidates an in-flight build. The branch is never refused over effort. Pi owns the clamp, so a pinned level the branch's model cannot run becomes that model's nearest supported level while the captain's raw pick is kept for a model that supports it, and the command reports the level the branch will really run at rather than the raw pin. A token Pi would not recognize at all is treated as no pin rather than passed to that clamp, which would otherwise collapse a typo into the model's lowest level. Only when main's effort cannot be read either does a build pass no effort override at all, which is the behavior from before this file existed. Pi's own effort vocabulary is pinned by a bidirectional type assertion against Pi's getThinkingLevel return type, so the tracked strict typecheck against the installed package fails the moment Pi adds or removes a level. docs/configuration.md owns the operator-facing schema for both pins. Portable regressions cover the pin on create and reopen, model-only and effort-only pins working independently, clearing a pin returning the branch to main's effort, live-follow of a mid-session change, the clamp, an unrecognized token, the unknown-main-effort fallback, and the command's two-step flow, persistence, cancellation, and honest reporting. The opt-in real-SDK guard proves the vendor surface all of that rests on, and also repairs a pre-existing gap that left it unable to load the extension at all. * no-mistakes(review): Resolve effective branch effort honestly * no-mistakes(document): Clarify Pi-owned effort picker behavior
Conflict resolution - the `Require no-mistakes` gate: Upstream replaced this repo's inline gate shell with the pinned shared `require-no-mistakes` composite action, which additionally binds the attestation to the current PR head. This fork carries a second proof the shared action does not implement: when the gate runs but its push target is rejected, the branch reaches the remote by hand and the body carries no signature even though every pipeline step ran, so a `no-mistakes(<step>):` commit subject stands in for the body marker. Take both rather than choosing. The pinned action judges the body first and a signed body is still decided on that body alone; only a body with no signature at all falls through to the fork's commit proof. - workflow: shared action runs with continue-on-error, and the fork's commit-proof step runs only when it did not succeed. - tests: upstream's verifier cases plus the fork's fallback cases, with the attestation cases now owned by the shared-action half. - CONTRIBUTING: describes head binding and both accepted proofs.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Fork renewal: bring
sanis/firstmateup to date withkunchenguid/firstmate@f7a387f(6 commits).Validation note: this PR was raised without the no-mistakes pipeline, by explicit captain instruction for this one change. Verified locally instead:
bin/fm-lint.shclean (ShellCheck 0.11.0 + actionlint 1.7.12, 3 workflows valid) andtests/fm-no-mistakes-required.test.shgreen (9/9).Upstream commits
f7a387ffeat(pi): let /supervision-model pick branch reasoning effort (feat(pi): let /supervision-model pick branch reasoning effort kunchenguid/firstmate#3079)9a01deafeat(pi): add persistent supervision branch model selection (feat(pi): add persistent supervision branch model selection kunchenguid/firstmate#3028)3e5577bfix: bind no-mistakes attestations to PR head (fix: bind no-mistakes attestations to PR head kunchenguid/firstmate#3027)6a2cd6cfix(pi): hide branch outcomes tool rows in Calm (fix(pi): hide branch outcomes tool rows in Calm kunchenguid/firstmate#3024)85d6c72fix: safely split supervision wake handling by actor (fix: safely split supervision wake handling by actor kunchenguid/firstmate#2953)038d0f7fix(bin): bound remote job worker supervisor restarts (fix(bin): bound remote job worker supervisor restarts kunchenguid/firstmate#2942)Conflict resolution
Three conflicts, all in the
Require no-mistakesgate. Upstream (3e5577b) replaced this repo's inline gate shell with the pinned sharedrequire-no-mistakescomposite action, which additionally binds the attestation to the current PR head. This fork carries a second proof the shared action does not implement (added in #7): when the gate runs but its push target is rejected, the branch reaches the remote by hand and the body carries no signature even though every pipeline step ran, so ano-mistakes(<step>):commit subject stands in for the body marker.Resolved by taking both rather than choosing:
.github/workflows/no-mistakes-required.yml— the pinned shared action runs first withcontinue-on-error; the fork's commit-proof step runs only when it did not succeed. A body carrying the signature is still decided on that body alone: the fallback refuses it rather than letting a gate commit stand in for an attestation the body claims to carry.tests/fm-no-mistakes-required.test.sh— upstream's pinned-verifier cases (head match, head mismatch, missinghead_sha) plus the fork's fallback cases, with the attestation cases now owned by the shared-action half. One new case pins that a rejected signature is not rescued by the commit proof.CONTRIBUTING.md— describes head binding and both accepted proofs.Risk
Low-moderate. Behavior change is confined to the PR compliance gate; the composed workflow is lint-clean and behavior-tested. The rest of the merge is upstream content applied cleanly.