Skip to content

feat(g01): connect paired terminal execution to bounded broker handoff - #62

Open
jjangg96 wants to merge 39 commits into
mainfrom
orca/g01-paired-broker
Open

feat(g01): connect paired terminal execution to bounded broker handoff#62
jjangg96 wants to merge 39 commits into
mainfrom
orca/g01-paired-broker

Conversation

@jjangg96

@jjangg96 jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #60. Ref #1; this does not close G01/G02 or authorize live execution.

Connects the reviewed paired terminal path to one same-process tagged g01-live mode and a fixed broker handoff, with bounded worker approval/state binding and one-shot admission.

Evidence

Initial head: 507850c.
Behavioral red: 3acd5ab. Green: 507850c.
The implementer reports Go 1.26.8 race/vet, tagged CLI and TLS/Unix fixture partitions, both experiment modules and GOTOOLCHAIN=go1.26.8 make check passed. Exact recorded commands/results and limitations are in docs/evidence/g01-paired-broker.md. Independent verification is pending.

Review and remaining gaps

Independent Luna/max contract and security/recovery reviews are running on this head. Hosted CI and exact-head GitHub Codex review must pass before conditional SHA-matched merge. Issue #61 separately addresses existing fixture deadline headroom without dropping tests.

No live GitHub/App/runner/workflow, Docker/Lima, Keychain or launchd operations were performed by the implementation. Real acknowledgement/acquisition/JIT recovery evidence remains outstanding. This is not the production daemon or supported crash resume.

Rollback

Source-only revert of these offline changes. No live resource was created. Future uncertain live outcomes require retaining owned journals/claims/resources, not broad cleanup or replay.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-08T14:36:15.431783Z 773cccc Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Independent Luna/max contract review has reproduced a blocking integration defect at head 507850c: paired-terminal local preparation requests a cleanup receipt, but brokerPreparationReceipt.valid requires the paired approval phase. The current synthetic positive broker test bypasses that real entrypoint. Review also identified missing actual TLS/Unix coverage through exported RunPairedTerminal. Merge is held; both reviewers are finishing on the frozen head before the integrator receives a combined TDD fix task. No live execution is authorized or claimed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 507850c808

ℹ️ 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".

Comment thread experiments/g02-auth/broker_entry.go Outdated
Comment on lines +188 to +192
phase := approval.Phase
if approval.Mode == "paired-terminal" {
phase = "cleanup"
}
return invokeBrokerPreparation(ctx, binary, files.StateDirectory, snapshotPath, files.ControllerStateDirectory, phase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align the paired preparation receipt with the cleanup phase

Every production paired-terminal invocation prepares the controller journal with phase cleanup, so the child returns a receipt whose Phase is cleanup; however, brokerPreparationReceipt.valid requires that field to equal p.approval.Phase, which can only be empty or paired-terminal for this mode. Consequently brokerExecute rejects the receipt at the preparation gate before authentication, and the paired handoff can never run. Track the actual preparation phase in the plan or validate cleanup for paired mode.

Useful? React with 👍 / 👎.

Comment on lines +399 to +403
if paired {
if a.Mode != "paired-terminal" || e.Worker == nil || !brokerSHA256.MatchString(e.Worker.Approval) || e.Worker.ApprovalFile.Device == 0 || e.Worker.ApprovalFile.Inode == 0 || e.Worker.State.Device == 0 || e.Worker.State.Inode == 0 {
return false
}
} else if e.Worker != nil || a.Mode == "paired-terminal" {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Validate historical claims independently of the current mode

When a paired invocation reads an admission ledger containing any earlier controller claim, this branch rejects that historical event solely because the current approval mode is paired-terminal. The terminal path necessarily starts from a controller journal with a prior successful create (newBaselineListenerHeld requires it in baseline_listener.go:54-71), so the normal controller-to-paired sequence cannot pass admission. The reciprocal check also prevents an approved controller inspect or cleanup from reading a failed paired claim, blocking recovery of retained resources; validate each event according to its own slot rather than the current request mode.

AGENTS.md reference: AGENTS.md:L8-L8

Useful? React with 👍 / 👎.

Comment thread experiments/g02-auth/broker_plan.go Outdated
}

func (a pairedWorkerApproval) validate(now time.Time) error {
if !a.RunnerUpdatesDisabled || !brokerSHA40.MatchString(a.HarnessSHA) || !brokerSHA40.MatchString(a.WorkflowSHA) || !brokerNonce.MatchString(a.OwnerNonce) || !brokerComponent.MatchString(a.Controller) || !brokerComponent.MatchString(a.DaemonID) || !strings.HasPrefix(a.ImageID, "sha256:") || !brokerSHA256.MatchString(strings.TrimPrefix(a.ImageID, "sha256:")) || a.Image != pairedWorkerImage || !filepath.IsAbs(a.Endpoint) || filepath.Clean(a.Endpoint) != a.Endpoint || len(a.Endpoint) > 103 || strings.ContainsAny(a.Endpoint, "\x00\r\n") || !a.ExpiresAt.After(now) || a.ExpiresAt.After(now.Add(24*time.Hour)) || len(a.Phases) != 4 {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Accept daemon IDs allowed by the worker approval

A worker approval whose DaemonID contains : or is 101–128 characters long passes the authoritative liveworker.Approval.Validate contract (liveworker/profile.go:24,29-34) and can be matched against Docker's /info response, but this broker-side copy validates it with the narrower brokerComponent expression and rejects it before handoff. Because paired mode consumes an already-reviewed worker approval, the broker should apply the same daemon-ID validation contract rather than silently excluding otherwise valid worker configurations.

Useful? React with 👍 / 👎.

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad7c2cf44c

ℹ️ 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".

Comment on lines +128 to +130
s := replay(j.Events())
if s.uncertain || s.deleted || s.setID != 0 || s.reserved || s.workObserved || len(j.Events()) != 0 {
return receipt, ErrQuarantine

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the controller history required by paired execution

When paired mode uses the controller state required by RunPairedTerminal, this condition rejects it because that state must already contain successful create and inventory records: newBaselineListenerHeld rejects a missing creation, while runPairedBaselineModeWithBinding requires an inventory record. Conversely, an empty journal that passes here reaches execution with setID == 0 and is rejected. Fresh evidence in this revision is the new PreparePairedJournal path enforcing len(j.Events()) == 0; it should validate and preserve the prerequisite controller history instead.

Useful? React with 👍 / 👎.

Comment thread experiments/g02-auth/broker_process.go Outdated
Comment on lines +175 to +176
ctx, cancel := context.WithTimeout(parent, 30*time.Second)
defer cancel()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Give paired execution enough time to complete

With the production cadence, the paired child cannot finish inside this deadline: sampleRounds(1, 4) and sampleRounds(5, 8) enforce a five-second gap after every prior round, so eight fresh rounds require at least 35 seconds before terminal cleanup even starts. The fixture replaces that cadence, but a real exec.CommandContext child is killed at 30 seconds, leaving journal and runner state uncertain and making successful paired-terminal completion impossible; use the parent/approval deadline or a bound covering the full terminal sequence.

Useful? React with 👍 / 👎.

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ecb06c175

ℹ️ 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".

Comment on lines +320 to +321
} else if a.Mode == "paired-terminal" {
slot = "paired-terminal"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Increase the ledger limit for the added paired slot

When all nine original slots have already been recorded, this newly valid tenth slot passes the current replay and appends its claim, but the parser at line 257 still rejects ledgers with more than 20 newline-split entries. Nine completed slots already occupy the header plus 18 events; appending the paired claim creates 21 entries, so a failed paired preparation permanently prevents a later authorized inspect or cleanup from reopening the ledger, while a completed pair leaves it even larger. Raise the structural limit to cover the header and claim/completion records for all ten slots.

Useful? React with 👍 / 👎.

Comment on lines +56 to +61
newSDKAPIForCommand = func(a livecanary.Approval, c livecanary.Credentials, stateDirectory string) (*livecanary.SDKAPI, error) {
config, err := readFixtureEndpointConfig(stateDirectory)
if err != nil {
return nil, err
}
return livecanary.NewSDKAPIForPairedFixture(a, c, config.BaseURL, []byte(config.CAPEM))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject fixture-enabled binaries at the broker gate

When g01-live is built with g01_pair_fixture, this override sends the broker-issued installation token to the loopback URL and CA selected by paired-fixture.json, yet validBrokerBuild rejects only osusergo and therefore accepts a clean, correctly stamped fixture-enabled binary. Such a binary can satisfy the approved hash/build checks while replacing the production GitHub transport (for both ordinary controller execution and paired execution) with a test endpoint that can capture the credential. Make the broker reject the g01_pair_fixture build tag.

Useful? React with 👍 / 👎.

Comment on lines +228 to 229
if p.worker != nil && p.worker.check() != nil {
return errBroker

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prepare and validate worker state before minting

When the worker journal or permanent worker admission claim is malformed, locked, or already bound to another state directory, this check still succeeds because brokerWorkerPlan.check validates only the approval file and state-directory identity. The broker consequently records the paired claim and mints a token before the child reaches liveworker.OpenJournal in paired_terminal.go:295 and refuses the locally invalid state; because the paired slot is one-shot, correcting the worker state cannot retry the terminal handoff. Add a credential-free worker preparation/receipt check before authenticated calls, analogous to the controller preparation gate.

Useful? React with 👍 / 👎.

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Independent contract and security reviews of 0ecb06c both reject merge despite successful Public CI. Current Codex findings independently reproduced: r3956753241 production binary gate accepts fixture-enabled executable; r3956753229 tenth paired slot exceeds ledger reopen capacity; r3956753245 malformed worker journal reaches mint before child refusal. Five previous findings were verified addressed, not merely declared stale. Contract reviewer additionally ran a strengthened temporary real-cadence bridge: child test 37.663s, wall 38.78s; this is local offline evidence, not yet a checked-in regression nor live recovery proof. A sole Luna/max runtime implementer is assigned all three fixes, permanent bounded wall-clock regression and reviewed CI integration. Grok continues separate PR59 security work. Both reviewers settled before writer assignment. No live operations authorized/performed; fresh independent reviews, exact-head Codex and CI remain required.

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Coordinator checkpoint on 1ebf0b1: runtime fixes and checked-in real-cadence bridge are pushed; reported race bridge duration36.196312875s/package39.633s. However, the CI seam uses120s despite the explicit45s approval, lacks the requested G02 generated failure/coverage matrix, and docs/CI still describes a single G02 invocation. Merge is held. A narrow CI/docs-only implementer is correcting the contract and measuring actual45s behavior; runtime files are frozen during that correction. Two fresh independent reviews will target the resulting final head, not a moving checkout. Codex review has been requested for currenthead; findings will be retained across subsequent pushes.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ebf0b1e50

ℹ️ 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".

Comment thread experiments/g02-auth/broker_plan.go Outdated
Comment on lines +145 to +156
path := filepath.Join(p.statePath, "journal.jsonl")
file, err := openBrokerPrivateFile(path, 0600, 1<<20)
if err != nil {
return errBroker
}
defer file.Close()
info, err := file.Stat()
if err != nil || brokerFileIdentity(info) != p.preparationReceipt.Journal {
return errBroker
}
data, err := io.ReadAll(io.NewSectionReader(file, 0, (1<<20)+1))
if err != nil || brokerBytesDigest(data) != p.preparationReceipt.JournalDigest {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Revalidate the worker admission claim before minting

When the worker admission.json is edited or replaced after the initial preparation receipt but before a later authenticated call, checkPrepared reaches this function and revalidates only journal.jsonl; the receipt's Claim and ClaimDigest are never compared with the current admission claim. Consequently guardLive can allow preflight and token minting against invalid worker authority, while the execution child refuses only after the one-shot paired slot has been consumed. Re-run the canonical worker preparation check or validate the current claim inode and digest alongside the journal at each pre-mint boundary.

Useful? React with 👍 / 👎.

Comment thread docs/evidence/g01-paired-broker.md Outdated
Comment on lines +18 to +19
- `/tmp/g01-paired-broker-review-0ecb06c.md`
- `/tmp/g01-paired-broker-independent-review-0ecb06c.md`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove private machine-local report paths

Replace these reviewer-local /tmp report references with durable repository or PR artifacts, or summarize their non-sensitive results directly. These paths are unavailable to other reviewers and CI, and committing personal machine paths or references to private test logs is explicitly prohibited by the repository instructions.

AGENTS.md reference: AGENTS.md:L9-L9

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bf278729a4

ℹ️ 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".

Comment thread scripts/check-offline-experiments.sh Outdated
Comment on lines +43 to +44
GOTOOLCHAIN="${exact_toolchain}" "${go_cmd}" test -race -count=1 -timeout=45s -run "${real_pair_cadence_regex}" ./...
GOTOOLCHAIN="${exact_toolchain}" "${go_cmd}" test -race -count=1 -timeout=45s -skip "${real_pair_cadence_regex}" ./...

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Increase timeout headroom for both G02 partitions

On a hosted or contended runner that is only about 12% slower than the recorded machine, either public-CI partition can time out despite correct behavior. Fresh evidence at this head is docs/evidence/g01-paired-broker.md:170-185, which records package times of 40.151s and 40.471s against these 45s limits; the named test alone includes seven unavoidable five-second cadence gaps plus a Git clone, a go build, and the bridge setup. go help testflag defines -timeout as: “If a test binary runs longer than duration d, panic.” Keep the split, but provide enough timeout headroom for normal hosted-runner variance.

Useful? React with 👍 / 👎.

The paired broker compared the worker journal inode/digest after
preparation but never reopened admission.json against the receipt
Claim/ClaimDigest, so same-inode mutation and replacement could mint
and launch. Revalidate the canonical claim at every pre-auth/mint/launch
fence. Cache synthetic RSA keys and split the remaining TestPaired
family from the unfiltered G02 complement so the 45-second race
partitions stay inside the existing deadline. Replace committed
reviewer-local report paths with GitHub-backed evidence.
@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Coordinator pre-review note for head 92632dde67a98c31146386ce2ce144326b0bdff9: please explicitly reproduce the worker-claim pathname binding case, not only bytes/inode replacement in place. workerClaimPath now searches an explicit directory, a sibling worker-admission directory, then the account-derived canonical root and accepts whichever matches the receipt inode. Static inspection raises the possibility that moving the prepared claim inode into the sibling fallback while replacing/removing the canonical claim could let the broker validate the old bytes although the execution child resolves different authority. This is a review hypothesis, not yet a reproduced failure; require a behavioral test showing canonical-path relocation/replacement stops before authentication/mint/launch. Test-only candidate locations must not become a production authority fallback. This review note does not authorize edits outside the current task or any live operation. Existing exact-head external and independent review gates still apply.

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Confirmed coordinator reproduction on immutable head 92632dde67a98c31146386ce2ce144326b0bdff9 (disposable source archive; active worktree unchanged):

GOTOOLCHAIN=go1.26.8 go test -count=1 -timeout=60s -run '^TestReviewPreparedWorkerClaimRelocationRefuses$' .

Result: exit 1, package 0.401s, relocated receipt inode bypassed changed canonical claim path.

Reproduction uses existing pairedPlanInputs, openBrokerWorkerPlan, and brokerSyntheticWorkerPreparation: obtain a valid receipt using an explicit private admission directory; verify checkPrepared passes; move that directory's admission.json inode into the sibling worker-admission/admission.json; write {} at the original claim pathname; expect the next checkPrepared to refuse. Current code returns nil by locating the old inode through the fallback candidate. The test exercises the preparation fence, not a full broker mint-count assertion; extend the eventual regression to authentication/mint/launch boundaries too.

This confirms the earlier pathname-binding hypothesis. Pin/revalidate the canonical claim location resolved by the trusted preparation contract, rather than searching candidate paths for any matching inode. Keep fixture path mechanisms out of production authority selection. No live resources/credentials were accessed; no production fix was made by the coordinator. Merge remains blocked until resolved and independently reproved.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 92632dde67

ℹ️ 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".

checkPrepared accepted a relocated admission inode when the original
pathname was replaced, because workerClaimPath searched sibling and
account-root candidates for a matching inode. Bind the named claim
path from the trusted preparation directory or the native-account pin
only. Offline fixtures use an explicit resolver seam.
@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@jjangg96

jjangg96 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Coordinator independent regression checkpoint at exact head 773cccc: replayed the unchanged TestReviewPreparedWorkerClaimRelocationRefuses counterexample from the prior 92632dd rejection in a disposable source archive. Command: GOTOOLCHAIN=go1.26.8 go test -count=1 -timeout=60s -run '^TestReviewPreparedWorkerClaimRelocationRefuses$' . Result: exit 0, package 0.483s. The prior same test failed at 92632dd because relocation bypassed the canonical claim path. This verifies that one preparation-fence regression only, not full mint/launch safety or live ACK/acquisition/JIT recovery. Independent full contract/security review, exact-head Codex verdict, all historical findings, and CI remain merge gates. No live operations performed.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 773cccc592

ℹ️ 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".

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.

[G01g] Wire paired terminal execution through a bounded broker handoff

1 participant