Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02b6f-7db1-7222-918b-e813a6bda38d
69 lines
2.9 KiB
Markdown
69 lines
2.9 KiB
Markdown
# Close-evidence outbox
|
|
|
|
Status: **durable core implemented, not connected to the live claim loop**.
|
|
|
|
The outbox preserves one bounded Activity Core completion or failure intent
|
|
after repository work. Replaying an outbox entry calls only the queue close
|
|
adapter; it never dispatches a model, invokes an approach, or repeats repository
|
|
mutation.
|
|
|
|
## Storage and identity
|
|
|
|
The default root is:
|
|
|
|
```text
|
|
$REIN_AHARNESS_STATE_DIR/close-outbox/
|
|
```
|
|
|
|
When that variable is absent, the harness uses
|
|
`$XDG_STATE_HOME/rein-aharness` or `~/.local/state/rein-aharness`. State lives
|
|
outside target checkouts. Outbox directories are mode `0700`; lock and JSON
|
|
files are mode `0600`.
|
|
|
|
An entry is keyed by the digest of the bounded Activity Core `run_id` and
|
|
repository `transaction_id`. Re-enqueuing the identical intent returns its
|
|
existing pending or delivered state. Reusing that identity for a different
|
|
action, result, error, or reopen decision is a conflict and is refused.
|
|
|
|
The v1 close intent contains:
|
|
|
|
- `action`: `complete` or `fail`;
|
|
- bounded normalized JSON `result` evidence;
|
|
- a caller-sanitized bounded error and explicit `reopen` decision for failures;
|
|
- no prompt, provider body, credential, raw tool stream, or workload callback.
|
|
|
|
Results allow only finite JSON values, bounded depth, collection size, string
|
|
length, integer range, key length, and a total encoded size of 64 KiB.
|
|
|
|
## Durability and replay
|
|
|
|
Enqueue and retry-state updates use a same-directory temporary file, file
|
|
`fsync`, atomic replace, and directory `fsync` under a process-safe `flock`.
|
|
The retry attempt is durable before the delivery callback begins.
|
|
|
|
Normal callback return marks the entry delivered and atomically moves it from
|
|
`pending/` to `delivered/`. An ordinary exception retains it in `pending/` with
|
|
only the exception class and a generic failure marker; exception text is not
|
|
persisted. Process interrupts propagate; the already-recorded attempt remains
|
|
pending. Invalid, oversized, or directory/state-mismatched records are moved
|
|
intact to `quarantine/` with a bounded reason sidecar and are never delivered
|
|
automatically.
|
|
|
|
A network timeout may occur after Activity Core accepted a close. Retrying the
|
|
same close intent can therefore repeat the queue mutation request, but cannot
|
|
repeat repository workload. Activity Core remains authoritative for terminal
|
|
row state and must provide idempotent or reconcilable close semantics.
|
|
|
|
## Activation gates
|
|
|
|
The live claim loop still returns an in-memory failure when close delivery
|
|
fails. Connecting it to this outbox requires:
|
|
|
|
1. the lease-bound repository transaction and accepted-result envelope;
|
|
2. enqueue-before-close using the same run and transaction identities;
|
|
3. Activity Core review of repeat close behavior for already-terminal rows;
|
|
4. startup/periodic replay that never calls workload code; and
|
|
5. operator status, quarantine inspection, and replay controls.
|
|
|
|
Until those gates are implemented and reviewed, no production close behavior
|
|
changes.
|