Skip to content

release: v0.19.8 with durable runtime ownership and verified acquisition - #819

Merged
antoinetoussaint-byte merged 10 commits into
mainfrom
codex/agent-download-auth-hint
Oct 27, 2026
Merged

antoinetoussaint-byte merged 10 commits into
mainfrom
codex/agent-download-auth-hint

Conversation

@lukazhupa

@lukazhupa lukazhupa commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Agent acquisition could install unverified archive bytes, detached-process owners lacked a public birth-bound signal API, and native scoped cleanup could lose workspace attribution after a controller died or Redis rewrote its process metadata. This PR fixes those owner capabilities, adds prepared GET query encoding and exact container parent attribution, and declares Core v0.19.8.

  • Acquisition reuses the GitHub SDK and one GITHUB_TOKEN→GH_TOKEN policy. Archives must match the producer checksum or GitHub digest before extraction; invalid or unreadable evidence refuses installation. Confirmed absence of both retains the historical explicit unverified warning.
  • runners/base.SignalProcess exposes the existing Linux pidfd / Darwin audit-token path for detached owners. Same-start/incompatible-boot evidence now returns an error and preserves live records; it is never converted or treated as PID reuse.
  • Tracked spawns persist launch workspace in authenticated-v2 before releasing the start gate. V1 has no new fields and retains its strict reader. Core explicitly reads/reaps both formats; older readers ignore v2. ListProcessGroups, LookupProcessGroup, and authenticated InspectOwnership.LaunchWorkspace keep namespace decoding and process identity with Core. Canonical filename/content binding and ambiguous-duplicate refusal prevent false successful discovery. CLI owns workspace selection and consumes these APIs; metadata never authorizes signaling.
  • runnable.CallRequestFor, CallRequest, and CallQuery encode the existing prepared-call contract. REST GET uses deterministic escaped scalar query parameters without a body; null is refused, and root/trailing-slash routes are preserved.
  • DockerEnvironment.WithServiceIdentity and ContainerServiceIdentity bind/inspect exact loaded module/service identity. Conflicting labels refuse adoption before drift replacement; legacy absence supplies no inferred parent and does not trigger replacement solely for a label.

Classification: fixes at the owning shared-library surfaces, reusing existing acquisition, start-gate, atomic registry, identity handles, prepared bindings, and Docker attribution. No parallel registry or consumer identity encoder is introduced. Updated behavior is documented in docs/agent-contract.md, docs/architecture.md, docs/runnable.md, and docs/session-ledger.md; the last explicitly documents the bounded strict-JSON registry exception and mixed-reader rollout limits.

Agent protocol 1, startup protocol 2 and declared operation contracts remain as reported in agents/contract/contract.json; no blanket protocol-driven fleet rebuild is required. Persistent-registry adoption is a separate requirement: older cleanup consumers cannot recover v2 producers. Redis #123 consumes durable provenance, Postgres #199 consumes detached birth-bound signals, object-storage #117 supplies exact parent identity, and CLI owns their composition qualification. Runtime/Robin consume prepared calls. These consumer obligations are not claimed complete by a Core-only pass. The existing workflow alone tags v0.19.8 after merge and green main CI; no manual tag.

Validation evidence retained: earlier combined Core full-suite and full dockerrun race passed at 6eadd92. Public Postgres v0.0.146 release downloads passed both anonymous/authenticated paths with complete archive verification. Exact container attribution independently passed creation/reuse/conflict/legacy tests; object-storage custody/PutGet evidence includes the initial unexplained IPv6 readiness failure and successful retry. Native provenance now passes real owner-dead/erased-environment sibling-isolation and v1 compatibility/recovery tests; removing only persisted workspace capture makes the new test fail. Base/sessionledger race passed in 115.997s/3.225s before final filename corrections; final focused race passed in 8.086s. Fresh independent follow-up closes both canonical filename/content mismatch and schema-exception findings at bc4e15c; reviewer race tests passed in 20.144s and six v1/v2 public corruption controls pass. Reports are /tmp/core858-provenance-review.md and /tmp/core858-provenance-followup.md locally. Exact-head base/sessionledger race passes in 130.291s/5.566s. Final full go test -v ./... -timeout 5m passes (base 83.928s, ciguard 143.209s, sessionledger 5.004s; dockerrun cached from the exact-head isolated run below). A separately compiled old Core 3d31544 reaper also preserves actual bc4 v2 bytes and live ownership in an isolated HOME.

The latest local full-suite run did not pass: dockerrun exceeded its 300s package deadline with TestDockerProcStdoutPipeRawBytes running 4s at the alarm. A subsequent isolated verbose dockerrun run passed every test in 280.620s within the unchanged 5m limit, followed by the successful full run above. The initial failure remains recorded; its cause is not established by the later pass. Exact-head CI and real consumer composition still gate release. No local Linux execution, forced PID reuse, system-clock change, power-loss injection or final released-agent Redis composition is claimed. Genuine CI and consumer qualification gate merge/publication and downstream release claims.

Final qualification at bc4e15c: exact-head GitHub codefly-core Build passed in 17m54s, including tagged coverage and full race; the other execution checks passed. Root-owned real composition at clean CLI8add9461/Corebc4e15ca and Redisbf62b03 passed even after both controller15406 and agent15431 were killed by typed owner APIs: Redis15501 remained authenticated with OwnerAlive=false and an empty observable workspace, then scoped stop exited0 and reaped it. Sibling agent94558/Redis94623 retained their exact boot/start identities and controller94520 remained live. Evidence: /tmp/codex-owner-stop-final-{before,controller-kill,agent-kill,orphan,after}.jsonl and -stop.log; fresh CLI review is separately owned. Redis full required-infrastructure rerun passed175.744s with unchanged source/assertions; the initial Singleflight failure remains preserved and unexplained (five current and20 prior-Core focused repetitions pass; prior-Core fullCluster exposed a separate ReplicaRefill assertion). These are source-composition results, not released-artifact delivery.

antoinetoussaint-byte and others added 3 commits October 27, 2026 15:48
… GET is callable

A prepared binding names a typed route, and the two are not sent the same way:
a Connect procedure and a REST mutation are POSTed with the input as the body,
while a REST GET — the one route core derives only as a read — carries its
input as its query and no body. Nothing turned a PreparedCall into a request
line, so each caller of a prepared binding assumed the Connect shape, and a
delivered GET was refused or dropped before it was ever sent.

runnable.CallRequestFor answers the method, the absolute path, the query and
the body for whichever arm the binding sets. runnable.CallQuery is the query
half: each member of the input object one parameter of that name, a string as
written, a number or a boolean in its JSON spelling, sorted by name so one
input object addresses one request line. It is the encoding side of the rule
PackageFromOpenAPIOperation already derives a GET under, so a member a query
string cannot spell — a null, an object, an array — is refused by name rather
than spelled some other way: the owner published no parameter to carry it in.

It addresses the call and nothing more. What authorizes the call, which headers
it carries, which client dials it, how an answer is classified and where a
receipt is read stay with the caller, because those differ between a durable
task and a chat turn and the request line does not.

It lives here because the wire form of HTTPRoute is this package's to define
and there is already more than one caller: obin-ai/module-runtime's task worker
and obin-ai/module-robin's chat turn. Writing it in each would put the same
encoding in two places that can disagree about one owner.

Verified: go test ./runnable/ green, including a Connect call unchanged, a REST
POST and PUT unchanged, a GET's query and absent body, two spellings of one
object addressing one request line, an escaped string staying one parameter,
and the refusals above each naming what they refused.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@antoinetoussaint-byte antoinetoussaint-byte changed the title fix(agents): explain anonymous release download 404s fix: verify agent downloads and share prepared-call and process operations Oct 27, 2026
@antoinetoussaint-byte antoinetoussaint-byte changed the title fix: verify agent downloads and share prepared-call and process operations fix: verify downloads and share process, call, and container identity contracts Oct 27, 2026
@antoinetoussaint-byte antoinetoussaint-byte changed the title fix: verify downloads and share process, call, and container identity contracts release: v0.19.8 with durable runtime ownership and verified acquisition Oct 27, 2026
@antoinetoussaint-byte
antoinetoussaint-byte merged commit a06da5f into main Oct 27, 2026
10 checks passed
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.

2 participants