You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0cf1a61
Browse filesBrowse the repository at this point in the historyBrowse files
fix: make an uncertain invocation diagnosable and a failed prepare recoverable
Review of the Builder-over-gRPC change found three defects in the new
"only a certain outcome writes a result" design and several smaller ones.
An uncertain outcome (timeout, interruption, invalid payload, invalid
return, import failure) deliberately writes no result document, which
makes stderr the only carrier of the reason. The harness emitted that
line from inside bounded_logs, so it competed with the handler's own
max_log_bytes budget and lost: a handler writing 4000 bytes to stderr
before returning a wrong-typed output left exit 65, no result, and no
reason at all. The diagnostic is now written after the handler's bound
is released, which is where the completion write used to happen.
The harness also never cleared the result path. Verified: a timed-out
attempt leaves an earlier attempt's SUCCEEDED document in place, and
core's Complete ranks a valid result above the launcher's own deadline
termination, matching it to the run by invocation_id alone. A launcher
reusing the path therefore reads a stale success as this run's proven
result, or at best misreports a crash as INVALID_OUTPUT. The harness
now removes the document before reading the request and refuses to
start if it cannot: a document at that path is always this run's. The
test fixture was pre-clearing the path and hiding this, so it no longer
does. write_completion also renamed a NamedTemporaryFile into place,
narrowing the result to 0600; it is now explicitly 0644, since which
accounts may read it is the facility's choice, not the harness's.
RunnableBuildInputs cleared the prepared snapshot before doing anything
fallible, and prepare refuses a non-empty destination. Retrying into
the caller's own output directory therefore failed with codes.Unknown
*and* discarded the good snapshot, leaving a prepared tree on disk that
Package then refused. It now rejects an occupied destination by name
with AlreadyExists before touching state, and installs the new snapshot
only once the replacement is complete. Unexpected failures across the
Builder are wrapped as codes.Internal instead of reaching callers as
codes.Unknown, and an empty artifact list is reported rather than
panicking on artifacts[0].
outputDirectory had copied Confine's symlink-resolution walk verbatim
and already drifted from it; both now share generate.Resolve/Within.
pkg/agent had no tests, so the containment guard that keeps a build
from copying its own output is now covered directly. The deleted
contract_test.go was the only thing comparing this repo's Go constants
against the Python literals; restored against core's own symbols, so a
core rename fails the build instead of exiting 69 in the fleet.
The generated harness bytes and the configuration digest both changed
while the manifest still said 0.0.1, so the same declaration produced
different package bytes under one agent version. Bumped to 0.0.2.
Every behavior change has a test that fails without it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
0 commit comments