# Technical Documentation: openclaw/clawsweeper

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/openclaw/clawsweeper)

### Overview (`README.md`)

# 🦞🧹 ClawSweeper



ClawSweeper is the conservative review bot for OpenClaw repositories. It keeps
the backlog reviewed, keeps maintainer-visible GitHub comments tidy, and applies
unchanged, high-confidence close proposals through deterministic safety gates.

The dashboard Worker's explicit production targets are `openclaw/openclaw`,
`openclaw/clawhub`, `openclaw/clawsweeper`, and `openclaw/fs-safe`. Additional
public `openclaw/*` and `steipete/*` repositories can use configured profiles or
conservative generic fallback review through event dispatch and scheduled
fanout.

Project vision and boundaries: [`VISION.md`](VISION.md)

Documentation by task and audience: [`docs/README.md`](docs/README.md)

## Contributing

For local setup, PR scope, main-body proof, and the author-owned review loop,
read [CONTRIBUTING.md](CONTRIBUTING.md) before opening or updating a pull
request. Use the [documentation index](docs/README.md) to reach architecture,
configuration, dashboard, policy, and operator references without scanning this
entire README. The contributing guide explains when to use
`@clawsweeper re-review`, why a changed head or PR body needs fresh evidence,
and why readiness is not merge authority.

The OpenClaw-hosted ClawSweeper instance is not a public review service and does
not provide free reviews for third-party repositories. If you want ClawSweeper
for your own project, fork this repository, deploy it in your own organization,
and configure that self-hosted instance for your repositories.

At a high level ClawSweeper:

- reviews open issues and pull requests on a schedule and on exact GitHub events
- writes one durable markdown report per item in generated state
- syncs one marker-backed public review comment per issue or PR, edited in place
- closes only unchanged, high-confidence, policy-allowed proposals
- routes maintainer commands `@clawsweeper review`, `@clawsweeper re-review`,
  `@clawsweeper explain`, and `@clawsweeper stop`
- can acknowledge maintainer comment commands through an optional GitHub App
  webhook before the GitHub Actions fallback starts
- can review local branch ranges with repository and GitHub access kept local
  while Codex connects to the configured model service
- publishes canonical review records to the Cloudflare Worker, action ledgers
  and assets to R2, and the remaining operational state to
  `openclaw/clawsweeper-state`

The [oversized PR close lane](docs/oversized-pr-close-policy.md) proposes closing
pull requests above 50,000 changed lines before hydration, scanning, or model
review, with a maintainer `size: accepted-large` exemption. See the
[close-policy index](docs/README.md#close-policy) for the guarded close lanes.

ClawSweeper is not a generic auto-close bot. Review is proposal-only, apply is
guarded, Codex never gets write credentials during review, and every GitHub
mutation is rechecked against live target state immediately before it happens.

## Capabilities

### Issue and PR Reviews

Scheduled runs scan open issues and pull requests, while target repositories can
forward exact issue/PR events through keyless OIDC Worker intake for low-latency
one-item reviews. Each review writes
`records/<repo-slug>/items/<number>.md` with the decision, evidence, proposed
maintainer-facing comment, runtime metadata, and GitHub snapshot hash.

PR checkout preparation captures only the recursive tree's entry types, object
IDs, sizes, and truncation flag from the GitHub CLI. This keeps path and URL
metadata from exhausting the response buffer while preserving the existing
checkout size limits and rejection of incomplete or malformed trees.

Media proof preparation recognizes image/video filename extensions and GitHub
attachment URLs, including legacy repository asset links. Attachments are fetched
with GET and classified by the response content type; images are saved locally
and videos are probed and converted to contact sheets. PR patches and supplemental
body excerpts never supply host download URLs.

ClawSweeper syncs one marker-backed public review comment per item and edits it
in place instead of posting repeated completed reviews. Scheduled review workers
use a separate temporary status comment for lease coordination. Command-triggered
exact reviews instead rewrite their existing acknowledgement and use the durable
queue claim as their coordination lease, so they do not add a second visible status
comment. Exact-review workers verify queue ownership before generation and during
finalization. Temporary lease comments are removed after publication. Pull request
comments include hidden verdict/action markers for trusted automation ownership.
See
[`docs/pr-review-comments.md`](docs/pr-review-comments.md).

Review prompts include compact related issue and PR context from explicit links,
linked closing PRs, existing local ClawSweeper reports, optional gitcrawl
clusters, and opt-in live GitHub issue search for exact event reviews. This is
advisory context for duplicate/superseded reasoning, not a standalone close
decision. Reviews also persist a typed, proposal-only root-cause assessment with
same-repository URLs and at most one evidence-backed canonical item; it does not
dispatch repair, suppress jobs, mutate siblings, close, or merge. See
[`docs/related-issue-discovery.md`](docs/related-issue-discovery.md).

For open issues with complete, current kept-open reviews, ClawSweeper also
projects selected structured review conclusions into advisory GitHub labels for
maintainer filtering and project views. These labels expose states such as
current-main reproduction, source reproduction, linked open PRs, queueable
fixes, verified small bugs suitable for `good first issue`, missing info, and
product/security review needs. They are advisory only
and do not trigger repair, merge, or close behavior. Label-only syncs record
`labels_synced_at` in the durable report so GitHub `updated_at` changes caused
by ClawSweeper-owned label writes do not look like fresh target-side activity to
the scheduler. See
[`docs/work-lane.md`](docs/work-lane.md).

### Apply and State

Apply mode re-fetches live GitHub state, checks labels, maintainer authorship,
paired issue/PR state, snapshot drift, and repository profile rules before
commenting or closing anything. Closed or already-closed reports move to
`records/<repo-slug>/closed/<number>.md`; reopened archived items move back to
`items/` as stale work.

Apply and artifact replay also maintain Codex-authored decision packet JSON at
`records/<repo-slug>/decision-packets/<number>.json` for reports that need a
maintainer ruling. Codex supplies the exact question, rationale, options,
recommendation, and likely owner as structured review output. Deterministic
code validates that intent, persists it, refreshes item state, and removes stale
packets; labels and report prose do not reconstruct the decision. Pass
`--decision-packets-dir` to write those packet files somewhere other than the
profile's default records directory.

Canonical review records live in the Cloudflare Durable Object store and are
snapshotted to R2. Immutable `ledger/v1/` action events, published `assets/`,
and the bounded content-addressed `artifacts/exact-review/v1/` retry cache also
live in R2. The `state` branch of `openclaw/clawsweeper-state` now retains
only `jobs/`, `results/`, `notifications/`, `apply-report.json`, and
`repair-apply-report.json`; its `main` branch remains the dashboard renderer
source. `scripts/hydrate-state.ts` combines those sources for local commands.
See [`docs/state-storage.md`](docs/state-storage.md) for the ownership table.

### Commit Reviews (retired)

The push/manual commit-review lane was retired in July 2026. Use
`pnpm local-review` for GitHub-isolated local branch reviews.

### Operations

Repository-specific rules live in `src/repository-profiles.ts`, so OpenClaw,
ClawHub, and ClawSweeper can share the same engine while keeping different apply
limits. Review supports manual workflow dispatch, reruns, and backfills.

## Guardrails

ClawSweeper may propose a close only when the item is clearly one of these:

- implemented on current `main`
- not reproducible on current `main`
- better suited for ClawHub skill/plugin work than core
- duplicate or superseded by a canonical issue/PR
- low-signal pull request whose branch is mostly unrelated or unmergeable churn
- external low-rated pull request whose requested real-behavior proof never
  arrived and whose branch has been idle for 14+ days
- external pull request abandoned for 30+ days as a draft, waiting on its
  author, or failing checks on its live head
- concrete but not actionable in this source repo
- incoherent enough that no action can be taken
- stale issue older than 60 days with too little data to verify

Maintainer-authored items stay open unless ClawSweeper can verify that the
request is already implemented on current `main`. Everything else stays open.
Issues with an open PR that references them using GitHub closing syntax such as
`Fixes #123` stay open until that PR merges, is closed, or ClawSweeper closes
that high-confidence PR candidate earlier in the same apply run.
Open issue/PR pairs from the same author stay open together unless the paired
item is already resolved or a maintainer explicitly asks to close one side.
Related PR links do not promote a completed keep-open review into a close
proposal. Codex owns that supersession decision; comment publication preserves
the verdict. Independent no-diff, stale-PR, and author-budget policies still
apply.

PR-to-PR duplicate/superseded closes also require a safe canonical target:
ClawSweeper refuses to close one PR as replaced by another PR that is closed
unmerged, missing positive real behavior proof, F-rated, already proposed for
close, not cleanly mergeable, or otherwise not a viable landing path.

Repository profiles can further narrow apply. ClawHub and ClawSweeper self-review
are intentionally stricter: they review issues and PRs, but apply may close only
PRs where current `main` already implements the proposed change with
source-backed evidence.

Maintainer-authored issues and PRs, and items labeled `maintainer`, created from
2026-10-15 03:50 UTC are reviewed like everyone else's: a PR gets one automatic
review and later reviews need a request; an issue follows the ordinary issue
cadence. Older maintainer items stay excluded from automatic reviews and
scheduled sweeps, and got one opening/ready reminder explaining how to opt in.
Only request `@clawsweeper review` when a review is needed and the
work and validation are complete; agents must not request reviews automatically
or repeat requests while one is queued or running. A one-off request does not
opt future pushes into reviews, but it stays open until it is answered: if the
item changes while it is reviewed, ClawSweeper re-reviews and still answers that
request. The retired `clawsweeper:autofix` and `clawsweeper:automerge` labels no
longer change review admission; they still protect an item from close proposals.

## Maintainer Commands

The canonical comment commands are:

```text
@clawsweeper review
@clawsweeper re-review
@clawsweeper explain
@clawsweeper stop
```

`review` and `re-review` request a fresh read-only issue/PR review; `explain`
summarizes the current result, and `stop` prevents further automatic handling.
The router checks repository permissions and the command's current source
comment before accepting work. Contributors may request a review of their own
items under the configured authorization policy.

The GitHub App webhook durably records eligible review comment versions before
acknowledging them. Exact item work is coalesced and leased by the Worker, so a
webhook burst does not create capacity-waiting Actions runners. Repair, autofix,
automerge, issue implementation, fix-ci, and address-review commands are retired.

## Dashboard

Live dashboard and generated state: https://github.com/openclaw/clawsweeper-state

Live pipeline dashboard: https://clawsweeper.openclaw.ai/

The Cloudflare control plane exposes read-only queue, review, publication,
and health telemetry. It never delegates GitHub mutations to the browser.
See [`docs/live-dashboard.md`](docs/live-dashboard.md).

The optional triage dashboard page at `/triage` exposes ClawSweeper advisory
issue labels as read-only maintainer views, including local routing groups
derived from existing `impact:*` labels. It is backed by GitHub Search snapshots
instead of GitHub Project writes. See
[`docs/triage-dashboard.md`](docs/triage-dashboard.md).

The optional PR proof triage page at `/pr-proof-triage` exposes open pull
requests that are blocked on real behavior proof labels, including missing
proof, supplied-but-not-sufficient proof, mock-only proof, and proof label
mismatches. See
[`docs/pr-proof-triage-dashboard.md`](docs/pr-proof-triage-dashboard.md).

The default-off unconfirmed product-direction policy can propose closure for a
strictly bounded class of technically correct, well-proven external feature PRs
that still lack maintainer-confirmed direction. Live maintainer signals and
automation opt-ins veto apply. See
[`docs/product-direction-close-policy.md`](docs/product-direction-close-policy.md).

The default-off per-author PR-budget policy gradually trims an external
author's oldest lowest-signal PRs only after apply verifies the live repository
count, seven-day inactivity, rating/proof eligibility, protected labels, and
maintainer engagement. See
[`docs/author-pr-budget-close-policy.md`](docs/author-pr-budget-close-policy.md).

## How It Works

ClawSweeper has two operational lanes:

- review lane: scheduled and event-driven issue/PR reviews, durable reports, and
  public review comment sync
- apply lane: guarded close/comment mutations, audit, reconcile, and state
  publishing

### Scheduler

The issue/PR scheduler decides what to scan and how often. New and active items
get more attention; older quiet items fall back to a slower cadence. Detailed
scheduling, capacity, and monitoring behavior is documented in
[`docs/scheduler.md`](docs/scheduler.md).

- hot/new and recently active items are checked hourly, with a 5-minute intake
  schedule for the newest queue edge
- target repositories can forward issue and PR events through OIDC Worker intake;
  the queue leases a dedicated executor to
  review one item, sync the durable comment, and apply only safe close
  proposals for that same item
- pull requests and issues younger than 30 days are checked daily once they
  leave the hot window
- older inactive issues are checked weekly
- apply wakes every 15 minutes and exits quickly when there are no unchanged
  high-confidence close proposals

### Review Lane

Review is proposal-only. It never closes items.

- The `ClawSweeper Review Plan` workflow (`review-plan.yml`) selects due items
  and offers them to the shared exact-review queue.
- Manual review runs in `review-plan.yml` can select `item_number` or comma-separated
  `item_numbers`, target branch, prompt, timeout, and hot-intake mode. Broad runs
  use the same queue capacity and pacing as scheduled feeds; per-run `batch_size`, `shard_count`,
  and `apply_after_review` inputs are retired. Use the separate `sweep.yml` `apply_existing`
  lane to apply eligible proposals.
- Each admitted item gets its own review workflow for the selected target.
- Codex reviews use `gpt-6.1-sol` with medium reasoning in the direct API auth
  modes (`login` and `proxy`); `clawrouter` mode instead runs its private
  inference alias. Issues and pull requests authored by an OWNER, MEMBER, or
  COLLABORATOR, or by anyone whose live repository permission is `write`,
  `maintain`, or `admin`, use priority (fast) service; other items use standard
  service. Write access alone does not make an item maintainer-authored for
  close policy. Assist answers always use priority service because only
  write-access maintainers can request them. Sweep planning and close-coverage
  proofs use the configured ordinary-item defaults. Reviews have
  a 10-minute per-item timeout.
- Each item becomes a flat report under
  `records/<repo-slug>/items/<number>.md` with the decision, evidence,
  Codex `/review`-style PR findings, suggested comment, runtime metadata, and
  GitHub snapshot hash. When GitHub exposes a merged closing PR for an issue,
  the report records that PR and the close comment links it as fix provenance.
- High-confidence allowed close decisions become `proposed_close`.
- After publish, the lane checks the selected items' single marker-backed Codex
  review comment. Missing comments and missing metadata are synced immediately;
  existing comments are refreshed only when stale, currently weekly.
- PR review comments keep the top-level note concise, put source links and full
  evidence in collapsed details, and use hidden verdict/action markers for the
  trusted ClawSweeper repair loop; see
  [`docs/pr-review-comments.md`](docs/pr-review-comments.md).

### Apply Lane

Apply reads existing reports and mutates GitHub only when the stored review is
still valid.

Reviewer decisions come only from the typed `review_record` stored in each report.
A missing or unreadable record requires a fresh review: apply records
`skipped_changed_since_review` without calling GitHub, and decision packets and
public decision renderers do not infer decisions from report prose. The completed
backfill command and workflow have been retired.

- Updates the single marker-backed Codex automated review comment in place.
- Closes only unchanged high-confidence proposals.
- Keeps the durable review comment. Applied PR closes also post one idempotent,
  marker-backed close receipt; issue closes currently leave the durable review
  as ClawSweeper's sole comment.
- Moves closed or already-closed reports to
  `records/<repo-slug>/closed/<number>.md`.
- Moves reopened archived reports back to the repo’s `items/` folder as stale.
- Commits checkpoints and machine-readable status during long runs.

Apply wakes every 15 minutes, no-ops when there are no unchanged
high-confidence close proposals, and narrows scheduled runs to the currently
eligible proposal list so idle runs do not scan unrelated keep-open records.
It defaults to all item kinds, no age floor, a 2-second close delay, and 40
fresh closes per checkpoint, with a hard cap of 40 to keep each GitHub App
token within its lifetime. After a checkpoint closes at least one item, it
queues another apply run with a fresh token; a saturated scan that closes
nothing stops and waits for the next scheduled tick instead of self-dispatching
indefinitely.

Apply health keeps the scheduler-admitted `apply_ready_count` separate from the
full promotion backlog, cooldown-eligible probes, proof-required work, guarded
retries, and inconsistent records. Its cycle estimate covers work actionable in
the current scheduler window rather than presenting every probe as immediately
closable.

All review execution uses the exact-item queue; broad runs only feed its planner. The read-only reviewer
handles only the selected item, uploads a hash-bound GitHub Actions artifact,
enqueues a separate durable publication lease, and then releases its review
lease without checking out or pushing the state repository. The queue retries
publication independently, so a cancelled publisher does not rerun Codex. The
source fallback uses adaptive minimum/base/maximum values of 4/24/48; production
overrides them with 8/32/32 and enables direct
publication plus up to 8 concurrent size-8 batches, with two isolated preparation
workers per batch. The Durable Object validates
each artifact's workflow run, queue tuple,
target, decision digest, file inventory, sizes, and SHA-256 hashes before a
publisher receives write tokens.
Publication leases reserve the bounded publisher lane's maximum queue wait;
terminal-run reconciliation releases dead dispatches early. The publisher then
uses the same review and apply paths with only the
immediate-safe reasons enabled by default:
`implemented_on_main`, `duplicate_or_superseded`, and
`low_signal_unmergeable_pr`. A stale tuple now terminates as `superseded`
instead of retrying, while permanent failures enter a bounded dead-letter store
after their confirmation retries. Artifacts remain available for 90 days; three
confirmed unavailable-artifact attempts queue one fresh exact review instead of
waiting for the retention deadline.

Deterministic terminal and remain-open outcomes flow through the same publisher.
Ordinary synced verdicts publish their exact durable comment, then queue an
executing target-wide comment-router scan. Exact publishers use the bounded
Durable Object lane while batch publishers remain per-target serialized. Exact publishers and the separate issue-implementation backfill workflow retain their guarded intake. Publication still does not claim an
atomic state-publish-and-route boundary.
`stale_insufficient_info` issue reports and `mostly_implemented_on_main` PR
reports are never applied to young items; apply requires those reports to be at
least 60 days old unless a manual run explicitly changes the threshold. A stale
issue also stays open when a non-bot comment was posted in the last 60 days.

The external state dashboard is fleet-scoped. Each configured repository gets
its own canonical record collection, status JSON, audit state, cadence counts,
and recent activity section, so event runs from one repo do not hide the state
of another.

There is still one deterministic apply path for writes. Review can propose and
sync stale public review comments, but closing remains guarded by apply so a
fresh GitHub snapshot, labels, maintainer-authorship, and unchanged item state
are checked immediately before mutation. Maintainer-authored or
`maintainer`-labeled items can still close when the only protected state is
maintainer ownership and the close reason is verified `implemented_on_main`.
Configured OpenClaw targets may close issues as `implemented_on_main` when the
fix is proven on current `main`, even before the next release ships.

### Commit Review Lane (retired)

The hosted commit-review lane was retired in July 2026 (zero successful runs in
its final month). The local, GitHub-isolated review engine survives as
`pnpm local-review`; see [docs/commit-sweeper.md](docs/commit-sweeper.md).

### Safety Model

Native reviews require host-owned TruffleHog admission before any model-backed
checkout inspection or review. The host scans the explicit initial prompt and
schema plus complete raw before/after blobs and the full introduced diff. Scan
coverage is independent of the 80-path/24K-character display evidence limits.
Clean text-converted checkouts retain both canonical Git and raw working bytes
in scan coverage. The host never starts a target-bundled autoreview helper or
second reviewer.

Hosted Codex and OpenClaw setup share `.github/actions/setup-review-tools`, which
caches only the checksum-pinned release archive. Every setup verifies its bytes,
extracts a fresh private binary, checks the exact version, and runs the benign
scan before advertising its path. Cache misses and corrupt archives use the
pinned download; installed binaries and review data never enter the Actions
cache. For local review,
ClawSweeper first qualifies a trusted host executable outside both checkouts; when it
is absent or reports a different TruffleHog release, it bootstraps the exact checksum-pinned release asset into a
user-owned cache outside both checkouts. The local bootstrap accepts no URL or
version override, verifies the download and cached executable, and runs a clean
environment version check before scanning. Missing tools, unclassified findings, scan errors, source
drift, incomplete ancestry/objects, changed gitlinks, and LFS pointers refuse the
review. The scan stages at most 256 MiB in private external temporary files and
uses the remaining review deadline; it never silently truncates or bypasses.
Diagnostics omit scanner output and source values. Restore prerequisites or
remove sensitive input before retrying a refusal.
Exact-review failure manifests distinguish a native output/scan-contract failure
from an unclassified finding. The latter records the first blocking finding's
bounded detector metadata and host-staged material identity: prompt, schema,
additional input, raw diff, patch, raw working bytes, or Git blob. Source
references contain Git revisions and hashed paths, with at most four references
and their total count. No raw paths, matched values, literal digests, or
verification messages are retained; this provenance does not authorize a finding.

The host classifies the reviewed synthetic malformed-configuration URI in
`test/action-ledger-runtime.test.ts` and the explicitly approved autoreview
negative-test URI in the [canonical autoreview test](https://github.com/openclaw/agent-skills/blob/a8466c1d860588a083610fe41fd277c1d88b14e0/skills/autoreview/tests/test_autoreview_hardening.py)
or its [vendored OpenClaw copy](https://github.com/openclaw/openclaw/blob/136eab023035dd5943818f791d3c3db7d92e4491/.agents/skills/autoreview/tests/test_autoreview_hardening.py)
as non-sensitive after a complete scan. OpenClaw's existing
[completion-webhook warning-redaction fixture](https://github.com/openclaw/openclaw/blob/226302c6ef7b496ced68f69f917669cd8a18f7ed/src/gateway/server-cron-notifications.test.ts#L735)
qualifies only for FTP detector 899
with the observed `PLAIN` and `HTML` decoders. Both native value digests, the
complete source file's SHA256, every literal occurrence's complete source line,
original path, regular-file mode, committed base/head roles, and native FTP
metadata shape must match. Any source-file edit requires requalification, including
unrelated changes: HTML decoding can hide another occurrence from plain-text
search. FTP patch findings and other decoders
remain blocking. See the [native before/after proof](docs/proof/cron-ftp-fixture/README.md).
The same exact-fixture policy covers
the reviewed OpenClaw Browser CDP authentication and credential-redaction fixtures in
[`chrome.test.ts`](https://github.com/openclaw/openclaw/blob/8e03b0c62e76dc25c77045a84ab3098a111a7be3/extensions/browser/src/browser/chrome.test.ts),
the [remote-CDP coverage](https://github.com/openclaw/openclaw/blob/58da2f5897feb6840937d8e50cf7ee6f26aa57d7/extensions/browser/src/browser/chrome.test.ts),
the [server-context redaction test](https://github.com/openclaw/openclaw/blob/4b5987829d0f82ea44ae50f2f418ffe5ea445e7f/extensions/browser/src/browser/server-context.ensure-browser-available.waits-for-cdp-ready.test.ts),
the [profile-status redaction fixture](https://github.com/openclaw/openclaw/blob/6419496e10404f624728f47d9ebcd874aaf60a79/extensions/browser/src/browser/server-context.list-profiles.test.ts#L424-L453),
the [remote-CDP documentation example](https://github.com/openclaw/openclaw/blob/bf15c87d2b1223610b42775b8154b8eec60b541d/docs/tools/browser.md),
the [credentialed-page rejection fixtures](https://github.com/openclaw/openclaw/blob/d5fb4903f1b13a4309d479f1011d995b1fc706ae/extensions/browser/src/browser-tool.test.ts),
the [guarded CDP authentication fixtures](https://github.com/openclaw/openclaw/blob/1cf6ff3bdc08a6ac08facb1006b1d7aabc0eaff4/extensions/browser/src/browser/cdp.helpers.test.ts),
the [MCP endpoint-redaction fixture](https://github.com/openclaw/openclaw/blob/ac21e89c13e42f6a7d152bf9be143e67edd44ed3/extensions/browser/src/browser/chrome-mcp.test.ts),
the [Crabbox fleet audit sanitization fixture](https://github.com/openclaw/crabbox/blob/937523aced0f6c2d3b9242461eeab1a03bd893e8/worker/test/fleet.test.ts),
the [Mac dashboard credentialed-subframe rejection fixture](https://github.com/openclaw/openclaw/blob/9ba01d6c7b1c308e7b41eac11ba6f43e0fd0393d/apps/macos/Tests/OpenClawIPCTests/DashboardWindowSmokeTests.swift#L273),
the [Mattermost slash-error sanitization fixtures](https://github.com/openclaw/openclaw/blob/9c0975c1c20ed635532c7aa0f510154224adee7f/extensions/mattermost/src/mattermost/slash-http.test.ts),
the [MCP Apps sandbox-origin rejection fixture](https://github.com/openclaw/openclaw/blob/f3971bbd56e4aadea0f8b0c1434f6860f953cbbd/src/config/config-misc.test.ts),
the [Gateway config CDP-redaction fixture](https://github.com/openclaw/openclaw/blob/4b5987829d0f82ea44ae50f2f418ffe5ea445e7f/src/gateway/server.config-patch.test.ts),
the [mocked marketplace telemetry-redaction fixture](https://github.com/openclaw/openclaw/blob/9c5ee4676d0732e72ee9a939ae4918dc89bcaab8/src/cli/plugins-cli.marketplace-refresh.test.ts),
the Signal URL-rejection fixtures in [client tests](https://github.com/openclaw/openclaw/blob/75d633a7b97240280ebf13e121a1960eb2ec2765/extensions/signal/src/client.test.ts#L172)
and [container tests](https://github.com/openclaw/openclaw/blob/41dd2e04897b9bdbde971cad8c6ff21ecccd38b7/extensions/signal/src/client-container.test.ts#L1461)
(including the exact [table-driven replacement](https://github.com/openclaw/openclaw/blob/1e49231d063bad36e4b6b187727d957fbfc7fdfb/extensions/signal/src/client-container.test.ts#L78)),
and the OpenClaw config [URL-redaction](https://github.com/openclaw/openclaw/blob/5fe22a7d88919f260e7999fc775733feff3cb1fa/src/config/redact-snapshot.test.ts)
and [restoration fixtures](https://github.com/openclaw/openclaw/blob/5fe22a7d88919f260e7999fc775733feff3cb1fa/src/config/redact-snapshot.restore.test.ts)
after a complete scan. Static host policy associates each
exact detector-matched URI SHA-256 with only its approved source paths and exact
scanner `Raw` digest, including when `Raw` omits a path retained by `RawV2`. The
matched value must be a literal in a host-staged Git blob from mode `100644`.
The three guarded-CDP/MCP entries, Crabbox fixture, Mac dashboard entry, MCP Apps entry, marketplace telemetry entry, Gateway config entry, two Signal entries, and four Mattermost entries also bind complete
reviewed source lines, including surrounding query text that TruffleHog's URI
detector does not match. Changes to those lines or additional literal occurrences
refuse classification. These witnesses do not expand native query detection.
The table binds exact values and paths across revisions, not particular commits.
The host locates that exact literal independently in the staged blob. Decoder
coordinates can shift, and TruffleHog can omit a companion plain-text finding,
so admission does not depend on another finding or a reported line matching the
original source. Repeated literals remain eligible unless an entry is bound to
an approved complete-line digest; those entries require exactly one occurrence
in the staged blob. Finding order and duplicate records do not change the exact
value, path, and mode checks.
Findings must use `PLAIN` or `HTML`, except the MCP Apps, marketplace telemetry, and Gateway config entries permit only
their observed `PLAIN` decoder and the two guarded-CDP fixtures also permit `BASE64`.
The pinned Base64 decoder preserves the rest of a chunk after
decoding another token, so an unchanged literal can acquire that decoder label
and win cross-decoder deduplication. Those entries still require the literal in
its exact original source line; encoded-only content remains blocking.

The OpenClaw [logging redaction fixtures](https://github.com/openclaw/openclaw/blob/fe0367a07a23660ea35007ac69bdb8f54309fc21/src/logging/redact.test.ts)
and the reviewed Crabbox PostgreSQL operations example use a separate flat
attribution table without changing the legacy URI policy above. Each row binds
the exact detector ID and name, observed native decoder, `Raw`, `RawV2`, and
complete source-line SHA-256 digests, path, and mode. The logging rows permit
only their observed `PLAIN`, `ESCAPED_UNICODE`, or `HTML` variants. `HTML` is
qualified only for the [rewritten fixtures](https://github.com/openclaw/openclaw/blob/58b18602329e5f6113056aa34c6daba0ecddd7f8/src/logging/redact.test.ts)
from OpenClaw #160879; the pre-rewrite rows remain for merge bases that predate
it ([proof](docs/proof/logging-redaction-fixtures/README.md)). The Crabbox
documentation row permits only its observed `PLAIN` or `HTML` variants. These
exact attribution rows are role-neutral; every logical staged reference must
independently match the row and have a committed `base` or `head` role. URI
findings require one literal `RawV2` witness unless the row declares an exact
ordered sequence of complete source-line digests. A declared sequence must match
every occurrence exactly; missing, extra, reordered, or changed lines refuse
admission. Derived host, username, and password fields must match native metadata;
the host preserves explicit default ports and original spelling, as TruffleHog
does. MongoDB and Postgres findings bind the scanner-reported line
and their exact native metadata shape. URI findings are attributed to the plain
literal wherever it occurs in the blob or patch; a decoded finding is not yet
bound to its own source location ([#1724](https://github.com/openclaw/clawsweeper/issues/1724)).
Any emitted subset and order may qualify;
duplicate exact findings, unknown variants, lossy decoder buckets, or an
unqualified deduplicated blob reference refuse admission.

The same table qualifies the exact embedded-credential rejection fixture in
OpenClaw's `extensions/matrix/src/matrix/client.test.ts` for URI detector 17,
only with `PLAIN` or `HTML` attribution. Both raw-value digests, the complete
source line, path, regular-file mode, and committed base/head references must
match. Retained source-only native scans observed PLAIN findings; the original
hosted refusal identified HTML for its first finding but did not retain the
second finding's details. Constructed HTML regression records are not recovered
hosted evidence. Qualification does not waive that unknown finding or replace
fresh whole-input admission and a completed review.

The same table qualifies the existing OpenClaw [browser URL-port precedence
fixtures](https://github.com/openclaw/openclaw/blob/3e6f7494af752db12ee8f1f9160a8c950158174d/extensions/browser/src/browser/config.test.ts).
The HTTPS input and assertion require their exact two-line sequence; the two
loopback fixtures each require one complete source line. Only URI detector 17,
`PLAIN`/`HTML`, the pinned raw-value identities, regular-file mode, and committed
base/head references qualify. The native proof for PR #149651 observed `PLAIN`
findings; `HTML` is separately covered by constructed classifier records.

The marketplace entries telemetry test uses the same reviewed feed URI twice, in live and snapshot metadata. Its exact attribution binds both complete source lines in order, URI detector 17, observed PLAIN or HTML decoding, regular-file mode, and committed base/head roles. The refresh test keeps its existing legacy approval and repair roles. Policy selection follows the staged source references, including each patch witness, so a shared URI does not transfer changed-line approval or duplicate-record rules between these sources. See [the native proof](docs/proof/marketplace-telemetry-fixtures/README.md).

Six existing Crabbox scope-normalization and redaction fixtures use the same exact attribution table, limited to their observed URI detector 17 / PLAIN results. Both raw digests, each complete source line (including the ordered pair for the repeated fixture), the three original test paths, regular-file mode, and every committed base/head reference must match. No test file is exempt from scanning. See [the qualification contract and native proof](docs/proof/crabbox-config-fixtures/README.md).

The Gateway readiness error-privacy fixture in OpenClaw's
[readiness test](https://github.com/openclaw/openclaw/blob/876b4c34f16b46bb4cbff8569d6cb2ba39ee0e59/test/helpers/openclaw-test-instance.test.ts#L2002) is also qualified by this table.
The exact URI detector 17 identities, complete source line (including the
surrounding synthetic payload expression), regular-file mode, and committed
base/head references must match. Native 3.97.4 scans observed `PLAIN` and `HTML`;
only those two variants qualify. See [the native proof](docs/proof/readiness-privacy-fixture/README.md).

The browser CDP discovery fixture in
`extensions/browser/src/browser/pw-session.connections.test.ts` uses the same
exact table for its observed URI detector 17 `PLAIN` and `HTML` findings. Both
raw-value digests, the complete source line, original path, regular-file mode,
and committed base/head references must match. See [the native proof](docs/proof/agent-input-scan-context/README.md#browser-cdp-discovery-fixture).

The CDP authentication and explicit-port fixtures in OpenClaw's
[SDK browser tests](https://github.com/openclaw/openclaw/blob/38d949a549dbb8f9376d5d08a96422615c8e7ab0/src/plugin-sdk/browser-subpaths.test.ts) qualify only for their observed URI
detector 17 `PLAIN` findings. Both native value digests, each complete source
line (including the path suffix beyond the native match), the original path,
regular-file mode, and every committed base/head reference must match. Other
decoders and changed source lines remain blocking; the WebSocket fixture has
no qualification because the pinned scanner did not emit a finding for it.

The TypeSafe local-transport URL-rejection fixture in
`extensions/typesafe/src/local.transport.test.ts` binds its exact URI detector 17
identities, full source line, regular-file mode, and committed base/head references.
Native 3.97.4 scans observed `PLAIN` and `HTML`; only those variants qualify.
See [the native proof](docs/proof/agent-input-scan-context/README.md#typesafe-local-transport-fixture).

The native-worker endpoint and startup-config rejection fixtures in
[transport tests](https://github.com/openclaw/openclaw/blob/93dbee664f93ca80668f85ab346c8e7a4e07db7e/src/worker/native-runtime-transport.test.ts) and
[startup tests](https://github.com/openclaw/openclaw/blob/93dbee664f93ca80668f85ab346c8e7a4e07db7e/src/worker/native-runtime.test.ts)
qualify only through their exact URI-17 PLAIN/HTML attribution, both value
digests, complete source lines, regular-file mode and committed source references.
No whole test file is exempt. See [the native source-admission proof](docs/proof/native-worker-fixtures/README.md).

One source path may contain multiple independently reviewed fixtures; each
digest/path/mode tuple must match exactly, so source membership alone never
qualifies a finding.
The model-egress fixtures in OpenClaw's
[Crabbox model runner](https://github.com/openclaw/openclaw/blob/15c14e982fd7640a77b0c2b9bab6e5b4b168f705/extensions/crabbox/src/crabbox-model-run.test.ts) and
[configured model egress](https://github.com/openclaw/openclaw/blob/15c14e982fd7640a77b0c2b9bab6e5b4b168f705/src/secrets/model-egress.test.ts) tests qualify three synthetic URI identities using
their complete source lines and committed regular-file references. Native
TruffleHog 3.97.4 observed `PLAIN` and `HTML` for each identity; only those
variants qualify. See [the native proof](docs/proof/agent-input-scan-context/README.md#model-egress-fixtures).
Deduplicated blobs retain every scanned logical endpoint's role, path, and Git
mode, including mode-only transitions and shared-path aliases. Every captured
reference must qualify under the same exact attribution policy before any source
is eligible for classification or an audit notice.
The policy does not trust checkout ignore rules, domain patterns, fixture words,
test names, or unchanged-line inference; no nearby fixture is implicitly approved.
The mandatory scanner regression suite validates the immutable host-owned
attribution table for malformed or duplicate rows. Normal scans do not repeat
that static policy check: native scan completeness, staged source material,
line attribution, and secret matching are still verified for every scan.
Explicitly supplied test policies are validated before classification.
When review evidence quotes an exact reviewed synthetic URI, prompt preparation
replaces the URI with a visible reference to its source file, preserving closing
Markdown and sentence punctuation. The original context is preserved, and changed
paths, credentials, or additional query text remain untouched. This omission does not classify a native finding or prove
its verification status. Source blobs, introduced patches, and scanner admission
retain their existing checks.
The create-profile response-redaction fixture in OpenClaw's
`extensions/browser/src/browser/profiles-service.test.ts` also binds its exact
URI identity, complete source line, regular-file mode, and committed base/head
references. Native 3.97.4 scans observed only `PLAIN` and `HTML` attribution;
the policy accepts those two variants.

The plugin settings redaction fixtures in OpenClaw's
`ui/src/pages/custodian/custodian-session-store.test.ts` and
`ui/src/e2e/plugins-help.e2e.test.ts` bind their exact synthetic URI, ordered
complete source lines, regular-file mode, and committed base/head references.
Native 3.97.4 scans observed `PLAIN` and `HTML` attribution for these fixtures;
only those exact tuples qualify.

The autoreview hardening negative-test fixtures in
`skills/autoreview/tests/test_autoreview_hardening.py` and its OpenClaw mirror at
[.agents/skills/autoreview/tests/test_autoreview_hardening.py](https://github.com/openclaw/openclaw/blob/b2d3d0f86be704f80a04c11110aa1a7082a961a6/.agents/skills/autoreview/tests/test_autoreview_hardening.py) use the same exact
attribution table. URI detector 17, each row's qualified `PLAIN` or `HTML` decoder, both pinned
raw-value digests, every complete source line in order, regular-file mode, and
committed base/head references qualify. The existing legacy value-only row stays
available for review-context omission; changed patch lines require these exact
tuples. No other literal or source line in either test file is implicitly approved.
The additional empty-username and encoded-NUL identities permit only their
observed `PLAIN` decoding. See [the repeated native proof](docs/proof/agent-input-scan-context/README.md#autoreview-hardening-fixtures).

The full generated patch remains scanned. Every literal occurrence of an
eligible URI must bind to committed regular-file bytes through canonical
same-path headers, full Git object IDs, hunk coordinates, counts, and newline
markers. Unchanged context requires the identical full line in both blobs.
Added lines require the head blob; removed lines require the base blob, and
both require exact ordered full-line attribution policy. Legacy value/path-only
rows remain context-only. Every retained blob reference must independently pass
the existing fixture policy.
New and deleted files additionally require one matching host-captured raw Git
diff record proving the absent endpoint, correct zero object ID and mode, and
the complete present-file hunk. A textual `/dev/null` header or missing blob is
not absence proof; contradictory captured references refuse admission.
Headers containing the URI, binary patches, ambiguous paths, mode changes,
uncommitted endpoints, and encoded-only matches remain blocking. Decoder line
coordinates are diagnostic only; source matching does not rely on them.
Patch notices retain the original material ID, scanner line, decoder, and literal
line, with `patch` provenance recording both revisions and each source blob/line.
The prompt omission helper is never applied to scan input. See
[the reproducible admission proof](docs/proof/agent-input-scan-context/README.md).

CloudflareGlobalApiKey detector 58 can pair Git's generated 40-character blob
IDs with nearby email context. An unverified `PLAIN`/`HTML` finding in a patch or raw diff
requires a separate provenance scan only when every literal occurrence is an exact
object-ID field in canonical same-path regular-file patch/raw-diff headers.
Modified executable files also qualify when both endpoint modes remain `100755`;
their raw records, patch headers, and blob references must agree on that mode.
Executable additions/deletions, mode changes, and symlinks remain unsupported.
The two endpoint revisions, paths, modes, and full staged blobs must agree;
the host independently rehashes each present blob. Added and deleted files require
matching zero endpoints, mode/status fields, patch headers, and absence of source
references at the missing endpoint. Raw records and matching patch sections must
be unambiguous; malformed, duplicate, or unmatched records refuse. The matched bytes must be absent
from every staged prompt, schema, additional input, raw working file, and full
blob, preventing detector deduplication from hiding a content occurrence.
Missing retained bytes, unsupported metadata, malformed native fields, verified
findings, and scanner errors still refuse. The complete patch, raw diff, and
blobs remain scanned unchanged. Metadata notices identify their classification
and use a SHA-256 digest in the existing notice identity field; matched object
IDs and verification values are never emitted. OpenClaw Bay is unaffected.

Those witnesses alone never admit a review: HTML decoding can create another
matching value from source content while its reported line differs from the
original bytes. The host scans a second complete copy of each affected patch or raw diff with only the proven
object-ID fields masked at their original lengths. All filename context and
content bytes remain unchanged, and the staged bytes record that actual masked
copy. The same pinned scanner, verification flags, completion checks, and shared
deadline apply. Any remaining unclassified finding or request for metadata proof
refuses admission; success notices are emitted only after this replay and the
final source fences. Raw-diff replay has no fixture-admission route: any remaining
finding refuses. Existing URI-only reviews retain their original single scan.

Findings attributed to prompt, schema, additional-input, other-path,
or unqualified patch material remain blocking, as do other findings, verified
findings, and incomplete scans. Unverified findings alone never qualify: every finding must
match the exact bytes, source association, and strict detector contract. This
classification does not expand TruffleHog's detection coverage.
The classification is pinned to TruffleHog 3.97.4's output contract; scanner
upgrades require requalification. See `src/agent-input-scan-fixtures.ts`.
After successful cleanup and final source fences, each accepted fixture/source
pair emits a host-side structured stderr notice with `event`, `fixtureSha256`,
`source`, `detector`, and `findings` entries containing `blob`, `decoder`, and
`occurrences`; role-bound findings also include `role`. Each finding retains its
reported `scannerLine` and a `literalLine` for the first exact literal in the
staged blob. This bounded witness establishes literal presence; it does not
identify which occurrence produced a decoded hit.
Counts are per source: a shared blob can appear in both source
notices and those counts must not be summed across sources. A refused or drifted
scan emits no success notice. Raw values and verification diagnostics never
appear in that audit notice.

Generated review and repair prompt diagnostics retire the previous attempt's
copy before admission and persist only successfully scanned exact prompt bytes
with owner-only access. Commit review, assist, and close-coverage proof do not
retain unused prompt copies. Original input records remain operator-owned outputs.

This admission boundary is not universal provider-egress scanning. Automatically
loaded project docs, resumed/steered history, later tool results, and unchanged
repository history are outside its scope. Planning, assist, and close-coverage
calls scan their explicit prompt/schema; they do not attest a source review.
No dashboard projection or observer API changes; OpenClaw Bay is unaffected.

Maintainers can run the dispatch-only `Hosted native review scan smoke` job in
`ci.yml`. It uses the existing `OPENAI_API_KEY` and `CLAWSWEEPER_MODEL` secrets
only during host setup, with no App mutation token. The proof artifact records
zero Codex launches on refusal, then proves the production review path completed
a read-only command over a synthetic committed diff before returning a
schema-valid decision and terminal turn. Raw commands, output, prompts,
transcripts, fixture values, runner identities, and model identities stay in
ephemeral private files; the uploaded artifact contains only booleans and counts,
including explicit false coverage flags for external repositories, review
publication, and queue lifecycle.

- Review and repair base fetches use fully qualified branch refspecs so inherited
  `fetch.prune` or `remote.origin.prune` settings do not delete the requested
  tracking ref. Validation uses the same repair fetch helper; no host Git
  configuration changes are required.
- Maintainer-authored items are excluded from automated closes unless the close
  reason is verified `implemented_on_main`.
- Protected labels block close proposals.
- Apply rechecks older skipped fixed-close reports and archives skipped item
  records when GitHub already shows the item closed.
- Apply can retry older `kept_open` close reports and clear linked-PR issue
  blockers after ClawSweeper closes the PR earlier in the same apply run.
- Open PRs with GitHub closing references block issue closes until the PR is
  resolved or closed earlier in the same apply run.
- Open same-author issue/PR pairs block one-sided closes.
- Codex runs without GitHub write tokens.
- Issue/PR event jobs create target write and report-push credentials only after
  Codex exits.
- The retired hosted commit-review lane no longer mints target credentials;
  `pnpm local-review` operates on the local branch range without GitHub writes.
- CI keeps the target checkout read-only and gives Codex issue/PR reviewers a managed
  network proxy restricted to the hosts in
  [the review permission profile](.github/actions/setup-codex/review-permissions.toml):
  GitHub, npm, Node, MDN, and OpenClaw documentation. Limited mode inspects HTTPS
  and permits only GET/HEAD/OPTIONS; other hosts are blocked. When supplied by the
  review job, Codex tools receive the target repository's read-only GitHub App token
  only as `GH_TOKEN` (contents, issues, and pull requests read; expires within the
  hour). Use authenticated GitHub reads to avoid public rate limits; never put
  the token in a URL, log it, or send it to a non-GitHub host. Without a token,
  use public endpoints and pre-fetched context. Read downloaded media through
  the local proof manifest. A blocked request is not evidence against a PR.
  Setup must prove allowed HTTPS, denied unlisted HTTPS, and denied checkout
  writes before reviews can publish. Offline local reviews retain their existing
  network restriction. The `review-network-smoke` PR CI job proves the same
  enforcement on Ubuntu without secrets. Capability text follows the active
  runner: OpenClaw uses gateway network execution without the Codex proxy or
  filesystem sandbox, strips GitHub tokens through its final child environment
  allowlist, and must keep the checkout read-only by instruction.
- Reviews fail if Codex leaves tracked or untracked changes behind.
- Snapshot changes block apply unless the only change is the bot’s own review
  comment.
- The retired hosted commit-review lane no longer publishes Commit Check Runs.

### Audit

`pnpm run audit` compares live GitHub state with generated records without moving
files. It reports missing open records, archived open records, stale records,
duplicates, protected-label proposed closes, and stale review-status records.
Protected proposed closes are reported only for active repo `items/` records
because archived repo `closed/` records are historical and cannot be applied.
Missing open records are classified as eligible, maintainer-authored, protected,
or recently created so strict audit mode can flag actionable drift without
treating expected queue lag or excluded items as failures.
Use `--update-dashboard` to publish the latest audit state under
`results/audit/` in `openclaw/clawsweeper-state` without making every normal
status update scan all open GitHub items. The state repo renders reviewable
findings such as missing eligible records, reopened archived records, and stale
reviews from that state. The separate `audit.yml` workflow refreshes audit state
on the existing six-hour schedules. Every manual dispatch of `audit.yml` runs an
audit; it accepts only `target_repo`, with no `audit_dashboard` input:

```bash
gh workflow run audit.yml -f target_repo=openclaw/openclaw
```

Review planning dispatch uses `review-plan.yml`; target fanout dispatches review
plans there and audits to `audit.yml`. Exact event review and apply remain in
`sweep.yml`. The read-only audit lane covers `openclaw/openclaw`,
`openclaw/clawhub`, and `openclaw/clawsweeper`; it falls back to public
workflow-token reads when the ClawSweeper App token is not available for a target.

## Local Run

Requires Node 24.

Issue/PR sweeper:

```bash
source ~/.profile
corepack enable
pnpm install
pnpm run build
pnpm run plan -- --target-repo openclaw/openclaw --batch-size 5 --shard-count 89 --max-pages 250 --codex-model internal
pnpm run review -- --target-repo openclaw/openclaw --target-dir ../openclaw --batch-size 5 --max-pages 250 --artifact-dir artifacts/reviews --output-retention debug --codex-model internal --codex-timeout-ms 600000
pnpm run apply-artifacts -- --target-repo openclaw/openclaw --artifact-dir artifacts/reviews --skip-dashboard
pnpm run audit -- --target-repo openclaw/openclaw --max-pages 250 --sample-limit 25 --update-dashboard
pnpm run reconcile -- --target-repo openclaw/openclaw --dry-run
```

Advisory exact local issue/PR review:

For Codex users, the repo-local skill `$local-clawsweeper-review` wraps this
workflow with setup checks, target checkout hygiene, and artifact readout. Skill
usage is documented in
[`docs/local-clawsweeper-skill.md`](docs/local-clawsweeper-skill.md).

```bash
codex login --device-auth -c 'service_tier="fast"'
pnpm run codex:local:check -- --diagnostics
pnpm run review -- --local-only --target-repo owner/name --item-number 123
```

`--diagnostics` checks the selected Codex binary and its login status without a
model request. It does not prove model access or review readiness. Omit
`--diagnostics` to also run the existing model smoke test, which consumes model
usage.

`review` is the single issue/PR review command. `--local-only` makes it an
advisory local run: it skips the review-start placeholder comment, defaults the
Codex service tier to `fast` for local CLI compatibility, and preserves local
Codex auth. Persistent output is opt-in. The default `--output-retention none`
uses private run-owned scratch, prints the result, and removes scratch after
ordinary completion or a caught failure. Operating-system termination keeps its
default behavior so cancellation is not delayed by synchronous review work; an
unhandled signal or `SIGKILL` can leave the bounded private scratch behind. Use
`--output-retention summary` for the report
without raw prompt/stream files, or `--output-retention debug` for the existing
artifact tree. An explicit legacy `--artifact-dir` still selects debug
retention. Summary destinations are created exclusively for one invocation.
Managed transient output is capped at 96 MiB/256 files; managed debug output is capped at
1 GiB/4,096 files with per-item allocations and at most 128 selected items per
invocation. Existing destination files count toward these limits. Metadata,
cached and fresh reports, and model output use the same run admission checks.
None and summary batches hash each item's report and stream evidence
into the canonical ledger before pruning that item's run-owned engine files;
summary retains only the reports. Required pull-request checkouts use a separate private run workspace:
tracked paths and Git blob sizes are admitted before materialization, with a 2x
allowance for bounded EOL expansion. Active filters, working-tree encodings, and
ident expansion are refused through a bounded private Git index compatible with
Git 2.39. That index reserves at most two files/128 MiB plus the workspace disk
reserve before creation and is removed after inspection. Checkout hooks are disabled. Projected and
actual checkout usage is capped at 200,000 files/2 GiB, and 1 GiB remains
reserved on each filesystem used for checkout materialization or missing Git
object acquisition; a shared filesystem is charged once. Media proof downloads
use at most 64 MiB per debug item and derived metadata/contact sheets at most
16 MiB, subject to the remaining run byte and file allowances. Non-debug items
use at most 32 MiB and 8 MiB respectively. Media admission reserves the non-media
output pools before starting another download or transcode. These are producer
admission and retained-output limits, not a peak disk quota: curl and ffmpeg can
temporarily exceed their requested limits, and arbitrary model-written files
are not quota-controlled. Oversized managed media output is discarded.
Existing or unrelated retained runs are
never pruned automatically.
`--result-format json` returns the same result as valid JSON. For a committed-range
review, add `--preflight` to generate a bounded advisory PR-body block in that
JSON without another model call or GitHub write. See the
[local preflight summary](docs/portable-review-receipt.md) for source checks and
limitations; it does not grant a hosted-review exemption.

```bash
pnpm run review -- --local-only \
  --target-repo owner/name \
  --item-number 123 \
  --target-dir ../target-checkout \
  --output-retention summary
```

Pre-submission committed-range review uses the same full proof-aware review
without requiring an open GitHub item. From the clean checkout containing the
branch to review:

```bash
pnpm run review -- --local-range \
  --target-repo openclaw/clawsweeper \
  --base origin/main
```

The built source checkout also provides a local-only entrypoint:

```bash
node dist/clawsweeper-local.js review --target-repo openclaw/clawsweeper --base origin/main
node dist/clawsweeper-local.js --help
node dist/clawsweeper-local.js --version
```

Both range commands use the same review engine, scanner, reports, history and
output cleanup. The local entrypoint loads that engine only when review starts;
help and version do not invoke Codex. Hosted admission, leases, action-ledger
publication and cache metrics stay in the hosted command. This is a source
checkout entrypoint, not an installable package. Diagnostics integration remains
separate; `codex:local:check` still invokes its existing model smoke test.

Without `--target-dir`, `--local-range` reviews the checkout where the command
was invoked. Pass `--target-dir <path>` when invoking ClawSweeper from a
different checkout. The range is `merge-base(<base>, HEAD)..HEAD`, includes
committed work only, and refuses a dirty working tree. `--body-file` can supply
the proposed PR body and `--additional-policy` can layer an extra local policy.

This mode withholds GitHub token variables, points `gh` at an empty config
directory inside private run scratch, disables Codex web search, skips host-side
URL/media preprocessing, and makes no GitHub reads or writes. It is not
air-gapped: the Codex model invocation still uses its configured network
service. Debug local reviews preserve the latest local result in the same
bounded review-history format used by hosted review. The next debug run receives
the previous findings and dispositions so it can verify fixes and avoid
re-raising resolved findings. Summary retention keeps only the current reports.
In debug mode, exact-item history stays in the selected artifact directory.
Committed-range debug history stays under `.git/clawsweeper/reviews/` and is reused
only for the same target repository and resolved base when its reviewed commit
is an ancestor of the current `HEAD`; changing the base or switching to an
unrelated branch starts a fresh history.

Summary/debug reports use a unique
`.git/clawsweeper/reviews/local-range-<time>-<pid>/` directory unless
`--artifact-dir` overrides it. Default no-retention runs leave no persistent
ClawSweeper review directory.

When output is retained at the default local artifact destination, read the
report at `artifacts/local-review-<number>/<number>.md`. Key fields are
`review_status`, `main_sha`, `pull_head_sha`, `decision`, `confidence`, and
`Review Findings`. Do not run `apply-artifacts` or `apply-decisions` unless you
intentionally want to move reports into durable state or sync GitHub comments.
Add `--verbose` when you need the underlying `[review]` diagnostic logs.

If you prefer API-key auth, keep the key out of the repository and shell
history. For POSIX shells:

```sh
printf '%s' "$OPENAI_API_KEY" | codex login --with-api-key -c 'service_tier="fast"'
unset OPENAI_API_KEY
```

For PowerShell:

```powershell
$env:OPENAI_API_KEY = Read-Host "OpenAI API key"
$env:OPENAI_API_KEY | codex login --with-api-key -c 'service_tier="fast"'
Remove-Item Env:OPENAI_API_KEY
```

`--local-only` preserves local Codex auth environment variables only for that
advisory local run. Normal production review workers still strip Codex, OpenAI,
and GitHub write credentials before invoking the model. Set `CODEX_BIN` to an
absolute executable path if the desired Codex CLI is not the first spawnable
binary on `PATH`.

Apply unchanged proposals later:

```bash
source ~/.profile
corepack enable
pnpm run apply-decisions -- --target-repo openclaw/openclaw --limit 40 --apply-kind all --skip-dashboard
```

Sync durable review comments without closing:

```bash
source ~/.profile
corepack enable
pnpm run apply-decisions -- --target-repo openclaw/openclaw --sync-comments-only --comment-sync-min-age-days 7 --processed-limit 1000 --limit 0 --skip-dashboard
```

Manual review runs in `review-plan.yml` are proposal-only. Dispatch `sweep.yml`
with `apply_existing=true` to apply unchanged proposals later. Scheduled apply runs process both issues and pull requests by
default, subject to the selected repository profile; pass `target_repo`,
`apply_kind=issue`, or `apply_kind=pull_request` to narrow a manual run.

Scheduled runs cover the configured product profiles. `openclaw/openclaw` runs
normal backfill every 20 minutes in `review-plan.yml`, alongside hot-intake schedules;
scheduled hot intake and normal backfill share a
32-worker cap in the durable review queue. `openclaw/clawhub` runs on offset review/apply/audit crons so its reports
live under `records/openclaw-clawhub/` without colliding with default repo
records. `openclaw/clawsweeper` has a scheduled read-only audit row and is
available for manual and event self-review smoke tests. Broad hot-intake sweeps
use the queue's scheduled admission budget; manual normal and hot-intake matrices
have at most 89 and 44 slots when quiet, while exact event reviews still use one shard.
Normal review and hot intake are
background lanes, so they shrink automatically while repair or exact-item work
is active. Throughput defaults live in
[docs/limits.md](docs/limits.md) and `config/automation-limits.json`.

### Worker Budget

ClawSweeper has one main capacity knob:
`config/automation-limits.json` -> `workers.max`. The current value is `128`.
This is a Codex worker budget, not a GitHub Actions runner limit. Deterministic
exact-review publishers, comment routers, and lease reconcilers are
control-plane workflows and do not consume these 128 slots.
Lane limits are derived from that number: manual normal review defaults to 89
requested shards and hot intake to 44; the interactive and expansion reserves
leave 104 background slots when quiet. Scheduled work has a separate
32-slot admission cap and fills what organic reviews leave of a 220-review/hour
admission target with a 24-item burst; hot intake is capped at 30/hour. Organic
work remains unconditional, so this is not a total-execution or spend cap. The
existing repair/issue implementation lanes use 40% of `workers.max`, currently
51 live workers. Imported gitcrawl cluster repair allows 2 live workers by default.
Exact-item review, repair, and issue implementation are priority work; normal
review and hot intake are background work and automatically
yield when priority work is active. Exact-item runs use a durable Worker queue
that coalesces item deliveries, leases at most 80 concurrent reviews, and admits
up to 64 active exact reviews per target repository. Other lanes use the
checked-in 128-worker scheduling model. A separate 194-slot exact-review
Actions budget supports the production maximum of 32 legacy publisher slots, the
enforced 16-slot control-plane reserve, and additional Actions headroom without
raising the Codex review ceiling.
Use `workers.max` first when turning total Codex usage up or down; use
`lanes.repair.cluster_max_live_runs` to tune the imported legacy cluster-repair
lane separately, and individual environment overrides only for temporary
lane-specific exceptions.

Target repositories can opt into event-level latency by installing the
dispatcher workflow in [docs/target-dispatcher.md](docs/target-dispatcher.md).
The keyless dispatcher sends the target repo and exact item number to the Worker
using GitHub Actions OIDC; ClawSweeper then leases one event executor that
reviews, comments, and checks immediate safe apply instead of waiting for the
next hot-intake cron or bulk publish lane. The independent App webhook remains
enabled; legacy `repository_dispatch` receivers remain during migration.

## Checks

```bash
pnpm run check
pnpm run oxformat
```

`oxformat` is an alias for `oxfmt`; there is no separate `oxformat` pnpm package.
The `CI` GitHub Actions workflow uses the latest Node 24 release. Locally,
`pnpm run check` runs the whole gate: the full test suite, a strict
changed-surface coverage threshold, and a full compiled-repo coverage ratchet.
It builds once, runs `check:fast` (static checks, build, lint, and the
changed-surface coverage), then the full coverage run. CI splits the same gate
into parallel jobs on pushes, pull requests, and manual dispatches:
`check fast gates` runs `check:fast`; `check tests (i/N)` jobs each run one
round-robin shard of the suite and upload its raw V8 coverage profiles; and
`check coverage` replays every shard's profiles through Node's own coverage
report with the same thresholds. The single `pnpm check` job passes only when
all of them pass. Standalone `test`, `test:repair`, and coverage commands still
build their required outputs; their internal `*:no-build` variants are for the
composed gate after `build:all`.

Node test files are expanded by `scripts/run-node-tests.mjs` instead of the
shell, so the same targets work on Linux, macOS, and Windows. The runner defaults
to the smaller of the machine's available parallelism and 16, prints the chosen
value, and accepts an explicit `--test-concurrency` override for diagnostics.
`CLAWSWEEPER_TEST_CONCURRENCY` sets the default for CLI runs when that flag is
absent, allowing controlled concurrency experiments through package scripts.
CI retains the adaptive default. The runner owns each target's coverage
thresholds (`--coverage`), and its `--shard`, `--coverage-out`, and
`--coverage-from` options are the CI shard and merge steps; see
`node scripts/run-node-tests.mjs --help`. Crabbox diagnostic bundles under `.crabbox/` are generated scratch
and are ignored by Git.

On Linux and macOS, the shared synthetic GitHub CLI fixtures clear
`NODE_V8_COVERAGE` before starting their Node stand-ins. Those fixtures do not
execute ClawSweeper source; interrupting their profile writes must not break the
real coverage report. Production subprocesses keep inherited coverage. Other
fixture launchers and Windows retain their existing behavior.

## GitHub Actions Setup

Required secrets:

- `OPENAI_API_KEY`: OpenAI API key used by the per-job local Codex Responses
  proxy. Codex subprocesses inherit only the proxy-backed `CODEX_HOME`, not the
  raw API key.
- `CLAWSWEEPER_APP_CLIENT_ID`: public GitHub App client ID for `clawsweeper`.
  Currently `Iv23liOECG0slfuhz093`.
- `CLAWSWEEPER_APP_PRIVATE_KEY`: private key for `clawsweeper`; plan/review
  jobs use a short-lived GitHub App installation token for read-heavy target API
  calls, and apply/comment-sync/check jobs use the app token for comments,
  closes, and optional checks.
  Keep App credentials scoped to the `actions/create-github-app-token` step.
  Review shards run Codex over attacker-controlled issue/PR text, so
  `codexEnv()` also strips these App variables before spawning Codex.

Token flow:

- Review jobs create an isolated per-run `CODEX_HOME`, start a local Responses
  proxy from `OPENAI_API_KEY`, write proxy-only Codex config there, and run Codex
  without OpenAI or Codex token environment variables.
- ClawSweeper uses the `clawsweeper` GitHub App token for read-heavy target
  context.
- Apply mode uses the same app token for review comments and closes, so GitHub
  attributes mutations to the app bot account instead of a PAT user.
- GitHub-isolated `pnpm local-review` does not mint target write/check
  credentials or publish hosted commit-review results; Codex still connects to
  the configured model service.
- The ClawSweeper GitHub App commits only the remaining operational paths to
  `openclaw/clawsweeper-state`; reports publish to the canonical Worker store.

Required `clawsweeper` app permissions:

- Contents: read/write for state publication and contents-scoped dispatch.
- Issues: read/write, for issue comments, labels, closes, and maintainer command
  authorization context.
- Pull requests: read/write for PR comments and labels.
- Actions: read/write on `openclaw/clawsweeper` for run cancellation and dispatch.
- Checks: read/write on target repositories, for structural cache state and
  commit Check Run publication.
- Commit statuses: read on target repositories, for structural cache state.

ClawSweeper no longer falls back to PAT-based write tokens. If the GitHub App
installation does not grant the requested permission set, the workflow fails at
token creation instead of silently switching identity.

Target repository setup:

- install the issue/PR dispatcher from
  [docs/target-dispatcher.md](docs/target-dispatcher.md) for exact item event
  reviews

---

### Overview (`changelog.d/README.md`)

# Changelog fragments

- Status: active contributor and release runbook
- Owner: ClawSweeper maintainers
- Source of truth: [`scripts/changelog-stitch.mjs`](../scripts/changelog-stitch.mjs)
  and its tests in [`test/changelog-stitch.test.ts`](../test/changelog-stitch.test.ts)
- Last verified: `openclaw/clawsweeper@65f9c3a3057621385b6c4f52640a2ce190c18c57`
- Update when: the fragment format, the stitch, or the release changelog
  procedure changes

This applies to `openclaw/clawsweeper` only. ClawSweeper pull requests record
user-visible changes here instead of editing [`CHANGELOG.md`](../CHANGELOG.md),
so concurrent pull requests never conflict on the top of the Unreleased section.
Target repositories keep their own release-note policy; in `openclaw/openclaw`,
`CHANGELOG.md` stays release-owned and pull requests carry release-note context
in their body and commit message.

## Add an entry

Create one new file per change: `changelog.d/<pr-number-or-slug>.md`, for
example `changelog.d/1719-parked-stale-revisions.md`. Use a name nobody else
will pick; a branch-style slug is fine before the PR number exists.

The file holds exactly one house-style bullet on one line, with no wrapping:

```markdown
- Report retained stale-revision publications as parked instead of ready. Thanks @contributor.
```

Rules enforced by `pnpm run check:changelog`, which also runs in
`pnpm run check`:

- the name is lowercase `[a-z0-9._-]` and ends in `.md`; only regular files
  belong in this directory;
- the content is a single `- ` bullet line ending in one LF newline, with no
  blank lines, trailing whitespace, CRLF, or byte-order mark;
- the bullet is not already listed in `CHANGELOG.md` and is not repeated in
  another fragment, so a merge cannot quietly re-add a stale entry.

Edit or delete your own fragment when the change evolves. Do not edit other
fragments or `CHANGELOG.md` in a normal pull request.

## Stitch at release time

The release maintainer folds the fragments into `CHANGELOG.md` before
finalizing the version heading:

```bash
pnpm run check:changelog
pnpm run changelog:stitch
```

The stitch inserts every fragment bullet at the top of the single
`## <version> - Unreleased` section in file-name order and deletes the
fragments. It replaces `CHANGELOG.md` before deleting anything; when a fragment
bullet is already in the Unreleased section, as after an interrupted run, the
fragment is deleted without adding a duplicate. A second run reports no
fragments and leaves `CHANGELOG.md` unchanged. The stitch refuses to write when
a fragment is invalid or the changelog does not have exactly one Unreleased
heading.

After stitching, review the diff, rename the Unreleased heading to the released
version and date, and add the next `## <version> - Unreleased` heading in the
same release commit.

---

### Overview (`docs/README.md`)

# ClawSweeper documentation

- Status: active documentation index
- Owner: ClawSweeper maintainers
- Source of truth: the linked repository files and their owning code,
  configuration, workflows, and tests
- Last verified: `openclaw/clawsweeper@647503ec44b8e777dd172adf974a945367da0d19`
- Update when: a document is added, retired, moved, changes lifecycle, or gains a
  new canonical owner

ClawSweeper reviews GitHub issues and pull requests, publishes durable results,
and applies or repairs only through guarded maintainer-controlled paths. Start
with the task or audience below; this page is a map, not another operator
manual.

## Start here

| Goal                                                | First page                                    | Next step                                           |
| --------------------------------------------------- | --------------------------------------------- | --------------------------------------------------- |
| Understand the product boundary                     | [Project vision](../VISION.md)                | [Orchestration](orchestration.md)                   |
| Set up a development checkout                       | [Contributing](../CONTRIBUTING.md)            | [Local run](../README.md#local-run)                 |
| Understand review and scheduling                    | [Scheduler](scheduler.md)                     | [Automation limits](limits.md)                      |
| Add or operate a target repository                  | [Target repositories](target-repositories.md) | [Target dispatcher](target-dispatcher.md)           |
| Inspect production without mutation                 | [Live dashboard](live-dashboard.md)           | [Public observer API](public-api.md)                |
| Inspect observer routes and configuration ownership | [Public observer API](public-api.md)          | [Operator configuration](operator-configuration.md) |
| Prepare proof for a change                          | [Contributing](../CONTRIBUTING.md)            | [Agent instructions](../AGENTS.md)                  |
| Review a local committed range                      | [Local branch review](commit-sweeper.md)      | `pnpm local-review -- --base origin/main`           |
| Qualify the full local review artifact              | [Private local package](local-package.md)    | Build, pack, and install outside the checkout      |

Production mutation commands are intentionally not repeated here. Follow the
linked runbook, confirm its status and source of truth, and keep deployment,
queue, and apply gates closed unless the current operator has explicit authority.

## Document lifecycle

Every evergreen page belongs to one of these states:

- **active**: current guidance for a supported surface
- **proposed**: a future design or runbook that grants no execution approval
- **compatibility-only**: retained for still-readable state or a supported
  migration boundary, but not for creating new work
- **historical**: completed proof or decision history, not current procedure

Active runbooks and volatile configuration references should begin with status,
role owner, owning source, last-verified revision, and update triggers. “Owner”
is a responsibility role until maintainers approve a stable GitHub CODEOWNERS
individual or team. Generated or checked values should name their checker;
everything else requires human comparison with current main.

## Concepts and architecture

- [Project vision](../VISION.md) — active; product goals and boundaries
- [Orchestration](orchestration.md) — active; planner, review, publish, apply,
  and repair shape
- [Scheduler](scheduler.md) — active and volatile; scheduled and exact-event
  execution behavior
- [State storage](state-storage.md) — active; Worker, R2, and Git-backed state
  ownership
- [Canonical body tiering](canonical-body-tiering.md) — proposed; preserve records
  while moving exact bodies from SQLite to the existing R2 bucket
- [Action ledger](action-ledger.md) — active; mutation receipts and replay
  boundaries
- [Issue review advisory labels](work-lane.md) — active; structured review labels
- [Review cache](review-cache.md) — active; reusable review-state contract
- [Intake triage](intake-triage.md) — active; bounded preliminary classification
- [Local review preflight summary](portable-review-receipt.md) — proposed
  local-range export; bounded advisory PR-body handoff and review-content reader
- [GitHub webhook read model](github-webhook-read-model.md) — active; signed
  ingress, App subscriptions, snapshot freshness, and safety boundary
- [Review authority contract](review-authority.md) — proposed integration;
  inert role classifier and API evidence requirements

## Configuration and repository onboarding

- [Automation limits](limits.md) — active; validated by
  `pnpm run check:limits`
- [Target repositories](target-repositories.md) — active; profiles, generic
  fallbacks, inventory, and apply membership
- [Target dispatcher](target-dispatcher.md) — active; exact-event integration
- [OpenClaw event hooks](openclaw-event-hooks.md) — active; event routes
- [Local branch review](commit-sweeper.md) — active local/GitHub-isolated
  replacement for hosted commit review

## Operations and runbooks

- [Live dashboard](live-dashboard.md) — active; public observer surface and
  operator diagnostics
- [Queue-service split runbook](queue-service-split-runbook.md) — proposed;
  unapproved production migration plan
- [Local ClawSweeper skill](local-clawsweeper-skill.md) — active; read-only
  local exact-item or committed-range review

## Dashboards and observability

- [Live dashboard](live-dashboard.md) — active; Worker status and operational
  telemetry
- [Agent performance metrics](agent-performance-metrics.md) — execution timing, repeated work, chart ownership and observation limits
- [GitHub publication egress telemetry](github-egress-telemetry.md) — active;
  wire denominator, credential attribution, completeness, and retention
- [Triage dashboard](triage-dashboard.md) — active; cached issue triage
- [PR proof triage](pr-proof-triage-dashboard.md) — active; maintainer proof
  inspection

## Contributor, review, and proof guidance

- [Contributing](../CONTRIBUTING.md) — active; setup, scope, PR evidence, and
  author-owned review loop
- [Agent instructions](../AGENTS.md) — active and binding for coding agents
- [Changelog fragments](../changelog.d/README.md) — active; one-bullet
  ClawSweeper release-note fragments and the release-time stitch
- [PR review comments](pr-review-comments.md) — active; review-thread handling
- [Related issue discovery](related-issue-discovery.md) — active; duplicate and
  adjacent-report context

`docs/proof/**` contains inspectable artifacts for specific changes. Those
files support their recorded claim but do not override current runbooks.

### Proof media retention

Commit lightweight, diffable proof records: the claim and limits, exact source
or head SHA, reproduction command, provider/image/lease provenance, fixture
hashes, observable assertions, and compact normalized JSON. Full-resolution
screenshots, videos, and traces may be committed while a pull request is under
review, but prune them from `main` after merge once the durable review and proof
record exist; git history retains the review-time bytes.

Keep a heavy binary only when an active canonical document embeds or links it,
or when runtime or test tooling consumes it. Prefer one current compressed
poster or WebP over accumulated before/after sets.

## Close policy

- [Implemented-on-main paired close policy](implemented-on-main-close-policy.md)
  — active policy and formal GitHub-link requirement
- [Obsolescence policies](obsolescence-close-policies.md) — active policy map
- [Unsponsored feature policy](unsponsored-feature-close-policy.md) — active
- [Product direction policy](product-direction-close-policy.md) — active
- [Material SQLite change discussion proposal](sqlite-change-policy-proposal.md)
  — proposed; maintainer decision required before any enforcement
- [Author PR budget policy](author-pr-budget-close-policy.md) — active
- [Stalled PR policies](stalled-pr-close-policies.md) — active
- [Oversized PR policy](oversized-pr-close-policy.md) — active

## Security and special-purpose surfaces

- Security-sensitive work must use maintainer security handling rather than a
  normal public PR or public documentation page.

## Update triggers

Review the relevant pages in the same change when any of these surfaces move:

- `config/automation-limits.json` or workflow limit literals: automation limits
  and scheduler
- `config/target-repositories.json`, repository profiles, target inventory, or
  apply membership: target-repository and dispatcher docs
- exact-review queue schema, retry classification, publication capacity,
  batching, direct publication, or state writing: scheduler, limits, dashboard,
  and queue runbooks
- dashboard route, projection, or public-field changes: dashboard docs
- publication GitHub request paths, credential selection, or egress fields:
  GitHub egress telemetry and public API docs
- mutation, close, proof, repair, or merge policy changes: policy pages,
  CONTRIBUTING, AGENTS, and repair operations
- workflow retirement or replacement: every command example and compatibility
  page that names the workflow

## Automated drift checks

`pnpm run check:docs` validates exact-case relative links and Markdown anchors,
documented package scripts, workflow files, repository source paths, and the
selected configuration-derived claims in
`config/documentation-sync.json`. It runs through the existing static check and
CI path. Add a manifest claim when volatile production configuration is quoted
as a concrete value in prose. Stage newly added files before running the check
so its repository inventory matches the proposed commit rather than unrelated
untracked workspace contents. `pnpm run check:changelog` runs in the same static
check and validates pending `changelog.d/` fragments.

The check deliberately does not crawl external URLs, infer policy, assign
ownership, or treat historical proof commands and paths as current contracts.
The index, lifecycle labels, and whether a configuration claim should become
policy remain human-reviewed.

The public documentation build reads `config/documentation-site.json` as its
exhaustive lifecycle manifest. Active pages appear in navigation, search, the
sitemap, and `llms.txt`. Proposed, historical, and proof pages remain available
at stable generated paths for evidence links, but carry a visible lifecycle
banner and `noindex` metadata and are excluded from canonical discovery. The
documentation check fails when a page is unclassified or classified twice.

---

### Overview (`docs/proof/acpx-autoreview-fixtures/README.md`)

# acpx autoreview old-base fixture qualification

Lifecycle: focused classifier proof and native source-admission comparison complete; owner review and landing pending.

## Behavior contract

Qualify three exact URI detector 17 / PLAIN attribution variants from
[acpx PR 806](https://github.com/openclaw/acpx/pull/806), solely at
`.agents/skills/autoreview/tests/test_autoreview_hardening.py`, mode `100644`.
The host policy retains both native value digests and every complete line
witness in occurrence order. Existing rows stay intact; the classifier,
staging, native verification, completion checks, and source-provenance gates
are unchanged.

The committed consumer range is base
`a7410abdf67dda4aa06db6b92bf57e007e67459e` to head
`6151f4f4d0fd9d4d63590b6ceb95d309e5752266`. The implicated base blob is
`8ed5acee1791b128c7d7a69132afd83fa0533ed4`; the head blob is
`c1de717504d47d854f5abd189bf61be98242d0f6`. These pins identify the proof
inputs, not extra runtime approval rules. ClawSweeper baseline is
`9fb3a5d5887891c08e0310cafc54b09ab3023c2a`, which lacks all three variants.

Two variants add the ordered base-line witnesses at 3064 and 3075 for the
existing full-port proxy URI and its shorter native prefix. The second line
uses a fixed `HTTPS_PROXY` string under a reserved invalid TLD in a rejection
test. Its environment patch uses `clear=False`, so only that matched string
is classified as static fixture data; no whole-test hermeticity is claimed.
The third variant binds base line 2898: a fixed reserved-host `SERVICE_URL`
string that `safe_test_env` is expected to exclude. That URI is independent of
the test's separate temporary credential fixtures and saved ambient state.

Focused classifier regressions exercise real Git-generated removed patch lines
and committed base blobs, including both overlapping proxy identities. They
must refuse unapproved literal, line, path, mode, role, decoder, occurrence,
reference, verification, duplicate-record, and incomplete-scan variants.
Existing approved witness sets remain valid: in particular, the full-port
proxy's original one-line set is still approved, so reducing the new two-line
set to that existing set is not a negative control.

Classifier-only support on macOS with Node 24.21.0: all nine new positive
attribution cases refuse on the baseline. After adding only the three policy
rows, `node --test test/agent-input-scan-fixtures.test.ts` passes all 295 cases,
including 68 new cases. This uses synthetic scanner records and is not native
source-admission proof.

## Native source-admission proof

The task owner executed the existing real staging/scan runner locally on macOS
with Node 26.9.0, native TruffleHog 3.97.4, normal verification, and no model call:

```sh
pnpm run build:node
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/clean-disposable-acpx-at-head \
  a7410abdf67dda4aa06db6b92bf57e007e67459e \
  6151f4f4d0fd9d4d63590b6ceb95d309e5752266 \
  /path/to/native-admission.json
```

Run the same complete range against the baseline and candidate host policy.
The baseline should retain its refusal. Candidate admission requires a complete
native scan with every emitted finding and source reference qualified; a new
unqualified finding must remain a refusal. Retain sanitized result receipts,
policy and consumer identities, runtime/provider/image/lease identity, scanner
version and binary checksum/provenance, command, prompt/schema hashes, resolved
merge base, canonical generated patch hash, source-manifest identities, and
stated limits. The runner does not retain the complete native manifest or all
Raw/RawV2 digests; record any needed sanitized identity evidence separately.
Its trusted-PATH scanner path is checked by version, while managed bootstrap
checks archive checksums; retain the actual binary provenance. The output
directory must already exist. The native scanner ran with normal verification. No model execution or
hosted retry was part of this proof.

The prior network-denied, no-verification inventory informed the exact tuple
review. It is not a replay of the ten findings from hosted run
[36192271913](https://github.com/openclaw/clawsweeper/actions/runs/36192271913).
The first retained hosted coordinate maps to base line 3075, where both proxy
identities overlap; its unique Raw/RawV2 identity and the other nine hosted
identities remain unknown. Native findings may vary, so a missing finding is
not negative proof.

The controlled prompt used by this runner proves only source admission. Hosted
review must scan its own current complete prompt, schema, and source inputs;
this draft does not authorize a hosted retry or establish hosted admission.
OpenClaw Bay is unaffected: no queue, status, API, publication, dashboard, or
observer contract changes.

## Observed comparison and limits

[native-results.json](native-results.json) records baseline refusal on an
unclassified URI-17/PLAIN finding at patch line 23455, with 11 findings reported.
The candidate admitted its complete committed range after classifying six
emitted notices covering four source tuples. The new base SERVICE_URL tuple
appears at source line 2898 and through its removed patch line. Neither new
old-base proxy witness variant was emitted in the candidate run; focused
classifier cases supply separate exact-record coverage within the 295-test
file, including 68 new cases for this qualification. No absence
is treated as a cleared finding.

Both runs completed with native waits and output EOFs, without an outer timeout
or forced cleanup; their known target groups were absent and staging temporary
directories were empty. The operator asserted unchanged recorded source,
runtime, target and tool hashes and a clean unchanged consumer checkout.
Per-file post-run hash arrays and the full native staging manifest were not
retained, so independent assessments preserve that reconstruction limit.
The scanner was the existing trusted-PATH binary, selected by version and
recorded by SHA-256; the managed archive-checksum bootstrap was not used.

The offline 17, original hosted 10, native baseline 11 and native candidate 6 counts
remain distinct. These are successful narrow native observations, not a
byte-identical hosted replay, approval of absent findings, or a hosted review.

---

### Overview (`docs/proof/actions-hook-boundary/README.md`)

# GitHub activity hook-boundary proof

Status: historical proof for PR [2064](https://github.com/openclaw/clawsweeper/pull/2064). Owner: ClawSweeper maintainers. Runtime owners: `.github/workflows/github-activity.yml`, `src/repair/notify-github-activity.ts`, and `src/repair/openclaw-hook.ts`. Re-run when the job condition or hook boundary changes.

Claim: the actual `notify` job condition rejects a fork-origin `workflow_run` failure before the authenticated agent hook, while a same-repository failure reaches that hook exactly once.

Run from the repository root with Node 24 or newer and existing dependencies:

```sh
pnpm run build:repair
node docs/proof/actions-hook-boundary/run-proof.mjs
```

The driver reads and pins the real YAML `if:` expression, then evaluates it with a minimal, exact-expression evaluator. Assertions cover case-insensitive GitHub string comparisons and `contains`, absent properties, routine conclusions, both synchronize filters, and unrelated events. A changed expression fails closed and requires an evaluator update. The string-only fixture domain needs no mixed-type coercion; the implicit job `success()` condition is assumed true.

For each synthetic failure event, the evaluator controls invocation of the real `repair:notify-github-activity` script's compiled CLI entry. The admitted event calls `runGithubActivityNotifier` and `postOpenClawAgentHook` using the real HTTP transport against a loopback server. The server records method, path, payload, idempotency key, and whether the bearer token matches. The token is synthetic and its value is redacted from artifacts. The fork event must skip the CLI with zero requests; the same-repository event must produce exactly one authenticated `POST /hooks/agent` and a successful notifier result.

Artifacts default to `.artifacts/actions-hook-boundary/`: `summary.json` records head, workflow and fixture hashes, local provider/Node version, decisions, and request counts; `requests.json` records the redacted final-effect trace. Event fixtures, the notifier report, and its step summary are also retained. An optional first argument selects another output directory.

Limits: this is offline job admission followed by real local CLI/HTTP behavior, not a hosted Actions scheduler execution. Successful setup and sufficient API budget are assumed. It does not exercise checkout, secret provisioning, GitHub API access, a production hook, or Discord delivery. No container image or lease is used on this macOS host; no real credentials, external writes, or workflow dispatches are needed.

---

### Overview (`docs/proof/active-item-debounce/README.md`)

# Active-item debounce proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

An item that already completed two exact reviews in the last hour must not
start a full review for every organic push. Its next organic revision waits ten
minutes from the latest push (capped at fifteen minutes from the first pending
enqueue) and dispatches once with the latest head. Explicit commands, first-time
items and a queue store written before the change keep their existing timing.

The retired `proof-active-item-debounce.mjs` driver
bundles the baseline and candidate queue into real workerd SQLite Durable
Objects and follows each object's own alarm schedule on a controlled clock. A
dispatched review claims its lease at once and completes seven minutes later
unless a newer push revoked it. Scenarios:

- `churn`: pull request pushes at 0 and 10 minutes (two completed reviews),
  then three pushes at 20, 24 and 28 minutes.
- `command`: two completed issue reviews, then an explicit command at 20 minutes.
- `fresh`: a first-time pull request push at 20 minutes.
- `upgrade`: the baseline writes a completed review and a pending revision to a
  persisted store; the candidate opens that store and receives the next edit.

```sh
npm install --prefix /tmp/clawsweeper-active-item-proof-tools --no-save --no-audit --no-fund --ignore-scripts wrangler@4.107.0
node scripts/proof-active-item-debounce.mjs c46e375c825223a7b3fbcf592794dc949065f0f8 /tmp/clawsweeper-active-item-proof-tools .artifacts/active-item-debounce
```

Observed with workerd 1.20260701.1, Miniflare 4.20260701.0 and Node 24.21.0. The baseline is `c46e375c82` (main with the generation-start budget charging from https://github.com/openclaw/clawsweeper/pull/1738), and the candidate is the integrated head `e78f8bf0ec`. The earlier run against `8d659e7cb9` produced the same table:

| Measure                               | Baseline           | Candidate             |
| ------------------------------------- | ------------------ | --------------------- |
| Churn dispatches after 20 minutes     | 3 (21.5/25.5/29.5) | 1 (35.0, latest head) |
| Reviews revoked by a newer push       | 2                  | 0                     |
| Queue wakes between 20 and 35 minutes | 3                  | 2                     |
| Explicit command dispatch delay       | 1 s                | 1 s                   |
| First-time item dispatch delay        | 90 s               | 90 s                  |
| Upgraded store: next edit wait        | n/a                | 90 s (no history)     |

The receipt (`result.json`) records Git revisions, source hashes, runtime
versions, every enqueue, wake, dispatch and completion. GitHub is a loopback
HTTP fixture with a synthetic RSA credential; workerd egress is restricted to
it. This exercises the real queue admission, alarm, dispatch, claim, completion
and SQLite storage, but not the review workflow, inference, production state or
GitHub mutations. Unit tests cover the recovery bypass, window expiry and the
in-flight revocation heartbeat.

OpenClaw Bay is not affected: no public field, backoff reason or control is
added; held items keep the existing `dispatch_debounce` reason.

---

### Overview (`docs/proof/agent-input-scan-context/README.md`)

# Exact fixture admission in committed patches

The scanner admits reviewed synthetic URIs in context, added, and removed patch
lines while continuing to scan the complete patch. Context binds both committed
regular-file blobs; added and removed lines bind the head and base respectively.
Changed lines require exact ordered full-line attribution policy. Legacy rows
remain context-only. Every literal occurrence and every retained source reference
must qualify through canonical paths, full object IDs, and hunk coordinates.

New and deleted files also require an unambiguous host-captured raw Git A/D
record proving the absent endpoint. The full present-file hunk and rehashed blob
must agree. Missing blobs and textual `/dev/null` headers alone cannot qualify.

The regression suite uses the public classifier and real Git-generated patches
for additions, removals, new files, and deletions. It rejects missing, conflicting,
and malformed raw endpoint evidence; incomplete hunks; wrong newline markers;
unapproved full lines, aliases, modes, roles, and revisions; encoded-only content;
verified or mixed findings; and duplicate exact-attribution records. It preserves
legacy changed-line refusal, separate decoder/line attribution, and legacy
duplicate counts. CRLF bytes and files without a final newline are covered.

```bash
pnpm build:node
node --test test/agent-input-scan.test.ts test/agent-input-scan-fixtures.test.ts
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/trusted/openclaw \
  05c501ab7ebead40dc13b6758c80a5583d9b71c1 \
  b8382f64ea7db05db1b0a6ac3c7ae80b68025fc3 \
  /path/to/admission-proof.json
```

The proof uses `scanAgentInput`, its pinned native scanner, isolated environment,
canonical verification, complete committed source range, and a controlled prompt.
Only safe classifier notices and a bounded result are retained. It does not run
a model or replace the hosted review's own prompt/schema/source admission.

The separate [Autoreview BASE64 qualification](autoreview-base64.md) records
the bounded blob-only policy, its historical native refusal, and the executed
candidate qualification with its distinct baseline observation.

## Model-egress fixtures

OpenClaw [PR 156207](https://github.com/openclaw/openclaw/pull/156207) adds two
mock loopback proxy credentials and an endpoint-rejection URI. The input scan in
[run 35822733897](https://github.com/openclaw/clawsweeper/actions/runs/35822733897)
refused these unqualified fixtures before model execution. The host policy binds
each native Raw/RawV2 digest, complete source-line digest, original test path,
regular-file mode, and observed `PLAIN` or `HTML` decoder. No target ignore rule,
fixture-name pattern, scanner-verification change, or production credential is involved.

The controlled proof uses the complete committed source range that failed:

```bash
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/disposable/openclaw-at-pr-head \
  8868f7ed8c1e340c5eb70d796b58955d042638d4 \
  15c14e982fd7640a77b0c2b9bab6e5b4b168f705 \
  /path/to/model-egress-admission-proof.json
```

Native macOS arm64, Node 26.8.2, and pinned TruffleHog 3.97.4 reproduced six
unverified URI findings across source blobs and the generated patch before
qualification. The same range admits after qualification with verification
enabled. The existing exact-attribution regression harness now covers all three
identities in additions, removals, and unchanged context; changed values, lines,
paths, modes, roles, verification status, unsupported decoders, and additional
literal occurrences remain refused.

OpenClaw Bay is unaffected: the change only qualifies host-side scanner input;
it changes no dashboard API, queue lifecycle, or public action surface.

OpenClaw PR [149354](https://github.com/openclaw/openclaw/pull/149354) supplies the
real regression source. Hosted runs
[35012046356](https://github.com/openclaw/clawsweeper/actions/runs/35012046356)
and [35014912047](https://github.com/openclaw/clawsweeper/actions/runs/35014912047)
independently refused the unchanged create-profile fixture and unchanged patch
context respectively. The original source-row fixture dates to
[103139](https://github.com/openclaw/openclaw/pull/103139); its complete line did
not change in this browser repair.

OpenClaw Bay is unaffected: this changes scanner admission and host-side proof
notices, not the dashboard API or public action surfaces.

The plugin settings stack adds a committed-range case with both a new test file
and added fixture lines in an existing test file:

```bash
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/trusted/openclaw \
  3a4f9db62ee46701c3e7c494d981b07c74170c8f \
  598dc5aebd5aee9488f39898b2d6041f3993cc46 \
  /path/to/plugin-fixture-admission-proof.json
```

This is the complete source range for OpenClaw PR
[149330](https://github.com/openclaw/openclaw/pull/149330) at that head. It exercises
both exact source-blob attribution and added-line attribution, including the
new file's captured absence evidence. Native verification and completion checks
remain unchanged.

## Autoreview hardening fixtures

Claim: the maintainer-reviewed synthetic URI fixtures in the canonical autoreview
hardening test and its OpenClaw mirror admit through exact source attribution,
including Git-generated changed lines; a one-byte literal change still refuses.
This qualifies six identities at both exact paths without changing scanner,
verification, completion, source, mode, or patch-provenance gates.

The canonical file at agent-skills
`a7e91e188fa0c3d692ac69b3137f24c6c3a2d2c9` and the mirror in OpenClaw PR
[152039](https://github.com/openclaw/openclaw/pull/152039) at
`b2d3d0f86be704f80a04c11110aa1a7082a961a6` are byte-identical: 325358 bytes,
SHA-256 `87f42dcab4063224e75202ea0b47520c56ed7e283772a63572b332a1394893d8`.
[The identity evidence](autoreview-hardening/identities.json) records full
Raw/RawV2 and complete source-line digests, source paths, modes, and decoders.
Every identity occurs once in that file. The encoded-newline and encoded-NUL
identities share one complete source line.

Native scans emitted different finding subsets for identical bytes. In addition
to the four originally reported identities, they observed the empty-username
proxy fixture on head line 6596 and the encoded-NUL rejection fixture on line 6609. Both are in `AuthenticatedProxyTests`; neither comes from material outside
the reviewed autoreview test. These additional rows permit only observed PLAIN
decoding. Native evidence retained here is PLAIN; HTML coverage for the original
four identities uses constructed classifier records, not recovered native evidence.

The controlled runtime proof uses the complete committed range, the canonical
pinned TruffleHog 3.97.4 scanner, and enabled verification. It ran on September 18,
2026 using native macOS arm64, Node 26.8.2, and pnpm 12.4.1 (provider: local host;
no container image or lease). The trusted OpenClaw checkout stayed unchanged;
a disposable shared-object checkout was pinned to the PR head because committed
admission requires the checkout HEAD to match. The base is the merge base obtained
from the trusted checkout's origin/main.

```bash
pnpm build:node
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/disposable/openclaw-at-pr-head \
  a9fea70fcba242ff715cf248291c19c2e469de4c \
  b2d3d0f86be704f80a04c11110aa1a7082a961a6 \
  /path/to/admission-proof.json
```

[Before qualification](autoreview-hardening/before.json), the proof refused with
`findings / literal_not_reviewed` and no success notices. After qualification,
three consecutive runs of the same range admitted with zero refusals:
[run 1](autoreview-hardening/after-1.json),
[run 2](autoreview-hardening/after-2.json), and
[run 3](autoreview-hardening/after-3.json). They retained four, three, and three
bounded success notices respectively. An external observation hook recorded only
native finding hashes and line witnesses; it left scanner arguments, output,
exit status, and classification unchanged.

The regression suite separately exercises additions and removals using real Git
patches at both paths, all qualified decoder variants, every one-byte literal
mutation, and changed source lines for the existing legacy value. Retaining the
legacy row for review-context omission does not restore value-only changed-line
admission.

Limits: this proof runs no model and does not replace admission of the hosted
review's own prompt, schema, and source inputs. Three successful repetitions
establish the requested bounded repeatability evidence, not a guarantee about
every future scanner finding. OpenClaw Bay is unaffected: only host-side fixture
attribution changes; there is no dashboard API, telemetry, or public-action change.

### Malformed proxy prefix qualification

Historical qualification, September 24, 2026: agent-skills
[PR 274](https://github.com/openclaw/agent-skills/pull/274) at
`3cea808464166fa205092958b1da075334396bff` retained an unchanged synthetic
malformed-proxy rejection fixture. It predates that PR, introduced by
`567e63060e03503e965e91f0af06c5633be1221f`. The test supplies a reserved invalid
host through a mocked environment and expects rejection before engine startup.

The original hosted scan in
[run 35954755271](https://github.com/openclaw/clawsweeper/actions/runs/35954755271)
reported 11 findings and retained metadata identifying head blob
`076472cab0910a2fc56620e82e76260269b01ad6`, line 4661, as an unqualified PLAIN URI.
Its raw identities and original prompt were not retained. An unchanged-policy
full-input reproduction observed nine findings and reproduced that exact source
coordinate. Eight findings matched existing policy; the ninth was the malformed
port's native prefix. The reproduced nine records do not recover the original 11.

The native Raw and RawV2 digest is
`7b8ee01b06a7e5b375164f2c45249bb258c75726a60b27e20a0ba6e42d5d0b27`.
That prefix also occurs in the existing valid-proxy fixture. Both occurrences
therefore require the exact ordered full-line digests
`1a0920c31a227ead081fd2e6582572dfee060995e266a5520f66021acaa918c9` and
`c445f98d7d20b87bca6fead0e081385981add30abd58123db8d8d71c799d14a9`.
The two host-policy rows bind only the canonical test path and its OpenClaw
mirror, regular-file mode, URI detector, and observed PLAIN decoding. HTML,
changed suffixes outside the native match, missing or reordered witnesses,
extra occurrences, and other unqualified findings remain refused.

Qualification leaves the source fixtures, legacy omission policy, classifier,
scanner arguments, enabled verification, and non-retryable refusal unchanged.
The controlled native proof uses the complete committed range, the current
public PR metadata and discussion through `serializeReviewContext`, the host
review template, and the actual decision schema. It runs no model and cannot
replace the hosted review's own admission of its exact prompt and source.
OpenClaw Bay is unaffected; no queue, API, or public action surface changes.

Native macOS arm64 proof used Node 26.7.0 and pinned TruffleHog 3.97.4. The
canonical before/after runs had identical prompt, schema, all 14 staged input
hashes, scanner binary, and arguments. The first admitted run omitted the new
identity; one bounded follow-up admitted seven findings including that identity
at both base and head. OpenClaw's byte-identical, then-unpublished mirror candidate
`56f6f6a7210e77188c14b2e43d74388d54dd9b57`, against base
`4f6eb26b1beda60044ee9b94cd352f37c63718e9`, admitted nine findings across 22 staged
inputs, including the qualified prefix at both endpoints. The classifier's
success notices confirmed the exact canonical and mirror source paths.

## Question URL rejection fixture

Maintainer-approved qualification: admit only the existing
synthetic userinfo-rejection fixture in `ui/src/app/question-prompt.test.ts`.
The fixture was introduced by OpenClaw commit
`a37eb17fdfd688e0ed7e7be31950381cf15fb9bd` and is unchanged at line 220 in both
endpoints of [PR 152096](https://github.com/openclaw/openclaw/pull/152096).
[Identity evidence](question-prompt/identities.json) records both full blob IDs,
the regular-file mode, complete source-line digest, and native match digests.

Native TruffleHog 3.97.4 reports the same fixture through PLAIN or HTML decoding.
Its Raw value omits the path and RawV2 stops before the hyphen in `/sign-in`.
Both proposed attribution tuples therefore bind the complete original source
line as well as the native Raw/RawV2 pair, detector 17, exact path, and mode
`100644`. No value-only fixture row, scanner option, verification check, source
binding, or patch-attribution rule changes.

The controlled native proof ran on macOS arm64 with Node 24.21.0 and pnpm 12.4.1,
using a disposable OpenClaw worktree pinned to the requested head. It exercises
the complete PR source range with verification enabled:

```bash
pnpm build:node
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/disposable/openclaw-at-pr-head \
  24caac494ee4858989e58300925c5775a4dd45b2 \
  1db1bd5c9289f5c348e2c06ce0253aa9f5533584 \
  /path/to/question-fixture-proof.json
```

[Before qualification](question-prompt/before.json), the native proof refuses
with `literal_not_reviewed`, matching the hosted review diagnostic. The same
range admits in three consecutive runs:
[run 1](question-prompt/after-1.json), [run 2](question-prompt/after-2.json), and
[run 3](question-prompt/after-3.json). Adjacent `.native.json` observations retain
only finding hashes, coordinates, and bounded native metadata; the observation
hook does not alter scanner arguments, results, exit status, or classification.

The focused regression exercises real Git-generated added, removed, and context
lines for both decoders. It also refuses a one-byte literal change, changed full
source line, different path, executable mode, verified finding, and unqualified
decoder. Existing scanner tests retain all other admission guards.

Limits: no model runs, no hosted review is bypassed, and no runtime policy is
published by this proof. Hosted review must scan its own complete inputs after
an approved rollout. OpenClaw Bay is unaffected; only host-side fixture
qualification changes, with no dashboard API or action surface change.

## GitHub unsafe-check-link fixture

Maintainer-approved qualification for the single synthetic userinfo-rejection
fixture in `extensions/github/src/detail-checks.test.ts`, introduced by
[OpenClaw PR 153274](https://github.com/openclaw/openclaw/pull/153274). The test
asserts that unsafe check-run and commit-status URLs are omitted. Its reserved
example hostname and synthetic userinfo are test data, not live credentials.

[Identity evidence](pr153274/identities.json) binds the complete source line,
regular-file mode, source blob, native Raw/RawV2 hashes, and captured Git A record
for this new file. The qualification adds only the observed URI detector's PLAIN
and HTML variants at that exact source path. It does not add a value-only row or
a directory-wide exemption.

The controlled proof ran on Linux x64 with Node 26.8.2, pnpm 12.4.1, and the
canonical pinned TruffleHog 3.97.4 scanner, with verification enabled. A disposable
shared-object checkout was pinned to the real PR head; the canonical source
checkout was not changed. From a built ClawSweeper checkout:

```bash
pnpm run build:node
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/disposable/openclaw-at-pr-head \
  6f3aa8d6bc409bd4502902382c0055ed489ace38 \
  4df6f54115cde20d9225f791805a82b4bfcf3898 \
  /path/to/fixture-admission-proof.json
```

[Before qualification](pr153274/before.json), the full committed range refused
with `findings / material_not_reviewed`. Native observations retained only
finding hashes and coordinates; scanner arguments, output, status, and
classification were unchanged. All observed findings had the same Raw/RawV2
identity. HTML decoding can report patch line 511 while the literal is on line
512; the existing owner resolves that literal to committed source line 388.
The qualification binds the actual complete source line, never the neighboring
line or the scanner coordinate alone.

The same range admitted in three consecutive runs:
[run 1](pr153274/after-1.json), [run 2](pr153274/after-2.json), and
[run 3](pr153274/after-3.json). Adjacent `.native.json` files record the bounded
observations. Each successful scan retained exact source-attribution notices.

A separate disposable commit changed one ASCII byte of the fixture password,
with the path, mode, and test structure otherwise unchanged. The canonical native
scan [refused that mutation](pr153274/negative-one-byte.json) with
`findings / literal_not_reviewed`; that local proof commit is not a published
OpenClaw change. The focused scanner/fixture suite passes 365 tests, including
new real-Git added, removed, and context-line cases for both observed decoders
and refusal controls for literal, full-line, path, mode, role, verified status,
unqualified decoder, and an additional occurrence.

Limits: no model runs and no hosted review is replaced. Hosted ClawSweeper must
rescan its own current prompt, schema, and complete source inputs after the
normal policy landing. Existing scanner, verification, completion, source,
mode, and patch-provenance gates remain enabled. OpenClaw Bay is unaffected: no
dashboard API, telemetry schema, or public action surface changes.

## Browser CDP discovery fixture

Claim: the approved synthetic credentialed-CDP discovery fixture in
`extensions/browser/src/browser/pw-session.connections.test.ts` admits through
exact source attribution; a one-byte mutation still refuses. This unblocks
[OpenClaw PR 153597](https://github.com/openclaw/openclaw/pull/153597), whose
browser changes retain the existing fixture unchanged.

[Identity evidence](browser-session/identities.json) records the two observed
URI detector 17 tuples, for `PLAIN` and `HTML`. Each binds both native value
digests, the complete source line,
original path, regular-file mode, and committed base/head references. The
scanner's verification and complete-input admission checks stay enabled.

The controlled proof runs the actual `scanAgentInput` entry point with pinned
TruffleHog 3.97.4 against the complete committed PR range on macOS arm64,
Node 26.8.2, and pnpm 12.4.1. Provider: local host; no image or lease.

```bash
pnpm run build:node
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/disposable/openclaw-at-pr-head \
  ca128370df1057f5d1169e5918dfe551ac212a81 \
  2d674c57c1d9e5e174c0cecc6961763cf4230157 \
  /path/to/browser-session-admission.json
```

[Before qualification](browser-session/before.json), ClawSweeper main
`20e7ed8e9aab5e58217708f4aebe89d3af157b8f` refused with
`findings / literal_not_reviewed`. [After qualification](browser-session/after-1.json),
the identical range admitted in 6.4 seconds, classifying the browser fixture at
both endpoints and the separately approved browser documentation fixture. This
run observed PLAIN; the earlier native fixture scan observed HTML as well.

A disposable commit changed exactly one byte of the fixture, preserving the
path and mode. The same canonical scan [refused it](browser-session/negative.json)
with `findings / literal_not_reviewed`.
[The negative-control record](browser-session/negative-control.json) binds its
original and changed blobs and line digests; the mutation was not published.

The regression suite uses real Git-generated added, removed, and context lines
for both qualified decoders. Negative controls cover changed values, full lines,
paths, modes, uncommitted roles, verified findings, other decoders, and extra
occurrences. The three positive browser cases fail on the unqualified policy.

Limits: no model runs. Hosted review must rescan its own complete prompt, schema,
and source inputs. OpenClaw Bay is unaffected; there is no dashboard API,
telemetry, or public action surface change.

## TypeSafe local transport fixture

Claim: the approved synthetic loopback credential-rejection fixture in
`extensions/typesafe/src/local.transport.test.ts` admits through exact source
attribution, while a one-byte mutation still refuses. This unblocks the
input scan for [OpenClaw PR 154059](https://github.com/openclaw/openclaw/pull/154059).
It adds no model-side instructions or scanning bypass.

[Native identity evidence](typesafe/native-observed.json) records URI detector 17,
both observed `PLAIN` and `HTML` decoders, and the exact Raw/RawV2 digests.
The policy also pins the complete source line, original path, regular-file mode,
and committed base/head witnesses. No other fixture in the file is qualified.

The actual `scanAgentInput` entry point scanned the complete committed range
with pinned TruffleHog 3.97.4 and enabled verification on macOS arm64,
Node 26.8.2, pnpm 12.4.1 (local host, no container or lease):

```bash
pnpm run build:node
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/disposable/openclaw-at-pr-head \
  7d14778dc23424b7763f4e47e87aca2b63d6b363 \
  3ee5b1050b7f94ba65dc596ef13188b6ea7a602f \
  /path/to/typesafe-admission.json
```

[Before qualification](typesafe/before.json), ClawSweeper
`a09e6cefb31adcd12bba10e1658cae5fced08c80` refused with
`findings / literal_not_reviewed`. [After qualification](typesafe/after.json),
the same range admitted in 2.24 seconds, with independently attributed source
and added-patch findings. A disposable commit changed one byte in the fixture;
[that control](typesafe/negative-control.json) was [refused](typesafe/negative.json).
The control commit is not published.

The shared real-Git fixture suite covers added, removed, and context lines plus
changed literal, line, path, mode, role, verification status, decoder, and extra
occurrence refusals. Scanner completion and verification checks remain unchanged.
No model runs in this proof; hosted review must rescan its current prompt, schema,
and complete source inputs. OpenClaw Bay is unaffected: no dashboard API,
telemetry, or public action surface changes.

## Gateway question rejection fixture

This historical proof qualifies the Gateway sibling of the UI question fixture,
introduced by the same OpenClaw commit
`a37eb17fdfd688e0ed7e7be31950381cf15fb9bd`. Its bytes and source path differ,
so the existing UI qualification correctly refused it. The Gateway test rejects
a synthetic credentialed URL on the reserved `example.test` domain before
publishing a question, with no manager entry or broadcast. The fixture is unchanged.

OpenClaw PR [155339](https://github.com/openclaw/openclaw/pull/155339) at
`0688c464ba61caff8492d4d0f95ed7c27e7eecac` was refused by hosted review
[35678098402](https://github.com/openclaw/clawsweeper/actions/runs/35678098402):
URI detector 17, HTML decoder, unverified. The complete committed range from
`2c23442435e829a868fbc69f9e26ab747a4fd7fa` reproduced two findings locally: the
same exact fixture in base and head blobs, reported through PLAIN. Both decoder
rows bind exact Raw/RawV2 identities, complete line bytes, regular-file mode,
and `src/gateway/server-methods/question.test.ts`; scanner verification, source
references, and patch/hunk validation remain unchanged.

On Linux x64 with Node 24.20.0 and pinned TruffleHog 3.97.4, the existing
`run-proof.mjs` command above, using these base/head arguments, changed from
refusal in 3.268 seconds to admission in 2.236 seconds. A disposable committed
clone replacing one indentation space with a tab on line 338 still refused in
2.228 seconds, while retaining the URI bytes. The public classifier tests cover
both decoders and real Git-generated added, removed, and context attribution,
plus changed literal, line, path, mode, role, decoder, verification, and occurrence.

[The sanitized receipt](question-gateway/proof.json) preserves source identities,
native hashes, and results. A separate one-byte username mutation was not emitted
by the native detector; its admission is recorded as a detection limitation, not
negative proof. The changed-literal classifier regression still rejects emitted
mutations. This proof uses a controlled prompt, runs no model, and does not replace
the hosted review's own complete prompt/schema/source scan. OpenClaw Bay remains
unaffected: no dashboard, queue, publication, or observer contract changes.

## Session Share rejected userinfo links

OpenClaw [PR 156736](https://github.com/openclaw/openclaw/pull/156736) adds
receiver-origin and sidebar-link rejection cases on the reserved
`team.example.com` domain. Both use generic placeholder userinfo solely to
assert rejection. The source tests and their meaningful negative coverage remain
unchanged.

The complete committed range refused in hosted
[run 35911889455](https://github.com/openclaw/clawsweeper/actions/runs/35911889455)
is reproduced by the existing proof command using base
`bc6fedbe4633d3ccc0e4bb84ef323fa62794c6fd` and head
`6a6946b800f21a8f6b09f0bb7426b9c35ff32422`. Its merge base is
`0052923d044f0e44664c9b2d352e0db84525dc14`.

[The pre-qualification receipt](session-share/before.json) records refusal.
[Sanitized native evidence](session-share/before.native.json) accounts for all
four reproduced findings: the receiver test line 118 in the committed blob and added patch
(PLAIN), and the sidebar test line 13 in its committed blob (HTML) and added
patch (PLAIN). Hosted diagnostics retain only the first finding; the other
identities here come from complete-range native reproduction, not omitted hosted
records. Each retains detector/decoder, Raw/RawV2 digests, full-line digest,
canonical source path, regular-file mode, and committed source identity. Native
location metadata is resolved against the exact blob or canonical generated
patch line; no raw credential-shaped values are retained.

The four host-owned rows qualify only those observed identities and decoders,
including the receiver URI's exact shared-prefix occurrence in the sidebar line.
The first full-range proof correctly [refused that missing witness](session-share/before-shared-prefix.json)
until its complete sidebar line was separately qualified; the classifier's
all-occurrences requirement is unchanged. The regression suite includes this
shorter native identity in the full sidebar source line.
The real-Git regression harness covers additions, removals, and unchanged
context, and refuses changed literal bytes, whole lines, source paths, modes,
roles, source revisions, verified findings, unsupported decoders, and additional
occurrences. At that first qualification, the receiver's unobserved HTML decoder remained refused. Scanner
execution, verification, source freshness, and patch validation remain enabled.

Native detector results can vary: another observation of the same range emitted
only the two sidebar findings. A missing native finding is not negative proof.
Classifier mutations supply deterministic refusal coverage; native complete-range
admission still does not replace hosted review's prompt/schema/source scan.
OpenClaw Bay is unaffected: no dashboard, queue, or publication behavior changes.

On Linux x64, Node 26.7.0, and pinned TruffleHog 3.97.4
([runtime identity](session-share/runtime.json)), the same original complete range
[admits after qualification](session-share/after-original.json) in 3.994 seconds,
including the receiver's shared-prefix patch witness. The parent-confirmed final
OpenClaw head `26c03d2466f7b95e3c77da9912377e115d65f24d` also
[admits](session-share/after-final.json) in 3.890 seconds using the same base.
[Its native observation](session-share/after-final.native.json) reports two
sidebar findings; this is complete-range admission, not a claim that every
native detector emits every synthetic value on every run. The
[final source identities](session-share/final-identities.json) verify both exact
qualified lines unchanged (receiver line 124, sidebar line 13). No model ran.

### Session Share HTML follow-up: complete-material proof

[Hosted run 35921576228](https://github.com/openclaw/clawsweeper/actions/runs/35921576228)
used policy `6500b62dfd4c4efb0e2b821c1e9c427e128febef` and refused URI detector
17, HTML, unverified at receiver blob `b018d18acd4686a7dafa1899c4f20653c06ee42c`,
line 124. The source head and base were unchanged from the final proof above.
The diagnostic retained finding 3 of 4, but no raw-value digests, other finding
records, or original prompt. No model ran and no unchanged hosted retry followed.

Before changing policy, a representative full-input scan on that same policy
[reproduced the exact diagnostic](session-share-html/before.json). It used the
host review template, captured PR metadata and discussion through
`serializeReviewContext`, the actual decision schema, and the complete committed
range. All four reproduced native records are accounted for:

| Material                          | Native line | Decoder | Identity |
| --------------------------------- | ----------- | ------- | -------- |
| Complete patch, receiver addition | 537         | PLAIN   | Receiver |
| Sidebar committed blob            | 13          | HTML    | Sidebar  |
| Complete patch, sidebar addition  | 1378        | HTML    | Sidebar  |
| Receiver committed blob           | 124         | HTML    | Receiver |

[Full identity receipts](session-share-html/identities.json) retain detector,
decoder, unverified state, Raw/RawV2 digests, exact source line/path/ref/mode, and
all literal source witnesses. Both identities are existing generic userinfo
rejection fixtures on the reserved `team.example.com` domain. The first three
records are reproduced evidence, **not recovered hosted records**. The receiver
HTML record matches every retained hosted field, including index/count. The
original hosted prompt and first three exact identities remain unavailable.

The two new attribution tuples qualify only the observed receiver HTML identity
at its exact receiver line and the same identity's exact shared-prefix witness
in the sidebar line. The latter is required when that receiver finding occurs
in the complete patch containing both files. It is a source witness, not a claim
that the scanner emitted a separate shorter sidebar URI. There is no new
value-only exemption or classifier algorithm change.

Why did the earlier local proof pass? The
[identical-input comparison](session-share-html/same-input-variability.json)
shows two scans with the same binary, arguments, prompt hash, and complete staged
manifest: four findings/refusal, then only two sidebar findings/admission, **both
before qualification**. Pinned TruffleHog 3.97.4 recognizes TypeScript generics in
the receiver blob as HTML-like input. Its concurrent engine deduplicates identical
Raw/RawV2/source metadata without including the decoder in the key; its URI
detector also skips later candidates after caching DNS `IsNotFound` for that
host. These verified mechanisms explain the observed subset/decoder variability;
per-run scheduling and DNS traces were not retained. A missing finding is not
negative proof. The prompt/schema difference is a proof gap, not established
cause of HTML decoding in a separately staged blob.

The prior controlled proof omitted the hosted schema and used a short prompt.
The existing runner now accepts optional prompt and schema files and records
their hashes without publishing their contents:

```bash
node docs/proof/agent-input-scan-context/run-proof.mjs \
  /path/to/openclaw-at-pr-head \
  bc6fedbe4633d3ccc0e4bb84ef323fa62794c6fd \
  26c03d2466f7b95e3c77da9912377e115d65f24d \
  /path/to/admission.json \
  /path/to/representative-review-prompt.txt \
  schema/clawsweeper-decision.schema.json
```

The deterministic regression builds a real two-file Git range and supplies its
full patch, raw metadata, both endpoint blobs, prompt, and schema together. It
always exercises both observed decoders and the cross-file shared-prefix witness,
independently of native sampling. The existing adversarial cases cover changed
literal, complete line, path, mode, role, revision, verified state, unsupported
decoder, and extra occurrence; the full-material case also refuses an altered
sidebar witness. Scanner and verification remain enabled.

The [post-qualification native receipt](session-share-html/after.json) uses the
same complete representative input. No model execution, deployment, OpenClaw
source edit, or hosted-review replacement is claimed. The exact original hosted
prompt was not retained; this is representative full-input proof, not its
byte-for-byte recovery. OpenClaw Bay is unaffected: no dashboard, queue,
publication, telemetry schema, or public action surface changes.

---

### Overview (`docs/proof/agent-input-scan-git-metadata/README.md`)

# Git object metadata admission

Claim: generated Git object IDs can be classified without clearing credentials
that native decoding reconstructs from source content. The host keeps its complete
primary scan unchanged. Exact raw-diff, endpoint, path, mode, and rehashed full-blob
witnesses only request another native scan; they never admit a review by themselves.

The supplemental complete patch or raw diff masks only proven object-ID fields at their
original lengths. Filename context and all content bytes remain unchanged. It uses
the same pinned native scanner, verification flags, completion checks, and shared
deadline. Any unclassified finding, further metadata request, or incomplete scan
refuses admission. Success notices follow both scans, cleanup, and source fences.

Raw-diff findings use the same witness owner, including canonical added and deleted
regular files. Both materials must agree on full object IDs, file modes, paths,
change status, and endpoint presence; every present blob is independently rehashed.
Matching bytes in content or paths, malformed or duplicate records, unexpected
references at an absent endpoint, and missing patch witnesses still refuse.
The complete original raw diff remains in the primary scan and retained provenance.
Its supplemental copy is marked as proof material and cannot qualify another finding.

The regression from OpenClaw PR 156363 was reported by hosted TruffleHog 3.97.4 as
detector 58, PLAIN decoding, unverified, raw-diff line 1. The safe hosted artifact
does not retain matched digests, so exact hosted Raw/RawV2 identity cannot be recovered.
A verification-enabled local scan of that original hosted range with the normal
results filter emitted no findings; a diagnostic scan that also reported unverified
results matched complete Git blob IDs with versioned patch filenames. That diagnostic
does not prove hosted admission or recover the hosted finding identities.

The controlled native added/deleted-file fixture does reproduce the raw-diff
rejection. On macOS arm64 with Node 26.9.0 and checksum-qualified TruffleHog 3.97.4,
the pristine `60a77566c685fbe18600595a28964e5bd8135878` owner refused the same
committed fixture as detector 58 / PLAIN / raw-diff line 1 in 2.06 seconds; the
candidate admitted after replay in 3.34 seconds with a native raw-diff finding.
A literal additional-input collision still refused in 1.82 seconds. Tag-split
and hexadecimal-entity additional inputs also refused as separate HTML findings
in 2.16 and 1.81 seconds. Verification flags were unchanged.

Build the candidate and a trusted checkout of the pinned baseline, then run:

```bash
node docs/proof/agent-input-scan-git-metadata/run-raw-diff-proof.mjs \
  /path/to/raw-diff-proof.json /path/to/built-baseline
```

The driver requires an actual native raw-diff finding; a finding-free scan cannot
stand in for the admission proof. Owner tests separately inject the native report
shape to cover residual/verified findings, scan errors, and incomplete completion.

A review concern about a raw-diff finding hiding a decoded finding in another input
was rejected against the pinned native implementation and the cross-input proof.
[The v3.97.4 deduplication key](https://github.com/trufflesecurity/trufflehog/blob/v3.97.4/pkg/engine/engine.go#L1339)
includes detector, Raw, RawV2, and source metadata;
[the filesystem source](https://github.com/trufflesecurity/trufflehog/blob/v3.97.4/pkg/sources/filesystem/filesystem.go#L396)
stores each staged filename in that metadata. Separate raw-diff, patch, blob,
prompt, and additional-input files therefore cannot erase one another's findings.
The existing replay still protects same-input decoded content and metadata ambiguity.
OpenClaw Bay and public action surfaces are unchanged.

When the same patch contains an approved URI, its source witness uses the retained
primary patch only after the host binds the supplemental path, input identity,
revisions, and exact derived masked bytes. The native input remains masked. Changed
hunks, stale associations, and unreviewed or verified URI findings still refuse.

```bash
pnpm install --frozen-lockfile
pnpm run build:node
csw_scanner="$(node scripts/setup-review-tools.mjs --timeout-ms 120000)"
node --test --test-name-pattern='^(Git object metadata|metadata admission|metadata replay|metadata owner|approved URI findings in unchanged patch context|patch admission keeps)' test/agent-input-scan.test.ts test/agent-input-scan-git-metadata.test.ts
PATH="$(dirname "$csw_scanner"):$PATH" node docs/proof/agent-input-scan-git-metadata/run-proof.mjs /path/to/proof.json
```

To include the original dependency update, append its isolated checkout and exact
source range to the proof command:

```text
/path/to/openclaw 47d9a40df0afa279da03cc08e14031d05738d456 b87e5b75ffcf4386e01789b512e53d73b94437da
```

The native matrix requires the metadata-only case to pass, and tag-split, hexadecimal
entity, decimal entity, URL-encoded attribute, zero-width, and additional-input copies
to refuse. No decoded fixture blob contains the literal object ID. The Git filename
supplies the detector keyword, so full-blob scanning alone cannot protect against a
decoded patch finding being attributed to an unrelated metadata occurrence.
Owner tests also require the supplemental invocation, unchanged primary bytes,
preserved content, and refusal of verified results, missing completion, and scan errors.
The shared-object proof uses two modified files with the same URI-free old blob.
One path supplies Cloudflare detector context; the other adds the existing approved
URI lines in its unique new blob. Metadata masking therefore reaches both patch
sections without adding an unapproved URI alias or changing fixture policy.

[The shared-object driver](run-shared-oid-proof.mjs) requires both native detector
classes and a primary metadata-proof classification before it invokes the unchanged
baseline and candidate owners against the complete committed source:

```bash
PATH="$(dirname "$csw_scanner"):$PATH" node docs/proof/agent-input-scan-git-metadata/run-shared-oid-proof.mjs /path/to/shared-oid-proof.json /path/to/baseline-runtime "$csw_scanner"
```

The driver verifies the scanner against the existing checksum-pinned bootstrap
for the current platform and records the actual executable digest. Keep its cache
outside the candidate and separately built baseline checkouts. It requires both
native detector classes, no verified findings, baseline refusal as
`material_not_reviewed`, and candidate admission after complete primary and replay
scans. Verification flags stay unchanged. The receipt records counts, notices,
source identities and results; a single-path probe without both detectors is not
a reproduction of this composition bug.

The existing failure is tracked upstream in
[TruffleHog issue 3266](https://github.com/trufflesecurity/trufflehog/issues/3266).
Pinned native source confirms that
[HTML extraction](https://github.com/trufflesecurity/trufflehog/blob/v3.97.4/pkg/decoders/html.go)
changes text and line positions; its
[result deduplication](https://github.com/trufflesecurity/trufflehog/blob/v3.97.4/pkg/engine/engine.go)
includes source metadata but supplies no original-byte mapping for decoded matches.
The proof uses that native implementation instead of duplicating its decoder.

This runs the real scanner against controlled Git fixtures and optionally the full
original source range. It neither executes a model nor replaces the hosted review's
own prompt, schema, or source scan. Output contains classifications, safe diagnostics,
and digests, never matched values. OpenClaw Bay and public action surfaces are unchanged.

---

### Overview (`docs/proof/aggregate-review-recovery/README.md`)

# Aggregate Review Recovery

Status: historical controlled proof. Owner: ClawSweeper maintainers.

## Claim

A failed aggregate shard must not turn its planned matrix into retry authority.
Only recognized native retryable item terminals from the complete exact
producer attempt may reach recovery admission. Completed and nonretryable
items stay excluded; uncertain, missing, ambiguous, and unstarted work stays
held. Verified completed reports survive for the existing guarded publisher.

## Reproduce

Use Node 24, Bash 4+, and the pinned frozen dependencies in a clean environment.

```sh
pnpm run build:all
node docs/proof/aggregate-review-recovery/run-proof.mjs --baseline --output .artifacts/recovery-baseline.json
node docs/proof/aggregate-review-recovery/run-proof.mjs --output .artifacts/recovery-candidate.json
node --test test/repair/review-recovery.test.ts test/sweep-workflow.test.ts
```

The baseline executes the workflow at
`7f29952363878ca3b5d1f25be8d40a9f6ced784c`. Its failed-shard recovery admits
every planned item, including a nonretryable refusal, completed items, an
uncertain late mutation, and an unstarted tail. The filtered fixture uses the
production selection owner: planned `[1,2,3]` becomes selected `[1,3]`, but
baseline recovery still admits all three. These are intended red outcomes.

## Executed Boundaries

The native review ledger owner emits starts, logs, item terminals, coordination
receipts, and the final batch terminal. Its native finalizer writes canonical
shards. A synthetic input-scan refusal exits the producer process with code 79;
recovery never changes that outcome. Negative fixtures use native canonical
writers, except the deliberate byte-corruption unit case.

The harness executes the actual workflow staging and enqueue shell blocks.
The built production workflow utility reads exact-attempt artifacts and stages
verified reports; production `apply-artifacts --skip-reconcile` and targeted
`reconcile` consume them through the existing publisher boundaries. The
retained-prefix success and late-uncertainty cases also run `publish-main`,
comment-only `apply-decisions`, and both required artifact/comment receipt
workflow blocks. Their signed record tuple, comment, and immutable receipt
writes must contain only the retained items.

The actual enqueue `curl` reaches only a local signed HTTP server, which checks the
signature, delivery identity, item membership, and non-superseding decision.
Queue, GitHub, and read-model responses and credentials are synthetic. The
existing ledger-isolation transport restricts Node sockets and fetches to that
server and adapts the production GitHub command boundary.

Scenarios cover accepted, deduplicated, shed, disabled, and failed ACKs;
completed/cached and nonretryable exclusion; filtered membership; late and
unmatched mutation; resolved accepted/rejected mutation; mutation-only and
unsupported/ambiguous terminals; missing/incomplete/foreign artifacts; and
report identity/digest mismatches. Failed ACKs retain the existing three tries
per eligible item and a failed recovery exit. Item dispositions, admission
results, and the original review failure remain visible in the actual summary.

Receipts record the checkout/base SHAs, workflow/fixture/harness/source digests,
actual queue requests, producer/recovery exits, and retained report names.
Focused CLI tests additionally reject every foreign producer identity field,
corrupted canonical bytes, and linked reports.

## Limits

This proves executable production command boundaries with synthetic data, not
hosted Actions scheduling/artifact availability, model execution, scanner
effectiveness, live queue admission, production record durability, or public
comments. The real record and receipt clients receive synthetic loopback
acknowledgements; this is not production publication. Existing publisher guard
and receipt paths are unchanged. No live
apply, queue, workflow dispatch, deployment, or credential change is used.

Bay's existing public projection is checked for every optional-ledger and
recovery job step. Workflow wording prevents recovery from being presented as
active model review or completed publication. No dashboard runtime or controls
change. The existing review-step failure and job-level continuation policy are
preserved; a green aggregate job is not evidence that every item recovered.

Automatic unstarted-tail recovery and independent locked-item classification
remain named follow-ups, not inferred behavior in this change.

---

### Overview (`docs/proof/alarm-hydration-dedup/README.md`)

# Alarm hydration deduplication proof

## Claim

The real dashboard Worker and `ExactReviewQueue` Durable Object produce byte-identical normalized
public queue state for the same populated batch-publication alarm scenario, while two redundant
full item-table hydrations are removed from that alarm execution.

## Exercised surface

- Merge-base and candidate source trees, each installed and built independently on Node 24+
- Real `wrangler dev --local` Workers and SQLite-backed `ExactReviewQueue` Durable Objects
- Eight publication records seeded through the signed `/internal/exact-review/enqueue` route
- Automatic Durable Object alarms and a loopback GitHub App/API stub that accepts the real batch
  workflow dispatch
- Public `/api/exact-review-queue` snapshots immediately after seeding and after batch dispatch
- The existing test-only SQLite adapter around each revision's actual queue class, counting the
  full `SELECT item_key, item_json FROM exact_review_queue_items` hydration query

Only volatile clock-derived fields, request IDs, and UUIDs are normalized. The harness requires
the normalized merge-base and candidate JSON bytes to match both before and after the alarm.

## Eliminated reads

| Reused hydration | Why the second read cannot differ |
| --- | --- |
| Alarm housekeeping transaction snapshot | Between the legacy compatibility mirror and the former next-line read, the callback only returns and the synchronous transaction closes; neither path writes the normalized item table or dispatcher. |
| Post-terminal-preflight snapshot used for batch reservation | Between the recheck and reservation, the code performs only synchronous capacity, admission, candidate, and backoff calculations; there is no `await` or normalized-state mutation. |

Every later alarm read remains because an external await or a possible queue-state write intervenes.

## Run

From the repository root on Node 24 or newer:

```bash
docs/proof/alarm-hydration-dedup/run-proof.sh
```

Generated evidence is written under `docs/proof/alarm-hydration-dedup/artifacts/`, including exact
base/head provenance, raw and normalized queue snapshots, an empty normalized diff, Worker logs,
GitHub-stub requests, scan-count test logs, and `proof-summary.json`.

## Limits and OpenClaw Bay impact

The GitHub service is a loopback behavioral stub; no production repository, Worker, secret,
comment, workflow, or queue is contacted or mutated. SQL scan counts come from the existing
test-only storage adapter, because Wrangler does not expose per-query counts without production
instrumentation. This is state-equivalence and query-count proof, not a CPU benchmark.

OpenClaw Bay is unaffected. The change alters neither queue/lifecycle data nor any public observer
schema or control boundary.

---

### Overview (`docs/proof/app-token-scoping/README.md`)

# Worker cache and recovery proof

Historical proof recipe for PR [2063](https://github.com/openclaw/clawsweeper/pull/2063).

The claim is that the production dashboard reader separates repository and permission
scopes, refreshes a revoked cached token once without widening its grant, and that
canonical-target authorization gates the recovery effect. Run from the repository
root with Node 24+ and installed dependencies (including existing build output for
the shared test storage adapter):

```sh
pnpm run build:node
TMPDIR="$(cd "$(getconf DARWIN_USER_TEMP_DIR)" && pwd -P)" node docs/proof/app-token-scoping/run-proof.mjs
```

On other operating systems omit the macOS `TMPDIR` assignment. An optional first
argument chooses the JSON output file; the default is
`.artifacts/app-token-scoping/worker-proof.json`. Standard output is the same JSON.
The receipt includes HEAD, dirty state, runtime, each assertion, bearer aliases mapped
to grants, request status codes, and recovery mutations. Private keys and actual
opaque bearer values never appear in the receipt.

The script imports the actual `dashboard/worker.ts` reader and starts a real loopback
HTTP server. Generated RSA credentials sign App JWTs, which the server verifies.
Each token mint creates a distinct opaque token with the requested repositories and
permissions. Repository mismatches return 404, ungranted permissions return 403,
and revoked tokens return 401. Explicit negative controls test the stub itself.

The canonical credential switch lives in the production dead-letter operator's
`inspectRecoveryTarget`, not in the Worker's read-token cache. The proof runs that
unmodified CLI with an isolated environment: an issue lookup for
`openclaw/openclaw#321` resolves to a PR in `openclaw/canonical-target#321`.
The canonical PR read must use a separately minted, canonical-only token. Denying
that read leaves the dead letter open and produces no recovery request. Allowing it
passes through the real signed Worker recovery route into the real queue, resolves
the dead letter, and creates exactly one pending source review. This direct
`recover-fresh` route deliberately preserves the original source identity; it does
not claim to migrate the queued review to the canonical repository.

The initial run on `b1f3ee65c9ffdd50862aa180066f9469c611e2a4` failed at the revoked
cached token with `GitHub 401 for /repos/openclaw/alpha/issues/3`. After the fix,
that read observes 401, then 200 with a newly minted alpha/issues-read token; the
next read reuses that replacement. Regression tests also cover a rejected
replacement, a permission denial, a supplied token, and delayed concurrent 401s.

Limits: local Node (`provider=local-node`, image/lease not applicable), synthetic
GitHub authorization, and the existing SQLite-backed test storage/namespace
adapter. The production Worker, signer, token/cache code, CLI, and queue recovery
logic execute; Cloudflare deployment, alarms, and live GitHub authorization do not.
No real credentials, live GitHub calls, production writes, or new configuration are
used. The earlier live composite proof remains separate evidence.

---

### Overview (`docs/proof/apply-cursor-livelock/README.md`)

# Apply cursor livelock proof

## Claim

The automatic `openclaw/openclaw` apply loop always executes its numeric cursor frontier before
opportunistic urgent repairs, regardless of the order in which `item_numbers` arrives. The loop
chooses the smallest number strictly greater than the active cursor and wraps to the smallest
selected number only when no greater number exists. Per-pass-terminal outcomes can therefore
advance the durable cursor, while a runtime yield on the frontier itself leaves the cursor
unchanged for a truthful retry.

This fixes the livelock observed in production run
https://github.com/openclaw/clawsweeper/actions/runs/31544381133. That run selected 39 urgency-ranked
records before frontier `#105870`, exhausted its 300-second budget at urgent record `#85937`, and
never reached the only record that could advance cursor `#105854`.

## Controlled scenario and fixture

`run-proof.mjs` uses the exact 40-number selection from the production run and a synthetic action
mix matching its terminal classes: durable comment sync, changed-since-review, stale-sync skip,
kept-open, an already-closed canonical record, and a runtime-clipped record.

The selector, apply loop, and cursor-completion helper are exercised four ways:

1. The old urgency-first order examines the terminal urgent prefix but not frontier `#105870`; it
   reports `cursor_count=0` and leaves the cursor at `#105854`.
2. The new batch selector places `#105870` first. After that frontier and the same terminal urgent
   prefix complete, a yield at `#85937` advances the cursor exactly to `#105870`.
3. A yield on the first frontier records no examined item and leaves the cursor at `#105854`.
4. An ascending-sorted request places `#105870` last after four lower urgent records. The apply
   loop nevertheless examines `#105870` first, and completion consumes that trusted execution
   trace to persist `#105870` while every other record remains unexamined.

The proof also runs the repository's focused wrap/cycle tests. The selector reorder remains useful
for non-apply consumers, but the TypeScript apply-loop selection is the load-bearing guarantee.
The implementation does not change `cycle_start_after_number`, `cycle_wrapped`, their reset rules,
or the special automatic-policy branch.

## Run

```bash
docs/proof/apply-cursor-livelock/run-proof.sh
```

The container entrypoint additionally installs jq 1.8.2 only after verifying the
repository-pinned official release digest:

```bash
docs/proof/apply-cursor-livelock/container-proof.sh
```

## Result

`fixture-result.json` is the committed machine-readable fixture result. `behavior-report.json`
records the source-blind behavior validation.

The final committed-head proof ran `2ebe882831f99d9f22dd6f696f48d2a4e80f3195`
inside `node:24-bookworm` through Crabbox `provider=aws`, lease `cbx_a9f86ad7a357`
(`quick-prawn-5920`), run `run_61dcc42eb8d2`. jq 1.8.2 was installed only after its
`jq-linux-amd64` digest matched the repository-pinned value. All five focused fixture/wrap tests
passed, Crabbox exited 0, and the lease stopped automatically. `container-provenance.json` records
the complete receipt and the earlier proof-harness attempts.

## Limits and Bay impact

The fixture reproduces the cursor ownership and runtime-yield boundary without GitHub credentials
or production mutation. It does not reproduce the live API latency or claim that urgent records no
longer require later repair.

OpenClaw Bay is unaffected. This changes only internal apply-lane batch execution order and removes
a redundant pre-lease cleanup attempt; it does not change lifecycle publication or the
observer-only dashboard contract.

---

### Overview (`docs/proof/apply-read-generations/README.md`)

# Apply read generations proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

- Status: historical proof artifact
- Owner: ClawSweeper publication maintainers
- Tested source: `openclaw/clawsweeper@82d9a3b14961793d13f3d0b113078eb84e4caf00`
- Update when: apply generation keys, mutation observation, lease/proof barriers, or PR hydration watermarks change

## Claim and exercised surface

The controlled loopback exercises the production `LiveReadGeneration`, apply
guard memoization, two-sided lease guard, and PR hydration coordinator through
real HTTP endpoints. Identical fetch/context/policy reads share one value only
inside a generation. An observed GitHub mutation advances the generation,
clears its entries, and makes a previously bound context fail a runtime
generation assertion.

The pre-comment and pre-close lease barriers deliberately bypass a warm
generation. Each barrier therefore performs two live pull-head reads around one
live complete comment-list read. Fixtures advance the generation after a
concurrent head change and after a new durable comment; both cases block apply.

Apply parses the persisted PR hydration snapshot from report front matter and
validates the live head SHA, `updated_at`, file/commit/inline-comment counts,
and the just-in-time activity revision before reuse. Existing v2 snapshots can
reuse commits and inline comments while reading their missing file window.
Current v3 snapshots also retain that bounded file window, so a validated v3
hit performs zero pull-file, commit, or inline-comment list reads. Any mismatch
uses the normal full list path.

OpenClaw Bay is unaffected. This changes internal publication reads and
cache-only report metadata, not Bay's observer contract or action boundary.

## Generation and invalidation inventory

| Event | Generation behavior | Covered mutation surfaces |
| --- | --- | --- |
| Apply starts one item | Create one generation and bind guard reads to it | item fetch, context hydration, policy guards |
| Mutation runner reports accepted | Advance generation and discard bound context | lease post/delete, label definition/item labels, durable comment post/patch, placeholder delete, recovery label removal, close comment, item close |
| Mutation runner reports ambiguous outcome | Advance generation before propagating the error | every observed GitHub write attempt whose non-mutation cannot be proven |
| Mutation runner reports rejected/no-op | Preserve generation | guard rejection and explicitly known no-mutation errors only |
| Final proof, comment, or close guard | Bypass generation cache | final `fetchItem`/context freshness and low-signal policy checks |
| Two-sided lease verification | Bypass generation cache | head/source, comments, head/source |

## Counted formula and safety result

For the representative apply slice, `F` is the first item fetch, `C` context
hydration, `P` policy reads, `L` the irreducible lease barrier, and `U` the six
unique generation reads:

```text
before = F(1) + C(4) + P(6) + L(3) = 14
after  = U(6) + L_live(3) = 9
```

The `L(3)` floor is unchanged. With the generation already warm, both the
pre-comment and pre-close barriers still recorded two `/pull` requests and one
`/comments` request. Concurrent head and comment changes were both rejected.
A validated v3 snapshot recorded files=0, commits=0, inline-comments=0.

## Environment and commands

The exact source passed the complete host gate on Node 24.19.0:

```bash
pnpm run check
```

Result: 3,444 tests, 3,435 passed, 9 platform skips, 0 failures. Coverage was
81.57% lines, 74.01% branches, and 87.39% functions. Static checks included
`check:dashboard-strict`, docs, limits, formatting, all TypeScript builds, and
all linters.

The deterministic transport proof ran through Crabbox's explicitly requested
Docker-backed `local-container` provider on Ubuntu 26.04/arm64 with Node
24.19.0 and pnpm 11.10.0. The successful fresh-PR lease was
`cbx_0241049e673e` (`golden-barnacle-01a8`) and stopped automatically.

```bash
proof_source_head="$(git rev-parse HEAD)"
proof_source_tree="$(git rev-parse 'HEAD^{tree}')"
git cat-file -e "${proof_source_head}^{commit}"
git cat-file -e "${proof_source_tree}^{tree}"
PROOF_SOURCE_HEAD="$proof_source_head" PROOF_SOURCE_TREE="$proof_source_tree" \
  /Users/steipete/Projects/crabbox/bin/crabbox run \
  --provider local-container \
  --fresh-pr openclaw/clawsweeper#1161 \
  --no-hydrate \
  --allow-env PROOF_SOURCE_HEAD,PROOF_SOURCE_TREE \
  --preflight --timing-json --ttl 30m --shell -- \
  "awk '/^echo CRABBOX_PHASE:check$/{exit} {print}' scripts/e2e/run-apply-read-generations-container.sh | bash"
```

The successful receipt covers the checked-in toolchain, all three builds,
source identity, and loopback behavior phases. A separate Linux full-gate
attempt reached the repository workflow fixtures but those macOS-authored
cursor-trace fixtures reject Linux filesystem metadata; the exact same complete
gate is green on the required Node 24 host. No product assertion relies on that
platform-specific shard.

## Static verification recipe

Run from the repository root. The final diff check permits only this proof
directory after the tested source commit.

```bash
receipt="docs/proof/apply-read-generations/receipt.json"
jq -e '
  .schema_version == 1 and
  .crabbox.provider == "local-container" and
  .crabbox.runtime == "docker" and
  .crabbox.exit_code == 0 and
  .crabbox.run_status == "succeeded" and
  .crabbox.lease_stopped == true and
  .requests.before == 14 and
  .requests.after == 9 and
  .requests.barrier == {"pull": 2, "comments": 1} and
  .requests.validated_snapshot == {"files": 0, "commits": 0, "inline_comments": 0} and
  .assertions.concurrent_head_blocked == true and
  .assertions.concurrent_comment_blocked == true and
  .assertions.generation_bound_value_rejected == true and
  .full_gate.dashboard_strict == true and
  .full_gate.fail == 0
' "$receipt"
tested_head="$(jq -r '.source.head' "$receipt")"
tested_tree="$(jq -r '.source.tree' "$receipt")"
git cat-file -e "${tested_head}^{commit}"
git cat-file -e "${tested_tree}^{tree}"
test "$(git rev-parse "${tested_head}^{tree}")" = "$tested_tree"
test -z "$(git diff --name-only "$tested_head"..HEAD -- . \
  ':(exclude)docs/proof/apply-read-generations/**')"
```

## Limits

The behavior fixture uses deterministic loopback endpoints, not live target
mutations. It proves request ownership, invalidation, barrier transport, and
race decisions; it does not claim production latency. v2 records cannot avoid
the one file-list read because that schema did not persist files. No Worker,
dashboard, queue, or target repository state was mutated by the proof.

---

### Overview (`docs/proof/azure-endpoint-fixture/README.md`)

# Azure endpoint fixture admission proof

The exact synthetic userinfo URL in Crabbox's endpoint-rejection test was not yet in trusted fixture policy, so the normal review input scan refused before model execution. The change adds one URI/PLAIN attribution with exact Raw/RawV2 digest, complete source-line digest, path and file mode. The static policy validator recognizes that exact test path; classification still requires every identity and source witness.

The fixture appears unchanged in base blob `903bf2f5ba35048a1a2142c5173eacf93e8d152e` and head blob `9e2499dd540bda2f69bd6ea2afd4b804bde6da03`, at line 287 of `internal/providers/azuredynamicsessions/client_test.go`. It is a quoted negative case in `TestAzureDynamicSessionsEndpointRejectsUnsafeTokenDestinations`, whose assertion requires rejection. Its synthetic userinfo is not an Azure credential. The hostname uses an Azure service suffix: classification relies on this exact reviewed test context, not a reserved-host heuristic.

## Real scanner comparison

On macOS with Node 24.21.0, the unchanged trusted host at `efd9be863116673997c5935ba4c06321a3f122c8` refused the complete committed range with `literal_not_reviewed`. The candidate admitted that same range through `scanAgentInput`, yielding seven reviewed-fixture notices covering sixteen finding references. Both used checksum-qualified TruffleHog 3.97.4 with normal verification, a controlled nonsecret prompt, and no model execution.

Run against a checkout containing the exact commits after building the host:

```sh
node docs/proof/azure-endpoint-fixture/run-proof.mjs \
  /path/to/crabbox \
  226db96ab9beb6988f2e8601a751dd7e19d96367 \
  f0950d96ead0e2feaf1ca10285a874e5ab06cc97 \
  /private/evidence/azure-fullrange.json
```

The added fixture participates in the existing mutation table: altered literal or line, path, mode, worktree role, decoder, verified status, extra occurrence, mixed references, duplicate native record and incomplete scanner completion are rejected. Existing fixtures now also explicitly test absent completion records.

This proof scans all changed committed source material through the production admission owner, not only the newly qualified blob. It does not establish hosted review completion: that workflow must independently scan its own source, prompt and schema. No target source was changed to evade scanning, and no detector, verification or completion setting was weakened.

## Validation

The TypeScript main and repair builds completed. The three focused scanner suites passed all 424 tests in a credential-free environment with network access restricted to loopback, followed by successful documentation, formatting, lint and diff checks. An initial broader-suite attempt lacked the repair build artifact; after building it, the same suite passed. No finding required relaxing an admission rule.

---

### Overview (`docs/proof/backfill-shadow-cleanup/README.md`)

# Canonical backfill shadow cleanup proof

- Status: historical proof fixture; never deploy
- Owner: ClawSweeper maintainers
- Source of truth: the actual queue and direct-publication store bundled here
- Baseline: `b4cc911db6ed4a995d99f4fc7cc1eeb5492a4051`
- Update when: the cleanup predicate, checkpoint, or alarm ownership changes

Run `node docs/proof/backfill-shadow-cleanup/run-proof.mjs` with Wrangler on PATH.
The runner archives the pinned baseline's build inputs, starts its actual queue,
and restarts the same local SQLite object under the candidate. All storage and
R2 objects are disposable, local, synthetic fixtures. The Worker rejects outbound
fetches and never contacts production Cloudflare.

The fixture checks canonical publication and tuple replay, retained queue and
lifecycle rows, full paginated export and delta equality, snapshot bytes,
SQL/KV rollback, persisted finite progress, automatic idle alarms, completion,
and preservation of a future queue wake. Missing or mismatched ownership,
numeric aliases, live imports, and both commit export sources are preserved.

The populated case measures a 64-row batch with 2 MiB logical bodies and four
512 KiB Base64 chunks per row. It seeds one record at a time, then reports native
SQLite row counts, elapsed alarm time, logical retired bytes, and physical
database bytes separately. External admission timestamps include a warm baseline,
the cleanup interval, and a separate control object. These are local synthetic measurements, not a
production capacity guarantee, eligible-byte census, or reclamation promise.

---

### Overview (`docs/proof/backlog-recovery/README.md`)

# Backlog recovery behavior proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

Claim: reduce redundant inline-review reads and retry churn without relaxing
source integrity, source freshness, scanner checks, or queue ownership. Prepare
two members per batch while preserving identical publication plans and outcomes.
OpenClaw Bay needs no change: public payloads, lifecycle meanings, and its
observer-only boundary are unchanged.

## Environment and commands

Measured on macOS with Node 24.21.0, using the production hydration functions,
Git binaries, curl/bootstrap script, batch controller/publisher/apply paths, and
queue handler. Fixtures are synthetic. Baseline: `438cd3b870ca4355a6e78eaf4e4e94b162170f96`.
No credentials or live GitHub mutations are used by these drivers.

```sh
pnpm run build:all
node scripts/e2e/ci-comment-read-budget.mjs --inline
node scripts/e2e/backlog-source-recovery.mjs
node scripts/e2e/backlog-dead-letter-inventory.mjs
node scripts/e2e/backlog-batch-concurrency.mjs
```

To reproduce the inline baseline, save the baseline version of
`src/clawsweeper-item-context.ts` as
`dist/clawsweeper-item-context-baseline.js` with Node's
`stripTypeScriptTypes`, retaining the same sibling runtime dependencies, then
run `node scripts/e2e/ci-comment-read-budget.mjs --inline --baseline`.

## Observed results

- [Inline before](inline-before.json) / [after](inline-after.json): 10/40 inline
  comments require 2 → 1 reads when followed by a same-generation full read;
  250 inline comments require 5 → 3. Prompt windows and complete revision bytes
  match. A middle-comment edit is detected after explicit bypass and after
  generation invalidation. The transport is a loopback HTTP fixture, not GitHub.
- [Source recovery](source.json): real partial Git clone and native fetch install
  one of three missing blobs before an injected transport failure. The retry
  fetches only the remaining two. A warm rerun fetches nothing. The completion checks reuse the older-Git-safe
  tree-scoped missing-object probe; they never feed known-missing promisor blobs
  to `cat-file`. Real curl retries
  a refused connection and one loopback 503, then the unchanged pinned checksum refuses a corrupt archive.
  The fixture redirects the scanner URL and supplies Linux platform detection on
  macOS; it does not execute a synthetic scanner or weaken production validation.
- [Inventory](inventory.json): the production dead-letter handler uses two key
  lookups and no active-item payload scan despite 1,000 unrelated SQLite rows
  containing 32 MB of payloads. Active publication/recovery entries still block
  fresh recovery. Native file-backed SQLite is real; Cloudflare KV/scheduling
  are local adapters.
- [Preparation](concurrency.json): eight members finish in 5.33 seconds at one
  worker and 2.67 seconds at two, with byte-identical plans, actions and outcomes.
  The real controller, validator, apply and publisher paths use synthetic GitHub
  transport and artifacts. Quota failure admits only the two in-flight members;
  the other six defer without attempts. Heartbeat failure admits zero members.
- [Mixed circuit regression](mixed-circuit.json): one initial download is throttled
  while its sibling succeeds. The quota lookup is held until the next member
  reaches an outcome. At baseline `4f75de1dc7fec35e006f2781eafc3620df7fcf3a`, that member made a third artifact request;
  afterward only the original two download, the successful sibling prepares its
  result, and six members defer without attempts. A provisional circuit is written
  before awaiting the reset lookup, which is bounded to 30 seconds. Authoritative
  reset data can subsequently extend the initial one-minute fallback.

These controlled measurements establish behavior, not production throughput or
resolution of every historical HTTP 500. A bounded production error tail did not
reproduce the intermittent claim failures; existing claim retries and ownership
checks remain unchanged. The bounded inventory lookup removes an observed
unnecessary queue-wide read, without asserting it caused those failures.

## Older Git compatibility

ClawSweeper identified a regression in the initial completion probe. The corrected
production source and native proof also pass on Git 2.39.5 / Node 24.18.1 in
`node:24-bookworm` on Crabbox provider `aws`, lease `cbx_60711a84a0c5`,
[run `run_d12c06776f33ae027a6d0c20556235e5`](https://crabbox.openclaw.ai/portal/runs/run_d12c06776f33ae027a6d0c20556235e5),
exit 0 with 18 focused retry tests passed. [Retained result](source-old-git.json)
binds the corrected source hash and records partial-pack reuse, zero warm
fetches, connection-refusal/503 recovery, and corrupt-archive refusal. The native
source failure uses Git's standard `returned error: 503` wording. The scanner
server starts only after observing curl's connection refusal, avoiding a timer race. The
existing Git trace regression also requires every availability probe to use
exact tree roots, with zero nested lazy fetches and one explicit successful fetch.

## Rollout and rollback

Worker/review limits remain 128 total, 80 exact globally, 64 per target and 32
scheduled. Intake remains 60/hour with burst 6; publication max is 32, Actions
budget 194, imported-cluster cap 2. Only batch preparation moves from 1 to 2.
Compare complete 15-minute GitHub egress observations, publication completions,
oldest-ready age and quota deferrals after deployment. If throughput regresses
or sustained throttling worsens, restore
`EXACT_REVIEW_BATCH_PREPARE_CONCURRENCY: "1"` in the batch workflow. Missing
telemetry is unknown, never evidence of zero errors.

Source metadata retains its 30-second budget. Commit/history and missing-blob
fetches each have a separate 120-second transport budget, at most two attempts
of 60 seconds, including local object verification between attempts. Full-tree
materialization uses the same acquisition owner; attribute blobs retain the
caller's absolute metadata deadline. Installed blobs are reused only after their
type and size match the admitted tree metadata. History completeness is still
required; shallow repositories are unshallowed. Target-branch refresh requires a
successful remote fetch, even when a local tracking ref exists. Only transport
failures retry; authentication/ref failures fail normally. Fetch attempts reserve
graceful Git termination, forced escalation, and owned-process settlement inside
their deadline. Git performs its own lock cleanup; ClawSweeper never deletes Git
locks. Fetch-owned automatic maintenance is disabled. Missing supervisor receipts
or uncertain settlement stop the current acquisition without object reuse or an
exact-SHA fallback, and retain unsafe private workspace state for recovery.
Windows aborts require successful bounded `taskkill` while the parent still owns
its tree; an uncertain result cannot authorize a retry. Offline verification
processes use bounded hard termination. Commit-existence probes also deny all
transport protocols, including Git versions without the `GIT_NO_LAZY_FETCH` guard.
Scanner download uses 15-second connection and 60-second request deadlines with
at most two curl retries, including failures before an HTTP response; digest, version and benign scan gates remain.

---

### Overview (`docs/proof/batch-publication-outcome-summary/README.md`)

# Batch publication outcome summary proof

- Status: active controlled CLI proof
- Owner: ClawSweeper maintainers
- Source of truth: `src/repair/exact-review-batch-cli.ts`, its terminal outcome
  type, and `run-proof.mjs` in this directory
- Verified scope: the candidate's built CLI; each run prints its source HEAD,
  dirty state, compiled CLI hash, Node version, and observed outputs
- Update when: completion classifications, acknowledgement fields, or CLI
  summary output changes

The built `complete` and `release` commands must report five separate
`submitted_outcomes` counts alongside server acknowledgement totals. This
proof uses mixed batches, fully skipped submissions, and empty no-ops. It
checks the real signed HTTPS requests and CLI stdout without replacing fetch,
timers, or CLI modules. The coordinator is a loopback fixture; its returned
batch membership is empty to ensure output is not inferred from that view.

Run from a qualified checkout with Node 24+, OpenSSL 3, and dependencies ready:

```sh
pnpm run build:repair
node docs/proof/batch-publication-outcome-summary/run-proof.mjs
```

To record the same scenarios against an already built baseline:

```sh
node docs/proof/batch-publication-outcome-summary/run-proof.mjs <baseline-directory>/dist/repair/exact-review-batch-cli.js --baseline
```

The candidate asserts the reporting contract; baseline mode records its old
summaries while still checking wire outcomes and acknowledgement totals.
TLS keys, the certificate, manifests, and receipts are created in a disposable
temporary directory and removed when the run finishes. Only the child CLI
trusts that certificate through [Node's extra CA setting](https://nodejs.org/api/cli.html#node_extra_ca_certsfile);
certificate verification remains enabled.

This proves reporting and transport behavior, not the real queue's retry,
refresh, or dead-letter disposition. The synthetic coordinator returns
aggregate accepted/skipped counts without accepted identities. No production
Cloudflare state, GitHub state, inference, schema, or retry policy is changed.

---

### Overview (`docs/proof/bay-authoritative-lifecycle/README.md`)

# Authoritative Bay lifecycle metrics proof

This proof starts the actual local Wrangler Worker and its Durable Object, then
uses signed internal lifecycle requests to admit and complete public review
requests triggered by a new pull request, new commits, a changed pull-request
body, `@clawsweeper review`, and `@clawsweeper re-review`.

It proves that the public status route receives 21 durable completions across
those sources, advances a 20-review completed tide, retains the next completion
in the lane, records `last_tide_at`, and excludes a private repository from the
public aggregate. The one-hour timing coverage intentionally remains warming in
this short scenario; the emitted aggregate contains all samples while the page
correctly withholds a partial average.

Run from the repository root:

```bash
BAY_LIFECYCLE_PROOF_OUTPUT=.artifacts/bay-lifecycle-metrics \
crabbox run \
  --provider local-container \
  --local-container-image mcr.microsoft.com/playwright:v1.60.0-noble \
  --no-hydrate \
  --timing-json \
  --script docs/proof/bay-authoritative-lifecycle/run-proof.sh \
  --require-artifact '.artifacts/bay-lifecycle-metrics/proof-summary.json' \
  --require-artifact '.artifacts/bay-lifecycle-metrics/bay-lifecycle-metrics.png' \
  --artifact-glob '.artifacts/bay-lifecycle-metrics/**'
```

---

### Overview (`docs/proof/bay-duration-chart/README.md`)

# Bay duration inspection proof

## Current follow-up

At Martin’s September 7, 2026 request, the production chart keeps its highlighted
five-minute interval but replaces the native interval dropdown and permanent
detail row with a floating tooltip and one plot-wide focusable slider. The
separate inline-proof cohort selector remains. The original chart contract is
preserved in [behavior-contract.md](behavior-contract.md); the follow-up extends
its interaction checks rather than weakening the data or accessibility boundary.

The refreshed production HTML/CSS/browser script passed **16 Chromium scenarios**:
hover and scrubbing, hoverable/Escape-dismissable details, arrows/Home/End, stable
slider DOM/focus/bucket identity through refresh, mobile tap and frame-settled
horizontal drag, capture through refresh, viewport containment, aged-out bucket
clamping, immediate unavailable-state and transport-failure removal, live-region identity, sparse/zero/
empty/partial buckets, stale/browser-clock-skewed data, source query cutoff, and
independent retained lifecycle counts. No visible alternate chart picker remains.





## Provenance and reproduction

These are executed **working-tree captures**, based on
`22a614ce1493487d5be5b6e3a860b6ef3e8c80bb` plus the follow-up changes. Their
production-page SHA-256 and scenario/network results are in [summary.json](summary.json).
They do not claim the base commit alone contains the change. The final rewritten
head, exact-head proof, CI and review belong in the follow-up PR body.

- Provider: Crabbox `local-container`, compatible engine Podman.
- Lease: `cbx_521a951843c7`; run: `run_5534ce0996d0`, exit 0.
- Image: `docker.io/library/node:24-bookworm`.
- Node: `v24.20.0`; Chromium: `152.0.7977.82`; Playwright Core: `1.62.1`.
- Captured viewports: 1440×1000 desktop, 360×800 mobile with touch input.

```sh
pnpm install --frozen-lockfile
pnpm run build:all
node --test test/bay-duration-chart.test.ts test/bay-inline-proof.test.ts
PLAYWRIGHT_CHROMIUM_EXECUTABLE=/usr/bin/chromium node docs/proof/bay-duration-chart/run-proof.mjs
pnpm run check
```

The browser runner writes screenshots, `trace.zip`, assertion results and network
records under `.artifacts/bay-duration-chart/browser/`. It renders production
`bayHtml()` with controlled same-origin API responses; unrelated APIs return 404
and external fonts are blocked. Native touch moves are inspected after their
frame-coalesced events settle.

## Boundaries

The chart uses `bay.timings.window_ended_at` from the actual timing query. It
never substitutes the earlier status timestamp or browser clock. Missing source
time leaves the chart unavailable. Missing bucket data remains unavailable, not
zero; a rolling hour can intersect 13 intervals while the API retains 12 points.

This proves the rendered production interaction, not real-device screen-reader
certification, live backend completeness, or proof-producer execution. The separate
[inline-proof fixture](../bay-inline-proof/README.md) exercises the real Worker/
SQLite Durable Object and public cohort API. No production mutation, deployment,
workflow dispatch or live producer is part of either fixture.

---

### Overview (`docs/proof/bay-inline-proof/README.md`)

# Bay inline-proof participation — behavior-proof contract

- Claim: Bay compares full request-to-final review durations for all reviews, reviews with an accepted inline-proof request, reviews tracked from admission with no such request, and unknown history. A request is not execution, producer redemption, returned evidence, or proof sufficiency. Inline time is never subtracted.
- Surface: exact-review Durable Object request admission and durable lifecycle projection; bounded last-hour telemetry; public Worker status API; real browser comparison control.
- Scenario: controlled current-head review leases with accepted/deduped requests, rejected stale owners, no request, historical missing tracking, lease clearing/retry, final receipt dedupe, and legacy publication paths. No live producer dispatch or credentials.
- Command/environment: Node >=24; Docker/Podman-backed Crabbox `local-container`; isolated local Wrangler Worker/SQLite Durable Object; Playwright Chromium. Exact commands, source revision, lease, image and results recorded after execution.
- Observable result: closed enum survives lease cleanup, is fenced to the admitted revision, historical absence is unknown, each completion appears once, cohort counts/median/mean equal fixture arithmetic, browser selection changes only timing cohort and composes with legacy filtering.
- Artifact: sanitized API JSON, assertions, browser screenshots/trace and Crabbox execution summary under `.artifacts/bay-inline-proof/`.
- Limits: controlled local fixtures do not prove live Telegram/Web UI producer execution, deployment, GitHub publication effects, or production population coverage. Legacy publication records lacking original-review tracking remain unknown. Public Bay remains observer-only; no capabilities, plans, observations, credentials or request identifiers are projected.

## Semantics

`requested` means the DO accepted at least one inline-proof request for this admitted review revision. It remains requested even if that attempt later fails or is retried: those attempts are part of the same request-to-final journey. `not_requested` means tracking began at original admission and no request was accepted; while active this means “not requested yet”. Missing, historical, reconstructed or invalid tracking is `unknown`. New source/head revisions do not inherit the previous revision’s classification. The legacy publication-path flag stays independent.

## September 7 chart interaction refinement

- Claim/surface: production Bay retains its highlighted five-minute interval and readable axes, but has no interval dropdown or permanent bucket detail panel. The separate inline-proof cohort selector remains.
- Stimulus: desktop hover/scrub, keyboard arrows/Home/End/Escape, touch tap/horizontal drag, response refresh, resizing, missing/stale/unavailable snapshots.
- Invariant: one plot-wide focusable slider exposes the same interval, median, mean and sample count in a compact floating tooltip. Tooltip and axes remain within the viewport; valid refresh preserves slider DOM identity, focus and logical bucket key. Unavailable data removes stale interaction without inventing zero samples.
- Proof: production DOM/CSS in Chromium at desktop/mobile sizes in local-container. Capture screenshots, trace, geometry, source cutoff and input outcomes. Replace picker assertions with equivalent slider/tooltip safety assertions, not weaker tests.
- Limits: controlled local status fixtures and real Worker/DO; no production dispatch/deployment or live producer execution.

---

### Overview (`docs/proof/bay-live-status/README.md`)

# Bay live status cache proof

Claim: a valid queue with `source_incompatible` and `unknown` parked reasons
remains complete after status serialization and cached re-reading. Bay can use
its existing live cards and timing; malformed queue totals still fail closed.
The queue's dedicated closed projector owns this public contract.

The fixture uses synthetic inputs with twelve public-reference cards, four
timing samples, and one item in each affected parked bucket. The production
Worker serves `/api/status` and `/bay`; its real local cache and `StatusStore`
Durable Object persist each returned response before the next read. Three HTTP
traversals expose the original bug: the first drops the two reason fields, and
subsequent reads reject the inconsistent parked total. The proof also checks
that the synthetic private sentinel is removed and malformed totals are rejected.

Start each revision with its own local state and port:

```sh
pnpm --config.ignore-scripts=true dlx wrangler@4.131.1 dev \
  --config docs/proof/bay-live-status/wrangler.toml --local \
  --ip 127.0.0.1 --port 8798 --inspector-ip 127.0.0.1 --inspector-port 8799 \
  --persist-to .artifacts/bay-live-status/after-state
node docs/proof/bay-live-status/run-proof.mjs \
  http://127.0.0.1:8798 after .artifacts/bay-live-status
```

For the baseline, copy this proof directory to an isolated checkout of
`15e21a3b3948590955d2f19eb7e1e996b6b3d73d` without changing its production
source. Use a second port/state directory and invoke the same script with
`before`. Record the exact candidate head and patch digest alongside the
reports. When running through Crabbox, supply `BAY_PROOF_PROVIDER`,
`BAY_PROOF_LEASE`, and `BAY_PROOF_IMAGE` from its actual receipt.

Each proof leaves its server ready for browser inspection at `/bay`.
`POST /fixture/reset` with `{"scenario":"forward"}` moves one synthetic card
for the separate sweeping-animation check. The root task records browser
screenshots and desktop, narrow-layout, and reduced-motion observations.

Limits: synthetic operational inputs; real local Worker, cache, HTTP, and
Durable Object storage. This does not prove live GitHub data collection,
dispatch, review execution, or publication. The fixture is loopback-only,
has no live credentials, and must never be deployed.

---

### Overview (`docs/proof/bay-public-reference-blade/README.md`)

# Overview public-reference blade proof

This deterministic browser proof exercises the real Overview
HTML served by the local Wrangler Worker. A synthetic status response contains
two verified public GitHub references plus marker-bearing private fields that
must never render.

The proof searches for and clicks a reference, checks the local
blade, verifies canonical repository and issue/PR links and keyboard
focus, and confirms malformed deep links fail safely. It also proves that the browser
sends no mutations or direct GitHub API requests and records screenshots and a
Playwright trace.

Run from the repository root with the pinned Playwright image:

```bash
BLADE_PROOF_SOURCE_SHA="$(git rev-parse HEAD)" \
crabbox run \
  --provider local-container \
  --local-container-image mcr.microsoft.com/playwright:v1.60.0-noble \
  --no-hydrate \
  --allow-env BLADE_PROOF_SOURCE_SHA \
  --timing-json \
  --script docs/proof/bay-public-reference-blade/run-proof.sh \
  --require-artifact '.artifacts/bay-public-reference-blade/trace.zip' \
  --require-artifact '.artifacts/bay-public-reference-blade/proof-summary.json' \
  --artifact-glob '.artifacts/bay-public-reference-blade/**'
```

The fixture is deliberately synthetic and the canonical links are inspected
without being opened. This proves the interaction and privacy boundary, not
live dashboard freshness or external GitHub availability.

Run the broad Linux gate from the same exact tree with:

```bash
(
  set -e
  bundle=docs/proof/bay-public-reference-blade/exact-tree.bundle
  trap 'rm -f "$bundle"' EXIT
  git bundle create "$bundle" HEAD origin/main
  BLADE_PROOF_SOURCE_SHA="$(git rev-parse HEAD)" \
  BLADE_PROOF_TREE_SHA="$(git rev-parse 'HEAD^{tree}')" \
  BLADE_PROOF_BUNDLE="$bundle" \
  crabbox run \
    --provider local-container \
    --local-container-image node:24.13.0-bookworm \
    --no-hydrate \
    --allow-env BLADE_PROOF_SOURCE_SHA \
    --allow-env BLADE_PROOF_TREE_SHA \
    --allow-env BLADE_PROOF_BUNDLE \
    --timing-json \
    --script docs/proof/bay-public-reference-blade/run-gates.sh
)
```

## Visual artifacts

- [`overview-blade.png`](overview-blade.png) shows the local reference blade on
  the Overview page.
- [`bay-blade.png`](bay-blade.png) is historical evidence from the retired
  OpenClaw Bay page; the current runner does not reproduce it.

The runnable proof also emits `proof-summary.json` and `trace.zip` under the
ignored artifact directory. The PR body records the exact-head Crabbox receipt
and hashes after the final committed run.

---

### Overview (`docs/proof/bay-readable-layout/README.md`)

# Readable Bay — controlled runtime proof

This directory contains the reproducible proof harness, not a claim that an
arbitrary checkout passed. The accompanying PR body must identify the current
candidate, successful run, findings disposition, validation and visual review.
A failed or incomplete run is retained as diagnostic evidence, never signoff.

## Claim and exercised surface

The production /bay page is served by the real local Worker and its closed
/api/status projection. Deterministic source snapshots persist through the real
StatusStore Durable Object, enter the production versioned status cache, and
pass through the unmodified public projection and browser validator. The harness
asserts collection completeness before UI comparisons and rejects private
sentinels. It does not fulfill API requests with Playwright mocks or replace the
application with standalone HTML.

A separate initial phase exercises actual ExactReviewQueue admission and durable
lifecycle finalization, including batch-inclusive versus direct timing. The UI
remains public, indexable and observer-only; batch publication and backend
mutation policies are unchanged.

## Environment and invocation

Active proof harness owned by Bay maintainers; source of truth is the production
page/layout plus this executable matrix. Update when geometry, navigation,
projection, cache schema or fixture contracts change. This follow-up compares
the pre-density layout after the main-branch integration at base
8e008cbc0b4c9153f46a1b90167b215dea9ccdad. The baseline must be present locally;
fetch that mainline commit first when using a shallow checkout.
Use the repository-resolved Crabbox provider and an explicitly authorized existing
lease. This task uses Linux AWS proof, not an assumed Windows or local Docker
host. Use --no-hydrate to avoid Actions dispatch. Node >=24 and a sandbox-capable
Chromium installation and `setsid` are prerequisites. Each local Worker owns
a separate process group; cleanup terminates its pnpm/Wrangler/workerd tree so
subsequent runs cannot reuse an old fixture store. No TLS or browser-sandbox bypass is
permitted. Record actual provider, lease, image and tool versions with each run.

Stage intended source additions before proof. Crabbox sync transports working
files but not the caller index: inside the isolated synced lease, restore
intent-to-add for the explicitly intended new source files before running proof:

```sh
git add -N -- dashboard/bay-layout.ts test/bay-readable-layout.test.ts \
  docs/proof/bay-readable-layout/{README.md,fixture-worker.mjs,fixtures.mjs,run-proof.mjs,run-proof.sh,settled-master.mjs,wrangler.toml}
```

This changes only the isolated index, not source or commits. The runner rejects
missing source index entries instead of silently omitting them. Compare the
remote combined patch digest to the originating worktree before claiming proof.
The source manifest includes only
Git-tracked candidate files, not untracked files or private/generated Crabbox,
OpenClaw and artifact directories. The binary candidate patch excludes those
private/generated roots too; source deletions remain represented in the patch.
Use full-index patch digests so local and remote Git abbreviation settings
cannot change candidate identity.

From the candidate repository root **inside the admitted lease**, supply actual
BAY_PROOF_PROVIDER, BAY_PROOF_LEASE, BAY_PROOF_IMAGE,
PLAYWRIGHT_CHROMIUM_EXECUTABLE and BAY_PROOF_CANDIDATE provenance. For each attempt,
choose a new output and absolute scratch directory:

```sh
export BAY_PROOF_CANDIDATE="$(git rev-parse HEAD)+patch-sha256:$(git diff --binary HEAD --full-index -- . ":(exclude).crabbox/**" ":(exclude).openclaw/**" ":(exclude).artifacts/**" ":(exclude)artifacts/**" | sha256sum | cut -d' ' -f1)"
export BAY_PROOF_OUTPUT="$PWD/.artifacts/bay-readable-layout/attempt-N"
export BAY_PROOF_SCRATCH="$PWD/.openclaw/tmp/bay-readable-runtime-attempt-N"
bash docs/proof/bay-readable-layout/run-proof.sh
```

The runner validates that the supplied candidate equals the actual HEAD plus
the generated full-index source-patch digest, and refuses stale or mistyped
provenance before starting Workers. It refuses to overwrite prior evidence. It reconstructs the pinned base
with git archive, adds only fixture infrastructure to that baseline, installs
frozen dependencies, and starts separate local Workers and SQLite/R2 state.
HTTP ports are 8794/8795 and debugger ports 8796/8797; all bind to loopback.
Both pages receive the same scenario epoch and source data. Both pages default to all review paths; baseline production layout is untouched.

## Scenarios and assertions

The matrix covers normal, crowded, mixed-repository, long-reference, empty,
stale, partial-diagnostic, unknown-participation, terminal, active batch-fallback,
missing-timing, partial-activity and forward-transition fixtures, plus 20 active
cards in Reviewing with one in each neighboring lane, 20 in every active lane
(24 queue plus 96 live references within the existing 124-reference public
contract), and 24 in one lane to prove the 20-card cap and off-beach finder. Viewports are 2400x1050,
1920x1080, 1440x1000, 1200x525, 1199x900, 768x1024, 430x932 and 360x800.
The full scenario matrix runs at the original five breakpoints; additional
2400/1920/1200 canvases exercise normal, crowded, sparse-neighbor, 20-per-lane
and over-cap density. `BAY_PROOF_WIDTHS` and `BAY_PROOF_SCENARIOS` can select a
narrow debugging subset; receipts record that scope, which is not full-matrix proof.

It checks the genuine 20-card active-lane cap, responsive 44px target packing,
deterministic repeat-snapshot placement, compact finder width, quiet-lane
borrowing, enlarged hover/focus faces with outlines, edge clearance and pointer
continuity into the enlarged bounds without repacking, normal-motion finder,
edge-hover and ready-focus bounds across complete animation cycles, plus actual
scripted sweep/landing bounds while the creature stays inspected, and
pairwise disjoint hit targets while every available sample stays reachable;
aggregate/sample/drawn distinctions; all six active stages and both outcomes;
repository filters that leave timing unchanged; all inline-proof cohorts and
independent review-path selection; exact terminal-list
filtering; keyboard, pointer and touch; nested-modal forward/backward Tab,
Escape and focus return; refresh to newly persisted data, including removal of a
focused desktop card; resize retention and visible navigation-focus fallback;
longest cohort selection; normal/reduced motion, patrol resumption and tide preview. Browser
traffic must remain same-origin GET. Fixture seeding is separate local traffic
and never touches live producers or workflows.

Settled sweeper checks protect transformed bounds against visible records,
labels and controls, require a loaded visible asset inside the beach, and cover
viewport/area/resize changes. Active sweep, climb and settling overlap is
intentionally exempt. Mobile active layout position is independently checked
against the unchanged scene height; normal- and reduced-motion resting states
must regain clearance.

## Inspectable evidence

Each output directory contains:

- source-head.txt, candidate.patch, source-manifest.json and fixture hashes;
- durable-receipt-status.json and per-scenario public API responses;
- matched actual-page before/after PNGs and browser traces;
- measurements.json for header/chart, label overlap, 44px and first-screen checks;
- settled-master.json for resting clearance and active-motion observations;
- network.json, Worker logs and summary.json with explicit PASS/INCOMPLETE state;
- bounded focus or master-clearance diagnostics when those assertions fail.

Keep failed attempt directories alongside the succeeding run. The PR body must
link the actual current evidence, exact candidate/base, provider/image/lease,
commands, outcomes and limitations. Human inspection of representative desktop,
phone, crowded, long-reference and empty/partial images is a separate visual
review; a passing assertion suite alone does not provide that signoff.

## Supporting checks and publication gates

For narrow edit-speed regression checks:

```sh
node --test test/bay-duration-chart.test.ts test/bay-readable-layout.test.ts test/openclaw-bay-proof-network.test.ts
```

On the configured provider, build with pnpm run build:all and run the entire
canonical test/dashboard-worker-bay-records-routes.test.ts before repeating
pnpm run check. Those checks, lint and clean static review support but do not
replace the real matrix. Only results for the stated candidate count.

Fresh native Codex review precedes commit; committed branch-versus-base review
follows at the required boundary. Put current proof and findings disposition
in the main PR body before requesting ClawSweeper review. Current-head/current-
body review and CI remain owner work through maintainer-look readiness. No
merge, automerge or deployment is implied by this proof.

## Limits

Controlled snapshots prove local storage/cache/projection/UI integration, not
live producer execution, production throughput, or GitHub rate-limit recovery
itself. Batch classification uses the existing public contract and is not new
provenance. The receipt phase is real local lifecycle evidence, not a live
GitHub publication. Schema/cache-version drift must fail loudly; no validator,
privacy assertion or real retention limit may be weakened to make a fixture pass.

---

### Overview (`docs/proof/blob-hydration-env/README.md`)

# Blob-hydration old-Git compatibility proof

## Claim

Restricted PR review hydration detects missing promisor blobs without an implicit lazy fetch on
Git 2.39.5, resolves their sizes through the existing bounded metadata callback, explicitly fetches
only blobs within the per-review byte limit, and leaves the repository usable offline afterward.

## Root-cause verification

On unmodified `origin/main` (`ae04c61896effe1fb7795ef021c4feac99ddaea3`), the focused test file
inside `node:24-bookworm` reported Git 2.39.5, 2 passes, and the three expected failures. An
isolated genuine blobless clone showed why: `GIT_NO_LAZY_FETCH=1 git cat-file --batch-check`
exited 128 with zero output rather than emitting a `missing` row for the unavailable promised blob.

Git's [2.45.0 release notes](https://github.com/git/git/blob/master/Documentation/RelNotes/2.45.0.adoc)
place the correct client-side `--no-lazy-fetch` behavior in that release. The first replacement
probe incorrectly retained `--no-walk=unsorted`. On Git 2.39.5, its path-limiting fallback spawned
an implicit promisor fetch; the integration test counted that fetch without proving it was the
production path's explicit bounded fetch. That masked the missing traversal and let the old proof
appear green.

The repaired probe starts from the exact tree objects instead:

```text
git rev-list --objects --missing=print <base>^{tree} <head>^{tree} -- <bounded-paths>
```

Tree recursion emits the selected blobs while commit-history traversal is impossible. A fixture
with an earlier history-only blob and a separately fetched unrelated ref proved that neither was
observed. The same real blobless-clone scenario passed on Git 2.39.5 and Git 2.55.0: all four
expected blob IDs were observed, two were reported missing, no fetch ran under the probe, and the
later explicit `--stdin` fetch ran exactly once.

## Chosen option

This is the production-path fix from option 1 of the work order, not a test skip. Hydration now
uses `rev-list` to classify the object IDs reached from the exact base/head trees and bounded
changed paths. `cat-file` receives only IDs already proven local. Existing GraphQL size resolution,
the 4 MiB aggregate limit, explicit one-request fetch, unsafe-path rejection, and fail-closed
behavior remain unchanged.

Hosted production does not currently depend on this compatibility path. Recent
[run 31466811047](https://github.com/openclaw/clawsweeper/actions/runs/31466811047) records Ubuntu
24.04 runner image `20260720.247`; its
[software manifest](https://github.com/actions/runner-images/blob/ubuntu24/20260720.247/images/ubuntu/Ubuntu2404-Readme.md)
records Git 2.54.0. The fix matters for older self-hosted and container deployments and lets the
Bookworm proof suite exercise real behavior instead of carrying three environmental failures.

## Tree-traversal repair proof

The after-fix traversal trace used a genuine local filter-capable bare origin, a `blob:none` main
clone, a depth-one PR-head fetch, and a depth-one unrelated-ref fetch. The selected base and head
trees contained four distinct review blobs; two head-side blobs were absent locally before
hydration. The probe reported every expected blob ID without fetching, excluded both the
history-only and unrelated-ref blobs, and the production hydration function then completed its
single explicit bounded fetch.

The current-Git trace is retained in
[`artifacts/current-git-tree-traversal.log`](artifacts/current-git-tree-traversal.log). The matching
Git 2.39.5 trace is retained in
[`artifacts/git-2.39.5-tree-traversal.log`](artifacts/git-2.39.5-tree-traversal.log). The latter ran
inside `node:24-bookworm` through Crabbox provider `aws`, lease `cbx_7e3080158c5c`
(`coral-lobster-9594`), run `run_0a87aaf605e6`; Crabbox reported exit 0 and `leaseStopped=true`.

The strengthened integration test now separately asserts that the probe output includes every
known blob ID, that production invokes the two `^{tree}` roots without `--no-walk`, that no nested
promisor fetch occurs, and that the one counted fetch is the explicit `--stdin` fetch.

## Original full-suite scenario and command

Crabbox checked out pushed PR
[`openclaw/clawsweeper#1118`](https://github.com/openclaw/clawsweeper/pull/1118) at code head
`964d9d8d88b7e0a2394f7d555fa9b6d5cf0f923e` with `--fresh-pr` inside a Docker-backed
`local-container` using `node:24-bookworm`. The unprivileged lease installed Corepack shims under
`$HOME/.local/bin`; jq 1.8.1 was downloaded from its official release and verified against the
published SHA-256 checksum before installation in the same directory.
The retained `worktree_changes=1` is the uploaded `.crabbox/scripts/` proof harness; the remote PR
checkout itself was clean before Crabbox installed that harness.

The proof ran these gates in order:

```text
pnpm install --frozen-lockfile
pnpm run build:all
pnpm run test:no-build
pnpm run lint
pnpm run format:check
pnpm run check:active-surface
```

## Original observed result

Every gate passed. The full suite reported 3,318 tests, 3,310 passes, 8 platform skips, and zero
failures. All three named blob-hydration tests passed on Git 2.39.5 rather than being skipped. The
verbatim retained result is in
[`artifacts/full-suite-result.log`](artifacts/full-suite-result.log), and the gate markers and
runtime/tool checks are in [`artifacts/gates.txt`](artifacts/gates.txt) and
[`artifacts/runtime.txt`](artifacts/runtime.txt).

This original run predates the tree-traversal repair and is retained only as regression history; it
does not establish the repaired behavior. Crabbox reported provider `local-container`, lease
`cbx_553522239697` (`quick-crab-969a`), command
time 375,055 ms, total time 401,893 ms, exit 0, and automatic lease cleanup. Full machine-readable
details are in [`artifacts/crabbox-provenance.json`](artifacts/crabbox-provenance.json); the
captured remote streams and generated proof receipt are retained alongside it.

## Limits

The proof uses genuine partial clones and real local Git transport, but the fixture's bounded size
callback reads blob sizes from its source repository rather than GitHub GraphQL. Existing metadata
request tests cover the one-request GraphQL mapping. The run does not mutate GitHub items, queues,
production state, or deployment configuration.

## OpenClaw Bay

No Bay change is needed. This is local review-context Git compatibility; lifecycle, publication,
queue, telemetry, dashboard data contracts, and the observer-only action boundary are unchanged.

---

### Overview (`docs/proof/bounded-status-store-reads/README.md`)

# Bounded StatusStore reads proof

## Claim

The public automerge-metrics and apply-observability responses are unchanged while the dashboard's
`StatusStore` Durable Object no longer reads and reprocesses the full retained event population on
every poll.

Automerge reads use the timestamp embedded in the durable key as the storage range, include a fixed
eight-day pre-window session-context margin, consume the result in storage order, and return only
the completed summary across the Durable Object boundary.
Apply observations are stored in UTC day+repository buckets; reads fetch only overlapping buckets
plus compatible legacy rows and also return only the summary.

## Transition strategy

Apply writes switch directly to day+repository buckets at deploy time. Reads merge those buckets
with the existing per-run legacy keys, deduplicate by repository/run/attempt, and prefer the newest
observation. Legacy rows already have a seven-day TTL, so they disappear without a migration,
backfill, destructive rewrite, or flag day. After that natural drain, only the range's handful of
day buckets are returned from storage.

## Exercised surface

- Real `wrangler dev --local` Worker and SQLite-backed `StatusStore` Durable Object for merge-base
  and candidate.
- Real `/api/events` automerge ingestion and signed `/internal/apply-observability` ingestion.
- Public 6h, 24h, and 7d queries, both unfiltered and repository-filtered; automerge also exercises
  policy filtering.
- Automerge sessions spanning every requested-window boundary, plus a session entirely before the
  6h window, so command-to-merge latency and terminal inclusion match the unbounded implementation.
- A proof-only counting storage adapter around each revision's actual `StatusStore` class. It counts
  rows returned by `list()` and `get()` without changing production code.
- A replayed apply observation exactly at a UTC day boundary.

## Run

From the repository root on Node 24 or newer:

```bash
docs/proof/bounded-status-store-reads/run-proof.sh
```

The harness enables Corepack, installs the locked dependencies, extracts merge-base into a
disposable directory, starts both Wrangler runtimes on loopback, seeds 308 automerge events and 170
apply observations through production routes, and compares 12 normalized responses. Only
request-time-derived fields are normalized: `generated_at`, `range_start`, and automerge bucket
`start`/`end` timestamps.

The eight-day automerge margin is derived from the seven-day active-session reconciliation horizon
in `scripts/dashboard-reconcile-automerge.ts`, plus a 24-hour delayed-delivery cushion. That horizon
also exceeds the 104.84-hour maximum command-to-terminal span observed in the public seven-day
metrics response at `2026-08-11T08:49:10.916Z`. The largest query therefore reads at most 15 days
of the 90-day retained event population.

## Local result

The controlled run completed with all 12 normalized responses byte-identical. Storage-row reads
were:

| Endpoint | Range | Before | After |
| --- | ---: | ---: | ---: |
| automerge-metrics | 6h | 6,600 | 690 |
| automerge-metrics | 24h | 6,600 | 744 |
| automerge-metrics | 7d | 6,600 | 1,176 |
| apply-observability | 6h | 169 | 2 |
| apply-observability | 24h | 169 | 4 |
| apply-observability | 7d | 169 | 16 |

See [`artifacts/local-summary.json`](artifacts/local-summary.json),
[`artifacts/row-counts.json`](artifacts/row-counts.json), and the per-query hashes and normalized
payloads in [`artifacts/response-comparison.json`](artifacts/response-comparison.json).

## OpenClaw Bay impact

None. The same observer responses retain the same fields and values; no Bay projection, lifecycle,
control, queue action, or public observer boundary changes.

## Limits

The population is synthetic local data, not production volume or a CPU benchmark. Row counts show
storage records returned to the implementation, not serialized bytes. During transition, live
legacy apply rows are still read and merged until their existing seven-day TTL expires. The proof
performs no production deployment, GitHub write, workflow dispatch, queue mutation, or Bay action.

---

### Overview (`docs/proof/canonical-body-tiering/README.md`)

# Canonical body tiering native proof

- Status: controlled native proof passed; no production execution authority
- Owner: ClawSweeper storage and queue maintainers
- Source: `worker.ts`, `run-proof.mjs`, and the canonical queue/store owners
- Frozen persisted baseline: `291ab8a0090a8f76c08e4d0e39ea4cf1fdcbe0c0`
- Frozen throughput baseline: `ea6d72efc0a2e2c0683ad984b060b5c22008ce57`
- Update when: representation, publication fences, export/snapshot protocol, or runtime changes

Run from the repository root with pinned Miniflare, Workerd and esbuild available
through a directory containing `package.json`:

```sh
PROOF_TOOL_ROOT=/path/to/runtime-tools node docs/proof/canonical-body-tiering/run-proof.mjs
```

When the remote checkout has no Git metadata, set `PROOF_BASELINE_ARCHIVE` to a tar
created by `git archive 291ab8a0090a8f76c08e4d0e39ea4cf1fdcbe0c0 dashboard src config package.json`.
The runner reports that archive’s SHA-256. It never substitutes a synthetic old schema.
The serial-throughput comparison also needs an archive of the same paths at
`ea6d72efc0a2e2c0683ad984b060b5c22008ce57`, supplied as
`PROOF_THROUGHPUT_BASELINE_ARCHIVE` when Git history is unavailable.

The fixture imports the actual frozen queue and canonical owner, seeds schema 1,
then restarts the candidate against the same named SQLite Durable Objects and
native R2 bucket. Outbound fetches are rejected. The runner uses temporary source,
bundles and persisted databases, removed on exit. Nothing is deployed to Cloudflare.

Assertions cover exact exports across restart and detachment, empty/Unicode/NUL,
inline/chunked/maximum bodies, all sections and tombstones, unchanged receipt and
export identities, per-pass caps, native conditional object reuse, missing-body
errors, abandoned upload preparation, final queue ownership fences, direct versus
batch receipt retries, and snapshot restoration through the actual runner client.
Query plans and native rows-read counts compare baseline, dormant candidate, and
migrated pages, and instrument every actual migration pass. Timings include fixture IPC and R2; host RSS and CPU are not isolate
memory or CPU measurements and do not qualify production capacity.

The throughput comparison uses the actual frozen serial owner and the candidate
on identical synthetic records, native SQLite and native R2. Both timed legs use
prewarmed immutable objects and exercise conditional reuse under equal bucket
preconditions. A controlled 20 ms delay per operation exposes overlap; full GET streams still
pass through the production integrity reader. It records wall time, operation
count and peak concurrency, requiring four concurrent candidate operations and
identical exported bytes, revisions and tombstones. Failure proof requires all
started I/O to drain with SQL and checkpoint unchanged and no new PUT pipeline
after failure. Foreground publication must interleave and win its tuple CAS.
These timings are a synthetic comparison, not a production throughput estimate.

Requalification proof restarts a partially migrated serial checkpoint under a
new deployment identity, rejects ordinary preview and the wrong approval hash,
applies the reviewed envelope, rejects old prepared passes and replays, then
restarts again and resumes with every progress field preserved.

Focused tests add SQL-commit rollback, concurrent overwrite and deletion capture,
complete tuple conflict hydration, stale-source answers, coverage parity including
astral Unicode and SQLite NUL termination, warm format fencing, retention-boundary retries, bounded stream
cancellation, lifecycle policy comparison using controlled responses, and mixed
canonical/backfill preservation with concurrent export changes and invalid owner pointers.

The real bucket lifecycle, deployed identity, approved rollback floor, production
headroom, and the human production execution confirmations remain separate gates.

Throughput and requalification proof passed on 2026-10-19 through AWS Crabbox
(`run_ffe608e45de9`), Node `24.19.0`, Workerd `1.20260911.1`, Miniflare
`5.20260911.0-alpha`, and esbuild `0.28.1`. The frozen serial source archive hash
was `1a7756c6b4f2ae90da5835fe8f3b0ece2d515c7b842b808b15163b9ab7323dd3`.
Both timed legs migrated the same 96 records in six passes with prewarmed bodies
and 20 ms added per R2 operation: serial 2,077 ms / 96 calls / peak 1; candidate
564 ms / 60 calls / peak 4. The export digest was identical before and after.
The injected failure drained all eight started operations with no new PUT after
failure. Foreground publication won its tuple CAS. Requalification retained the
96-row frontier, cursor 16 and migrated count 16 across restart, rejected the
wrong approval hash, old prepared pass and replay, then completed all 96 rows.
The full format-upgrade fixture also passed 253 bounded passes; its maximum
observed source bytes per pass remained 6,291,878, below the fixed 8 MiB cap.

Observed on 2026-10-16 with Workerd `1.20260911.1`, Wrangler `4.131.1`,
Node `24.19.0`, and the frozen baseline archive SHA-256
`3cf5aca6439184c2c1c3a846f7ac293a4ee3c58aad1edd74dfe2b3e39bed5c6a`:

| Check                           | Observed result                                                                                                                                                                              |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Lossless physical move          | 3,028 rows; exact before/after export digest, revisions, timestamps, receipts and sequence equal                                                                                             |
| Resumable migration             | 253 passes; at most 13 scanned identities and 6,291,878 source bytes in this fixture; configured caps remain 64 identities, 4 tuples and 8 MiB                                               |
| Migration SQL reads | Maximum native rows read per query: records 64, tuple metadata 19, schema catalog 160; at most eight tuple queries per pass; both physical stores seek all three composite-key columns |
| Mixed canonical/backfill tuple | Separate frozen-baseline fixture: one backfill-only plan among 17 export entries; body, pointer and full export roundtrip equal after migration and restart |
| SQL allocation                  | 18,489,344 bytes before; 18,505,728 peak; 2,260,992 after                                                                                                                                    |
| New maximum-size writes         | 6 MiB of native R2 bodies; 12 KiB SQL growth; unchanged v1 row count                                                                                                                         |
| Snapshot and runner             | 1,011 live files restored byte-for-byte; watermark 3,028                                                                                                                                     |
| Indexed coverage/listing/export | Native maximum rows read per query: baseline 206/200/103; dormant 408/402/103; migrated 402/402/103; no body-view materialization                                                            |
| Queue authority                 | Expiry, cancellation, generation change, batch expiry and replacement all refused after the final R2 await                                                                                   |
| Retry and recovery              | Accepted direct response replay, strict changed direct rejection, changed batch replay during R2 outage, upload-before-commit restart, and missing/corrupt body infrastructure errors passed |

The observed migration pass wall time was about five seconds total, including
native R2 and fixture IPC. This small fixture does not establish production
throughput, an isolate CPU budget, or an isolate memory bound. A single explicit
CLI invocation can run up to 100,000 passes or 50 minutes and resume the same
approved plan later. Actual bucket lifecycle inspection, production headroom,
qualified deployment identity and explicit operator approval remain required.

---

### Overview (`docs/proof/changelog-fragments/README.md`)

# Changelog fragments proof

[openclaw/clawsweeper#1719](https://github.com/openclaw/clawsweeper/pull/1719)
hit four `CHANGELOG.md`-only conflicts in one day because every ClawSweeper PR
inserted its entry at the top of `## 0.3.1 - Unreleased`. Each resolution moved
the PR head and forced a fresh full review.

## Contract

- **Claim:** with one-bullet `changelog.d/` fragments, two concurrent PRs that
  both add a changelog entry merge without conflict; `pnpm run changelog:stitch`
  folds pending fragments into the real Unreleased section deterministically
  and idempotently; `pnpm run check:changelog`, part of `check:static`, rejects
  a malformed fragment and a fragment that re-adds a released entry.
- **Surface:** `scripts/changelog-stitch.mjs` (stitch and `--check` modes), the
  `changelog:stitch` and `check:changelog` package scripts, and the
  `check:static` gate.
- **Scenario:** [`run-proof.mjs`](run-proof.mjs) exports one revision with
  `git archive` and uses that revision's own mechanism and real `CHANGELOG.md`:
  (A) synthetic PR A and PR B each add an entry, PR B lands, PR A merges `main`;
  (B) three synthetic fragments plus any pending repository fragment are
  stitched, the stitch is rerun, and a second copy with reversed fragment
  creation order is stitched and compared byte for byte; (C)
  `pnpm run check:changelog` runs on the clean tree, then with a two-line
  fragment and a fragment holding the newest released entry.
- **Command and environment:**
  `node docs/proof/changelog-fragments/run-proof.mjs --rev <sha> --out <file>`
  on macOS arm64, Node v24.21.0, Git 2.54.0, pnpm 12.4.1. Synthetic Git
  repositories run with `GIT_CONFIG_GLOBAL=/dev/null`, a fixed identity, and
  fixed dates, so reruns produce byte-identical receipts.
- **Limits:** local temporary trees only; no GitHub, workflow, queue, or review
  path runs. The release-time heading rename stays manual. The stitch orders a
  batch by file name, not merge time.

## Result

| Check                                       | Before `65f9c3a305` (origin/main)  | After `c2b98a820d`                   |
| ------------------------------------------- | ---------------------------------- | ------------------------------------ |
| A. PR A merges `main` after PR B lands      | conflict in `CHANGELOG.md`         | clean merge; merged tree check passes |
| B. Stitch three fragments into CHANGELOG.md | script missing (exit 1)            | exit 0; only the Unreleased top grows |
| B. Second stitch run                        | n/a                                | "No changelog fragments" and same bytes |
| B. Reversed fragment creation order         | n/a                                | byte-identical `CHANGELOG.md`         |
| C. `check:static` runs `check:changelog`    | no                                 | yes                                  |
| C. Malformed and stale fragments            | no validator (`ERR_PNPM_NO_SCRIPT`) | exit 1 naming both fragments          |

Receipts:

- [`receipt-before.json`](receipt-before.json), revision
  `65f9c3a3057621385b6c4f52640a2ce190c18c57`, SHA-256
  `c47ba9b0ffbf5bb1e4b375c59621d08ddfee656ba126f9c1c03b17ead8a12d7a`
- [`receipt-after.json`](receipt-after.json), revision
  `c2b98a820d51fe2e557755ef6b05c18e9378f4d7`, SHA-256
  `1286e7dffd4f885d98f8f144c71b66c6729de3d3e276c3eb12393820abe6cd37`

The after revision is the implementation commit; the commit that adds this
directory changes only `docs/proof/changelog-fragments/`. Temporary roots are
normalized to `<tmp>`; the receipts hold no local absolute paths or secrets.

## Merge-only review carry-forward diagnostic

Each receipt also records `diagnostic_merge_only_carry_forward`, which does not
depend on the revision. It tests the proposed carry-forward preconditions (PR
diff `git patch-id --stable` unchanged and no PR file changed between the old
and new merge bases) on two synthetic merge-only heads. After a `CHANGELOG.md`
conflict resolved by keeping both entries, the patch ID changes and
`CHANGELOG.md` changed on both sides, so the preconditions fail. A merge of an
unrelated base change satisfies them. Carry-forward therefore would not have
saved the #1719 reviews; removing the shared insertion point does. It was not
implemented because it conflicts with the exact-head review policy; see the
pull request body for the policy analysis.

OpenClaw Bay is unaffected: no observer data, routes, or controls change.

---

### Overview (`docs/proof/ci-comment-read-budget/README.md`)

# CI comment read budget

- Status: active behavior proof
- Owner: ClawSweeper publication maintainers
- Update when: comment context hydration, apply read generations, or freshness barriers change

## Contract

Claim: review/publication context fetches the complete issue-comment thread once,
derives its bounded prompt window locally, and shares that complete read with
later guards in the same apply generation. It avoids duplicate REST pagination
without retaining comments across mutations or explicit fresh-read boundaries.

Surface: production context hydration, GitHub pagination, source-revision hashing,
and `LiveReadGeneration`, exercised through a local HTTP server with synthetic
GitHub issue/comment responses. Cases cover short threads, truncated prompt
windows, multiple REST pages, unknown counts, empty threads, a changed middle
comment, explicit bypass, and generation invalidation.

Command/environment: Node 24+, the repository's pinned pnpm, compiled production
modules, and `node scripts/e2e/ci-comment-read-budget.mjs`. Run the same harness
against the baseline and candidate builds and retain request-count JSON traces.
Focused tests and `pnpm run check` supplement this runtime proof.

Observable result: fewer comment REST requests for context plus a same-generation
guard, unchanged bounded comment content and full-thread source revision, and a
new complete read after bypass or invalidation. Existing two-sided mutation
barriers must retain their live reads and reject concurrent changes.

Limits: loopback GitHub responses are synthetic. The proof does not claim a
production quota reduction measurement or mutate GitHub, queue state, production
limits, or deployments. OpenClaw Bay is unaffected: no public status schema,
rendering, navigation, or action boundary changes.

## Observed result

On macOS with Node 24.21.0 and pnpm 12.4.1, the same production-runtime harness
measured the following comment REST requests for context hydration followed by
a same-generation complete-comment read:

| Thread | Baseline | Candidate |
| --- | ---: | ---: |
| Empty | 1 | 1 |
| 10 comments | 2 | 1 |
| 40 comments | 2 | 1 |
| 250 comments | 5 | 3 |
| 40 comments, unknown count | 1 | 1 |

Source revisions and bounded prompt comments matched the baseline. A middle
comment edit remained invisible to the current generation, but was detected by
an explicit bypass and after generation invalidation. The existing apply
read-generation loopback independently retained both live pull-head reads and
the complete-comment read at each mutation barrier, and rejected concurrent
head/comment changes. All 51 focused tests passed.

```sh
pnpm run build:all
# Baseline build, before applying the runtime change:
node scripts/e2e/ci-comment-read-budget.mjs --baseline
# Candidate build:
node scripts/e2e/ci-comment-read-budget.mjs
node --test test/context.test.ts test/primary-body*.test.ts \
  test/live-read-generation.test.ts test/apply-read-generations-loopback.test.ts
```

The machine-readable before/after observations and runtime source identity are
in [results.json](results.json).

---

### Overview (`docs/proof/closure-evidence/README.md`)

# Closure evidence controlled proof

With the pinned dependencies already installed, run:

```sh
node docs/proof/closure-evidence/run-proof.mjs
```

The fixture exercises the built `apply-decisions` CLI with isolated temporary
reports, plans, closed records, model output, and GitHub transport. It removes
credentials and isolates GitHub auth. Both configured and raw PATH `gh`/`ghx`
calls terminate in a synthetic transport. Unexpected commands,
explicit mutations, implicit payload POSTs, and GraphQL mutations are rejected
before any external dispatch. Four final-effect scenarios additionally admit
only an exact synthetic closeout POST and, for the eligible control, the exact
synthetic PR close command. Their receiver records local state and never
delegates to GitHub. No real GitHub endpoint is contacted.

It runs `pnpm run build:node` with an environment allowlist and Corepack network
disabled. The receipt binds every tracked and untracked source input, every
built file, and the fixture helpers. It checks these manifests remain unchanged
through the build and proof. The agent runner is pinned to the fake Codex binary.

All four product-scope reasons run without dry-run, with relevant flags enabled
and the `all` reason allowlist. They must reach the exact manual-decision
refusal, retain their proposal, and emit zero write intents. Obsolete-fix cases
retain path-only nominations, useful regression-test residuals, and current-main
drift. A reachable canonical-covered dry-run control proves the coverage stage
and eventual close path are connected.

Four additional cases run without dry-run against that recording receiver.
The eligible canonical-covered control must publish one distinct closeout note,
dispatch one final close, and archive its report. A recent human edit to an old
bot-authored comment must keep the item open even after a later bot edit. A new
human comment or current-main drift introduced only after the closeout POST
must prevent the final close and retain the open report. Each case asserts the
exact refusal or retry, stage witnesses, and zero forbidden transport intents.

Results and call traces go to stdout; temporary state is removed. The proof
does not establish semantic source equivalence, model accuracy, or a hosted or
live close. The local receiver demonstrates final-effect guard plumbing;
semantic source equivalence and real GitHub writes remain outside this proof.

---

### Overview (`docs/proof/cluster-intake-portable/README.md`)

# Portable cluster intake proof

The claim is that cluster intake accepts the store's raw and gzip snapshot
formats, treats empty portable cluster tables as an empty result, and preserves
processed-snapshot deduplication. Invalid gzip archive or decoded hashes must
fail before the workflow admits an import.

`run-proof.mjs` executes the actual `Prepare intake` shell from the workflow,
then the built importer against synthetic SQLite files. Empty cases also run
the real selector without credentials and assert that no candidate is selected.
The upstream store owns decompression and archive verification; intake copies its
materializer into a private temporary directory and checks a reviewed SHA-256
before execution. A changed publisher-supplied helper fails before import.
Provide the store's
`scripts/portable-artifact.mjs` to the proof rather than substituting a decoder.

Run on Node 24+ with Bash 4+, gzip, GNU coreutils, and dependencies installed, using the
repository's resolved Crabbox provider:

```sh
pnpm run build:node
node docs/proof/cluster-intake-portable/run-proof.mjs /tmp/portable-artifact.mjs .artifacts/cluster-intake-portable/candidate.json
node docs/proof/cluster-intake-portable/run-proof.mjs /tmp/portable-artifact.mjs .artifacts/cluster-intake-portable/baseline.json a9ed9b5ba7eb12357da7cc2360d87cc5397c3c36
```

The baseline runs its original workflow and TypeScript importer alongside
current compiled dependencies. Receipts include the source revision, dirty
state, workflow and importer hashes, materializer hash, runtime, and each
scenario's observable outcome. The baseline rejects gzip-only input and fails
on empty portable tables; the candidate accepts both, preserves raw input and
forced reimports, skips processed snapshots before decompression, and rejects
unreviewed materializer code and archive/decoded hash mismatches.

The reviewed materializer pin also enforces the store's current archive-size
contract and bounds decompression. The fixture uses a maximum archive size below
100 MB and verifies that expansion beyond the declared output size is rejected
before import. Refresh the digest only after reviewing the changed helper and
rerunning this proof; an upstream helper update must never silently authorize
new executable code.

This is controlled runtime proof, not a production intake or inference call.
It does not restore clusters omitted by an upstream export, verify raw database
hashes beyond the store helper's contract, or exercise live GitHub publication.
OpenClaw Bay is unaffected: its public status and data contracts do not change.

---

### Overview (`docs/proof/cluster-selector-deadlines/README.md`)

# Cluster selector deadline proof

Active executable proof owned by `src/repair/select-cluster-candidate.ts`.
Run from the repository root after `pnpm run build:repair`:

```sh
node docs/proof/cluster-selector-deadlines/run-proof.mjs /opt/homebrew/bin/gh
```

Pass a different native gh path on another host. The compiled CLI runs against
synthetic evidence in private temporary directories. Its existing fetch transport
is redirected to a local HTTP peer while preserving the production request and
AbortSignal. Separate requests stall before headers and during a partial JSON
body, each using the actual two-minute budget. A default native gh evidence read
stalls at a local CONNECT proxy and must stop at the configured 30-second floor.
Failure must publish neither a selected-path file nor a selection report.

Successful selected and rejected decisions also run through the compiled CLI and
native fetch. The selected case must perform the final-open GitHub read before
writing its normal durable output. These success cases use a synthetic gh adapter;
the GitHub timeout case uses native gh. All authentication is synthetic. There are
no live GitHub mutations or model calls.

The command prints a redacted JSON trace and removes its private fixtures.
Update the proof when selector I/O, its deadlines, or durable selection output
changes. Verified with this repair on Node 24 and gh 2.100.0. This proves local
transport behavior, not live model quality or GitHub availability. OpenClaw Bay
is unaffected: no public observer or status schema changes.

---

### Overview (`docs/proof/comment-router-current-report/README.md`)

# Current comment-router report proof

The latest report must describe this invocation. A GitHub throttle before command
discovery must not inherit prior commands or count requested comment IDs as
discovered commands. Current partial reports and their event shards must survive.

```sh
pnpm run build:node
node scripts/e2e/comment-router-throttle-loopback.mjs
```

This runs the actual wrapper, built router and action-ledger finalizer against a
loopback HTTP GitHub fixture in an isolated temporary runtime. It seeds a stale
report, throttles before broad discovery, and repeats with an explicit comment ID
and no prior report. Both must report zero commands, preserve the durable ledger
and cursor, and satisfy the workflow's existing empty-finalization condition.
Another request discovers commands before throttling; its partial report and
real event shards must finalize successfully. Existing abuse/429, fatal-error and
incremental cursor recovery cases remain covered.

To reproduce the stale-report failure, pass the baseline wrapper revision as the
only argument. The harness uses current unchanged compiled dependencies with
that wrapper and must fail because the stale count is retained. The candidate
receipt records the current head, dirty state, wrapper hash, named assertions and
loopback requests.

Only synthetic credentials, repository identities and event producers are used.
No live GitHub calls, workflow dispatch, inference or production state mutations
occur. OpenClaw Bay is unaffected: no command ledger, cursor, event schema or
public projection contract changes.

---

### Overview (`docs/proof/crabbox-config-fixtures/README.md`)

# Crabbox configuration fixture admission

## Behavior contract

Qualify only six existing synthetic URI fixtures in Crabbox's `internal/providers/all/claim_scope_test.go`, `internal/providers/all/command_routing_test.go`, and `internal/cli/config_test.go`. These exercise legacy scope normalization, command-line credential redaction, and signed-image display redaction. The reviewed values use reserved example hosts and descriptive placeholder userinfo, not operational credentials. Their shape is explanatory context, never a runtime approval rule.

Each host-policy row binds URI detector 17, observed PLAIN decoding, exact Raw and RawV2 digests, all complete source lines in order, the original path, mode `100644`, and every committed base/head reference. The repeated routing fixture has two distinct ordered line witnesses. Keep the classifier, scanner verification, native completion checks, metadata consistency checks, and rejection of unknown findings unchanged.

The source range is [Crabbox PR 2488](https://github.com/openclaw/crabbox/pull/2488), base `4c57142affd408a57ee25260c97c95b83a42a84a` and head `9990dc65a0073522198e7c653f26e2e8f7357f4f`. The fixtures are unchanged across that range; the host policy binds bytes and provenance across revisions, not these commit IDs.

## Native proof

Use the existing source-admission runner with its controlled prompt and checksum-qualified native TruffleHog 3.97.4. It invokes the actual host staging and admission path with normal verification and no model call:

```sh
pnpm run build:node
node docs/proof/marketplace-telemetry-fixtures/run-proof.mjs \
  /path/to/crabbox \
  4c57142affd408a57ee25260c97c95b83a42a84a \
  9990dc65a0073522198e7c653f26e2e8f7357f4f \
  /path/to/proof.json
```

The original policy must refuse the complete range with `literal_not_reviewed`; the candidate must admit it only after a complete native scan. Retain bounded notices and refusal diagnostics without credential-shaped literals. Focused regressions must reject changed literal/line/path/mode/role/decoder, additional occurrences, mixed approved/unapproved references, duplicate exact findings, verified findings, and incomplete scans.

The [2026-09-22 native result](native-results.json) records the original policy refusing 12 emitted findings and the candidate admitting 11 emitted findings across all six qualified identities. Both used normal native verification over the same complete source range on Node 24.21.0/macOS. Emitted unknown-finding subsets can vary; policy approval still requires every emitted finding and every logical source reference to qualify. This is not evidence that the original hosted scan's 11 findings were recovered byte-for-byte.

This is source-admission proof, not a hosted review or clearance of other findings. The hosted workflow still scans its own complete inputs and must publish a current review before the Crabbox changes land. OpenClaw Bay is unaffected: no status, queue, publication, or observer contract changes.

---

### Overview (`docs/proof/crabpot-lockfile-checkout-identity/README.md`)

# Lockfile pnpm materializes on a lockfile-less target repo misread as a checkout mutation

Production run [`32812081965`](https://github.com/openclaw/clawsweeper/actions/runs/32812081965) (`automerge-openclaw-crabpot-283`, `Execute credited fix artifact` step) failed with `target dependency setup mutated checkout identity: contentTreeSha, status, worktreeSha256`, thrown from `assertValidationSourceIdentity` right after `prepareTargetToolchain`'s pnpm install. The same job retried five times over six hours against the identical `source_head`, failing identically every time, no flakiness ([issue #1243](https://github.com/openclaw/clawsweeper/issues/1243)).

`openclaw/crabpot` has empty `dependencies`/`devDependencies` and no `pnpm-lock.yaml` committed. `pnpm install --frozen-lockfile` doesn't error against a repo with no lockfile to freeze; it silently writes one. `validationSourceIdentity`'s `worktreeSha256` and `contentTreeSha` both fold in untracked files (`git ls-files --others --exclude-standard`), so that newly-created, non-ignored file reads as a real checkout mutation and the guard fails closed. Confirmed by directly cloning `openclaw/crabpot` at the failing commit and running `pnpm install` with ClawSweeper's exact install flags: clean tree before, one untracked `pnpm-lock.yaml` after.

**Fix**: capture the pre-install lockfile state (`captureTargetFile`, an existing helper already used for the outdated-lockfile fallback path) and, only when that snapshot records the lockfile as absent, remove whatever pnpm just wrote before the post-install identity check runs. A lockfile that was already tracked or already present untracked is left untouched by this new path, `--frozen-lockfile` already guarantees those cases don't change, and the existing fallback logic for a genuinely outdated lockfile is unaffected. Regression coverage in `test/repair/target-validation.test.ts` proves all three states: absent (new test), pre-existing untracked (existing sibling test), and tracked mutation still fails closed (existing sibling test).

The executable contract is in [`behavior-contract.md`](behavior-contract.md), RED/GREEN evidence is in [`red-green.md`](red-green.md), and [`run-proof.sh`](run-proof.sh) is the Docker-backed Crabbox launcher, executed literally end to end inside the lease, not just copy-pasted piecemeal. [`receipt.json`](receipt.json) binds the head that was actually exercised, `f1cb0dfa666584da87cdf34f80f89fff2b99cc4d` (the fix and its tests; this proof directory was added in a later commit on the same branch that changes no tested file), provider `local-container`, lease `cbx_3e31cb90a5dd` (`coral-krill`), Docker image `node:24-bookworm@sha256:934240a162082fd8b8a2f90cd5114446443f1eba1c5378f6687167ca405e6584`, the full focused `test/repair/target-validation.test.ts` suite (203 passing, 3 skipped for a documented kernel-capability gate unrelated to this change, 0 failing), clean `format:check`, clean `lint`, clean `build:all`.

**Environment note on the production RED/GREEN comparison**: this bug's own code path only runs inside `runContainedCommand`'s Linux namespace containment, which this specific Docker-backed `local-container` lease can't itself nest (confirmed symmetrically: both unfixed and fixed code hit the identical `validation process containment failed: stage=namespace_setup` wall inside the lease, see `red-green.md`). So the actual before/after bug reproduction against the real `openclaw/crabpot@0cb363fdae97a06cc91f96525529cb3907ae20ad` checkout was run directly against a toolchain with working namespace/Landlock support instead, same compiled `dist/repair/target-validation.js`, same real target commit. Everything else (the focused unit suite, format, lint, build) ran inside the Crabbox lease itself and is reported in full above.

**Scope note**: this proof does not run the full `pnpm run check` gate, for the same reason as the prior `lockfile-deprecated-field-network-policy` proof (`test:coverage:no-build` needs CI-only secrets, unrelated to the changed surface). Per `CONTRIBUTING.md`'s guidance to use the narrowest meaningful validation for the changed surface, this proof scopes to build, lint, format, the full test file the change lives in, and the production real-behavior proof. This proof was also not produced or reviewed by ClawSweeper's own Codex `/review` loop; that step is GitHub-tooling-side and outside what a contributor can run locally, flagged here rather than silently presented as complete.

---

### Overview (`docs/proof/cron-ftp-fixture/README.md`)

# Completion-webhook FTP fixture qualification

Status: historical proof for this exact fixture qualification. The policy owner
is `src/agent-input-scan-fixtures.ts`; the native entry point is
`src/agent-input-scan.ts`. The candidate is based on ClawSweeper
`32cd4db41a50b57f301a955bd0e291cbfeb714e1`.

## Claim and exercised surface

The host input gate may classify the existing synthetic warning-redaction fixture
in [OpenClaw PR #161161](https://github.com/openclaw/openclaw/pull/161161) only when
FTP detector 899, the observed PLAIN/HTML decoder, both native value digests, the
complete source-file SHA256, complete line for every occurrence, original path,
regular-file mode and committed base/head reference match. Native metadata must retain empty `RawV2`, exactly `key=Raw`
secret parts, null extra/structured data and an unverified result with a
verification error. The OpenClaw fixture and scanner flags are unchanged.

## Native before/after proof

On macOS arm64 with Node 26.10.0, pnpm 12.4.1 and checksum-qualified TruffleHog
3.97.4, the existing proof entry point scanned the complete committed range with
verification enabled:

```sh
node docs/proof/agent-input-scan-context/run-proof.mjs \
  <clean-openclaw-checkout> \
  28885d3f8745f51e39ecb54389283dc391c15381 \
  226302c6ef7b496ced68f69f917669cd8a18f7ed \
  <receipt.json>
```

The original policy [refused](before.json) the range with an unclassified FTP
finding. An HTML-only qualification also refused an observed PLAIN finding; both
native variants therefore need the same exact qualification. The first candidate
[admitted](after.json) the unchanged range in 4.044 seconds, reporting HTML for
both committed blobs. PLAIN was also observed during the native qualification,
including the original refusal. The [native identity receipt](identity.json)
records the independently inspected finding shape without matched values.

## HTML source binding

The committed-branch review found that a second, HTML-encoded occurrence could
retain the same native authority and evade the plain literal search. The canonical
scanner [reproduced that admission](html-before.json): an HTML-marked synthetic
source retained the approved plain line and an entity-encoded occurrence on a
different line. Its HTML finding was incorrectly attributed to the plain line.

The policy now pins the complete bytes of the two inspected source blobs. It
hashes the actual staged bytes and filters the same attribution rows used for
line, path and mode checks. Any byte change, even unrelated to the fixture, needs
explicit requalification. This deliberately conservative boundary avoids a second
HTML decoder or a new replay policy.

The [source identity receipt](source-pins.json) shows that both original source
blobs remain byte-identical in the refreshed OpenClaw range
`2fc693e33eff44730a0113d33f8f68b1642db0a3..340c1ff4441b3c5e8b573c41c7c319df46ddec81`.
The same native command with these new base/head arguments
[admits that range](source-pins-after.json) in 2.841 seconds. It reports HTML for
both blobs under the production policy. Both observed decoders are covered
deterministically by the classifier tests.

Reconstructed synthetic Git sources have the same complete blob IDs as the
retained failing reproduction. The fixed native gate
[refuses the extra HTML occurrence](html-after.json) in 2.516 seconds and
[refuses the encoded-only control](html-only-after.json) in 2.230 seconds with
`source_not_reviewed`. No scanner or verification flag changed.

The focused regression passes 30 reported cases in 0.57 seconds wall time. It accepts both
observed variants and rejects changed host, credential, query, complete line,
path, file mode, source role/kind, decoder, detector, verification and native
metadata. Additional occurrences on an unapproved line, incomplete scans,
duplicate findings and FTP patch material also fail. It additionally refuses
HTML-encoded extra occurrences, unrelated source-byte changes, missing/malformed
source pins and a line-only replica under the production policy. Its small
algorithm fixtures use the existing custom-attribution argument with frozen
source hashes; the native proof above exercises the actual production pins.
The original policy failed
the positive regression; the additional-occurrence case failed before the
qualification reused the existing whole-blob literal witness check.

## Scheduler-routing coverage requalification

[OpenClaw PR #161703](https://github.com/openclaw/openclaw/pull/161703) adds routing
coverage without changing the synthetic fixture. The exact line witness remains
`47389a842fa9b1a3cb74c54ab2455b02b9cb0bd41c4b832eaf83aa52fbccbdc8`, moving from line
769 to 844. The reviewed head file has SHA256
`9e9ec747fe268991cde3f65280c0b4480e9d7748b9e9ce4d539a28f6f8fc23a1`.

On ClawSweeper `ce985956ca4f3dd962f87ef2e841fee83a7816cc`, the existing native proof
runner [refused the complete committed range](161703-before.json)
`b9a2236578c39079b067a642f0956638567fe7ba..c07112b4c58763176de2021f1c310641b2a8ab81`.
Adding only the new complete-source hash [admits that same range](161703-after.json),
with canonical verification enabled. Both base and head produce the existing HTML
FTP attribution. The exact same qualified source pair at a different path
[remains refused](161703-foreign-path.json), as does an otherwise identical head
with an [unqualified source-byte change](161703-changed-source.json). These controls
use complete, clean synthetic Git sources and the production policy.

Proof ran on macOS arm64, Node 24.21.0 and pinned TruffleHog 3.97.4. All 30 existing
FTP classifier cases also passed, covering both native decoder shapes and changed
literal, metadata, path, mode, and occurrence controls. No detector, matcher,
verification flag, queue, status, or Bay contract changes are involved. This source
qualification does not complete a hosted review or release its hold.

## Webhook outcome integration requalification

The same PR receives the canonical webhook-outcome coverage and moves its existing
payload/presentation case to the presentation test owner. The synthetic FTP line
is unchanged, with the same complete-line witness above, now at line 854. Its new
complete source SHA256 is
`64919155ae619bb0159a37d7ea97b6aba473671c50120cf78be7c27f8a15dae4`.
Only that hash is added; the existing base hash remains qualified.

Using ClawSweeper `74dc4c6a2fc204e456fb92677ca9271af104e9cc`, the maintained native
runner [refused the complete committed range](161703-webhook-native-before.json)
`b9a2236578c39079b067a642f0956638567fe7ba..028a1c3970f0353be974db89844da73215d967ca`
with `source_not_reviewed` for head blob
`6995635c757edddf9f538b3734fce12b71a1e806`. The single-hash addition
[admits that same range](161703-webhook-native-after.json) with verification enabled:
HTML for the base at line 769 and PLAIN for the head at line 854, one occurrence each.
No protected-main source hash is added speculatively.

The same complete source pair at a foreign path
[remains refused](161703-webhook-foreign-path.json). An otherwise byte-identical
qualified head with one extra newline
[also remains refused](161703-webhook-changed-source.json). Both controls use the
existing runner and clean synthetic Git sources. All 30 existing FTP classifier
cases pass, including the native metadata and whole-source negative controls.
Proof ran on macOS arm64, Node 24.21.0, and pinned TruffleHog 3.97.4. The detector,
raw-value digests, line/path/mode/ref/occurrence checks, native verification, and
scanner flags are unchanged. Bay and hosted queue/publication contracts are
unaffected. This proof does not complete a hosted review or release a hold.

## Receiving merge-base qualification

The verified receiving merge changes the actual review base to
`e1b701b44da537b740c10ae01f7652ee1712e913` and the head to
`3b9da2643fd25f22cf6c4af0f25f1cb27e0a7a8c`. The head still contains qualified blob
`6995635c757edddf9f538b3734fce12b71a1e806`. The actual base now contains blob
`c9ad3bf550d7f4cdf9c8b9062312fc70767865d3`, with the unchanged fixture witness once
at line 807 and complete-source SHA256
`e181c69bd874b3e50d70631a6f1a94eed2308d765f05046ec66a84089a62c7cb`.

The maintained native runner on ClawSweeper
`d7fd40ed0f8e8283c0c91c3b7c94f3c485bb608a`
[refused this exact committed range](161703-receiving-native-before.json) with
`source_not_reviewed`, explicitly identifying that base blob and revision.
Adding only its complete-source hash
[admits the same tuple](161703-receiving-native-after.json), with one PLAIN finding
for each role: base at line 807 and head at line 854. Verification stays enabled.
The earlier `b9a2236..028a1c3` result remains evidence only for its original tuple.

The identical newly qualified pair at a foreign path
[still refuses](161703-receiving-foreign-path.json). Appending one newline to the
newly qualified base source, while retaining the qualified head,
[also refuses in the base role](161703-receiving-changed-source.json). Both controls
use clean synthetic Git sources and the same production scan entry point.
All 30 existing FTP classifier cases pass. Proof uses macOS arm64, Node 24.21.0,
and pinned TruffleHog 3.97.4. Detector, decoder, literal, line, path, mode, ref,
occurrence, native verification, and complete-source checks remain unchanged.
No Bay, queue, or publication contract changes are involved.

## Destination-owner final-source qualification

[OpenClaw PR #168996](https://github.com/openclaw/openclaw/pull/168996) retains the
same synthetic FTP warning-redaction fixture. Its frozen receiving tuple is
`b5a9b9b41c343f4a11c44dd511a49c348f63d704..c407dec21ac280710a2bec2c0ff524139e00b94c`.
The [source identity receipt](168996-source-identities.json) records the complete
base and head files, both at `src/gateway/server-cron-notifications.test.ts` with
mode `100644`:

| Role | Blob | Complete-source SHA256 | Fixture line |
| --- | --- | --- | --- |
| Base | `4bdb2e246f6859f49ae0312d79900e175050cbc6` | `dae36fe07e5b25c4c2f306a9a7e5ceaa0a8967d0789c9677b4e7a9eb6b7668c7` | 684 |
| Head | `d5b62b493f2bd24a8e65e8604062bb5b43b785d3` | `f42428917e28d417c8a6d7867d7abdb3d1ee76e2d9fce6f93965f319e0fcd061` | 732 |

On ClawSweeper `27fbecbbe4a92831a667e76fff1b73412ef89b14`, the maintained native
runner [refused that exact range](168996-native-before.json) with
`source_not_reviewed`, identifying the base blob. Adding only these two source
hashes [admits the unchanged range](168996-native-after.json) in 3.784 seconds.
The final native scan reports one PLAIN FTP finding per role at the lines above.
The complete-line digest remains
`47389a842fa9b1a3cb74c54ab2455b02b9cb0bd41c4b832eaf83aa52fbccbdc8`.

The same complete source blobs [remain refused at a foreign path](168996-foreign-path.json).
Appending one newline to the head file [remains refused in the head role](168996-changed-source.json).
These controls use clean, complete synthetic Git sources and the same native
production entry point. All 30 existing FTP classifier cases pass, covering
PLAIN and HTML, native metadata, source identity, and occurrence controls.

Proof ran on macOS arm64 with Node 24.21.0, pnpm 12.4.1, and pinned TruffleHog
3.97.4. Detector 899, both decoder rows, native Raw/RawV2 digests, full-line,
path, mode, committed-ref, occurrence, and verification checks are unchanged.
No scanner flag, policy bypass, test exclusion, Bay, queue, or publication
contract changes are involved. This admission proof does not itself complete
a hosted review or release a review hold.

## Limits

This is source-admission proof with a controlled prompt. It does not run a model,
complete a hosted review, release its hold or authorize a merge. Hosted review
must rescan its own source, prompt, schema and other inputs. PLAIN/HTML selection
can differ between native scans; neither label permits different fixture bytes.

No queue, status, or publication contract changes are involved.
Requalify if any source-file bytes, fixture location, scanner version or the host source-binding
contract changes. No test file or input range is excluded from scanning.

---

### Overview (`docs/proof/csw-092/README.md`)

# CSW-092 runtime proof

Current-head, redacted Linux runtime evidence for PR #995 is recorded here.
The captured files are generated by the repository's supported OpenClaw Bay
Playwright proof and use a fully synthetic status fixture. They prove the real
local Worker route and Bay page rendering, not production telemetry or
production performance.

See `proof-summary.json` for the exact current head, environment, assertions,
request classification, and fixture checksum. `runtime-transcript.md` records
the exercised surfaces, observations, and fixture limits. The visual captures
used during review remain available in git history rather than the docs tree.

---

### Overview (`docs/proof/csw-093/README.md`)

# CSW-093 Workstream 5 proof contract

## Claim

OpenClaw Bay renders a bounded lifecycle Kanban from only the durable
`ExactReviewLifecycleProjection` reducer. Its read path neither changes queue
or Durable Object state nor treats a workflow, worker step, or action result as
a lifecycle fact.

## Exercised surface

- Public Worker route: `GET /api/durable-lifecycle-bay`
- Durable Object route: `GET /lifecycle-bay`
- The built `/bay-demo` page and its lifecycle Kanban renderer

## Controlled scenario

A local Worker/Durable Object fixture records synthetic lifecycle projections
for: pending, acknowledgement pending, completed, superseded, requeued,
dead-letter, target closed/missing, policy/guarded/failure, and acknowledgement
skipped. It includes a re-review sequence where an older revision remains
requeued or superseded while a later revision starts in its own earlier lane.
The fixture also covers malformed, mixed, unavailable, stale, and 513-row
sources, plus a 25+ card complete source to exercise the 24-card round-robin
sample.

## Required observations

- The pure Worker/DO read causes no Durable Object write, schema initialization,
  prune, lease reclaim, alarm scheduling, or GitHub request; a subsequent
  ordinary initialized queue request against that same local DO still succeeds.
- Cards retain the target/revision/fence record cardinality internally and never
  expose a fence, run, claim, delivery, receipt, comment, or digest identifier.
- `Completed` appears only from the lifecycle reducer; acknowledgement-pending
  and acknowledgement-skipped cards do not appear in Completed.
- Incomplete, malformed, mixed, unavailable, stale, or over-cap data renders
  one Unknown state with no partial lane totals or cards. A complete zero-row
  response renders Empty instead.
- Browser screenshots capture Completed, Terminal attention, Unknown, and the
  bounded sample view.

## Command and environment

Run the focused tests and builds plus the generated proof script through
Docker-backed Crabbox local-container on `mcr.microsoft.com/playwright:v1.60.0-noble`,
with `--no-hydrate` and `--timing-json`. Run lint, format, and diff checks as
the final local branch gates. The proof blocks external network access except
the local Worker; it never contacts GitHub, production Worker/DO state, queues,
gates, or R2.

## Artifacts and limits

The proof script writes a redacted runtime transcript, a readable Worker/DO
initialization transcript, machine-readable sequence/summary, response captures,
and screenshots under this directory. It proves the controlled Worker/DO and
browser surface only; it does not claim production data volume, production
freshness, or live Activity behavior.

---

### Overview (`docs/proof/csw-098/README.md`)

# CSW-098 Live Activity proof

`run-proof.sh` runs a controlled Linux/Wrangler/Playwright proof. It verifies
the real local Worker endpoint fails closed without its GitHub status source,
then uses the built Bay page with controlled redacted activity payloads to show
active display, stale-to-Unknown expiry, unchanged durable Kanban cards, and
GET-only browser traffic. Generated artifacts are retained in `artifacts/`.

---

### Overview (`docs/proof/csw-099/README.md`)

# CSW-099 Workstream 6 proof contract

## Claim

Only a caller that holds the established `EXACT_REVIEW_OPERATOR_SECRET` can
read the redacted, paginated lifecycle audit inventory. The inventory is a
short-lived frozen snapshot of reducer-derived lifecycle facts; it is not a
public Bay API and it never derives `Completed` from workflow activity.

## Exercised surface

- Admin Worker route: `POST /internal/exact-review/lifecycle-audit/inventory`
- Durable Object route: `POST /lifecycle-audit/inventory`
- Public Bay page: `/bay-demo`, to prove it does not call the admin route

## Controlled scenario

The focused Worker/DO test seeds synthetic durable lifecycle rows, verifies
operator HMAC authentication, captures a two-record page, changes the live
projection, then reads the next page from the frozen snapshot. It also proves
redaction, invalid-page rejection, and stale-snapshot fail-closed behavior.

The Linux proof starts the real local Wrangler Worker with only a disposable
operator secret. It initializes the disposable DO through an existing public
aggregate read, posts a correctly signed empty inventory request, rejects a
shared-secret signature, and confirms that the public guessed API path is not
available. Playwright then loads the built Bay page and confirms it makes no
request to the admin inventory route.

## Contract

- Request: signed `POST` body `{ "page_size": 1..100, "cursor"?: "<uuid>.<offset>" }`.
- First page creates a snapshot from at most `10,000 + 1` source rows. More
  than 10,000 rows returns `Unknown/over_cap`, never a partial inventory.
- At most four snapshots may exist, each for five minutes. A late cursor returns
  `Unknown/stale`; expired snapshot rows are deleted when the next snapshot is
  created. A metadata-only tombstone lasts one further five-minute window solely
  to preserve that stale result, then is removed.
- Records expose the reducer card fields only: target/revision, reducer state
  and lane, coarse durable facts, timestamps, and fixed provenance. They never
  expose fence, delivery, status-marker, comment, receipt, run, claim, or
  digest identifiers.
- Source unavailability, malformed rows, mixed rows, over-cap input, or an
  expired snapshot returns an all-null `Unknown` envelope. `Completed` remains
  solely the existing reducer result.

## Limits

This is controlled local Worker/DO and browser evidence. It uses synthetic
tests and an empty disposable local Worker snapshot; it does not access a
production secret, lifecycle record, queue, R2 object, deployment, workflow,
gate, or GitHub API.

---

### Overview (`docs/proof/csw-1089/README.md`)

# PR 1089 real-boundary publication retry proof

## Claim

A batch publication that reaches a real transport failure with no HTTP status,
HTTP 429, or HTTP 5xx is completed by the built `exact-review-batch-cli` as
`retryable_failure` / `state_contention`. The real `ExactReviewQueue` Durable
Object accepts that tuple, returns the publication item to `pending`, increments
its attempt count, schedules `next_attempt_at`, and does not create an open dead
letter.

The production policy contrast is 48 attempts / 24 hours for
`state_contention` versus 14 attempts / one hour for `unknown_failure`. This
bounded proof exercises the first real retry for both classifications. It does
not claim to have waited through the full old retry budget; see Limits.

## Exercised surface

- Built `dist/repair/exact-review-batch-cli.js` `commit` and `complete` commands
- Real localhost TLS sockets returning a connection reset, HTTP 429, and HTTP 503
- Signed Worker routes for enqueue, batch claim, and batch completion
- Real local Wrangler Worker and `ExactReviewQueue` Durable Object
- Public queue item-status and aggregate status routes

## Controlled scenario

The script builds the repair CLI and dashboard, generates a disposable
self-signed localhost certificate, and starts a bounded HTTPS listener on
`127.0.0.1`. For each transport case the actual CLI fetches a batch, posts the
canonical publication payload over a real socket, retries the reset/429/503,
and posts its completion envelope back over the socket. The listener verifies
the HMAC and captures the raw tuple; it does not replace or monkeypatch `fetch`,
timers, or CLI modules.

Separately, the script starts the real Worker and Durable Object with pinned
Wrangler 4.107.0 and disposable local persistence. It uses a synthetic local
HMAC secret to enqueue and claim a publication item, posts the CLI-captured 429
completion tuple, and reads queue status before and after. A second fresh item
repeats the same Worker/DO sequence with only the reason changed to
`unknown_failure` for an attempt-one control.

## Required observations

- Reset, 429, and 503 each produce a raw CLI completion with
  `terminal_outcome: "retryable_failure"` and
  `reason_code: "state_contention"`.
- Every CLI request crosses a real loopback socket and carries a valid HMAC.
- After the real Worker/DO accepts the `state_contention` completion, item
  status reports `state: "pending"`, `attempts: 1`, a future
  `next_attempt_at`, and no open dead letter.
- The attempt-one `unknown_failure` control is also retained for retry, as the
  old policy requires before its 14-attempt / one-hour limit.
- No request points at production, GitHub, or any non-loopback application
  endpoint. No real secret is used or retained.

## Command and environment

Run from the repository root on Node 24 or newer:

```bash
docs/proof/csw-1089/run-proof.sh
```

The script uses `npx --yes wrangler@4.107.0 dev --local --persist-to ...` on
`127.0.0.1` with the repository's normal local queue configuration. No
publication retry limit, age, delay, or clock is changed.

## Artifacts

Generated artifacts live in `docs/proof/csw-1089/artifacts/`. They include the
runtime transcript, three raw CLI completion envelopes and receipts, signed
transport request trace, Worker enqueue/claim/complete responses, queue item
status before and after both completions, final aggregate queue status, proof
summary, build logs, and a bounded redacted Wrangler log.

## Limits

Driving one item through 14 authentic claims is intentionally not automated:
the real retry delays are 1, 2, 4, then capped 5+ minute backoffs, requiring
roughly 51 minutes before attempt 14. There is no supported endpoint for
advancing the Durable Object clock or `next_attempt_at`. This proof therefore
does not show the `unknown_failure` item entering the dead-letter store at
attempt 14, nor the `state_contention` item remaining pending at that same
attempt count. It records the real attempt-one classification and queue result
for both and leaves the terminal contrast to the unchanged retry-policy code
and existing focused tests. It does not fake time, edit Durable Object storage,
stub the Worker/DO, or change a retry constant.

## Crabbox provenance

The proof in this directory was re-run unchanged against the reviewed head inside a
Docker-backed Crabbox `local-container` lease, from a clean remote checkout of the PR
(`--fresh-pr openclaw/clawsweeper#1089 --no-hydrate`) rather than from a local working tree.

| Field | Value |
| --- | --- |
| Provider | `local-container` (Crabbox CLI 0.39.0) |
| Container engine | Docker 29.4.0 (OrbStack) |
| Image | `node:24-bookworm` |
| Lease | `cbx_9797931e8d4d` (`coral-prawn`), stopped after the run |
| Reviewed head | `d54d60abf5de708713e0fbedce496cd5a21dd251` |
| Runtime | Node v24.19.0, pnpm 11.10.0 |
| Result | `exit 0`, 21 assertions, `run_status: succeeded` |
| Timings | sync 10.2 s, command 55.6 s, total 65.8 s |

Machine-readable provenance, including the captured queue observations, is in
[`artifacts/crabbox-local-container-provenance.json`](artifacts/crabbox-local-container-provenance.json).
The raw container transcript is in
[`artifacts/crabbox-local-container-stdout.log`](artifacts/crabbox-local-container-stdout.log).

The run needs no elevated privileges. Corepack is enabled into the container user's own
`~/.local/bin`, because the lease user is unprivileged and cannot write to `/usr/local/bin`.

### What this provenance does and does not add

It establishes that the proof reproduces on the exact reviewed head, in a clean containerized
environment, with no dependency on this workstation's state. It does not change what the proof
itself demonstrates; the limits recorded above and in the provenance JSON still apply, in
particular that both queue observations are at attempt 1 and the retry-budget divergence itself is
covered by unit tests and by the production dead-letter statistics quoted in the PR body rather
than by this run.

---

### Overview (`docs/proof/csw-127-phase0-5/README.md`)

# CSW-127 Phase 0.5 executed proof

The controlled runtime proof succeeded on Docker-backed Crabbox
`local-container` lease `cbx_1df4ca79b0b1` (`blue-krill-5534`) using
`mcr.microsoft.com/playwright:v1.60.0-noble`. The lease stopped automatically
after the run. It exercised source head
`3a95d75996e654d9a97294d55a3235998fc3cd43` on base
`ae36d608d01701af7e06c313be96689068b5c890`; the follow-up commit that records
this refreshed receipt changes evidence files only.

## Observed result

- All 324 focused queue, command-intake, publication, health, Bay, and egress
  telemetry tests passed.
- A real local Worker and Durable Object accepted signed v2 egress telemetry,
  deduplicated its receipt, and created exactly one attributable
  `repository_actions` circuit from a complete `public_read_fallback`
  observation.
- The pending publication could not be claimed before the raw reset or at the
  raw reset boundary. It became claimable only after its deterministic bounded
  recovery jitter.
- A `target_app` observation without an owner and an Actions observation with
  remaining quota did not create circuits.
- Reusing a receipt ID with conflicting attributable reset evidence was
  deduplicated and could not introduce or extend a circuit.
- The public queue response contained no `pool_identity`; the bounded recovery
  reason counters were present.
- The same real Worker/Durable Object state requeued one controlled cancelled
  review and rendered `1 recovering after workflow cancelled` on OpenClaw Bay;
  the redacted current-head screenshot is `bay-recovery.png`.
- Builds and scoped dashboard/script lint completed cleanly in the container.
- No GitHub workflow, queue, DLQ, gate, credential, deployment, or production
  state was touched.

The structured receipt is in `container-receipt.json`. The exact executable
fixtures are `run-proof.sh`, `run-proof.mjs`, and `github-mock.mjs`.

## Transport and formatting limits

Normal Crabbox rsync failed before execution on two local-container leases with
rsync protocol error 12. The successful run used Crabbox's supported read-only
host bind mount, copied the worktree (excluding `.git`, `node_modules`, and
`.crabbox`) into an isolated container directory, normalized only the copied
proof shell script's Windows line endings, and ran there.

The first complete behavior run passed its build, 321 tests, and Worker/DO
scenario, then the repository-wide format check rejected the Windows checkout's
CRLF representation across 682 untouched files in Linux. The final green
container run therefore used scoped lint. On the Windows checkout, build, full
lint, and every non-format static gate passed; repository-wide formatting had
the same unrelated CRLF failure. This does not limit the runtime behavior
claim.

The broad Windows coverage command was also attempted. Its unrelated
shell-oriented fixtures failed because WSL has no `/bin/bash`, while other
fixtures hit Windows temporary-directory `EPERM` cleanup failures. The seven
directly affected test files remained green on both Windows and Linux.

## Limits

- The loopback proof validates ClawSweeper's response handling and durable
  transitions; it does not prove GitHub's external scheduler or quota refill.
- It does not assign a provider-side cause to the earlier cancelled workflow
  runs because no runner step or trustworthy provider diagnostic existed.
- Phase 1 remains inactive and is not exercised by this proof.

---

### Overview (`docs/proof/csw-127-phase0-6/README.md`)

# CSW-127 Phase 0.6 proof receipt

The product-and-proof commit rebased onto merged PR #1169,
`92d91e812f810c5bf9f7e0f470cb017533aee43c`
(tree `84f9205a89d0fafdd20e9796affb7b67bd534fe2`), passed the production-shaped
boundary proof defined in [behavior-contract.md](behavior-contract.md).

## Environment

- Provider: Crabbox `local-container`, lease `cbx_b188010777d1` (`swift-krill-16ae`)
- Image: `node:24-bookworm`
- Runtime boundary: `wrangler@4.107.0 --local` plus the real SQLite-backed
  `ExactReviewQueue` Durable Object
- Result: exit `0`; lease stopped; 272,317 ms total
- Source identity: the container reconstructed the immutable `git archive` and
  asserted tree `84f9205a89d0fafdd20e9796affb7b67bd534fe2` before running proof

The proof used [run-crabbox-bind.sh](run-crabbox-bind.sh) as the local-container
entry point and [run-proof.sh](run-proof.sh) as the in-container harness. The
explicit read-only source bind was used after the normal Windows rsync transport
failed before transferring the checkout. `jq` was installed only inside the
disposable proof container because the selected Node image does not include it.

## Observed result

- All 235 focused telemetry, queue, batch-publication, and batch-CLI tests passed.
- The Worker accepted signed queue transitions and the SQLite Durable Object
  exposed independently reconciled, closed-dimension retry and refresh causes.
- The proof seeded the production caps of 50,000 rollup rows and 10,000
  rate-limit rows, then caused exactly two rollup evictions and one rate-limit
  eviction.
- The 15-minute and one-hour views remained honestly complete because their
  windows did not overlap the actual evicted evidence; the overlapping six-hour
  view remained incomplete.
- A real Worker restart preserved eviction watermarks plus retry- and
  refresh-cause reconciliation.
- A retryable batch completion followed by a successful completion for the same
  durable revision retained attempt bucket `1`, matching the direct-completion
  path rather than overstating the terminal transition as a second failure.
- Public output passed the privacy assertions. A follow-up scan of the bounded
  receipts and redacted Worker log found no token, authorization header, private
  key, database URL, API-key, or token-assignment patterns.
- Fallback `complete` and `release` paths preserved a `target_app` circuit as
  `pool_class=target_app` rather than falling back to `repository_actions`.
- The full Linux `pnpm run check` gate passed. Coverage was 81.49% lines, 74.08%
  branches, and 87.35% functions.

## Rebased contract reconciliation

The proved Phase 0.6 branch was rebased once more onto `main` at
`6494ab5eb285cc2993d4679d6723e4b2486de99c`. The combined tree preserves the
landed [R2 artifact receipt store](https://github.com/openclaw/clawsweeper/pull/1163),
the [ETag broker](https://github.com/openclaw/clawsweeper/pull/1164) and its
`broker_lookup` and `conditional_response` telemetry units, the
[webhook materialized read model](https://github.com/openclaw/clawsweeper/pull/1167),
the [restored throttled-publication retry classification](https://github.com/openclaw/clawsweeper/pull/1168),
and [PR #1169's bounded per-run operational-health confirmation](https://github.com/openclaw/clawsweeper/pull/1169).
Phase 0.6 adds independent eviction watermarks and bounded
publication-transition cause buckets; it does not duplicate or replace those
contracts. PR #1169's webhook run-confirmation, exact-recheck, unknown-health,
and phantom-run eviction semantics remain unchanged; the two changes add
separate sections to `docs/live-dashboard.md`.

The first rebased local ClawSweeper range review found one P2 observer-only
defect: terminal batch outcomes advanced the attempt bucket after an earlier
failure. The rebased fix commit `3f3793dfff6a959a36cc3767101d902d7ff6e154` aligned the batch path
with direct completion and added the retry-then-publish regression above.

The committed Codex review then found one P2 owner-isolation defect in fallback
rate-limit completions. Commit `92d91e812f810c5bf9f7e0f470cb017533aee43c`
carries the active circuit scope through both batch `complete` and `release` and
adds regressions for the `target_app` path. The complete proof above was rerun
after this fix.

Two discarded Docker leases stopped before test execution. Lease
`cbx_42cd4a3fdb12` rejected the CRLF-mounted wrapper, and lease
`cbx_35f8c4b178f6` rejected ignored-file contamination through the worktree
bind. The successful run used the harness's immutable `git archive` input and
the same expected Git tree.

Machine-readable results and artifact digests are recorded in
[container-receipt.json](container-receipt.json). Raw local artifacts are not
committed because they contain synthetic fixture detail and do not improve the
reviewable proof boundary.

## Limits

This was a local, production-shaped boundary test with synthetic fixtures. It
did not touch production, GitHub, workflows, queues, DLQs, gates, schedules,
capacity, deployments, or credentials. It does not activate Phase 1. The
owner-isolated `target_app` closure-proof 403 remains separate. The post-merge
production cohort is authorized as read-only observation; Phase 1 activation
still requires a separate explicit decision even if that cohort passes.

---

### Overview (`docs/proof/dashboard-strict-slice-1/README.md`)

# Dashboard strict slice 1 proof

## Claim

Enabling strict TypeScript checks for the allowlisted small dashboard modules
does not change the dashboard Worker's queue or status responses.

## Exercised surface

`run-proof.mjs` reuses the established real-Worker comparison in
`docs/proof/queue-policy-readmodel-extraction/run-proof.mjs`. It archives the
merge-base, starts merge-base and candidate Workers through local Wrangler,
seeds each independent SQLite-backed `ExactReviewQueue` through the signed
enqueue route, and compares normalized `/api/exact-review-queue` and
`/api/status` JSON bytes.

The wrapper requires a clean committed checkout and writes a slice-specific
summary under ignored `.artifacts/dashboard-strict-slice-1/`. Its receipt is
`COMMITTED` only when `HEAD` is a commit and tracked files are clean.

## Run

From the repository root on Node 24 or newer:

```bash
docs/proof/dashboard-strict-slice-1/run-proof.sh
```

## Expected observation

- the seeded merge-base and candidate queues both accept six items;
- normalized queue and status responses are byte-identical;
- the proof summary records the merge-base, candidate head, response hashes,
  and `COMMITTED` receipt;
- no production system is contacted or mutated.

## OpenClaw Bay and limits

OpenClaw Bay is unaffected. Its public projection is included in the normalized
status response and remains byte-identical and observer-only; this slice adds
no queue, workflow, GitHub, recovery, deploy, or rollback action.

The scenario uses synthetic pending reviews and a deterministic loopback
GitHub error stub. It does not contact GitHub, acquire review leases, publish
records, deploy a Worker, or mutate production.

---

### Overview (`docs/proof/dashboard-strict-slice-2/README.md`)

# Dashboard strict slice 2 proof

## Claim

Enabling strict TypeScript checks for the remaining 13 non-giant dashboard
modules does not change the dashboard Worker's queue or status responses.

## Exercised surface

`run-proof.mjs` reuses the established real-Worker comparison in
`docs/proof/queue-policy-readmodel-extraction/run-proof.mjs`. It archives the
merge-base, starts merge-base and candidate Workers through local Wrangler,
seeds each independent SQLite-backed `ExactReviewQueue` through the signed
enqueue route, and compares normalized `/api/exact-review-queue` and
`/api/status` JSON bytes.

The harness starts Wrangler in its own process group, terminates that complete
process tree, and waits for exit before booting the next Worker. The wrapper
also asserts that six items came back from the durable queue, proving that the
Durable Object was instantiated rather than accepting a Worker-only response.

The wrapper requires a clean committed checkout and writes a slice-specific
summary under ignored `.artifacts/dashboard-strict-slice-2/`. Its receipt is
`COMMITTED` only when `HEAD` is a commit and tracked files are clean.
Crabbox raw sync intentionally omits Git metadata, so the container command
receives both revisions from programmatic host-side Git queries and hydrates a
temporary Git object store from an uncommitted `source.bundle`. The bundle is a
transport artifact only and is removed after the run.

The container entrypoint installs Corepack and checksum-verifies the official
jq 1.8.1 static binary before placing both tools under the unprivileged user's
`$HOME/.local/bin`.

## Run

From the repository root on Node 24 or newer:

```bash
docs/proof/dashboard-strict-slice-2/run-proof.sh \
  "$(git rev-parse HEAD)" \
  "$(git merge-base HEAD origin/main)"
```

## Expected observation

- `check:dashboard-strict`, the focused ratchet test, and the full `check` gate
  pass;
- the seeded merge-base and candidate queues both accept six items through the
  SQLite-backed Durable Object;
- Wrangler's complete process group exits between the two boots;
- normalized queue and status responses are byte-identical;
- the proof summary records the merge-base, candidate head, response hashes,
  and `COMMITTED` receipt;
- no production system is contacted or mutated.

## Crabbox receipt

The proof passed at committed implementation head
`b1828132c3f36445ce75b7ea618255bb818f9422` in Docker-backed Crabbox
`provider=local-container`, image `node:24-bookworm`, lease
`cbx_09029c0c14c9` (`amber-barnacle-e0c5`). The full `pnpm run check` gate
passed 3,415 of 3,423 tests with eight skipped and no failures. The local
Wrangler comparison instantiated the SQLite-backed `ExactReviewQueue`, seeded
six items in each independent Worker, killed the complete process tree between
boots, and produced byte-identical normalized queue and status responses.

[`receipt.json`](receipt.json) binds the provider, lease, tested revisions,
toolchain, timing, response hashes, transcript hashes, secret scan, and cleanup
state. The sanitized [container transcript](container-transcript.txt) and
[stderr](container-stderr.txt) were scanned with TruffleHog 3.96.0 with zero
verified or unknown secrets. Synthetic test-only 40-character fixture IDs and
one ephemeral test-repository commit were replaced with named placeholders so
the committed [Git object cross-check](sha-cross-check.txt) contains only real
repository revisions.

## OpenClaw Bay and limits

OpenClaw Bay is unaffected. Its public projection is included in the normalized
status response and remains byte-identical and observer-only; this slice adds
no queue, workflow, GitHub, recovery, deploy, or rollback action.

The scenario uses synthetic pending reviews and a deterministic loopback
GitHub error stub. It does not contact GitHub, acquire review leases, publish
records, deploy a Worker, or mutate production.

---

### Overview (`docs/proof/dashboard-strict-telemetry/README.md`)

# Dashboard strict telemetry proof

Status: active validation recipe. Owner: dashboard types and failure telemetry.
Source: the strict configuration and checker, failure telemetry, source revision
material, and durable-storage helper. Update when those contracts change.

This bounded slice adds three roots to the existing strict ratchet. The sole
production annotation records the complete closed stage map constructed from
the same constant used by its index validator; it changes no runtime logic.

```sh
node scripts/check-dashboard-strict.mjs
node --test test/check-dashboard-strict.test.ts
node docs/proof/dashboard-strict-telemetry/run-proof.mjs 49446cd30622e642efceb80e1c0347b2602a0117
```

Node 24+ runs the actual baseline and candidate modules against separate
on-disk SQLite databases. Four stage categories, duplicate insertion, and a
new store instance exercise persistence and aggregation. The storage helper
inspects the real table, and the source boundary accepts a valid synthetic
item and rejects malformed input. Baseline and candidate results must match.
The receipt records source hashes and runtime under `.artifacts/`.

No Worker deployment or production state is touched. Bay's existing telemetry
contract and observer-only behavior remain unchanged. The queue and Worker
monoliths and the broader public-observability module remain outside this slice.

---

### Overview (`docs/proof/dead-review-telemetry/README.md`)

# Dead per-item review telemetry proof

This proof exercises the built dashboard Worker and `ExactReviewQueue` Durable Object through real
HTTP using local Wrangler persistence.

The behavior contract is:

- a persisted queue database containing `exact_review_review_telemetry` and its three indexes
  upgrades without a schema error and drops the retired objects;
- after restart, a signed run-level telemetry write with a unique `run_id` forces the Durable
  Object to initialize, and that exact row exists in the same SQLite file inspected for the
  retired schema before the proof asserts that the retired objects are gone;
- `/api/status` omits `exact_review_queue.review_telemetry_health` while `/api/health` remains OK;
- a signed run-level telemetry write appears in the four-row `/api/review-observability` lane view;
- the removed internal per-item write route returns 404;
- the documented public per-item read route returns its stable HTTP 200 envelope with an empty
  `reviews` array.

The proof first boots the Worker to create the real queue database, stops it, and seeds the retired
table plus its three indexes. The stop terminates the full Wrangler process tree and confirms the
health endpoint is down, preventing a child process from surviving as a fake restart. After restart,
the first upgrade request is the signed run-level telemetry write. Once the remaining HTTP
observations are complete, the proof stops the Worker and uses `node:sqlite` to find that unique row
in the queue database. A missing row fails explicitly with `Durable Object did not initialize`;
only a confirmed row allows the retired-schema assertion to run. This prevents a cached or
snapshot-served HTTP 200 from being mistaken for Durable Object initialization.

Run `docs/proof/dead-review-telemetry/run-proof.sh`. Set
`DEAD_REVIEW_TELEMETRY_PROOF_OUTPUT` to keep artifacts outside the repository. The proof is local
Worker/Durable Object evidence; it does not deploy or mutate production and does not validate
production traffic volume.

## Earlier Crabbox provenance

The removal-only revision of this proof ran on reviewed head
`087100c3ab9343563c42ac57243cde03ad1733a5`
inside a Docker-backed Crabbox `local-container` using Crabbox CLI 0.39.0, image
`node:24-bookworm`, Docker 29.4.0 via OrbStack, lease `cbx_7e5d92b51d8b`, and a clean
`--fresh-pr` checkout. It completed with `PROOF_RC=0`. See the
[Crabbox provenance](artifacts/crabbox-local-container-provenance.json) and
[captured stdout](artifacts/crabbox-local-container-stdout.log). Corepack is enabled into the
container user's `~/.local/bin` because the lease user is unprivileged. Current fresh-PR container
provenance belongs in the pull request's `pr-behavior-proof` section.

Earlier revisions passed on macOS and failed in the container because `stop_worker` killed only the
Wrangler parent and left the child `workerd` alive, so the restart was a no-op and the Durable Object
was never re-initialized. The proof now kills the full process tree, waits for `/api/health` to stop
answering, and asserts that the posted `run_id` is present in the inspected queue database before
asserting the retired schema.

---

### Overview (`docs/proof/deferred-request-continuation/README.md`)

# Deferred request continuation proof

An explicit `@clawsweeper re-review` on a maintainer item must still be answered
when the item changes after its review handed the verdict to a deferred
publication. The publisher then requeues the claimed decision as
`source_drift_requeue` while it still holds that publication. This proof follows
that requeue from the queue to the final GitHub effects, shows that finished,
replaced, and lease-expired requests stop before any write, and reopens state
persisted by the deployed release.

## Behavior contract

- **Claim:**
  - The queue keeps the request's verification only while the publisher still
    holds the request's newest publication and no other command reached the
    item. The decision handed to the review job then publishes and closes
    through the real apply owner.
  - A requeue after the publication finished, after the publisher lease was
    lost, after a newer request was answered, or after a newer publication was
    admitted reaches the apply owner without authority and makes no write. So
    does an older producer's requeue while a newer publication of the same
    request is held: the requeue's delivery id binds it to its own producer.
  - Rows persisted by the deployed release load unchanged and take the new
    paths after the upgrade.
- **Surfaces:**
  - The real `ExactReviewQueue` Durable Object routes `/enqueue`, `/claim`,
    `/complete`, and its alarm dispatcher, with the lifecycle projection store.
  - The real apply owner (`apply-decisions --exact-event-publication`) on the
    OWNER-authored oversized pull request fixture of
    [`test/oversized-pr-close.test.ts`](../../../test/oversized-pr-close.test.ts),
    with a recording `gh`.
- **Scenarios:**
  - [`test/exact-review-deferred-publication-fixture.ts`](../../../test/exact-review-deferred-publication-fixture.ts)
    `deferredContinuationClaim`: a verified request is reviewed, the review
    enqueues its publication, a publisher run claims it, then (per scenario)
    nothing happens, the publication completes, the clock passes the lease, a
    newer request reusing the status comment is answered (also under another
    repository casing), a newer review
    generation's publication is admitted, or a second generation of the same
    request holds its own publication when the older producer's requeue arrives
    (and then answers the request). The publisher then sends the exact
    body of `enqueue source-drift`, and the requeued item's claim returns the
    decision under test.
  - [`upgrade.mjs`](upgrade.mjs): `origin/main` persists a held command
    publication, a leased publication with a newer request queued behind it,
    an ordinary queued request, and a pending terminal finalizer to file-backed
    SQLite. Another release reopens those exact files and continues.
- **Commands:**

  ```bash
  node --test --test-name-pattern="exact-close-held" test/oversized-pr-close.test.ts
  node --test test/exact-review-source-drift-loop.test.ts
  node docs/proof/deferred-request-continuation/upgrade.mjs seed <main checkout> <fresh dir>
  node docs/proof/deferred-request-continuation/upgrade.mjs verify <release checkout> <copy of dir>
  ```

  Each checkout needs `node_modules` and `pnpm run build:all`. Environment:
  macOS, Node 24.21.0, pnpm 12.4.1, no network (GitHub calls are answered by a
  local stub with a synthetic key).
- **Observable result:** apply actions and the recorded `gh` writes; queue rows,
  claimed decisions, lifecycle dispositions, and finalizer drivers after the
  upgrade.
- **Artifacts:** [`final-effects.json`](final-effects.json) and
  [`upgrade-result.json`](upgrade-result.json).
- **Limits:**
  - Controlled proof on the real queue and apply owner, not a live GitHub run.
  - Review execution is replaced by claim and successful completion.
  - The publisher workflow step is reproduced by its request body, which
    `test/repair/exact-review-batch-workflow.test.ts` pins for both publishers.

## Final effects

| Requeue after | Apply actions | Recorded writes |
| --- | --- | --- |
| Nothing (publication still held) | `review_comment_synced`, `closed` | `POST issues/141913/comments` (durable review), `pr close 141913`, `PATCH issues/comments/150913` (close notice) |
| Publication finished | `skipped_maintainer_authored` | none |
| Publisher lease lost | `skipped_maintainer_authored` | none |
| Newer request answered (same status comment, new marker) | `skipped_maintainer_authored` | none |
| Newer request answered under another repository casing (`OpenClaw/OpenClaw`) | `skipped_maintainer_authored` | none |
| Newer publication admitted | `skipped_maintainer_authored` | none |
| Older producer's late requeue while a newer publication of the same request is held; that publication then answers | `skipped_maintainer_authored` | none |

## Upgrade from the deployed release

State seeded by `origin/main` `bc3ae1d960`, reopened by #1981's head `131383c7`
and by this branch:

| Persisted row, next step | #1981 head | This branch |
| --- | --- | --- |
| Held command publication, publisher requeues | stored as `publisher-source-drift:…`, verification dropped; claim not explicit | stored as `held-publication-requeue:publisher-source-drift:…`, verified; claim explicit |
| Leased publication refreshed with a newer request queued | queued request rewritten to `artifact_retention_recovery` with the older marker; lifecycle `requeue`; newer request not explicit | queued `re_review` unchanged and explicit; refreshed command `superseded` with a terminal finalization |
| Pending terminal finalizer, organic `edited` | successor carries the finalized marker and verification | successor carries no command; the driver keeps the marker |
| Ordinary queued request | claim explicit | claim explicit |

Every persisted row loads on both releases, and `/stats` answers 200.

---

### Overview (`docs/proof/direct-publication-reject-detail/README.md`)

# Direct publication rejection detail proof

This proof exercises the built dashboard Worker and `ExactReviewQueue` Durable Object through real
HTTP using local Wrangler persistence. It verifies the diagnosability-only response change for
invalid direct publication plans.

The behavior contract is:

- the real Durable Object initializes before any rejection claim is made;
- a deliberately invalid revision returns HTTP 400 with
  `error: "invalid_direct_publication_plan"`, `fallback_required: true`, and a non-empty `detail`
  naming the invalid revision;
- a structurally different plan whose operation targets the wrong item returns the same unchanged
  error classification with a bounded `detail` that names the violated tuple invariant without
  echoing the submitted path;
- the two validation failures produce different bounded detail values.

The script boots the Worker, drives `/api/exact-review-queue`, terminates the full Wrangler process
tree, and inspects Wrangler's persisted SQLite database for the direct-publication table. Only that
schema observation allows the proof to restart the Worker and make the signed HTTP assertions. The
restart check waits for the health endpoint to stop answering so a surviving `workerd` child cannot
turn the second boot into a false positive.

Run from the repository root on Node 24 or newer:

```bash
bash docs/proof/direct-publication-reject-detail/run-proof.sh
```

Set `DIRECT_PUBLICATION_REJECT_DETAIL_PROOF_OUTPUT` to keep generated artifacts outside the
repository. The default ignored artifact directory contains the captured HTTP responses, runtime
transcript, build/install logs, and a redacted Wrangler log.

This proof does not change or test retry/permanence policy, does not identify or fix the underlying
CodexBar rejection, and does not deploy or mutate production. OpenClaw Bay is unaffected: the
change keeps internal publication rejection fingerprints distinct without exposing submitted
values, with no Bay observer data or control surface change.

---

### Overview (`docs/proof/direct-target-dispatch/README.md`)

# Direct target-dispatch intake proof

- Status: historical proof for the change that added `/github/target-dispatch`
- Owner: ClawSweeper queue maintainers
- Source of truth: [target dispatch ingress](../../../dashboard/target-dispatch-ingress.ts),
  [OIDC verifier](../../../dashboard/github-actions-oidc.ts),
  [dispatcher workflow](../../../.github/workflows/clawsweeper-dispatch.yml), and
  [target dispatcher](../../target-dispatcher.md#direct-queue-intake)
- Baseline: `cac974b3e1da900cac3e7480b91d02a36ca60163` (`origin/main`)
- Candidate (clean, committed, with that main merged):
  `8451be295b` (rerun after the proof's recording proxy was limited to the four
  allowlisted dispatcher and relay routes; an intermediate rerun was
  `6b887421a45700da207b5a1a74786ce0635bdeb9`, and the first candidate run was
  `8c66d243208da8e99946e09535af8b9bbd4061ec`, receipt SHA-256
  `a9c7225a2b7802937e7576eea780a5b2692948ff646040dc8c752c230ce0e83d`)
- Update when: the dispatcher step, the relay job, the OIDC claim binding, or
  the queue's ingress dedupe changes

## Claim

A target dispatcher issue or PR event reaches the real exact-review queue
without any `repository_dispatch`, so no `Review event item` relay run is
created. A replay of the same dispatcher run dedupes. Any direct failure falls
back to the unchanged `repository_dispatch`, and the relay that dispatch starts
still enqueues the event.

## What runs

For each variant (baseline, then the committed candidate) the harness extracts
the source with `git archive` and runs, unmodified:

- the `Dispatch exact ClawSweeper review` step script from that variant's
  `.github/workflows/clawsweeper-dispatch.yml`, under bash with native `curl`,
  `jq`, and `gh`; the OIDC request variables are present only when the
  variant's dispatch job grants `id-token: write`, as on Actions;
- that variant's `dashboard/worker.ts` and `ExactReviewQueue` in workerd with
  SQLite (Miniflare), reached under the production hostname through
  `~/.curlrc` `connect-to` and a proof-only certificate;
- for every `repository_dispatch` the step sends, the variant's sweep.yml
  `Enqueue legacy event through the durable control plane` script, which is
  exactly what that relay run executes.

GitHub (for `gh`, over `http_unix_socket`), the GitHub App, the Worker's
GitHub egress, the hosted-target registry, and the Actions OIDC issuer with its
JWKS are local synthetic fixtures.

## Command

```bash
node docs/proof/direct-target-dispatch/run-proof.mjs origin/main <tools-dir> <fresh-output-dir>
```

`<tools-dir>` must resolve `miniflare` and `esbuild`. Optional overrides:
`PROOF_GH` (native gh, default `/opt/homebrew/bin/gh`), `PROOF_BASH` (bash 4.4
or newer for the relay's `mapfile -d`), and `PROOF_OPENSSL`.

Recorded run: macOS arm64, Node v24.21.0, Miniflare 4.20260701.0,
workerd 1.20260701.1, gh 2.101.0, curl 8.7.1, GNU bash 5.3.

## Result

| Scenario | Baseline dispatches / relay runs | Candidate direct answer | Candidate dispatches / relay runs |
| --- | --- | --- | --- |
| PR opened | 1 / 1 | 202 `queued` | 0 / 0 |
| Same dispatcher run replayed | 1 / 1 | 202 `deduped` | 0 / 0 |
| Issue opened | 1 / 1 | 202 `queued` | 0 / 0 |
| App webhook first, then dispatcher | 1 / 1 (relay: `cross_route` dedupe) | 202 `deduped`, `cross_route` | 0 / 0 |
| Forced enqueue failure (visibility probe 500) | 1 / 1 | 503 `target_visibility_unverified` | 1 / 1, relay `queued` |
| Worker unreachable | 1 / 1 | connection refused | 1 / 1, relay `queued` |
| PR to non-default base branch | 1 / 1 | 403 `target_dispatch_identity_mismatch` | 1 / 1, relay `queued` |
| Total | 7 / 7 | | 3 / 3 |

Both variants end with the same six queue items. The baseline's relay after the
App webhook only produced a `cross_route` dedupe, which is the redundancy the
direct route removes.

- Receipt: [`result.json`](result.json), SHA-256
  `2a05fe0f15cc98a6672784629457335b549e4aec59fc833b8b73c8146eff62b3`
- Harness at the candidate head: SHA-256
  `c61abb95c5ed1379fc9bc65f049f0e5828274f7ce69b1ca5b62db9a7c2bf0cf3`
- Per-file source SHA-256s for both variants are inside the receipt;
  `sweep.yml` and `exact-review-queue.ts` are identical in both.
- The same harness passed with identical outcomes at two earlier
  base/candidate pairs as main advanced:
  `65f9c3a3057621385b6c4f52640a2ce190c18c57` /
  `393e5cad76ecd743baffccd09d0c8bc77b05e2bd` (receipt SHA-256
  `cd832763f558fad3bf2b51f5515b07d84644c43d8b5cfa4b87cffac20b9be79a`) and
  `1c3eea1da162cf6cc9d2b607ac2ca3212755fa66` /
  `c4ed347928f43bd1d93f9173829f41903548edbd` (receipt SHA-256
  `990c063e9c659238c62c76f9cd4673ca8abfef59d749e5b9a2a830f2c1825d8d`).

An earlier run against the intermediate commit
`2ce92f7ad80244cd80e34d8e99c41235fa353c96` answered every direct request with
401 and fetched JWKS zero times: workerd rejects `fetch(..., { redirect: "error" })`
with a TypeError, and the verifier failed closed. That run is why the shared
verifier now uses `redirect: "manual"`.

## Limits

The GitHub API, App credential, and Actions OIDC issuer are synthetic, so real
GitHub OIDC signing and claim shapes are not exercised. The step scripts run
under local bash, not a GitHub Actions runner. Queue alarms (executor
dispatch) are disabled, and the PR acknowledgement step is not exercised.
Production relay volume drops only after each target repository adopts the
updated dispatcher; `openclaw/openclaw`'s own dispatcher is outside this
repository.

---

### Overview (`docs/proof/etag-read-broker/README.md`)

# Durable ETag read broker proof

This receipt proves the rank-4 quota-savings contract over loopback HTTP with
the production broker algorithm, Worker HMAC routes, and queue Durable Object
store. The GitHub fixture implements normal ETag semantics: matching
`If-None-Match` returns 304 with no body, while a changed representation returns
200 and a replacement ETag/body.

The assertions cover first-read population, byte-identical 304 replay with a
digest check, changed-resource replacement, independent page keys, unchanged
wire-call count, and a final-guard-style read that always revalidates. The
operator secret is rejected from the publisher-scoped data plane.

The current runner also exercises the 128 KiB store limit: a 100 KiB response
is stored over loopback HTTP, a 200 KiB response is returned intact without
transmitting the response body (one size-only store request records the skip),
and a direct 200 KiB store request returns `body_size_bound`. Historical receipts below describe their recorded revision;
new runs report the current body limit from the shared contract.

Run locally after `pnpm run build:all`:

```bash
node docs/proof/etag-read-broker/run-proof.mjs \
  --output docs/proof/etag-read-broker/behavior-report.json
```

The Docker-backed Crabbox command is recorded in `receipt.json`; its script
runs the focused behavior tests, the loopback proof, dashboard strict, and the
full repository gate on Node 24, then validates the report with static `jq`.
`container-transcript-summary.txt` retains the exact phase and result markers;
the oversized raw coverage transcript is intentionally excluded from Git.

OpenClaw Bay is unaffected. This changes internal GitHub read transport and
telemetry dimensions only; the public observer payload and its read-only/no-
action boundary do not change.

Limits: GitHub and credentials are local deterministic fixtures; the proof does
not contact production GitHub or mutate production Worker state. A 304's
zero-point accounting is GitHub's documented REST behavior and is represented
by the fixture's separate `quota_charges` count.

---

### Overview (`docs/proof/evidence-command-schema/README.md`)

# Evidence command schema proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

The generator must honor the parser's existing physical-line boundary. Multiline
commands belong verbatim in evidence detail, with a null command field, rather
than being silently flattened or rejected after a successful inference.

Send the exact evidence-item subschema from the baseline and candidate decision
schemas to the Responses API as a strict `json_schema` text format. Use a
synthetic two-line command and ask for its exact bytes in `command`, or null with
the exact command in `detail` when the schema requires one physical line. Keep
authentication and model selection in the approved private caller. Save only
the resulting synthetic evidence objects, never the response envelope or logs.

After building ClawSweeper, validate those captured outputs through the real
parser. The committed `baseline.json` and `candidate.json` are the synthetic
outputs captured from the live probe; substitute fresh captures when rerunning
generation:

```sh
node scripts/proof-evidence-command-schema.mjs docs/proof/evidence-command-schema/baseline.json docs/proof/evidence-command-schema/candidate.json /tmp/evidence-command-receipt.json
```

The baseline output must fail the parser's unchanged multiline guard. The
candidate must satisfy the current evidence schema, retain the exact command in
detail, and parse successfully. The receipt records source revision, dirty state,
schema hash, runtime and outcomes. Separate regression coverage checks all four
line separators at each position, nullable values and literal escaped newlines.

This exercises live structured generation for the changed evidence-item schema
and parsing inside a synthetic decision. It does not prove a full hosted review,
production deployment, or elimination of other content/output failures. OpenClaw
Bay continues to consume the same review contract and needs no change.

---

### Overview (`docs/proof/evidence-url-scheme-case/README.md`)

# Evidence external-URL scheme-case proof contract

## Claim

Worker evidence is stripped of every non-`github.com` `http(s)` URL before it is
published, and the result validator rejects any that survive — regardless of the
**case of the URL scheme**. Before this change, `HTTPS://host/path` matched
neither the sanitizer nor the validator, so it was published verbatim as a live
external autolink and the result still validated as `passed`.

## Exercised surface

Both shipped surfaces that share the pattern, driven against the built `dist/`:

1. **Sanitizer** — `sanitizeResultEvidence()` in `dist/repair/url-safety.js`.
   This is the pre-publication mutation applied to a worker `result.json`.
2. **Validator** — `dist/repair/review-results.js`, executed as a real CLI
   subprocess exactly as `dist/repair/run-worker.js` invokes it
   (`run-worker.ts:373`).

The two must stay in lockstep: `url-safety.ts` carries a header comment
requiring its pattern to match `evidenceHasExternalUrl` in `review-results.ts`,
because a sanitizer that emits something the validator rejects would deadlock a
worker run.

## Controlled scenario and fixture

`run-proof.mjs` builds a throwaway run directory in the OS temp dir containing a
`cluster-plan.json` and a **fully valid** `result.json` — correct `mode`,
`idempotency_key`, `target_kind`, and a `target_updated_at` that matches the
preflight item. The only thing that varies between the two cases is the scheme
case of one external URL in `actions[0].evidence`:

- control: `https://attacker.example/exfil?data=secret`
- subject: `HTTPS://attacker.example/exfil?data=secret`

Because the fixture is otherwise valid, the external-URL failure is the *only*
validator failure, so the verdict is unambiguous. `attacker.example` is a
reserved-for-documentation name; the proof contacts no network.

## Expected observation

Post-fix, both cases behave identically:

- sanitizer output is `proof: <external link>` — the host does not appear;
- validator exits `1` with exactly `["#1 evidence contains non-GitHub external URL"]`.

Pre-fix, the uppercase case reported `LEAKED` from the sanitizer and
`exit 0 / status "passed"` with `failures: []` from the validator.

A companion focused test asserts that legitimate `HTTPS://github.com/...` and
`HTTPS://GitHub.com/...` links are still preserved, so the case-insensitive
pattern does not begin discarding valid GitHub references.

## Artifact and command

Supported-environment run (Node 24, Crabbox `local-container`):

```bash
crabbox run \
  --provider local-container \
  --local-container-image node:24 \
  --no-hydrate \
  --timing-json \
  --artifact-glob '.artifacts/evidence-url-scheme-proof/**' \
  --script docs/proof/evidence-url-scheme-case/run-proof.sh
```

`run-proof.sh` installs the pinned pnpm into a user-writable prefix (the lease
runs as the unprivileged `crabbox` user, so `corepack enable` cannot symlink into
`/usr/local/bin`), builds the repair lane, runs `run-proof.mjs`, and then runs the
focused suite.

Host-only quick check:

```bash
pnpm run build:repair
node docs/proof/evidence-url-scheme-case/run-proof.mjs   # exit 0 = PASS
```

## Provenance

- provider: Crabbox `local-container` (Docker/OrbStack)
- crabbox: `0.15.0`
- image: `node:24` @ `sha256:934240a162082fd8b8a2f90cd5114446443f1eba1c5378f6687167ca405e6584`
- container node: `v24.19.0` (satisfies `engines.node >= 24`)
- lease: `cbx_9546d1539ae1` (`brisk-krill`)
- run: `run_f0123d90f1c3`
- artifact: `.crabbox/runs/run_f0123d90f1c3/run_f0123d90f1c3-artifacts.tgz`
- result: exit `0`; sanitizer REDACTED both schemes, validator REJECTED both;
  focused suite `14/14`
- privacy: the fixture uses the reserved documentation name `attacker.example`.
  The proof makes no network calls, contacts no GitHub API, and performs no
  queue, GitHub, or production mutation. No credential is present in the lease.

Focused tests:

```bash
node --test test/repair/url-safety.test.ts
```

Red/green was verified by reverting only the compiled `dist/repair/url-safety.js`
pattern to `/g` and re-running the focused tests: 3 fail pre-fix, 14/14 pass
post-fix, with no change to the pre-existing assertions.

## Limits

This proof covers the sanitizer and the validator for the `http`/`https` scheme
case only. It does not exercise a live GitHub publication, Codex worker, or
queue; the published-comment rendering claim rests on GitHub's documented
case-insensitive autolinking rather than a live post. It does not change the
allowed-host set (`github.com` only), the URL terminator character class, or any
other URL matcher in the repo — several unrelated `github.com`-specific patterns
elsewhere are deliberately untouched.

---

### Overview (`docs/proof/exact-review-completion-metadata/README.md`)

# Lost completion callback proof

The production Worker and ExactReviewQueue were exercised on AWS Crabbox with
Node 24 and local Wrangler/workerd SQLite. Only initial lease setup and state
inspection use proof seams; publication, completion, reconciliation, signatures,
and lifecycle transitions use the production paths.

The same three scenarios run before and after the fix:

| Scenario | Main at `0d07398d4fab` | Fixed branch |
| --- | --- | --- |
| Completion delivered | One fresh source-drift revision | Same |
| Completion lost, accepted receipt | Owed review deleted | One fresh source-drift revision |
| Completion lost, superseded receipt | Completes without another review | Same |

Requeue disposition leaves Bay outcome tables and its public snapshot unchanged.
A separate workflow replay executes the real failure-annotation shell: a lost
queue callback is reported as `queue_completion_failure`; a failed review remains
`codex_or_content_failure`.

## Reproduce

The immutable drivers remain in the contributor's original commit, keeping
one-off proof scaffolding out of the maintained runtime and test tree. From a
checkout with dependencies installed:

```sh
mkdir -p .artifacts/completion-proof
proof_ref=138eacf9b30ced7465be928d9d6022f5647fa7d9
proof_path=docs/proof/exact-review-completion-metadata
git fetch origin "$proof_ref"
git show "$proof_ref:$proof_path/run-proof.sh" > .artifacts/completion-proof/run.sh
git show "$proof_ref:$proof_path/annotation-proof.mjs" > .artifacts/completion-proof/annotation.mjs
COMPLETION_METADATA_PROOF_SKIP_INSTALL=1 bash .artifacts/completion-proof/run.sh
node .artifacts/completion-proof/annotation.mjs
```

The runtime driver writes `proof-summary.json` and `transcript.md` under
`.artifacts/exact-review-completion-metadata`. Run it from the baseline and
candidate checkouts separately. It uses disposable SQLite and synthetic items,
with no production credentials or state mutations.

## Limits and evidence

The proof supplies the same terminal-run payload as the GitHub reconciler;
it does not exercise GitHub's run lookup or induce a production queue outage.
Local workerd proves the storage and HTTP behavior, not Cloudflare edge
availability. The annotation replay evaluates the workflow expressions locally.

Provider, lease, image, exact revision, commands, results, and subsequent
production deployment are recorded in the [PR proof](https://github.com/openclaw/clawsweeper/pull/1251).
The regression matrix additionally covers deduplicated receipts and repeat
reconciliation, asserting that the latter does not create another revision.

---

### Overview (`docs/proof/exact-review-do-json-errors/README.md`)

# Exact-review Worker safe JSON error proof

This proof starts the actual local Wrangler Worker and its ExactReviewQueue
Durable Object, then drives the signed internal
`/internal/exact-review/publications/list` route through the real Workers
Durable Object boundary. A proof-only entry module re-exports the production
`ExactReviewQueue` with its real SQLite `storage.sql.exec` wrapped so one
marked request fails the `SELECT item_key, item_json` state read with an
stack-bearing rejection string carrying a planted GitHub token and a synthetic
internal file path. The production route code, worker forwarding, HMAC
verification, storage initialization, and every other request run unmodified.

The scenario sends three identical-shape signed requests: a baseline list
(expect 200), the marked failing request, and a recovery list (expect 200).
The script detects whether the checked-out tree contains the fix and asserts
accordingly:

- before (base tree): the Worker returns the stack-bearing rejection text in
  its JSON 500, including the synthetic internal file path.
- after (fixed tree): the Durable Object still rejects so its transaction
  remains fail closed, while the Worker returns HTTP 500 with
  `content-type: application/json` and body
  `{"error":"exact_review_queue_unavailable"}`. The planted token and internal
  path never reach the client, and the Worker records the bounded
  `exact_review_queue_request_failed` diagnostic event.

Run from the repository root of the tree under test:

```bash
crabbox run \
  --provider local-container \
  --local-container-image node:24-bookworm \
  --no-hydrate \
  --timing-json \
  --script docs/proof/exact-review-do-json-errors/run-proof.sh \
  --require-artifact '.artifacts/exact-review-do-json-errors/proof-summary.json' \
  --artifact-glob '.artifacts/exact-review-do-json-errors/**'
```

The invariant proven is the Worker-facing failure contract: a stack-bearing
Durable Object rejection becomes a fixed JSON 500 without changing the Durable
Object transaction boundary or losing the internal failure event.

---

### Overview (`docs/proof/exact-review-revision-floor/README.md`)

# Exact-review revision floor

Status: historical proof that a re-admitted exact-review item never reuses a
revision it already published. The owning code is `nextExactReviewItemRevisionSync`
and `nextExactReviewCommandRevisionSync` in `dashboard/exact-review-queue.ts`,
`ExactReviewCommandIntakeStore.allocateItemRevision`, and
`ExactReviewDirectPublicationStore.maxRevision`. The direct-receipt immutability
check, fencing, and claim protocol are unchanged.

## Claim and exercised surface

Before this change, ordinary item revisions were floored only on the
publication-head table. Direct publications never advance that table, and a
completed queue row is deleted. A re-admitted item was therefore handed the
revision it had just published directly, and the retained receipt rejected the
new review with `conflicting direct publication retry` (production:
openclaw/openclaw#97616 at revision 548, #161554 at 1, #143911 at 39-47).
Artifact-refresh recovery hard-coded revision 1, so its review fell below its
own publication head and was dropped as superseded.

After this change, every ordinary allocation comes from the durable per-item
counter and floors on the fence's retained direct receipt, the target's
lifecycle projections (lowercase and GitHub-cased key), and the publication
head. Refresh recovery uses the same allocator.

The harness bundles both checkouts into the real `ExactReviewQueue` Durable
Object in workerd with SQLite. It drives `/enqueue`, the queue's own alarm and
repository dispatch through a synthetic GitHub fixture, `/claim`, the real
HMAC-signed Worker route `/internal/exact-review/publication-results`,
`/complete`, `/publication-batches/claim` and `/publication-batches/complete`.

Scenarios, run on each build:

1. `direct_readmission`: admit, claim, publish directly, complete (the row is
   deleted), re-admit with an edit, claim, and publish a different review
   directly.
2. `mixed_case_direct_readmission`: the same for `openclaw/Peekaboo`.
3. `artifact_refresh`: a producer at revision 2 enqueues its batch publication
   and completes; the batch reports `refresh_required`; the recreated producer
   is claimed and enqueues its own publication.
4. Controls: a fresh item; an item admitted after a publication head of 12; a
   re-review command re-admitted after a direct publication.

A separate upgrade run persists SQLite written by the base build and reopens it
with the head build. The base build publishes two items directly and completes
them. Eight days later a third accept prunes the `openclaw/Peekaboo#365`
receipt, leaving only its GitHub-cased lifecycle projection. The head build
then re-admits both items.

## Command

```sh
node docs/proof/exact-review-revision-floor/run-proof.mjs <base-checkout> <head-checkout> <tools-dir> receipt.json
```

`<tools-dir>` contains `wrangler@4.107.0` installed with `--ignore-scripts`,
which provides workerd 1.20260701.1, Miniflare 4.20260701.0 and esbuild. Both
checkouts are clean detached worktrees. Bare imports resolve from the
`node_modules` of the checkout that runs the harness; the lockfile is
identical at both heads. Node v24.21.0.

| Build | Head | Clean tree |
| --- | --- | --- |
| before | `cac974b3e1da900cac3e7480b91d02a36ca60163` (origin/main) | yes |
| after | `ad1b80e4d6aec86247bf1b0437299a4bd7544612` (fix commit) | yes |

| Artifact | SHA-256 |
| --- | --- |
| `receipt.json` | `46d7991eed61e596c15180ed2cc585e3bc902e9a1340b1b72f9328e01c1a2b24` |
| `run-proof.mjs` | `f8e0607db68976b9ee4f9a1c163024afe6a18d07fc195df9e4118097654d736c` |

A second run reproduced `receipt.json` byte for byte. The receipt also records
the SHA-256 of each bundled runtime source file per build. It contains no local
paths, lease ids or secrets.

## Observed

| Scenario | Before | After |
| --- | --- | --- |
| direct re-admission | revision 1 again; second direct POST `400 conflicting direct publication retry` | revision 2; second direct POST `202 accepted`; receipts 1 and 2 published |
| mixed-case re-admission | revision 1 again; `400 conflicting direct publication retry` | revision 2; `202 accepted` |
| artifact refresh | recreated at revision 1; its publication `superseded` and deduped | recreated at revision 3; its publication queued |
| fresh item (control) | revision 1 | revision 1 |
| after publication head 12 (control) | revision 13 | revision 13 |
| command re-admission (control) | revision 2; `202 accepted` | revision 2; `202 accepted` |
| upgrade, retained receipt | base wrote revision 1 | head re-admits at 2; `202 accepted` |
| upgrade, pruned mixed-case receipt | base wrote revision 1; receipt pruned, no counter row | head re-admits at 2 from the GitHub-cased projection; `202 accepted` |

The fixture saw no unexpected GitHub request. Four batch-publisher workflow
dispatches were absorbed by the fixture.

## Limits

- The inputs, the 2030 clock and the GitHub fixture are synthetic. Hosted-target
  probes are injected as public.
- The sweep workflow, the review model and the deferred batch publisher that
  production falls back to after a rejected direct publication are not run.
- No production state, GitHub writes or inference were involved.

---

### Overview (`docs/proof/exact-review-start/README.md`)

# Exact-review launch authority proof

- Status: historical proof for the synchronous launch check
- Owner: ClawSweeper review-workflow maintainers
- Source: `.github/workflows/sweep.yml`, `scripts/control-plane-curl.sh`
- Baseline: `6500b62dfd4c4efb0e2b821c1e9c427e128febef`
- Candidate: workflow SHA-256 in [after.json](after.json)
- Update when: the generation entry point, heartbeat tuple, rejection handling, or process cleanup changes

## Claim and scenario

An exact review whose queue lease was revoked during prior setup must not start
generation. The same full tuple is checked synchronously before both ordinary
and oversized generation. Known ownership rejection is a successful no-op;
transport/service uncertainty is a failed attempt, never a false supersession.
The positive current-owner path and existing post-start termination remain intact.

## Command and environment

```sh
pnpm run build:all
node scripts/e2e/exact-review-start-authority.mjs 6500b62dfd4c4efb0e2b821c1e9c427e128febef
node scripts/e2e/exact-review-start-authority.mjs
```

Provider: local native Linux shell and loopback HTTP; Node 26.8.2, Bash, curl,
jq, `setsid`, and GNU `timeout`. No infrastructure was provisioned. The script
executes the extracted generation step and the actual retry helper, passing a
synthetic full item/lease/revision/generation/run/attempt/head tuple. Harmless
shell processes replace the expensive review command, and a local JSON fixture
replaces the oversized GitHub read. No production credentials are inherited.
Raw per-scenario shell logs and results stay under `.artifacts/exact-review-start/`.

## Observed result

[Before](before.json): both already-stale paths started the process fixture
before discovering revocation. [After](after.json): neither starts. The remaining
controls establish inactive-owner rejection, unknown-conflict failure, exhausted
503 and broken-transport failure, recovery from 503 to current ownership, malformed
tuple refusal, current-owner progress on both generation paths, revocation during
the oversized GitHub refresh before launch, and revocation
after a real process tree starts. The running fixture and descendant are reaped.
Superseded output continues to exclude the existing artifact-publication gate.

## Limits and cost

This is a real workflow-shell, HTTP, and process-boundary proof with synthetic
coordinator responses and review work. It does not run a model, hosted Actions,
the production Worker, or GitHub publication. Queue event ordering and the
publication implementation are unchanged and are not reproved here.

The patch adds one full-tuple request per generation entry (at most four HTTP
attempts under the existing retry helper). A successful request causes one
additional queue heartbeat write; it does not multiply steady-state writes
by shortening the one-minute interval. Existing finalization checks, publication
authority, and process-group cleanup are retained.

Earlier checkout/setup can still continue after supersession. Ownership can also
change between the preflight and process creation. Ordinary generation keeps its
immediate background heartbeat and subsequent one-minute polls. Oversized
generation remains synchronous: revocation after launch is caught at finalization,
not by an active stop loop. This is not immediate cancellation or a hard
wall-clock stop guarantee.

OpenClaw Bay is unaffected: the existing superseded/failure outputs are reused;
there is no observer schema, field, route, or control change.

---

### Overview (`docs/proof/extract-dashboard-pages/README.md`)

# Dashboard page renderer extraction proof

## Claim

Extracting the server-side dashboard page renderers from `dashboard/worker.ts` into
`dashboard/dashboard-pages.ts` does not change the rendered bytes for `/`, `/triage`, or
`/pr-proof-triage`.

## Exercised surface

[`run-proof.sh`](run-proof.sh) starts the real local Wrangler Worker twice: once from the exact
`origin/main` merge base in a detached temporary worktree and once from the current committed head.
It fetches all three moved page surfaces, normalizes ISO timestamps and generated 40-character
hexadecimal SHAs, and requires the normalized diff to be empty. The source-blind validator executes
the separate [`behavior contract`](behavior-contract.md) through HTTP only.

## Artifacts

- `artifacts/page-comparison.json`: base/head byte counts, raw hashes, normalized hashes, and equality
- `artifacts/normalized.diff`: the normalized page diff; this file is empty on success
- `artifacts/behavior-validation.json`: source-blind HTTP behavior report
- `artifacts/provenance.json`: local runtime and exact base/head commits
- `artifacts/base-worker.log` and `artifacts/head-worker.log`: real Wrangler startup/request traces

## Run

From the repository root on Node 24 or newer:

```bash
docs/proof/extract-dashboard-pages/run-proof.sh
```

The script prints `PROOF_RC=0` on success.

## Local observation

The committed local run compared merge base `5a964dadc8131e6e6dc33e9be3536b8141d1d107` with head
`22d7808c136a10503fc9929fd9ba5904e005542f` on macOS arm64, Node 24.19.0, pnpm 11.10.0,
and Wrangler 4.107.0. All three raw response hashes and byte counts matched before normalization;
the normalized diff was empty, the source-blind behavior contract passed, and the harness completed
with `PROOF_RC=0`.

## Crabbox container observation

The same proof passed from a clean `--fresh-pr openclaw/clawsweeper#1116 --no-hydrate`
checkout at pushed head `a00e31c5ae40e33ab8718facac74d39d198dd994` inside Docker-backed Crabbox
`provider=local-container`, image `node:24-bookworm`, lease `cbx_36172f52e311`
(`golden-crayfish-3c9c`). Corepack supplied pnpm 11.10.0, and the upstream jq 1.8.1 checksum
manifest verified `jq-linux-amd64: OK` before execution. The real Worker comparison completed with
`PROOF_RC=0` and `CONTAINER_PROOF_RC=0`; the normalized diff was empty, and Crabbox stopped the
lease automatically. The container run exercised the exact proof rather than the full suite, so the
known three-failure blob-hydration baseline was not applicable.

See the [machine-readable Crabbox provenance](artifacts/crabbox-local-container-provenance.json).

## Limits

This proves page-shell rendering and route-level HTTP behavior. It does not exercise JSON API data,
browser interaction, GitHub writes, queue or state mutation, production deployment, or `/bay-demo`.
The `/bay-demo` renderer already lives in `dashboard/bay-page.ts` and is not part of the moved
surface.

## OpenClaw Bay impact

None. The rendered output is byte-identical, and this ownership-only move changes no Bay data
contract, lifecycle projection, observer-only boundary, or controls.

---

### Overview (`docs/proof/fix-automerge-quota-fixture/README.md`)

# Automerge quota publication proof

The automerge quota fixture already observed the intended one-request fail-fast behavior, but exact-event publication misclassified the clean apply yield introduced by #1166. A GitHub 403 or 429 became two `skipped_runtime_budget` apply records (the interrupted item and continuation sentinel); `publish-event-result` did not recognize that proof and converted it into `permanent_failure/unknown_failure`.

The fix preserves the structured rate-limit metadata in the apply-yield reason and reconstructs the quota error at the exact-publication boundary. Both HTTP cases must make one authenticated GET, make no DELETE request, exit the publisher honestly, and record `retryable_failure/github_rate_limit` in the workflow outputs and durable batch result.

`run-proof.sh` obtains the commit, tree, and merge-base objects programmatically, cross-checks all three with `git cat-file`, runs the real GitHub CLI over the fixture's owned Unix-socket HTTP server, validates the generated summary with static `jq`, and runs the full repository gate.

OpenClaw Bay is unaffected because this restores an internal exact-publication failure classification; no queue, workflow, status, telemetry, dashboard, or public observer contract changes.

Limits: GitHub traffic is deterministic loopback traffic using synthetic credentials. The proof does not mutate production GitHub, Worker, queue, comment, label, close, merge, deployment, or workflow state. The receipt commit adds proof metadata only after the tested runtime commit.

---

### Overview (`docs/proof/forged-evidence-fields/README.md`)

# Forged evidence continuation fields proof

> **Historical-only after S7b.** The driver intentionally throws before execution.
> Its frozen assertions exercise the retired Markdown parser, not today's typed
> record authority. Recover the original driver and this README from pinned
> pre-cutover commit `dbb40525904c2176d192ef6e92c588853e676207` and use that
> checkout's runtime and historical baseline recipe below. Do not run these
> commands against current source or change the frozen expectations to make them pass.
>
> Current replacement coverage is the record-authority and projection coverage in
> `test/review-record.test.ts`, `test/review-comment-rendering.test.ts`, and
> `test/pr-review-quality.test.ts`, together
> with the saved S6b render/apply/decision-packet parity drivers (`s6b/proof.ts` and
> `s6b/readers.mjs` in the review-record handoff). That parity compares the saved
> corpus at the pinned pre-cutover head; it does not re-exercise this historical
> synthetic parser exploit. Saved evidence and transcripts are unchanged.

Evidence entries are stored in the durable report as a bold list heading
followed by `- repo:`, `- file:`, `- sha:`, and `- command:` continuation
items, and related people as a heading followed by `- reason:`, `- commits:`,
`- files:`, and `- attribution source:` items. The report re-parser reads
those continuation items back, last occurrence wins. Evidence detail and
owner reason prose keep their line breaks, so a detail that quoted such a
list item used to attach a file, commit, or command that was never part of
the structured decision. The prose neutralizer now escapes those continuation
fields the same way it escapes finding `body`, `late`, and `confidence`
items.

[`run-proof.mjs`](run-proof.mjs) runs the compiled decision parser, durable
report writer, report re-parser, and public comment renderer on one synthetic
pull-request decision with a single evidence entry whose detail quotes a
`- repo:`, `- file:`, `- sha:`, and `- command:` block. The baseline arm
compiles `src/clawsweeper-report-helpers.ts` from the base commit inside an
isolated copy of `src/` under the output directory (with its own
`package.json` and a link to the repository's `node_modules`), so the tracked
checkout is never modified; the candidate arm uses the current build. No
model inference, GitHub call, or credential is involved.

```sh
pnpm run build
node docs/proof/forged-evidence-fields/run-proof.mjs --out .artifacts/forged-evidence-fields
```

`--base <rev>` selects the baseline commit (default: the merge base with
`origin/main`, or `HEAD~1` once the change is on `main`); `--baseline-dist`
reuses a previously compiled baseline. The driver writes both durable reports,
both rendered comments, and `summary.json` to the output directory and exits
non-zero unless the baseline re-parses the forged file, commit, and command
and links the forged commit in the comment while the candidate re-parses the
genuine entry with no file, commit, or command and its comment carries no
forged location.

Expected result: the baseline durable report keeps the quoted items as
trusted continuation lines, so the entry re-parses with `file: src/evil.ts`,
the forged 40-character `sha`, and `command: pnpm evil`, and the public comment
links the forged commit; the candidate report stores the quoted items as
`repo&#58;`, `file&#58;`, `sha&#58;`, and `command&#58;`, the entry re-parses
with the genuine repository only, and the comment mentions no forged path,
commit, or command.

Limits: controlled compiled round trip with a synthetic decision and
presentation adapters. It does not claim a live model produced such prose, and
it does not exercise GitHub publication or label mutation. OpenClaw Bay is
unaffected: no lifecycle, queue, telemetry, or dashboard contract changes.

---

### Overview (`docs/proof/forged-rating-lists/README.md`)

# Forged rating-list labels proof

> **Historical-only after S7b.** The driver intentionally throws before execution.
> Its frozen assertions exercise the retired Markdown parser, not today's typed
> record authority. Recover the original driver and this README from pinned
> pre-cutover commit `dbb40525904c2176d192ef6e92c588853e676207` and use that
> checkout's runtime and historical baseline recipe below. Do not run these
> commands against current source or change the frozen expectations to make them pass.
>
> Current replacement coverage is the record-authority and projection coverage in
> `test/review-record.test.ts`, `test/review-comment-rendering.test.ts`, and
> `test/pr-review-quality.test.ts`, together
> with the saved S6b render/apply/decision-packet parity drivers (`s6b/proof.ts` and
> `s6b/readers.mjs` in the review-record handoff). That parity compares the saved
> corpus at the pinned pre-cutover head; it does not re-exercise this historical
> synthetic parser exploit. Saved evidence and transcripts are unchanged.

Model prose stored through `requireReportText` keeps its line breaks, and the
durable report renders the rating summary above `Next rank-up steps:`.
The report re-parser reads the first line that equals that label, so a summary
that quotes the label line used to supply the published rank-up moves.
The prose neutralizer escapes that renderer-owned list label the same way
it escapes owned section headings.

[`run-proof.mjs`](run-proof.mjs) runs the compiled decision parser, durable
report writer, report re-parser, and public comment renderer on one synthetic
pull-request decision whose rating summary quotes a `Next rank-up steps:` block
with a forged step. The baseline arm compiles `src/clawsweeper-report-helpers.ts`
from the base commit in an isolated source copy; the candidate arm uses the current
build. The tracked checkout is never rewritten, including on interruption. No model inference, GitHub call, or credential is involved.

```sh
pnpm run build
node docs/proof/forged-rating-lists/run-proof.mjs --out .artifacts/forged-rating-lists
```

`--base <rev>` selects the baseline commit (default `origin/main`; use the pre-fix revision after landing); `--baseline-dist`
reuses a previously compiled baseline. The driver writes both durable reports,
both rendered comments, and `summary.json` to the output directory and exits
non-zero unless the baseline publishes the forged items and the candidate
publishes only the genuine `Real step` entry.

Expected result: the baseline report contains two `Next rank-up steps:` lines,
re-parses `Forged step`, and its comment lists `- Forged step.` under
`Rank-up moves`; the candidate report escapes the quoted label to `&#58;`,
re-parses `Real step`, and its comment lists only `- Real step.`.

Limits: controlled compiled round trip with synthetic decisions and
presentation adapters. It does not claim a live model produced such prose, and
it does not exercise GitHub publication or label mutation. OpenClaw Bay is
unaffected: no lifecycle, queue, telemetry, or dashboard contract changes.

---

### Overview (`docs/proof/github-body-deadlines/README.md`)

# GitHub response-body deadline proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

The queue's GitHub deadline must cover response bodies as well as headers.
Successful-body timeouts must retain typed retry classification in both queue
and App-token calls. Existing HTTP/rate-limit errors and malformed JSON retain
their meanings.

The retired `proof-github-body-deadlines.mjs` driver
bundles the baseline and candidate code into workerd. It invokes the actual
terminal-run resolver and App JSON helper against a Node HTTP fixture that
flushes headers before delaying or withholding its body. Native workerd egress
is restricted to that loopback fixture. No provider or GitHub credential is used.

Run through the repository's resolved Crabbox provider with its pinned Wrangler
tooling installed outside the checkout:

```sh
npm install --prefix /tmp/clawsweeper-worker-proof-tools --no-save --no-audit --no-fund wrangler@4.107.0
node scripts/proof-github-body-deadlines.mjs a9ed9b5ba7eb12357da7cc2360d87cc5397c3c36 /tmp/clawsweeper-worker-proof-tools .artifacts/github-body-deadlines
```

The receipt records source hashes, Git revisions, dirty state, Node/workerd
versions, elapsed time, error classification, and upstream cancellation. Finite
delayed bodies reproduce the baseline defects without hanging the proof.
Candidate cases additionally cover bodies that never finish.
Deadline cases must finish within six seconds after runtime readiness, allowing
headroom around the existing 4.5-second deadline. Ordinary JSON,
malformed JSON, empty 204, 503, and rate-limit responses guard existing contracts.

This proves the Worker transport boundary; it does not establish that stalled
bodies caused a particular production backlog. OpenClaw Bay is unaffected:
existing timeout/backoff states and public data contracts remain unchanged.

---

### Overview (`docs/proof/github-egress-telemetry/README.md`)

# GitHub publication egress telemetry real-boundary proof

## Claim

Phase 0 observes the real publication `gh` transport without changing command
stdout, cleaned ordinary stderr, or exit status. A paginated invocation records
one invocation and one wire attempt per page. Credential pool, normalized
method/route, first/repeat, claim generation, response status/latency, and
sanitized 403/429 reset headers remain bounded. Unsafe classification fails
open with `telemetry_complete=false` and no raw request data.

The resulting aggregate uploads through the production HMAC serializer to a
real local Worker and SQLite-backed `ExactReviewQueue` Durable Object. Stored
rows survive a Worker restart and an identical producer receipt is deduplicated.

## Exercised surface

- The production `scripts/github-egress-observer.sh` wrapper and built observer
  parser/CLI
- A real GitHub CLI binary over loopback TLS, including three REST pagination
  pages, an opaque artifact archive download, and an HTTP 403 with
  `Retry-After` and `X-RateLimit-*` headers
- `repository_actions`, `target_app`, and `public_read_fallback` call-site
  attribution
- A real signed telemetry upload and public query through `wrangler dev --local`
- The 15-minute public detail query through the same Worker and Durable Object
- The real SQLite Durable Object storage, receipt deduplication, and restart
  persistence
- Sentinel scans across workflow JSONL and public output
- Twelve baseline and twelve observed loopback invocations for bounded observer
  overhead measurement

## Run

From a clean repository root on Node 24 or later:

```bash
docs/proof/github-egress-telemetry/run-proof.sh
```

The script uses pinned Wrangler 4.107.0 and a disposable self-signed loopback
certificate. If `gh` is unavailable, it downloads GitHub CLI 2.102.1 into the
disposable proof directory and verifies the Linux AMD64 archive against the
committed SHA-256 from the official release checksum manifest before
extraction. It uses only synthetic credentials and loopback application
endpoints. It does not call GitHub APIs, mutate production, or touch queue,
schedule, gate, deployment, or credential state.

## Required result

- 18 transport invocations conserve to 19 observed wire attempts and one
  durable member; one artifact invocation is explicitly opaque and invents no
  wire count. A separate missing-sink fixture contributes exactly one
  incomplete, unattempted invocation marker and no invented wire/member count.
- The paginated invocation accounts for exactly three page attempts.
- The authoritative 403 produces exactly one sanitized reset observation.
- Public-read fallback and target-App each retain their actual selected pool.
- The unrecognized route is incomplete but preserves command behavior.
- A missing observer parser preserves the original throttled command's stderr,
  stdout, and exit status while stripping unsafe debug frames.
- Public output withholds pool identity and all raw sentinels.
- The 15-minute view returns `window.hours=0.25` with a complete query.
- Worker restart preserves rows and replaying the same receipt is deduplicated.
- Median loopback observer overhead remains below the proof's one-second safety
  ceiling; the measured value is reported, not treated as a production latency
  forecast.

## Artifacts and limits

Generated evidence is written to `.artifacts/github-egress-telemetry-proof/`:
a machine-readable summary, the bounded public observability response,
build/install logs, and a secret-redacted Wrangler log. The generated evidence
is intentionally outside the committed proof package; exact-head provenance is
recorded in the pull request.

The GitHub responses are deterministic loopback fixtures, not live quota
consumption. Artifact downloads remain deliberately opaque because GitHub CLI
debug output can cross a binary redirect; deterministic tests cover their
incomplete invocation accounting. This is observation proof only and makes no
claim about Phase 1 admission, circuit, permit, probe, or ramp behavior.

---

### Overview (`docs/proof/graphql-activity-cursor-v2/README.md`)

# GraphQL PR activity cursor v2 proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

- Status: historical proof artifact
- Owner: ClawSweeper publication maintainers
- Tested source: `openclaw/clawsweeper@221ba1c2cd159dfbc7c2e5a5fb12dbad73467bd7`
- Update when: the v2 query, decoder, fallback, stability wrapper, or batch bound changes

## Claim and exercised surface

The controlled loopback scenario exercises the production cursor/query decoder
through `createGitHubContext`: one stable v1 check performs reviews REST, inline
review-comments REST, and GraphQL review-thread reads twice; v2 replaces those
six requests with two complete GraphQL snapshots. The batch scenario aliases
eight PRs and preserves the same two-read invariant while reducing 48 requests
to two.

Fixtures cover inline-comment edits, review dismissal, thread resolution,
force-push handling through the unchanged head guard, and activity arriving
between the two reads. A partial nested comment connection activates the full
v1 reader, preserves the v1 decision, and emits one structured
`reviewed_pr_activity_cursor_v2_fallback` line.

The migration deliberately re-baselines persisted v1 reports. GitHub GraphQL
does not expose REST's immutable `side` and `start_side` fields, so a v1/v2
comparison returns `rebaseline`; apply reports “cursor version requires a fresh
review” and never claims that target activity changed. Fresh reports persist
v2 cursors.

OpenClaw Bay is unaffected. This changes internal GitHub read transport and
cursor comparison only; it does not change Bay's observer-only status contract,
public fields, lanes, or action boundary.

## Environment and command

The proof ran through Crabbox's explicitly selected Docker-backed
`local-container` provider on Ubuntu 26.04/arm64 with Node 24.19.0 and pnpm
11.10.0. The successful one-shot lease was `cbx_d96385e7eb89` and was stopped
automatically.

```bash
proof_source_head="$(git rev-parse HEAD)"
proof_source_tree="$(git rev-parse 'HEAD^{tree}')"
git cat-file -e "${proof_source_head}^{commit}"
git cat-file -e "${proof_source_tree}^{tree}"
PROOF_SOURCE_HEAD="$proof_source_head" PROOF_SOURCE_TREE="$proof_source_tree" \
  /Users/steipete/Projects/crabbox/bin/crabbox run \
  --provider local-container --no-hydrate \
  --allow-env PROOF_SOURCE_HEAD,PROOF_SOURCE_TREE \
  --preflight --timing-json --shell -- \
  "bash scripts/e2e/run-graphql-activity-cursor-v2-container.sh"
```

Local-container Actions hydration could not execute the repository's
`pnpm/action-setup` step, so the checked-in wrapper follows Crabbox's documented
`--no-hydrate` recovery: it installs a checksummed Node 24.19.0 tarball in the
ephemeral container, enables the repository-pinned Corepack/pnpm version,
builds all TypeScript targets, and runs the loopback scenario.

## Static verification recipe

Run from the repository root. The final command proves the tested source is
followed only by this proof directory, avoiding a self-referential commit hash
inside its own receipt.

```bash
receipt="docs/proof/graphql-activity-cursor-v2/receipt.json"
jq -e '
  .schema_version == 1 and
  .crabbox.provider == "local-container" and
  .crabbox.runtime == "docker" and
  .crabbox.exit_code == 0 and
  .crabbox.run_status == "succeeded" and
  .crabbox.lease_stopped == true and
  .requests.single == {"v1": 6, "v2": 2} and
  .requests.batch == {"size": 8, "v1": 48, "v2": 2} and
  .assertions.single_request_reduction == true and
  .assertions.batch_request_reduction == true and
  .assertions.fallback_decision_unchanged == true and
  .assertions.fallback_telemetry_lines == 1 and
  .assertions.concurrent_change_unstable == true and
  .assertions.double_read_preserved == true
' "$receipt"
tested_head="$(jq -r '.source.head' "$receipt")"
tested_tree="$(jq -r '.source.tree' "$receipt")"
git cat-file -e "${tested_head}^{commit}"
git cat-file -e "${tested_tree}^{tree}"
test "$(git rev-parse "${tested_head}^{tree}")" = "$tested_tree"
test -z "$(git diff --name-only "$tested_head"..HEAD -- . \
  ':(exclude)docs/proof/graphql-activity-cursor-v2/**')"
```

The receipt does not claim live GitHub mutation coverage. It proves request
shape, bounded decoding, fallback, migration behavior, and race detection; the
repository's full check supplies static, unit, integration, and coverage gates.

---

### Overview (`docs/proof/head-mismatch-supersede/README.md`)

# Head-mismatch dead-letter supersession proof

Production reconcile run `31648987909` at `2026-08-12T22:56:00Z`, the first run with the skip taxonomy from [openclaw/clawsweeper#1147](https://github.com/openclaw/clawsweeper/pull/1147), inspected 125 skipped targets and reported `head_mismatch: 121`, `blocked_alias: 3`, and `active_work: 1`, with zero recoveries. The open DLQ tail held 191 rows: 158 `retry_exhausted`, 31 `tuple_protocol_invalid`, and two `workflow_cancelled`. Samples such as [openclaw/acpx#485](https://github.com/openclaw/acpx/pull/485) and [openclaw/crabpot#245](https://github.com/openclaw/crabpot/pull/245) showed the endgame: immutable publication artifacts for old pull-request heads must never be replayed as current work.

The existing HMAC-authenticated canonical record route is the authority needed to distinguish genuinely superseded work from unexplained drift: `GET /internal/state/records/<repo-slug>/items/<number>`. Its Durable Object envelope contains the canonical content, digest, monotonic revision, and update time. The report content binds `repository`, `number`, `type`, `review_status`, and `pull_head_sha`. A complete same-target report at the live GitHub head proves that a stale dead-letter artifact for another head has been replaced by a durable completed review/publication. No new endpoint is needed.

The authenticated lifecycle audit inventory is useful corroboration—it exposes completed and superseded lanes plus canonical receipt outcomes—but intentionally omits source heads, so it cannot independently prove newer-head supersession. Public queue lane totals are aggregate-only for the same reason.

The bounded stage checks at most ten head-mismatched targets per cycle and resolves at most 20 supported rows per proven target. After reading canonical evidence, it immediately rechecks GitHub and requires the same open node identity and head before mutation. Drift leaves the row open as `head_mismatch_revalidation_changed`. A successful path writes a note with the full newer head and canonical path, sends the Worker a guarded `resolution_outcome: superseded`, and increments publication completed/superseded metrics. Missing, invalid, incomplete, wrong-target, failed, or wrong-head records leave rows open as `head_mismatch_unproven`. `tuple_protocol_invalid` and `workflow_cancelled` rows never enter this resolution path. Dry-run reports the planned counts but performs no mutation.

The executable contract is in [`behavior-contract.md`](behavior-contract.md), RED/GREEN evidence is in [`red-green.md`](red-green.md), and [`run-proof.sh`](run-proof.sh) is the Docker-backed Crabbox launcher. [`behavior-report.json`](behavior-report.json) records the source-blind contract result. [`receipt.json`](receipt.json) binds committed implementation head `10b45760a0c0fe1adf156909e2df0d737d5fef6a`, `provider=local-container`, lease `cbx_a7a8d9e75f26` (`brisk-shrimp-3201`), Docker image `node:24-bookworm`, all 224 focused scenarios passing (including the mutation-time B→C race), the full `pnpm run check` gate, clean pre-commit Codex autoreview, content hashes, captured transcripts, a zero-finding secret scan, and automatic lease cleanup.

OpenClaw Bay needs no change because the behavior is queue-owned and observer-only: existing metrics and skip maps reflect it, while Bay gains no action surface.

---

### Overview (`docs/proof/health-phantom-queued-run/README.md`)

# Phantom queued-run health proof

Production `/api/status` probes on 2026-08-14 reported one queued run aging
monotonically from 54 to 61 minutes even though live Actions inventories across
the nine involved repositories contained no queued, waiting, or pending run
older than 30 minutes. The symptom began after
[openclaw/clawsweeper#1167](https://github.com/openclaw/clawsweeper/pull/1167)
moved dashboard workflow health onto the webhook read model.

The complete-census gate itself was present: a workflow snapshot is usable only
after a successful run census and an observed `workflow_run` delivery. The gap
was below that repository-wide envelope. A queued row preserved because it
arrived after a census began had no per-row confirmation age in the consumer
response. A later fresh census timestamp therefore made the whole snapshot
usable while `statusSnapshot()` counted that unconfirmed queued row directly.
Repair upserts also ignored an equal `updated_at`, so a live poll that confirmed
an unchanged genuinely queued run could not refresh its row age.

Workflow reads now expose each run's last delivery-or-poll confirmation. Before
an expired row can contribute to `queued_over_threshold`, the Worker rechecks
at most the ten oldest stale rows per refresh. Ten is two waves at the existing
five-way concurrency, bounded below the 20-second refresh cadence even when
each exact request reaches its 4.5-second timeout. Omitted unconfirmed rows are
excluded from queue pressure and make health `unknown`; successive refreshes
continue through the backlog. Structured batch telemetry records the selected
and omitted counts. Live active state refreshes the row. Completed or missing
state removes the run and its dependent job snapshot behind a
verification-start boundary, then emits
`github_read_model_workflow_run_evicted`. A failed exact read removes the
unconfirmed row from the calculation and makes telemetry `unknown`. Repair-only
snapshots without observed subscription coverage still use the pre-#1167 live
status polls. Rows older than the existing 24-hour zombie boundary stay in the
separate zombie metrics and do not spend exact verification requests.

The executable contract is in [behavior-contract.md](behavior-contract.md), the
captured RED/GREEN result is in [red-green.md](red-green.md), and
[run-proof.sh](run-proof.sh) runs the focused loopback fixture, dashboard-strict,
the complete repository gate, static JSON validation, and committed-object
cross-checks in Docker-backed Crabbox. [behavior-report.json](behavior-report.json)
records the source-blind result. The final container receipt and compact
transcripts are recorded beside these files after the isolated run.

[worker-loopback-report.json](worker-loopback-report.json) is the real-boundary
trace requested in the first ClawSweeper review. It starts `wrangler dev
--local`, uses the real SQLite Durable Object plus signed webhook/repair HTTP
routes, waits through the five-minute production TTL, and serves exact completed
and 404 responses from a separate loopback GitHub HTTP server. Its round-3
scenario seeds 205 additional stale rows, proves a maximum of ten exact reads
per refresh with oldest-first selection and unknown health for omissions, then
drains the backlog across successive refreshes. The resulting
`/api/status` response was healthy, all 207 non-zombie candidates were absent
afterward, and the Worker emitted both original eviction telemetry verdicts.
The trace also seeds a 25-hour zombie, proves that no exact request is spent on
it, and leaves only that separately observable zombie row in the read model.

OpenClaw Bay is unaffected. The change repairs the dashboard's internal
observer read path and adds no public field or queue, workflow, GitHub, DLQ,
recovery, deploy, or rollback action.

---

### Overview (`docs/proof/hidden-payload-security/README.md`)

# Hidden payload security proof

Status: historical proof for the hidden-payload security guard. Owner: ClawSweeper maintainers. Runtime owners: `src/repair/security-signals.ts`, `src/clawsweeper-item-context.ts`, `src/clawsweeper-review-item.ts`, and `src/clawsweeper-apply-close-execution.ts`. Re-run when these boundaries change.

The claim is that an issue with a harmless feature request and a comment containing concealed shell content receives a deterministic security review and cannot be automatically closed, even if the model proposes an implemented-on-main close. The fixture uses only documentation IP `203.0.113.7` and a fake collector ID; its shell text is never executed.

Run from the repository root on Node 24 or newer:

```sh
pnpm run build
node docs/proof/hidden-payload-security/run-proof.mjs
```

The driver starts a loopback HTTP fixture that rejects GitHub mutations. Production GitHub context hydration reads that fixture through the CLI transport boundary. Production review preparation builds the actual prompt and consumes a deliberately payload-blind, fixed model result. The production report writer and public comment renderer preserve the resulting security review. The real `apply-decisions` CLI runs against isolated `items/` and `closed/` directories with `--skip-dashboard --item-number 1054 --dry-run`. It checks both a close proposal containing the security review and a legacy proposal without that review; both must remain open with a security moderation reason.

Artifacts are written to `.artifacts/hidden-payload/proof/`: `summary.json`, the prepared prompt, each report and public comment, apply output, and the HTTP request trace. The summary records the current head and local Node/platform provider. This is a local process proof on macOS, not a Windows/container lease. It does not contact GitHub, execute the payload, validate model judgment, or test a production deployment. The fixed model result isolates the host-owned guarantee from model variance. No credentials are supplied to the fixture.

Historical diagnosis: the September 1 review code at `04ab85792ab56e8ae51459f3d959bd085f26bdf3` retained comment bodies through `src/clawsweeper-item-context.ts:214` and `src/clawsweeper-context-hydration.ts:205`. The small campaign comment fit within its 6,000-character limit. Both profiles used that path. `prompts/review-item.md:470` defaulted non-PR security review to not applicable absent a security-sensitive report, while `src/repair/security-signals.ts:82` recognized only existing security markers and advisory IDs. `src/clawsweeper-close-decision.ts:291` checked protected labels, then high-confidence close evidence, without a general unresolved-security veto. The model recognized the ClawHub payload but missed the gogcli payload; no deterministic owner corrected that omission. `issue-source-guard.ts` hashed raw body/comment content for freshness; it did not classify it.

The source records are the durable review comments on [gogcli issue 1054](https://github.com/openclaw/gogcli/issues/1054#issuecomment-5493708494) and [ClawHub issue 3569](https://github.com/openclaw/clawhub/issues/3569#issuecomment-5493714348). Their raw collector text is intentionally absent from this proof.

---

### Overview (`docs/proof/historical-proof-classification/README.md`)

# Historical proof classification

> **Historical-only.** The obsolete driver was removed with the post-review
> proof stack. Recover the original driver and README from pinned pre-cutover
> commit `dbb40525904c2176d192ef6e92c588853e676207` to inspect that implementation.
> Saved evidence is unchanged. Current readers ignore historical attachments;
> they no longer fold receipts, render recordings, or derive blockers from them.
>
> Current record authority and proof projections are covered by
> `test/review-record.test.ts`, `test/review-comment-rendering.test.ts`, and
> `test/pr-review-quality.test.ts`.
> The saved S6b `proof.ts` and `readers.mjs` handoff drivers cover saved-corpus
> render/apply/packet parity, not every synthetic legacy receipt case in this
> recipe. Missing records now require fresh review rather than prose recovery.

- Status: historical repair proof recipe; not an execution runbook
- Owner: ClawSweeper review and publication maintainers
- Baseline: `f72ea010c1d7fd134b1bd0826b3a707778c312bc`
- Contract at the time: [Live proof](https://github.com/openclaw/clawsweeper/blob/f6ad0bf56/docs/live-proof.md#retired-post-review-proof).

The observations below describe the historical classification repair, not the
current runtime. There is no runnable receipt-republication recipe in this
checkout. Current attachment-ignore regression coverage is in
`test/live-proof-report.test.ts`.

## Input provenance and boundary

[The receipt](help-only-receipt.json) originated in a real PTY capture of a
synthetic help-only package on 2026-08-28. Its only behavior was printing
`Usage: openclaw [options] [command]`. No Gateway implementation existed in that
fixture. The captured output and assertion results are preserved, including
the historically reported pnpm version; that version is not a setup instruction.
Only repository, item, and head identity metadata were normalized to
`openclaw/clawsweeper`, `42`, and forty `a` characters. The original plan digest
and capture timestamp are retained.

[The sample report](help-only-report.md) is deliberately synthetic. Its claim
concerns authorization while its ordinary proof assessment is missing. Its
dummy PR binding is never looked up. The recipe also constructs failed and
malformed controls and independent reviewer assessments; these are explicitly
fixture data, not claimed fresh executions or newly verified owner traces.

The historical path used the now-retired post-review artifact publication and
attachment modules followed by comment rendering and automation projections.
That execution and compatibility contract has expired.

## Before and after

[The compact observations](observations.json) record the same original receipt
replayed before and after the repair. Both publications attached successfully;
the erroneous `Verified` and sufficient-label results changed from true to
false. All 22 maintained recipe cases passed locally. The observations record
the tested production diff and recipe hashes; rerun after changing either.

On the baseline, replaying the original captured receipt through the actual
publication CLI returned `published` / `attached`, marked real behavior
`Verified`, and proposed `proof: sufficient` despite the missing authorization
assessment. The intended rejection assertion failed. The fresh terminal
attempts on that baseline instead failed cleanup and produced no receipt;
they are a separate driver issue and are not evidence for this repair.

At that revision, the recipe expected successful attachment publication while
preserving the independent proof assessment, patch rating and authority-chain
requirements. Current readers instead ignore those attachments entirely.

The residual guidance/PASS-scope follow-up extends the recipe to 27 cases. Five
synthetic cases cover an `ExecHostExecutor.swift` coverage gap with unrelated help,
relevant changed-help evidence, substantive native terminal observations, and
independent signed-native linked-artifact/recording attribution. Native scenarios
distinguish successful normal write-half-close from explicit caller-abort
cancellation, PID teardown, and delayed-sentinel absence. These are constructed
classification inputs, not native runs or evidence that the prompt produced the
right assessment. Every attached case also checks that only the Live Proof
section changes, a second production CLI publication leaves the report identical,
and only PASS renders the scenario-scope disclaimer. The original 22 cases and
their core-fix observations above remain intact; current main already passes
them before this wording follow-up.

Limits: this is local publication/runtime evidence, not a live GitHub, R2,
Gateway, native, queue, or terminal-driver test. It does not judge whether a reviewer's
semantic assessment is correct. Bay needs no change: no observer API, lifecycle,
telemetry, timing, or action contract changes, and its retired-path display
switch remains presentation-only.

---

### Overview (`docs/proof/hosted-terminal-query-race/README.md`)

# Hosted terminal query race

This historical proof covered a tmux query race in the old post-review terminal
proof controller. That controller and its cleanup helper are now retired.
The standalone driver has been removed; this page is not a current runbook.

The historical claim was that an empty successful tmux query could be accepted
only after fresh matching DONE receipts and server/socket quiescence proved
controller teardown. Live servers and altered receipts still failed without an
extra kill command.

Current hosted review security regressions exercise the retained review-tree
admission owner and credential-free child in `scripts/hosted-review-scan-smoke.mjs`,
not the removed post-review terminal controller.

---

### Overview (`docs/proof/hydration-cache-cleanup/README.md`)

# Persistent hydration cache retirement

Run `node docs/proof/hydration-cache-cleanup/run-proof.mjs` in the prepared
Linux Crabbox workspace with `wrangler` available. This local-only fixture
starts the actual `ExactReviewQueue` from baseline
`8cf2991cefeee11414e011cdb5aa51f70c151f14`, then the candidate, then the baseline
again against the same named Durable Object and persisted Workerd SQLite.
The baseline Git object must be present; the runner never fabricates Git HEAD.

The proof seeds ordinary and chunked cached reports, durable publication and
tuple receipts, a queue item, and lifecycle state. It checks a failed atomic
checkpoint, restart and automatic alarm completion, exact removed UTF-8 bytes,
independently normalized exports, fresh delta and snapshot revisions, immutable
old snapshot bytes, original receipt replay, stale expected-digest rejection,
and rollback readability. It reports native SQLite rows read and written per
large-record alarm. Outbound requests fail locally. The fixture deletes its
own temporary state and stops only its recorded child process group.

This proves local Workerd behavior. It does not mutate Cloudflare, measure the
production cache fraction, or promise immediate physical database shrinkage.

---

### Overview (`docs/proof/hydration-watermarks/README.md`)

# Per-PR hydration watermark proof

Historical proof for the retired persistent hydration cache. Its scripts target
the recorded implementation head; current reviews fetch fresh inputs.

The signed Crabbox receipt proves the review-side hydration snapshot and activity-revision validation
at the implementation head recorded in its command, using Docker-backed Crabbox `local-container`.

The deterministic counting fixture models three unchanged and two changed PRs. Legacy hydration is
`2 * P = 10` commit/review-comment list reads. The candidate makes four GraphQL requests total: one
batched planning request for the five PRs plus one hydration-time revision check for each of the three
cache-hit candidates. Those unchanged PRs make zero list reads; an edited-comment PR makes one
`since` review-comment read and a changed-head PR makes two full reads: 7 total requests. Changed
hydration windows and complete inputs compare byte-for-byte with fresh full hydration. A
delete-plus-add fixture proves an invisible deletion causes merged ID cardinality to exceed the live
count and falls back to a full read.

The planner validation, hydration-time revalidation, and same coordinator passed through the real GitHub CLI transport against public
`openclaw/clawsweeper` PR #97. The endpoint returned its known edited review comment from a historical
`since` query. The planner made one GraphQL request; three snapshot reuses each made one just-in-time
GraphQL revision check and no list call; a
synthetic activity-revision change with unchanged parent metadata made one live
`since` request; a synthetic changed head made one live commit-list and one live review-comment-list
request. The proof is read-only.

Before implementation, a controlled probe on PR #1153 established the field contract: ADD introduced
a review, thread, comment ID, and comment timestamp; EDIT advanced the comment timestamp without
moving the parent PR timestamp; DELETE removed the review/thread/comment tuple while the parent PR
timestamp remained unchanged. The probe comment was deleted and its endpoint returned 404. The
revision therefore hashes all bounded thread/comment IDs and comment timestamps plus thread, comment,
and review counts. The hydration coordinator rechecks that same revision immediately before consuming
a candidate snapshot. A mismatch or any check error fails closed to normal hydration, so an edit in
the planning-to-hydration window cannot serve stale input.

ClawSweeper's first review identified that the initial snapshot retained whole REST objects. The
repaired snapshot now accepts only an exact minimized schema: commit SHA/login/message/author name
and the review-comment fields consumed by filtering, prompt compaction, related-link discovery,
content revision, and the activity cursor. A regression injects unrelated API metadata and proves it
never appears in serialized canonical state. Full comment bodies remain because they are required to
reconstruct byte-identical public review inputs.

The second review found that the persistence-only snapshot was attached to `ItemContext` and would
therefore enter Codex prompt JSON and media URL discovery. The repaired serializers explicitly omit
the snapshot while retaining the compact commit/review-comment windows. Focused sentinels prove a
compact review comment remains visible and the full cached comment is absent from both boundaries.

The final review found that the independent 1 MiB snapshot cap could still push a valid review over
the canonical publication boundary. The repaired report renderer now measures the complete serialized
UTF-8 record against the publication owner's shared 2 MiB constant. If the record is too large, it
replaces only the snapshot front-matter value with `unknown`; the review body remains byte-identical
and the next cycle rehydrates from GitHub. The boundary regression covers both this oversized fallback
and normal-size snapshot retention.

The full `pnpm run check` gate passed 3,419 tests: 3,411 passed, 8 skipped, and 0 failed. The focused
planner/coordinator/context/workflow proof passed 156 of 156 tests. The normalized transcript and stderr were
scanned with TruffleHog 3.96.0: 0 verified and 0 unknown secrets.

The canonical Worker report owns the cache metadata; the Git `clawsweeper-state` branch receives no
new file. OpenClaw Bay is unaffected because the publication limit and observer-facing record schema
are unchanged. The final container proof is read-only; the earlier field-choice experiment's temporary
GitHub comment was deleted. No Worker, lifecycle, or dashboard state was mutated.

---

### Overview (`docs/proof/issue-fixedsha-batch/README.md`)

# Fixed-SHA issue enrichment proof

This receipt proves the review-side fixed-SHA resolver at implementation head
`66cb6daba4b3a55d27c86f99abe9351b5c1ea361` in a Docker-backed Crabbox
`local-container` lease.

The counted fixture follows the real review path. Four repeated issue/fixed-SHA pairs carry their
existing high-confidence `fixed_pr_*` state from a prior canonical report. Three pairs are cold: one
matches a recent pull's unique merge SHA, one uses the exact lookup for a shared head SHA, and one is
absent from the recent list and falls back to the per-SHA commit-pulls endpoint. The legacy formula is
`R + C = 4 + 3 = 7` `commit_pulls` requests. The candidate makes one recent-pulls request, two bounded
fallbacks, and zero requests for repeats: `1 + (C - C_merge) = 1 + (3 - 1) = 3` counted requests.

The same request formula also passed through the real GitHub CLI transport against public
`openclaw/clawsweeper` PR #1138 and issue #1135. Four prior-report repeats made no `gh` call, the
real merge SHA used one recent-pulls list, and the real head and interior commit SHAs used two exact
commit-pulls fallbacks; all three resolved PR #1138. The run was read-only.

The full `pnpm run check` gate passed 3,408 tests: 3,400 passed, 8 skipped, and 0 failed. The focused
resolver/policy proof passed 34 of 34 tests. The transcript and stderr were scanned with TruffleHog
3.96.0: 0 verified and 0 unknown secrets.

The first proof attempt reached the full gate but the base `node:24-bookworm` image lacked `jq`, so
36 existing shell-workflow tests failed with `jq: command not found`. The proof harness now installs
that repository test prerequisite. ClawSweeper's first review then found that head SHAs can be shared
by multiple PRs. The repaired resolver now treats an exact `merge_commit_sha` match as authoritative,
because that merge commit belongs to one PR, even when another recent or older PR shares the SHA as
its head. Head-only and absent matches still use the legacy exact endpoint. The refreshed
successful final live-transport run used lease `cbx_06ffbac51895`; Crabbox stopped it automatically. Two
credential/rate-limit attempts stopped before tests, their captures were discarded, and the frozen
harness reran unchanged after quota reset. One unrelated
pre-existing exited local-container lease was left untouched.

This is controlled fixture evidence. It does not mutate GitHub, publish canonical Worker records,
write the operational state repository, deploy, or exercise OpenClaw Bay.

---

### Overview (`docs/proof/keyless-target-dispatcher/README.md`)

# Keyless target dispatcher behavior proof

- Status: historical local proof
- Owner: ClawSweeper maintainers
- Source of truth: the named Worker, queue, workflow, and executable fixtures
- Update when: intake claims, routing, acknowledgements, or the fixtures change

## Contract and environment

Claim: a keyless target workflow can submit a command locator through OIDC;
the Worker derives command authority from live GitHub data, shares the App
webhook handler, and coalesces review commands across both routes before the
queue acknowledges and admits one verified item.

Provider: local Node Worker harness on macOS; Node v26.12.0, pnpm 12.4.1.
No remote lease or container image was used. This is not the Windows host.
The repository's existing harness runs the actual Worker request handler,
ExactReviewQueue, alarm, and SQLite store. HTTP GitHub responses come from a
loopback server; RS256 test keys are generated in memory, and GitHub's JWKS
fetch returns the local test public key. No live GitHub credentials or network
writes are used. Hosted eligibility is a controlled harness predicate; the
Worker's visibility probe reads the stub GitHub repository API.
The non-review addendum runs the compiled production comment router and its
runner in isolated temporary state, using a loopback-only `gh` transport shim.
The shim translates the router's reads and label/comment operations into the
stub API; authorization, classification, execution, and ledger decisions remain
in the actual router.

Base HEAD: `ea6d72efc0a2e2c0683ad984b060b5c22008ce57` (the source hashes below bind the uncommitted candidate).

## Reproduction

With Node >=24 and the pinned package manager on PATH:

```sh
pnpm install
pnpm run build:node
node --test test/dashboard-target-dispatch-ingress.test.ts test/dashboard-worker-command-intake.test.ts test/target-dispatcher-workflow.test.ts
```

For the individual end-to-end proof:

```sh
node --test --test-name-pattern='keyless OIDC' test/dashboard-worker-command-intake.test.ts
```

## Observed result

The focused run passed 24 tests, with zero failures, cancellations, or skips.
The executable shell fixture submits item and comment payloads to a loopback
HTTP intake; 401, 503, redirects, failed token acquisition, missing OIDC, and
connection refusal all warn and exit zero without any `gh` dispatch.
The old committed template fails the new keyless assertion: it contains both
`secrets.` references and `create-github-app-token` steps.

The Worker proof rejected a wrong repository, workflow filename, branch ref,
event name, item binding, and payload-provided association/body/author. It
read the live comment before admitting a review, performed no optimistic ack,
and coalesced the matching App delivery. The queue alarm verified the comment
and PR head, admitted one item, and wrote one status comment and one eyes reaction.
It also coalesced an App-first edited command with the same timestamp and a
changed body digest. The non-review command reused the existing acknowledgement
and router path; an ordinary or unauthorized live comment did not dispatch.
A simulated acknowledgement 403 still dispatched the router without a status ID.

The hosted review identified that capturing a non-review dispatch alone did not
prove authorization at asynchronous execution. The added proof takes the actual
OIDC-produced `@clawsweeper stop` payload into the production router. A non-author
COLLABORATOR with live `write` permission removes `clawsweeper:automerge` and
`clawsweeper:autofix`, then adds `clawsweeper:human-review`. Delivering the matching
App webhook and running its router payload again produces no further label
writes. For a new comment version admitted while the collaborator is authorized,
the fixture revokes permission to `read` before starting the router. Both delayed
delivery and retry perform a fresh permission read, classify the command as
`ignored`, and leave the repair labels unchanged. This closes the requested
authorization-chain evidence gap without changing authorization policy.

Normalized output:

```json
{"proof":"keyless-comment-intake","oidc":"locally signed RS256 + test JWKS","liveCommentReads":16,"crossRouteDeduped":true,"verifiedQueueItem":"openclaw/openclaw#42","reviewAcknowledgements":1,"reviewReactions":1,"authority":"live GitHub comment","schemaChanges":false,"routerAllowedStop":"labels removed and human-review added","routerAllowedReplay":"coalesced","routerRevokedNonAuthor":"delayed delivery and retry ignored; zero label writes"}
```

Full local output: `.artifacts/keyless-target-dispatcher/focused-addendum.log` (ignored).
The source fixture and normalized output above are the portable evidence.

## Limits

This proves the actual local Worker/queue paths, not GitHub's token minting,
Cloudflare deployment, production subscriptions, or the 83 installed target
copies. External GitHub APIs, the CLI transport, and JWKS are controlled fixtures.
Non-review cross-route dedupe remains owned by the existing router ledger and is
exercised through the actual local router. This does not run GitHub Actions or
prove a permission change during one already-running router process; the
revocation scenario covers the Worker-to-router delay and separate retry jobs.
No workflow, target repository, live queue, or deployment was changed.

## Source hashes

- `dashboard/worker.ts`: `8f28543323b4e0815cff071917f73602ca8b119432c92f56ee4b739a4dbc8008`
- `dashboard/target-dispatch-ingress.ts`: `99fa8bd1181d56da81fa082a07a674a446688dd1ebfbe580b97dc4a51d338e2f`
- `.github/workflows/clawsweeper-dispatch.yml`: `dced71b9a5c0ce39933b7f35c348e30d17f299d321075bb39fba50f3883f2318`
- `test/dashboard-worker-command-intake.test.ts`: `b7303347f8c4484b7051bcb936d0bab5a9bb3b3860f712d4e1b4899981f10c11`
- `test/helpers/keyless-comment-router.ts`: `2211eccf648edf94e4391378cf5cc05daf36fb28e73f10c0a283d164a61c274a`

---

### Overview (`docs/proof/label-sync-identity-determinism/README.md`)

# Canonical label-sync recording proof

The effective addition/removal values produce the same recorded `issue_labels_sync`
identity across queue order and runner locale. Both lists use the existing
`compareCodeUnits`; normalized-key deduplication and last-operation-wins behavior
remain unchanged.

The executable connects the real batch producer to the real apply-ledger recorder,
reads persisted attempt/outcome events, and checks their business keys. Separate
Node children verify resolved en-US/sv-SE locales, reversed/sorted/rotated queues,
collator ties on both lists, exact values and arguments, duplicates, changed sets,
and distinct receipts for repeated synthetic adapter invocations. Children receive
fresh temporary home/config/cache/state directories and no inherited credentials,
workflow context, projection settings or runtime injection variables. Fixed
synthetic producer metadata enables local receipts inside each child; owned
canonical temporary roots are removed in `finally` after readback.

## Run

Use the repository root manifest and lockfile, their pinned package manager, Node
24 or newer with both ICU locales, and normally installed dependencies. From the
repository root:

```bash
pnpm run build
node docs/proof/label-sync-identity-determinism/run-proof.mjs
node --test --test-concurrency=1 test/label-mutation-batch.test.ts
```

For a contrast, separately prepare a compiled pre-fix label module with its normal
sibling imports, then name both inputs explicitly:

```bash
node docs/proof/label-sync-identity-determinism/run-proof.mjs \
  --baseline /path/to/prepared/dist/clawsweeper-label-mutations.js \
  --candidate dist/clawsweeper-label-mutations.js
```

Baseline success requires observed locale and collator-tie divergence; candidate
success requires the canonical golden identity/arguments and equal recorded keys.
A failed child, wrong resolved locale or setup error fails the probe. JSON includes
actual owner/recorder-module and manifest hashes, runtime versions, observations,
and receipt IDs without host paths. The focused test invokes this same executable.
Exact source/head, build provenance, provider and current execution evidence belong
in the PR body; these commands do not install, stage source or infer a Git base.

## Limits

As described in [Action Ledger](../../action-ledger.md#identity-and-replay), receipt
identity and execution policy are separate. The actual apply runner records an
attempt and then invokes the operation; this change adds no duplicate-edit gate.
The adapter counter is synthetic, not evidence of live GitHub or full apply effects.
Older locale-sorted records are not migrated. UTF-16 label ordering does not claim
to equal the ledger's UTF-8 ordering of canonical object keys. This proof establishes
canonical ordering of effective values, not collision-free encoding of all labels.

---

### Overview (`docs/proof/lifecycle-post-effect-retries/README.md`)

# Lifecycle post-effect retry proof

Claim: the compiled batch client recovers transient failures for router receipts
and terminal dispositions with byte-identical signed requests. The real Worker
and SQLite-backed queue deduplicate a committed operation after its response is
lost, including when a newer requeue arrives before the retry. Publication
enqueue remains single-attempt. The batch CLI opts into lifecycle retries;
other callers, including operator retirement, keep the single-attempt default.

Run on Linux or macOS with Node 24+ and pnpm after `pnpm run build:node`.
The driver resolves the repository's pinned Wrangler 4.107.0 through `pnpm dlx`.
Only Wrangler's esbuild, sharp, and workerd setup scripts are allowed for that
invocation, using packaged libvips rather than a host-installed copy.

```sh
node docs/proof/lifecycle-post-effect-retries/run-proof.mjs
```

The driver starts a local Wrangler Worker and a loopback fault proxy. It uses
synthetic lifecycle admissions, real HTTP requests, the production signature
validator, and the production queue/storage implementation. The proxy either
returns one HTTP 500 before forwarding or drops a response after the queue has
committed it. In the latter case, the queue instance is reconstructed over the
same SQLite storage before retry; a paired scenario also submits a newer requeue.
The receipt records each request count and final persisted lifecycle/driver state.

Fixture-only routes seed and inspect state. The fixture blocks all outbound
Worker fetches and suppresses alarm dispatch; no GitHub, model, or production
state is accessed. A client fetch adapter changes only the HTTPS origin to the
loopback HTTP fault proxy. This proves replay semantics, not production outage
recovery or throughput. OpenClaw Bay's data contract is unchanged; replay uses
the existing lifecycle projection without duplicating or reviving terminal work.

---

### Overview (`docs/proof/lockfile-deprecated-field-network-policy/README.md`)

# Lockfile "deprecated" field misclassified as an unapproved install destination

Production run [`32367984753`](https://github.com/openclaw/clawsweeper/actions/runs/32367984753) (`Execute credited fix artifact` step, 2026-08-20) stopped ClawSweeper's automatic implementation for [openclaw/openclaw#126659](https://github.com/openclaw/openclaw/issues/126659) with `target dependency install destination is not approved: https://github.com`, thrown from `assertApprovedInstallUrl` before any real dependency install was attempted. The issue being worked (Android `location.get` ignoring `maxAgeMs`) has nothing to do with dependency installation; the toolchain-preparation gate itself was misfiring.

`openclaw/openclaw`'s `pnpm-lock.yaml` carries a `packages:` entry for a deprecated transitive dependency, `@aws-sdk/core@3.977.1`, whose `deprecated` field is pnpm's verbatim copy of the npm registry's own deprecation notice for that version:

```yaml
'@aws-sdk/core@3.977.1':
  resolution: {integrity: sha512-...}
  engines: {node: '>=20.0.0'}
  deprecated: |-
    Deprecated due to Document number parsing bug in JSON, see
      https://github.com/aws/aws-sdk-js-v3/issues/8246. Newer version available.
```

That text is free-form maintainer-authored content, never an install source, but `assertStructuredInstallMetadataDestinations` (`src/repair/target-validation.ts`) only exempted the `funding` field from the install-destination URL scan for package records. `deprecated` wasn't exempted, so the GitHub issue link embedded in the deprecation notice tripped the scan and aborted `prepareTargetToolchain` before the fix worker ever ran. This is the same class of false positive fixed narrowly for `integrity` hashes in [#649](https://github.com/openclaw/clawsweeper/pull/649), a different field.

**Fix**: extend the existing package-record exemption to also cover `deprecated`, but narrower than `funding`'s exemption, since npm's registry only ever emits `deprecated` as a plain string (unlike `funding`, which is legitimately a string, object, or array), the exemption requires `typeof entry === "string"`, so a malformed object- or array-shaped `deprecated` field (not a real registry shape) still hits the fail-closed scan. A companion regression test proves a malicious `resolved` URL sitting beside a legitimate `deprecated` string in the same package record is still rejected, the per-field exemption does not widen to sibling fields.

The executable contract is in [`behavior-contract.md`](behavior-contract.md), RED/GREEN evidence is in [`red-green.md`](red-green.md), and [`run-proof.sh`](run-proof.sh) is the Docker-backed Crabbox launcher. [`receipt.json`](receipt.json) binds the head that was actually exercised, `bfda61b0b2520e34569f3797ab4e4089db6f1dd5` (the fix and its tests; this proof directory was added in a later commit on the same branch that changes no tested file, so it postdates that head without invalidating the proof), provider `local-container`, lease `cbx_c6901e89c73a` (`harbor-barnacle`), Docker image `node:24-bookworm@sha256:934240a162082fd8b8a2f90cd5114446443f1eba1c5378f6687167ca405e6584`, the full focused `test/repair/target-validation.test.ts` suite (202 passing, 3 skipped for a documented kernel-capability gate unrelated to this change, 0 failing), clean `format:check`, clean `lint`, clean `build:all`, and a real production-entrypoint run against the actual `openclaw/openclaw@e2f841bf1c1286940e3e89627ec2dc02514d9325` checkout on both the unfixed and fixed code.

**Scope note**: this proof does not run the full `pnpm run check` gate. That gate's `test:coverage:no-build` step exercises `test/sweep-workflow.test.ts`, which requires GitHub Actions-simulation secrets/tokens not available outside CI and fails identically on unmodified `main` in this same container; it is unrelated to the changed surface (`src/repair/target-validation.ts`). Per `CONTRIBUTING.md`'s own guidance to use the narrowest meaningful validation for the changed surface, this proof scopes to build, lint, format, and the full test file the change lives in, plus the production real-behavior proof. This proof was also not produced or reviewed by ClawSweeper's own Codex `/review` loop; that step is GitHub-tooling-side and outside what a contributor can run locally, flagged here rather than silently presented as complete.

---

### Overview (`docs/proof/logging-redaction-fixtures/README.md`)

# OpenClaw logging redaction fixture admission

## Behavior contract

Requalify the synthetic connection-string fixtures in OpenClaw's
`src/logging/redact.test.ts` after [OpenClaw #160879](https://github.com/openclaw/openclaw/pull/160879)
rewrote that file. The values use reserved `example.test` hosts and descriptive
placeholder userinfo inside a redaction test; they are not operational
credentials.

The rewrite kept four of the five remaining fixture lines byte-for-byte, but
changed the scan result in two ways. The `secret:***` Postgres fixture moved
into a differently indented assertion, so its complete-line digest no longer
matched. The new chunk contents also let pinned TruffleHog 3.97.4 label every
remaining identity `HTML` as well as `PLAIN` or `ESCAPED_UNICODE`. The label is
nondeterministic between runs of the same bytes, and the exact attribution table
never permitted `HTML` for this path. Any pull request touching the file was
refused before review, including through its unchanged base blob.

The host policy adds seven exact rows and permits `HTML` for this one source.
Each row still binds detector ID and name, decoder, `Raw`, `RawV2`, the complete
source-line digest, path, mode `100644`, and committed base/head roles. `HTML`
rows exist only for the five post-rewrite identities; the pre-rewrite rows stay
unchanged because pull requests whose merge base predates #160879 still stage
the old blob. Verified findings, changed lines, extra occurrences, unknown
decoders, other paths or modes, uncommitted roles, duplicate records, and
incomplete scans remain refused. Patch-embedded MongoDB/Postgres findings keep
their existing refusal.

## Native proof

The hosted refusal came from [run 36514869480](https://github.com/openclaw/clawsweeper/actions/runs/36514869480)
for [OpenClaw #160888](https://github.com/openclaw/openclaw/pull/160888): finding
2 of 10, URI detector 17, `HTML`, `finding_not_reviewed`, head blob `a2d4c9ad`.
Replay that exact range with the existing source-admission runner, which drives
host staging and admission through the checksum-pinned native scanner with
normal verification and no model call. The target checkout needs `HEAD` at the
head commit with a clean index; a sparse checkout of the four touched paths is
enough.

```sh
pnpm run build:node
node docs/proof/marketplace-telemetry-fixtures/run-proof.mjs \
  /path/to/openclaw \
  9b5b439dcb6e11b929c982d9b40e8ddcb4c9b2e5 \
  08d64d3b5ec802237eff61e10e0f1a3aeb8761b0 \
  /path/to/proof.json
```

The [native result](native-results.json) records three runs of the original
policy (ClawSweeper `main` at the pull request base) and eight of the
candidate over the same complete range on macOS, with `policySourceSHA256`
binding the candidate runs to the committed `src/agent-input-scan-fixtures.ts`.
The original policy refused every run, through the base blob that matches
current OpenClaw `main`: `literal_mismatch` for the rewritten Postgres line
under `PLAIN`, and `finding_not_reviewed` for an `HTML` MongoDB finding. The
candidate admitted every run and classified 66 emitted findings; every
identity appeared as `HTML` in the base role, and four of the five under all
three labels. Emitted subsets varied between four and five identities per run.
An earlier replay of the same range recorded one `duplicate_finding`
refusal: the native scanner emitted the same head-blob URI record twice for a
line inside the 3 KB peek overlap after a 10 KB chunk boundary, and the existing
duplicate-record guard refused it. That scanner property is unrelated to the
added rows and unchanged here.

## Known limit: decoded findings borrow the plain witness

The exact path locates the approved plain `RawV2` literal anywhere in the
staged blob, or as a patch witness, and never establishes where an `HTML` or
`ESCAPED_UNICODE` finding originated. An entity-encoded copy of an approved
synthetic value elsewhere in the same file decodes to the same identity and is
attributed to the plain line. This is the existing behavior of every exact row
that permits `HTML`; this change extends `HTML` to one more source. What such
a borrowed attribution admits is only the same digest-bound synthetic value,
so no new secret passes.

The artifact records the limit natively with local-only OpenClaw commits that
add an entity-encoded copy (each colon as a numeric entity) of the approved
browser URI: with the copy at line 4 of both base and head blobs, and with the
copy inserted two lines above the plain fixture so the hunk context carries the
plain line as a witness. The candidate admitted 2/2 runs of each scenario, and
the recorded scanner lines show the copy's own finding (line 4, patch line 135)
classified against the plain witness.

Binding the finding to the scanner-reported line is not a fix: the pinned
scanner counts lines in decoded chunk data, so five consecutive blank lines
shift an `HTML` finding by four lines, three `\u000a` escapes shift an
`ESCAPED_UNICODE` finding by three, and block-level HTML tags in a string shift
`HTML` by three, each refusing a legitimate fixture. The sound fix is a masked
native re-scan, as already used for Cloudflare metadata, tracked in
[openclaw/clawsweeper#1724](https://github.com/openclaw/clawsweeper/issues/1724)
for every exact `HTML`/`ESCAPED_UNICODE` URI row.

This is source-admission proof, not a hosted review. Hosted runs scan their own
complete inputs. Reviews already held after a terminal scanner refusal still
need a fresh explicit re-review; this change does not bump the retry-policy
epoch. OpenClaw Bay is unaffected: no status, queue, publication, telemetry, or
observer contract changes.

---

### Overview (`docs/proof/maintainer-review-routing/README.md`)

# Maintainer-only status routing replay

- Status: active proof recipe, not an operator runbook
- Owner: ClawSweeper review maintainers
- Source: `src/clawsweeper-next-step.ts`, `src/review-record.ts`, `src/clawsweeper-report-comment-helpers.ts`, and `src/clawsweeper-label-policy.ts`
- Verified baseline: `b79b76cc0cc46f266104fb1a8f95cdd2a74c8292`
- Update when: typed next-step kinds, durable review parsing, readiness, or status routing changes

## Claim and limits

Explicit maintainer-only next steps route to `status: ⏳ waiting on maintainer`,
not author work. They remain blocked from merge. Author findings and missing
proof still take precedence; unknown ownership does not become maintainer work.

The public examples are https://github.com/openclaw/openclaw/pull/177823 and
https://github.com/openclaw/openclaw/pull/167431. Their October 21 public labels
said waiting on author while their reviews named maintainer security approval
and, for the latter, a product decision. Their private canonical review records
were not recovered. **All persisted inputs here are synthetic**, not those live
records or a new review of either PR. The new producer must explicitly select
`kind: maintainer`; this patch does not guess ownership from legacy prose.

This driver runs the real compiled durable-record writer/reader, checklist,
automation-marker producer, and label selector. It writes complete generated
reports, comments and a JSON receipt; no model, GitHub mutation, apply command,
or hosted queue is called. Separate parser/schema and regression tests support
the result. Local rendering/routing proof is not hosted deployment proof.

## Reproduce

Use Node 24+ and the pinned pnpm dependencies from the repository root. Build
the full pinned baseline without changing the current checkout:

```sh
pnpm install --frozen-lockfile
pnpm run build:all
mkdir -p .artifacts/maintainer-routing-baseline
git archive b79b76cc0cc46f266104fb1a8f95cdd2a74c8292 | tar -x -C .artifacts/maintainer-routing-baseline
ln -s "$PWD/node_modules" .artifacts/maintainer-routing-baseline/node_modules
node_modules/.bin/tsc -p .artifacts/maintainer-routing-baseline/tsconfig.json
node docs/proof/maintainer-review-routing/replay.mjs
```

Use a fresh baseline directory for the first run; stop if preparation fails.
An optional first argument selects an already-built baseline `dist` directory.
The receipt records compiled hashes, but a supplied path is not independent
proof of its provenance. Rebuild current `dist` after changing source.

Inspect `.artifacts/maintainer-review-routing/result.json`, `before.md`, and
the per-scenario `.report.md` and `.comment.md` files. The receipt records the
current head, dirty flag, input/compiled hashes, runtime, provider, and limits.

## Observed result

On Node v24.20.0 / Linux x64 in the managed Docker sandbox:

| Input | Status | Readiness | Pass/repair marker |
| --- | --- | --- | --- |
| Legacy required approval, baseline and candidate | waiting_on_author | needs-changes | absent |
| Explicit security approval | waiting_on_maintainer | blocked | absent |
| Explicit security approval + product decision | waiting_on_maintainer | blocked | absent |
| Approval + contributor finding | waiting_on_author | blocked | absent |
| Approval + missing contributor proof | needs_proof | blocked | absent |
| Approval + unknown upgrade risk | no status label | blocked | absent |

All candidate scenarios preserve `security-review-required`. No security
approval, merge permission, repair action or change to either live PR is implied.
The managed sandbox image identifier is not exposed and no Crabbox lease was
used; this is a local deterministic production-path replay, not remote proof.

---

### Overview (`docs/proof/manual-review-publication/README.md`)

# Explicit manual publication proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

- Status: active proof recipe; current execution evidence belongs in the PR body
- Owner: ClawSweeper queue and publication maintainers
- Source of truth: [driver](../../../scripts/e2e/manual-review-publication.mjs); the manual Crabbox entry script is retired
- Update when: admission, policy, branch selection, artifact inventory, ownership, retry, lifecycle lineage, or consumer behavior changes

## Behavior contract

Explicitly selected manual items enter the existing exact queue **before review**
and publish only records and durable comments. A completed review can retry
publication without rerunning the model or widening authority. The canonical
restriction remains effective for background consumers after queue completion.

The driver runs the built CLI and actual local Wrangler Worker, Durable Objects,
SQLite, and R2. GitHub/Actions HTTP responses and review output are synthetic.
Claims and successful comment receipts are never seeded. Synthetic PR 76 must
receive publisher-generated completion markers for its exact head/source,
original `reviewed_at`, and real coordinator-owned review lease. An uploaded
report, progress comment, or imported old record cannot satisfy that assertion.

The runtime scenarios exercise:

- Checked-in manual admission with `release/proof`; a dispatch outage leaves
  requests pending while an ordinary `main`-branch event refreshes source facts.
  The eventual claim must preserve the manual branch, requested timeout, and
  one-off instructions, and advance its revision. The checked-in event-payload
  resolver must retain the requested 40-minute timeout instead of the default.
- Checked-in direct-publication and lifecycle shell steps. Selected bundle input,
  imported records, snapshots, and early refusal output stay in the chosen work
  root, even when the caller runs from another checkout. Raw producer diagnostics
  remain intact; extra sibling files, directories, and symlinks are refused.
- Authority-service HTTP 503 at initial validation, apply-child entry, mutation,
  and batch preparation. All retain `retryable_failure` / `state_contention` with
  zero comment writes and no GitHub inline retry. Mutation-failure cleanup makes
  its separate guarded authority read; that also refuses during the outage.
- Direct and batch canonical acceptance, unknown-acknowledgement recovery,
  source/head drift, replaced owners, real lease expiry, and artifact exhaustion
  without fresh review. An independently requested later review remains possible.
- Policy-aware implementation discovery and zero label, close, router, repair,
  merge, or sibling effects. Every request invokes synthetic review exactly once;
  all selected bundles and diagnostic files remain byte-identical.
- Current lifecycle audit and the public Bay endpoint, including producer
  revision 2 completed through publication revision 1. A later producer journey
  stays pending until its own publication. Public Bay exposes no lineage or
  owner material and remains observer-only.

Focused lifecycle tests additionally cover immutable lineage conflicts, missing
links, queue deletion/reconstruction, replay without duplicate telemetry, and
retained publication keys whose producer provenance is refreshed. Transport tests
cover timeouts, network failures including curl HTTP/2 exit 16, HTTP 429, error
sanitization, and hard ownership/authentication rejection. Existing retry budgets
and receipt/lease identities are unchanged.

## Run

Provision a fresh task-owned lease using the configured or explicitly approved
backend. The approved fallback for this task is **local-container**, not AWS or
Testbox. The driver allocates no resources and loads no production credentials.
Use Node 24+, pnpm 11.10.0, Wrangler 4.107.0, Bash 4+, jq, Python 3, tmux, and a
checksum-verified stock GitHub CLI with `http_unix_socket` support (tested with
2.98.0). Supply its absolute path, never a host wrapper that hydrates credentials.
The mandatory synthetic socket read and invalid `GH_HOST` guard outbound access.

Use a self-contained checkout with its actual Git objects. Verify the exact head
with `git rev-parse` and `git cat-file`; do not manufacture checkout metadata.
When copying from macOS, disable AppleDouble and extended-attribute files. Keep
HOME/XDG and application state isolated, install with the frozen lockfile, and
pass only the named non-secret toolchain settings into child commands.

The source digest covers actual source, workflows, configuration, compiler inputs,
schemas, and prompts independently of the checkout SHA. In the prepared environment:

```bash
node scripts/e2e/manual-review-publication.mjs source-id
```

Set `MANUAL_PUBLICATION_WRANGLER`, `MANUAL_PUBLICATION_GH`,
`MANUAL_PUBLICATION_PROVIDER`, `MANUAL_PUBLICATION_LEASE`,
`MANUAL_PUBLICATION_IMAGE`, and a fresh `MANUAL_PUBLICATION_OUTPUT`, then run:

```bash
bash scripts/e2e/manual-review-publication-crabbox.sh <verified-head> <source-sha256>
```

The entry script builds the source before running the driver. Collect `summary.json`,
`proof.json`, `result.json`, `trace.json`, `commands.json`,
`current-head-pr-completion.json`, runtime logs, and `cleanup.json` before stopping
and verifying deletion of the owned lease. Review captures for incidental secrets
before publishing evidence. Record the provider, image, lease, exact command,
head/source digest, observed result, and cleanup in the main PR body; local-container
runs have no hosted run URL. Failed runs remain failed evidence, not successful E2E.

## Limits and rollout

This does not establish production GitHub permissions or throttling, Actions
scheduling/expression evaluation or artifact provenance, model review quality,
production Cloudflare durability, or browser UI behavior. GitHub comment write
and canonical acceptance are separate services, not an atomic transaction.
Ownership changes between them require the canonical handoff to refuse. Direct
canonical retries still require the immutable accepted plan.

The approved lifecycle lineage is observational metadata in existing JSON, not
publication authority. Physical receipts and leases retain their original fences.
Missing or conflicting lineage cannot complete another producer journey. Bay's
public field set and mutation-free UI remain unchanged; its data projection is
part of this proof. Admission remains default-off until the separately authorized
[historical coordinated rollout](https://github.com/openclaw/clawsweeper/blob/27d4174225bba4558644d4bc0d03c85592e34478/docs/repair/operations.md#manual-publication-rollout).
No historical batch or foreign target is recovered or mutated by this harness.

---

### Overview (`docs/proof/marketplace-telemetry-fixtures/README.md`)

# Marketplace telemetry fixture admission

## Behavior contract

OpenClaw's marketplace entries test repeats an existing synthetic feed URL in live and snapshot metadata. Qualify only those two ordered complete source lines for URI detector 17, observed PLAIN or HTML decoding, the reviewed raw digests, regular-file mode, and committed base/head roles. Preserve the refresh test's separate legacy approval, including repair roles, duplicate context records, and rejection of introduced fixture lines. Unknown aliases, changed queries/fragments, missing/reordered/extra occurrences, verified findings, and incomplete scans remain rejected.

The unchanged entries fixture was present in both the base and head of [OpenClaw #145975](https://github.com/openclaw/openclaw/pull/145975). Its input scan failed before review. Run the canonical native scanner over that complete source range:

```sh
pnpm run build:node
node docs/proof/marketplace-telemetry-fixtures/run-proof.mjs \
  /path/to/openclaw \
  928dba98c56ae193ecb32140330abd6376d467dd \
  826f30fc2f4582c25f67fdc4957ca84481f096fe \
  /path/to/proof.json
```

The runner records only bounded owner diagnostics and accepted attribution notices, without raw fixture values. The original host policy refuses this range with `source_not_reviewed`; the candidate must admit it through the same pinned native scanner. Boundary tests exercise both source policies, strict witness order, aliases, repair roles and patch handling.

This is source-admission proof with a controlled prompt and no model invocation. It does not certify a hosted review: the hosted workflow must scan its own complete inputs and publish a current review before landing. OpenClaw Bay is unaffected; no status, queue, publication or observer contract changes.

---

### Overview (`docs/proof/mixed-case-publication-slugs/README.md`)

# Mixed-case publication slug proof

This proof exercises the built dashboard Worker and `ExactReviewQueue` Durable Object through real
HTTP using local Wrangler persistence. It verifies that GitHub repository casing does not block
direct exact-review publication while repository identity remains contained.

The behavior contract is:

- the real Durable Object initializes before any publication claim is made;
- a signed plan for `steipete/CodexBar#2516` whose operation uses the mixed-case
  `records/steipete-CodexBar/...` path returns HTTP 202 with an accepted or deduped receipt;
- the real Worker export surface serves that record only from `steipete-codexbar`, and the
  persisted Durable Object SQLite contains no `steipete-CodexBar` canonical or export row;
- a signed plan whose operation names `steipete-other` returns the HTTP 400
  `invalid_direct_publication_plan` response with a bounded tuple-invariant detail;
- a signed all-lowercase `openclaw/openclaw` plan still returns HTTP 202 with an accepted or
  deduped receipt.

The script boots the Worker, drives `/api/exact-review-queue`, terminates the full Wrangler process
tree, and inspects Wrangler's persisted SQLite database for the direct-publication table. Only
after that assertion does it seed disposable pending fences, restart the Worker, and submit the
three signed plans. It then reads the accepted mixed-case plan through the signed record-export
route, stops the Worker, and verifies the canonical, export-index, and stored receipt namespaces
directly in SQLite. Pending fences let the real Worker accept and persist the valid plans without
mocking the publication store or bypassing HTTP validation.

Run from the repository root on Node 24 or newer:

```bash
bash docs/proof/mixed-case-publication-slugs/run-proof.sh
```

Set `MIXED_CASE_PUBLICATION_SLUGS_PROOF_OUTPUT` to keep generated artifacts outside the repository.
The default artifact directory contains the signed request/response bodies, runtime transcript,
build/install logs, and a redacted Wrangler log.

This proof does not change retry or permanence classification, migrate stored records, deploy, or
mutate production. OpenClaw Bay is unaffected: the change only relaxes repository-name casing at
internal publication validation boundaries and does not change Bay data or controls.

---

### Overview (`docs/proof/modernize-stdlib-batch/README.md`)

# Modernize stdlib batch proof

This proof covers the behavior-preserving Node standard-library migration in this batch. It keeps the current CLI contracts—including exit codes, custom error strings, ignored `--` delimiters, and repeated scalar/array options—while requiring all seven leaf parsers to use `node:util` `parseArgs` with complete schemas.

Run from the repository root:

```sh
bash docs/proof/modernize-stdlib-batch/run-proof.sh origin/main
```

The red check extracts each parser from `origin/main` and fails because none of the seven files has adopted the stdlib parser. The green check inspects the working tree and requires the stdlib import in every migrated CLI. The committed [red log](artifacts/adoption-red.log) and [green log](artifacts/adoption-green.log) retain those outcomes.

For behavioral equivalence, the harness extracts the old `scripts/e2e/automerge.mjs` with `git show`, supplies its repository-relative fixture imports, and runs the same argv matrix through old and new sources: help, an ignored `--` delimiter, a repeated scalar option, an unknown option, and a missing value. It records exit status, stdout, and the semantic error line (excluding source-location-only stack frames). The [before transcript](artifacts/cli-before.txt) and [after transcript](artifacts/cli-after.txt) are byte-identical; [their diff](artifacts/cli-transcript.diff) is empty.

The controlled proof is local, read-only apart from its own artifacts, and uses no credentials or network calls. It does not exercise the migrated commands' external GitHub, Worker, Git, or Docker operations. Fresh pushed-head container provenance belongs in the pull request's `pr-behavior-proof` section.

---

### Overview (`docs/proof/native-worker-fixtures/README.md`)

# Native-worker rejection fixture qualification

Lifecycle: historical, task-specific proof. Owner: ClawSweeper review admission.
Source of truth: `src/agent-input-scan-fixtures.ts` and the pinned native scanner.
Verified scope: OpenClaw head `93dbee664f93ca80668f85ab346c8e7a4e07db7e`;
ClawSweeper baseline `f9d81c419e55740d5a48a546b6cd27e49b35250d`. Re-run when
these source witnesses, scanner version, staging, or classifier change.

## Claim and scenario

Permit only two exact synthetic URI rejection inputs from
[OpenClaw PR 158901](https://github.com/openclaw/openclaw/pull/158901):

- `src/worker/native-runtime-transport.test.ts`, blob
  `b4b313e03e7bcff43b7ba7426add5a76af436129`, line 341: a dummy-user/password
  URL on reserved `example.test`, asserted false by `isNativeRuntimeEndpoint`.
- `src/worker/native-runtime.test.ts`, blob
  `8ea970c7b3467718eb7b64ecee9ebe7bcf0256c4`, line 409: a dummy-user/password
  URL on reserved `example.com`, asserted invalid by `NativeRuntimeConfigSchema`.

These are different inputs, not duplicate findings. The existing host-owned
exact-attribution table binds URI detector 17, observed PLAIN/HTML decoding,
both native value digests, each entire source line, exact path, regular-file
mode, and every committed base/head reference. Changed/removed patch lines
reuse their proven source witnesses. No file, domain, detector, or checkout
allowlist is added; no original test is edited. Scanner arguments, verification
requirements, completion checks, source provenance, and fail-closed gates remain
unchanged.

## Command and environment

The native proof used Linux x64, Node 26.8.2, and the managed checksum-pinned
TruffleHog 3.97.4 binary. The managed bootstrap ran before isolation; its external
cache directory was then selected through trusted PATH. No cloud lease/container
image was used for this source scan. The full public consumer checkout was
hydrated beforehand with sufficient ancestry; no consumer code was executed.

From each built ClawSweeper policy checkout, with `TARGET` pointing to a clean
checkout at the recorded head, `SCANNER_DIR` the external pinned scanner cache,
and `OUT` an existing writable proof directory:

```sh
bwrap --unshare-net --ro-bind / / --dev /dev --proc /proc --tmpfs /tmp \
  --bind "$OUT" "$OUT" --clearenv --setenv HOME "$HOME" \
  --setenv PATH "$SCANNER_DIR:/usr/bin:/bin" -- /usr/bin/node \
  docs/proof/native-worker-fixtures/run-proof.mjs "$TARGET" \
  be46e6966c2b52c6cde06abf965c44f9a175a47f \
  93dbee664f93ca80668f85ab346c8e7a4e07db7e "$OUT/result.json"
```

Use the candidate proof helper unchanged with the baseline build to compare.
The helper asserts loopback-only interfaces and a cleared environment. It
observes the real `scanAgentInput` staging and native subprocess without changing
arguments or returned bytes. Only hashes, bounded metadata and classification
notices are retained; raw matches and verification messages are never printed.
The initial single-blob inventory additionally used `--no-verification`. The
canonical source scan retains production flags but has no external interfaces,
so it cannot verify any finding against a live service.

## Observed result and artifact

[results.json](results.json) records the red/green comparison. All four runs
staged the same 135 inputs: complete before/after source blobs, raw diff, full
patch, and controlled prompt. Each completed native scan emitted four unverified
findings: two distinct literals, each in its source blob and added patch line.
Baseline refused; interim narrow policies exposed the independently observed
HTML variants; the final policy classified all four and admitted the input.
The exact native value and whole-line digests, staged-manifest digest, scanner
checksum, completion counters and candidate policy digest are retained.

Five additional real native scans of disposable, locally committed transport
fixtures refused changed bytes, a wrong source path, a changed whole line, and
approved material mixed with unknown or real-shaped synthetic URI inputs. All
five completed with detected findings; none relied on absence of detection.
These controlled negative repositories did not edit the public consumer branch.

Focused regressions cover both fixtures in added, removed and context lines,
PLAIN/HTML, plus changed bytes/lines, wrong paths/modes/references, repeated
literals, mixed unknown and real-shaped synthetic values, wrong detector/raw/
source type/secret parts, verified records, missing verification errors,
incomplete scans, duplicate records and unsupported decoders.

## Limits and Bay disposition

The original hosted failure recorded a count of two and only the first finding
identity. Its omitted second record cannot be recovered from that manifest.
This controlled complete-source run identifies every one of its four records;
it is not a byte-identical replay of the hosted prompt or a claim that the
historical second record was retained. Native PLAIN/HTML deduplication varies.

This proves source admission only: no model call, hosted verdict, GitHub review
publication, deployment, merge or live automation action occurred. A hosted
review must scan its own current prompt, schema and source. OpenClaw Bay is
unaffected: no queue, lifecycle, telemetry, API or dashboard contract changed.

---

### Overview (`docs/proof/node-sqlite-migration/README.md`)

# Node SQLite migration proof

## Claim

The five gitcrawl SQLite query subprocesses now use Node 24's synchronous
`node:sqlite` API in read-only mode without changing their parsed row, scalar,
empty-result, or caller-level error contracts. The cluster-intake workflow no
longer installs the obsolete `sqlite3` executable.

## Host equivalence

`run-proof.mjs` creates a real portable gitcrawl database with committed rows
still resident in its WAL sidecar. It extracts the three old source files from
`origin/main`, verifies their five old `sqlite3` invocations, and executes the
same scalar and JSON queries through the host `sqlite3` CLI and the new
`node:sqlite` helper. Their parsed JSON bytes and scalar text must be identical.

Run after `pnpm run build:all`:

```sh
node docs/proof/node-sqlite-migration/run-proof.mjs
```

The machine-readable result is `equivalence.json`.

## Contract decisions

JSON query rows intentionally remain ordinary JavaScript objects containing
numbers. Statements read SQLite integers as BigInts and explicitly normalize
them with `Number()`, matching the old `sqlite3 -json` plus `JSON.parse` path,
including its precision loss above `Number.MAX_SAFE_INTEGER`. Scalar queries
retain exact decimal text; their existing callers continue to apply `Number()`.

Every query opens `DatabaseSync(dbPath, { readOnly: true })`, so committed WAL
rows remain visible while a missing database is no longer created as a side
effect. Related-context still catches query failures: a missing configured path
returns `[]`/`false` before a query, and a corrupt store returns `[]`/`null`.
Both importer entry points still fail nonzero for missing or corrupt stores.

## Container and gates

The seven local gates passed on Node 24.19.0 and pnpm 11.10.0:

1. Host old/new equivalence proof: three scalar and three JSON query cases,
   including missing/corrupt error evidence.
2. Focused real-database fixtures: 6 passed, 0 failed.
3. `pnpm run build:all`: all three TypeScript projects passed.
4. `pnpm run test:no-build`: 3,333 tests; 3,324 passed, 9 skipped, 0 failed.
5. `pnpm run lint`: all four lint lanes passed.
6. `pnpm run format:check`: 663 files passed.
7. `pnpm run check:static`: active-surface, dashboard boundary, docs, limits,
   and format checks passed.

The committed `container-proof.sh` requires a fresh PR checkout whose image has
no `sqlite3` binary. It installs the repository's pinned pnpm through Corepack,
downloads jq 1.8.1, verifies the selected jq binary against the official
published checksum, runs the focused real-database fixtures through only the
new path, and then runs the full `pnpm check` gate.

Container provenance and secret-scanned stdout are committed alongside this
proof after the required `--fresh-pr` run. Crabbox resolved `provider=aws` and
ran pushed head `31386dccd6ee9f77fe480ab6c705253647f4aaf2` in lease
`cbx_3ddd8eadc1bb` (`amber-barnacle-28b5`), run `run_61e78be4ed53`. The
`node:24-bookworm` command exited 0 after 187,543 ms: all 6 focused fixtures
passed, then full `pnpm check` passed 3,333 tests with 3,325 passed, 8 skipped,
and 0 failed at 81.60% line, 74.06% branch, and 87.40% function coverage.
`sqlite3` was absent before and after the rsync-only system dependency setup.

The full 571,547-byte stdout capture has SHA-256
`28669d632e2d5387d901c76504611ab37a19bd23de0c29453767e2bf5efe5c76`.
TruffleHog 3.96.0 scanned that exact file with zero verified or unverified
secrets; `container-stdout.log` retains the proof-bearing stdout lines. Full
machine-readable details, including the three discarded harness attempts, are
in `container-provenance.json` and `container-secret-scan.json`.

The run's project-local Crabbox 0.38.3-5 wrapper timed out while releasing the
otherwise successful lease. Crabbox 0.41.1 then explicitly released
`cbx_3ddd8eadc1bb`; a provider-specific lease listing returned empty.

## Limits and Bay impact

Fixtures are disposable local files; no proof command contacts Gitcrawl,
GitHub APIs, Worker storage, or another production service. The host needs
`sqlite3` only for old-path equivalence. The container intentionally cannot run
the old path because the binary is absent.

OpenClaw Bay is unaffected. This changes local read-only store access and one
workflow bootstrap step, not lifecycle publication, queue control, status
telemetry, dashboard data, or Bay's observer-only boundary.

---

### Overview (`docs/proof/notifier-completion/README.md`)

# Notifier completion proof

Status: active validation recipe. Owner: ClawSweeper notifications.
Source: the shared OpenClaw hook client and four notifier CLIs.
Update when completion classification, ledger persistence or report output changes.

```sh
pnpm run build:node
node docs/proof/notifier-completion/run-proof.mjs
```

The real built merge, event, maintainer-report and GitHub-activity CLIs talk to a
local HTTP server using synthetic hook responses and fixture inputs. Fifty-two
scenarios cover delivered, silent and channel-transform suppression, failure, ambiguous completion,
explicit channel suppression with later errors, attempted-but-unacknowledged empty and visible replies, omitted delivery flags,
legacy admission and no requested delivery. Merge/event ledger files survive
separate CLI invocations: conclusive outcomes deduplicate, while inconclusive
ones retry the same idempotency key. Event dashboard publication remains
independent of an inconclusive completion. GitHub activity writes its summary.

The receipt records runtime, source hash and outcomes in `.artifacts/`.
No production credentials or mutations are used. This proves notifier behavior,
not a deployed Gateway or Discord send. Completion observability requires a
Gateway with the [completion protocol](https://github.com/openclaw/openclaw/pull/139155).
The client remains safe with admission-only Gateways: the
[older payload normalizer](https://github.com/openclaw/openclaw/blob/d0137988844d201423fbe1918e8c5acef8ddfa8e/src/gateway/hooks.ts#L689)
ignores the added field, and the client preserves terminal `admitted` outcomes
without retrying them. Either deployment order is supported; this recipe does
not claim which protocol a configured production Gateway currently serves.

---

### Overview (`docs/proof/openclaw-bay/README.md`)

# Historical OpenClaw Bay deterministic browser proof

Status: reusable deterministic runner with historical checked-in artifacts.
The recorded artifact source, `0cf6b147fe86f56e4ec8c77352e3d31433e3a1d2`,
is not reachable from current repository history, so the checked-in report and
storyboard must not be treated as current exact-head proof. A new runner receipt
and artifacts must name their exact source SHA.

This proof package exercises the real `/bay` page and its checked-in
artwork in Chromium. Playwright replaces the dashboard's status, history, and
triage reads with fully synthetic, redacted fixtures so stage changes,
telemetry controls, and navigation can be reproduced without live dashboard
data, credentials, or GitHub API traffic.

The post-privacy-boundary throttle chart has a focused runnable entry point:

```bash
bash docs/proof/openclaw-bay/run-throttle-proof.sh
```

It supplies the strict aggregate-only public status shape and verifies the
6-hour, 24-hour, and 7-day throttle fetches, interval summaries, accessible
403/429 series, physical-pool totals, reset-header boundary, and screenshots.

The sequence proves:

- visible partial-telemetry diagnostics;
- public indexability: no robots metadata or `X-Robots-Tag`, while preserving
  `no-store`, CSP, and frame protections;
- the consistent public dashboard header, including a visible Bay link from
  Overview, issue triage, and PR-proof triage;
- the Bay timing badge naming its bounded **review trigger → final review** measurement, completed by the command-status update emitted after the durable review summary;
- a 390px portrait layout that stacks Arriving through Publishing and Applying vertically, keeps the terminal pools at the waterline, and has no horizontal page overflow;
- advancing crustacean-claw and master-sweeper animations;
- a READY flag followed by a physical forward sweep and landing;
- a changed run ID using the retrigger tunnel and resurfacing path;
- GitHub-reference search and focus;
- repository filtering;
- the read-only drawer's safe GitHub item, job, and workflow-run links;
- readable overflow controls that open the known queue sample and explicitly explain when aggregate queue IDs are outside the bounded public projection;
- compact review-admission, result-publication, and State writer charts with labelled y-axes, exact point hover labels, and cached 6-hour, 24-hour, and 7-day range controls;
- closed-bucket GitHub throttle history across those ranges, split by 403/429,
  summarized by physical pool class, and explicit about the 24-hour
  reset-header-detail boundary;
- lightweight hover/focus explanations on the beach lane signs;
- the local-only tide preview advancing through incoming, crest, backwash, and restored states while preserving terminal keys and count;
- the short static reduced-motion tide cue preserving the same preview state;
- completed and failed/cancelled outcomes grouped into their respective terminal pools;
- twenty completed outcomes fitting individually in the expanded terminal pool without a hidden overflow at the standard desktop width, plus a constrained-width layout that keeps twelve labels readable and makes the remaining eight explicit; and
- a generated real tide atomically proving all twenty terminal crustaceans and
  the final completion time are visible before clearing the shared buffer; and
- zero browser-to-GitHub API requests, mutation requests, unexpected console
  errors, or uncaught page errors. The deliberate synthetic health-history
  outage records one expected 503 console error while the resilience state is
  being exercised.

## Artifacts

- The labelled 23-state storyboard and Playwright action, DOM snapshot, and
  network trace were introduced in commit
  `1a5becc69fc1bdbc11e16aa22f5caaa44f05a59d`. They were pruned from the docs
  tree after review and remain available through git history. To inspect the
  historical trace without restoring it to the working tree:

  ```bash
  bay_trace_dir="$(mktemp -d)"
  git show 1a5becc69fc1bdbc11e16aa22f5caaa44f05a59d:docs/proof/openclaw-bay/trace.zip \
    > "$bay_trace_dir/trace.zip"
  npx --yes playwright@1.60.0 show-trace "$bay_trace_dir/trace.zip"
  ```

- [`proof-summary.json`](proof-summary.json) records all 51 passing assertions
  from its accompanying deterministic proof run,
  sanitized request/response metadata, safe drawer links, the unchanged
  terminal keys before and after both preview modes, the proved real-tide
  clear, and the held terminal failure tunnelling to its bounded live retry.
- [`run-proof.mjs`](https://github.com/openclaw/clawsweeper/blob/ad70f614a44359625584df30688e1ffd26f75bf3/docs/proof/openclaw-bay/run-proof.mjs)
  contains the Playwright assertions and artifact renderer.
  [`run-proof.sh`](https://github.com/openclaw/clawsweeper/blob/ad70f614a44359625584df30688e1ffd26f75bf3/docs/proof/openclaw-bay/run-proof.sh)
  installs the pinned Playwright package in `/tmp`, starts the real local
  Wrangler Worker, and runs that script without changing repository
  dependencies.
  [`run-throttle-proof.sh`](https://github.com/openclaw/clawsweeper/blob/ad70f614a44359625584df30688e1ffd26f75bf3/docs/proof/openclaw-bay/run-throttle-proof.sh)
  selects the focused aggregate-only throttle proof path. These scripts were
  retired with the `/bay` page; the links point at the last revision that has
  them.
- [`fixtures/`](fixtures/) contains the exact three checked-in synthetic
  `/api/status` transition responses. The runner derives dense-terminal and
  real-tide responses from the final fixture, provides a synthetic in-memory
  `/api/health-history` response for telemetry, and records the real-tide
  SHA-256 in the summary. It
  fails before launching Chromium if the checked-in sequence drifts.

The historical compact trace omitted Playwright's continuous screenshot film
strip; the storyboard supplied the visual milestones while the trace supplied
the independently inspectable DOM, action, and network record.

From the repository root, reproduce the proof with the known Playwright image:

```bash
BAY_PROOF_SOURCE_SHA="$(git rev-parse HEAD)" \
crabbox run \
  --provider local-container \
  --local-container-image mcr.microsoft.com/playwright:v1.60.0-noble \
  --no-hydrate \
  --allow-env BAY_PROOF_SOURCE_SHA \
  --timing-json \
  --script docs/proof/openclaw-bay/run-proof.sh \
  --require-artifact '.artifacts/openclaw-bay-proof/trace.zip' \
  --artifact-glob '.artifacts/openclaw-bay-proof/**'
```

## Provenance and privacy

- recorded historical behavior source (not reachable from current history):
  `0cf6b147fe86f56e4ec8c77352e3d31433e3a1d2`
- provider: direct local Docker under the user-authorized CSW-124 fallback;
  this is not a successful Crabbox lease receipt
- image: `mcr.microsoft.com/playwright:v1.60.0-noble`
- fixture SHA-256:
  `B0180F79C465964AD39E6E45F730211294742E1206EA4CE1A4C39DEB61AFCB71`
- exact response SHA-256 values:
  - `01-initial.json`:
    `9D6CA7EDD926508DBB3DB7ED3B8328405F8404E16AEE303AE9057CA6B3BA0397`
  - `02-forward.json`:
    `C38AEE2C3E4C8AB1F99FEB354F6B00886A00F8C21CA3575B229E97B9D5DAC8BD`
  - `03-retrigger.json`:
    `9BAF0B764E413369EC8D9554D731A4E6B008B2DCB266B5D2837E94E820CEEBFE`
- derived real-tide response:
  `078023220BCDBF72E4CF212011760751EB63A841CF98070A77E4777A5BD4386E`

These hashes are for the canonical LF bytes materialized from the exact Git
tree inside the Linux proof container. A Windows checkout may display a
different working-tree hash when Git applies CRLF conversion.

The browser allowed only `bay-proof.test:8787`, mapped to the local Wrangler
Worker. The trace contains no cookies or authorization headers. A binary text
scan also found no GitHub tokens, local Windows user paths, usernames, or live
private payloads.

This is deterministic interaction proof, not a claim that synthetic state is
live operational evidence. The separate deployment smoke covers the canonical
`/bay` route, the query-stripping legacy redirect, response headers, shared
schema, and static assets.

---

### Overview (`docs/proof/openclaw-worker-signal-termination/README.md`)

# OpenClaw worker signal termination proof

The OpenClaw process worker starts the `openclaw` CLI in its own process group
so that its own timeout can stop the whole tree. A signal delivered to the
worker itself, which is what a job cancellation, a runner shutdown, or the outer
`spawnSync` deadline sends, never reached that group: the worker exited and
the CLI and its descendants kept running. The Codex process worker already
forwards `SIGINT`, `SIGTERM`, and `SIGHUP` to its process tree; this proof
shows the OpenClaw worker now does the same, and that descendants are still
stopped when the direct child exits before the `SIGKILL` escalation fires.

[`run-proof.mjs`](run-proof.mjs) starts the compiled worker with a fake
`openclaw` binary that spawns a signal-ignoring grandchild and never exits on
its own, then sends `SIGTERM` to the worker and records whether the child and
grandchild are still alive three seconds later. Three scenarios run per arm: the
direct child ignores `SIGTERM`, and the direct child exits on `SIGTERM` while
its grandchild ignores it, and repeated signals while both ignore termination. Persistent
worker handlers keep the one-second escalation alive on repeated signals.
The baseline arm compiles
`src/openclaw-process-worker.ts` from the base commit inside an isolated copy of
`src/` under the output directory (with its own `package.json` and a link to the
repository's `node_modules`), so the tracked checkout is never modified;
the candidate arm uses the current build. No model inference, network access,
or credential is involved. The driver is POSIX only.

```sh
pnpm run build
node docs/proof/openclaw-worker-signal-termination/run-proof.mjs --out .artifacts/openclaw-worker-signal-termination
```

`--base <rev>` selects the baseline commit (default: the merge base with
`origin/main`, or `HEAD~1` once the change is on `main`); `--baseline-dist`
reuses a previously compiled baseline. The driver writes `summary.json` with
the worker exit status, the elapsed time until the worker exited, the elapsed
time until the tree was gone, and the recorded result signal for each arm and
scenario, and exits non-zero unless the baseline leaves both processes alive
in all three scenarios and the candidate stops both in all three scenarios.

Expected result: in all three scenarios the baseline worker dies from `SIGTERM`
without writing a result, and both the child and the grandchild survive the
three-second wait. The candidate worker forwards the signal; with a
`SIGTERM`-ignoring child it escalates to `SIGKILL` after one second and records
`signal: "SIGKILL"`, and with a child that exits on `SIGTERM` it sends `SIGKILL`
to the remaining process group when the child closes and records
`signal: "SIGTERM"`. In all cases it exits with code 0 and leaves no surviving
process.

Limits: controlled compiled run with a fake CLI; it does not claim a specific
production cancellation left an orphaned `openclaw` process. Windows keeps the
existing `taskkill /t` path and is not exercised. OpenClaw Bay is unaffected:
no lifecycle, queue, telemetry, or dashboard contract changes.

---

### Overview (`docs/proof/operational-health-zombie-runs/README.md`)

# Operational-health zombie workflow-run proof

## Claim

The real dashboard Worker excludes queued workflow runs older than 24 hours from queue-pressure health while retaining them in `queued_runs` and surfacing them through `zombie_queued_runs` and `oldest_zombie_queued_minutes`. A non-zombie run queued for 31 minutes still degrades operational health exactly as before.

The GitHub base-URL binding is dependency injection for testability. Production behavior is unchanged by default: when `GITHUB_API_URL` is unset, every dashboard GitHub REST and GraphQL request still uses `https://api.github.com`. Other HTTPS origins are rejected by design so credentialed requests cannot be redirected away from GitHub; only explicit-port HTTP loopback origins are accepted for local proof stubs.

## Exercised surface

- Real `wrangler dev --local` dashboard Worker and `/api/status` route
- Real HTTP requests from the Worker to a loopback GitHub REST stub
- The production operational-health and dashboard-health summaries
- The default-origin path with `GITHUB_API_URL` unset and no GitHub credentials

## Controlled scenarios and required observations

The proof boots three fresh Workers. Each boot gets a disposable Wrangler persistence directory, and the entire Worker process group is stopped before the next boot.

1. The GitHub stub returns one queued run aged 25 hours. `/api/status` must report `queued_runs: 1`, `zombie_queued_runs: 1`, `queued_over_threshold: 0`, operational status `healthy`, and no `workflow_execution_degraded` dashboard reason.
2. The stub adds a second run aged 31 minutes. `/api/status` must report one zombie plus one over-threshold live queued run, operational status `degraded`, and the `workflow_execution_degraded` dashboard reason.
3. `GITHUB_API_URL` is unset and no GitHub credential is provided. The resulting status payload and its public GitHub response or local-sandbox error shape are retained to demonstrate that the default-origin path remains active without sending credentials.

## Command and environment

Run from the repository root on Node 24 or newer:

```bash
docs/proof/operational-health-zombie-runs/run-proof.sh
```

The proof uses pinned Wrangler 4.107.0, loopback HTTP only for the injected stub, and a synthetic webhook secret. Generated payloads, request traces, logs, and `proof-summary.json` are written to `.artifacts/operational-health-zombie-runs/` by default.

## Limits

The stub implements the GitHub REST response shapes consumed by `/api/status`; it does not emulate GitHub authentication, GraphQL, rate limiting, cancellation, or the production scheduler. Unit tests cover the strict 24-hour boundary and URL validation. The live production population and the failed cancel/force-cancel attempts are prior coordinator measurements, not repeated by this proof.

## OpenClaw Bay impact

No Bay contract or implementation changes. Bay remains an observer-only projection of workflow and review journeys. This change affects only the dashboard status payload and its derived health reason; it adds no queue, workflow, GitHub, recovery, deploy, or rollback action.

---

### Overview (`docs/proof/operator-record-read-auth/README.md`)

# Operator canonical-record read authentication proof

Production exact-review reconcile run `31651591787` at `2026-08-12T23:38Z` checked ten head-mismatch targets and received `401` from every canonical completed-review lookup. The operator signed the existing read-only record GET with `EXACT_REVIEW_OPERATOR_SECRET`, while the Worker accepted only `CLAWSWEEPER_WEBHOOK_SECRET`. The shared-secret test setup for [openclaw/clawsweeper#1148](https://github.com/openclaw/clawsweeper/pull/1148) hid that boundary mismatch.

The fix keeps the route and signature shape unchanged. `GET /internal/state/records/<repo-slug>/items/<number>` verifies the webhook secret first and, only if that fails, verifies the operator secret because reconciliation reads active items only. The `closed`, `plans`, and `decision-packets` collections remain webhook-only. Existing 503 behavior remains unchanged for missing required credentials. The operator script and workflows remain unchanged.

The executable [behavior contract](behavior-contract.md) and [RED/GREEN record](red-green.md) close the shared-secret coverage gap. `run-proof.mjs` extracts the merge base, boots it with distinct secrets, publishes all four synthetic records, and proves the full operator/webhook/garbage matrix. It then kills the complete Wrangler process tree, confirms the health endpoint is down, and boots the candidate on the same port with separate persistence. The router-level unit test independently covers the same candidate matrix plus missing configuration.

Run the real-Worker comparison from a committed head with:

```bash
node docs/proof/operator-record-read-auth/run-proof.mjs \
  "$(git rev-parse HEAD)" \
  "$(git merge-base HEAD origin/main)"
```

The final Docker-backed Crabbox `provider=local-container` receipt, tested executable head, lease, full matrix, and gate totals are frozen in [receipt.json](receipt.json). The [behavior report](behavior-report.json), captured transcript, and stderr are recorded beside it.

OpenClaw Bay is unaffected: no queue lifecycle, telemetry, dashboard data contract, or observer/action boundary changes. The operational-cursor route is also unchanged because its only current consumer uses the webhook secret.

---

### Overview (`docs/proof/operator-skip-taxonomy/README.md`)

# Dead-letter operator skip-taxonomy proof

Production reconcile run 31646150689 at 2026-08-12T22:15Z reported `inspected_targets=3`, `recovered_targets=0`, and `skipped_targets=125`, but `skip_reasons={}`. With 191 open rows still in the dead-letter tail, the operator could not distinguish stale pull-request heads from active work, ineligible rows, caps, inventory safety exits, or other conservative skips.

This change makes the existing accounting honest without changing reconciliation decisions. Each deterministic skip branch records a stable class at the point where it already increments the target count. GitHub and transport failures retain the existing shared classifier. Revalidation aborts split the bulk count across the target that changed, targets already inspected, and targets not reached, so the summary remains exact instead of attributing unrelated targets to the triggering condition.

The runtime now emits a non-throwing `reconcile_skip_accounting_inconsistent` marker if the reason-count sum ever differs from `skipped_targets`. The loopback harness checks that marker across every successful reconcile scenario, while the mixed invariant fixture directly asserts four reason counts for four skipped targets.

The behavior contract is in `behavior-contract.md`; the red/green record is in `red-green.md`. After the single review fix round, the final Docker-backed Crabbox run used `provider=local-container`, lease `cbx_d053a32ae64d` (`coral-crayfish-d152`), and image `node:24-bookworm` against committed head `2d10e57a57b61dae2caf776c3f0004844366dca1`. It passed all 82 operator scenarios and stopped automatically. `receipt.json` binds that head, every executable proof input, the sanitized transcripts, the zero-finding secret scan, and cleanup state.

OpenClaw Bay needs no change: it already consumes the dynamic observer-only `skip_reasons` map, and this work adds neither a new transport shape nor an action surface.

---

### Overview (`docs/proof/paired-close-drift/README.md`)

# Paired-close drift proof

Active proof owned by apply close-policy and terminal mutation guards. Run from
the repository root after `pnpm run build`:

```sh
node docs/proof/paired-close-drift/run-proof.mjs
```

The command runs the actual compiled `apply-decisions` CLI in non-dry-run mode
with the native GitHub CLI against a strict, stateful local HTTP service.
The disposable gh configuration uses its documented `http_unix_socket` option;
all REST and GraphQL requests go through a private Unix socket. There is no
replacement gh executable and no inherited credential. Only a synthetic token
is provided, with public-network proxies disabled by an unreachable local proxy.
The server rejects unknown routes and mutations. It models GitHub's response
shapes, so native gh performs real request serialization and response parsing. Reports, runtime
artifacts, items, closed records, plans and canonical baselines are private
fixtures. The inherited private `TMPDIR` is preserved, including the short socket paths. The synthetic target
namespace is `openclaw/openclaw`, whose profile admits the minimal
`not_actionable_in_repo` fixture; no external repository is read or changed.

Both main and the candidate execute the same scenarios. The HTTP service triggers
counterpart drift only when it observes the parent's actual closeout-note write:

- A stable pair closes both synthetic items.
- A newly locked counterpart must prevent the parent close.
- A fresh counterpart read failure must preserve its known pair identity and
  prevent the parent close.
- A previously closed counterpart that reopens with a new timestamp must be
  re-evaluated and prevent the parent close.

Main closes the parent in the drift scenarios. The candidate performs terminal
revalidation and skips it. The read-failure run exits nonzero when the CLI later
tries to process the independently selected, unreadable issue; the decisive
observation is that the parent close was suppressed. Its partial apply report
contains the explanatory pair skip.

The output directory (default `.artifacts/paired-close-drift`) contains JSON
mutation traces, apply results, stdout/stderr and a concise summary. Temporary
runtime copies are removed on completion. Pass an output directory and one
scenario name to run a focused case.

This is a general same-author pair proof using supported reports with current review-activity cursors and without
lease tuples. Current lease and implementation-linked issue-first paths retain
their focused regression coverage. The change revalidates eligibility before
mutations; it does not provide a remote two-item transaction or guarantee against
changes after the final read. OpenClaw Bay has no schema or observer change.

Update this proof when pair admission, terminal policies or mutation sequencing
changes. Verified with this repair on Node 24.20.0 and native gh 2.100.0 on macOS.
This proof requires POSIX Unix sockets; set `PAIR_NATIVE_GH` for a different
native gh binary path. TLS and live GitHub availability are outside its scope.

---

### Overview (`docs/proof/parked-command-finalization/README.md`)

# Parked command finalization behavior proof

## Contract

Claim: exhausted command producers are not deleted or restarted on a GitHub close. A bounded, exact-revision plan schedules only the existing acknowledgement finalizer. Producer cleanup follows an observed receipt or explicit locked/missing skip. Reopen/takeover/unknown states cannot authorize cleanup. Bay distinguishes retained exhausted records, scheduled retries, and live workers without changing its public allowlist or introducing actions.

Surface: production dashboard Worker, ExactReviewQueue, real local workerd/SQLite persistence and signed HTTP routes; production Bay HTML in real Chromium. The fixture-only Worker wrapper seeds exhaustion and invokes the production alarm; it does not replace the runtime logic. External GitHub responses are loopback synthetic fixtures.

Command: `node docs/proof/parked-command-finalization/run-proof.mjs` in Docker-backed Crabbox `--provider local-container --local-container-image node:24-bookworm`. Requires frozen-lockfile dependencies, Wrangler, Chromium, and Node >=24.

Scenarios: marker-only/comment-ID-only commands; closed/merged/open/ambiguous; repeat and Worker restart; reopen and source takeover; failed receipt then retry; observed receipt and explicit locked/missing receipt skip. Mixed Bay queue state and no browser GitHub traffic. Unit/workflow regressions additionally cover the 11+1 skip census and pre-disposition retry wording.

Artifacts: `.artifacts/parked-command-finalization/result.json`, bounded HTTP trace, browser screenshot, and current-head/runtime identity. Record Crabbox lease/provider/image/run identity in the PR body after execution.

Limits: no live queue, real contributor, production dispatch, deployed Worker, or complete hosted Actions job. Fixture control routes exist only in this local proof configuration. No audit inventory/private repository identifiers are used or published. Tests alone do not replace this proof.

Build `pnpm run build:all` before the proof: it executes the compiled production
command-status CLI as a subprocess. The proof-only `gh-fixture.mjs` adapter
transports that CLI's GitHub requests to the loopback fixture. One case advances
the producer during comment lookup and proves zero PATCHes; another proves the
just-in-time fence, actual PATCH, release, and correlated receipt. The existing
Worker routes and SQLite owner are used, not an extracted-function replacement.

A parked finalizer reserves a bounded status-write window. After comment reads,
the CLI revalidates the original producer, target, lease and acknowledgement
attempt. Successor dispatch waits while that write window is owned. Known stale
conflicts skip without a status mutation; unclassified failures remain failures.
PATCH has a shorter transport deadline than the reservation, and a successful
write releases ownership. Missing receipt and locked-conversation outcomes retain
the existing explicit terminal-skip path.

The finalizer workflow runs terminal eligibility admission before requesting its
target write token. The runtime proof executes that exact Bash/curl step against
the real local Worker with no runner GitHub credential, proves revocation returns
allowed=false, and then proves restored eligibility authorizes the later step.
The token action is gated on allowed=true; status PATCH additionally requires
successful token creation. This is controlled workflow-boundary proof, not a
hosted GitHub Actions execution.

Additional recovery scenarios exercise a second closure without an intervening
webhook and a failed status writer releasing a held new-source successor. The
former allocates only fresh acknowledgement/lifecycle ownership and never
resets review budgets. The latter uses real signed enqueue/alarm/retry HTTP
routes; only that separately supplied new source may become eligible for a
normal review dispatch to the synthetic GitHub adapter.

---

### Overview (`docs/proof/parked-reconcile-skip-reasons/README.md`)

# Parked reconciliation skip-reason proof

## Claim

Parked-review reconciliation now reports bounded, sanitized, per-target inspection-failure reason
classes and samples. The 20 skipped rows in scheduled production run
https://github.com/openclaw/clawsweeper/actions/runs/31449984643 were caused by the workflow GitHub
token's target-read boundary: replaying that run's immutable 20-row inventory through the unchanged
read-only operator with Peter's personal `gh` token classified every target.

The after-fix trace also proves the error path through a real loopback HTTP listener: 20 issue-read
403s produce exactly 20 `http_403` skips, while a mixed run with two open targets produces exactly 18
`http_403` skips and preserves the two successful targets.

## Exercised surface

- Production artifact `exact-review-dlq-reconcile-31449984643-1` (artifact id `9085971968`)
- Built `scripts/exact-review-dead-letter-operator.mjs --action reconcile-parked` without `--execute`
- Peter's personal GitHub token from `gh auth token`
- The live public queue-pressure payload (`idle`, capacity 128, active 7)
- Node 24.19.0 and pnpm 11.10.0 on macOS

The production environment-scoped `EXACT_REVIEW_OPERATOR_SECRET` is intentionally non-retrievable.
The signed inventory request was therefore replayed over loopback from the immutable production
artifact. Null `excluded_reason` fields added by artifact sanitization were omitted to restore the
signed list route's wire shape. GitHub target inspection and classification remained live and used
the personal token. No queue mutation route was available from the loopback replay, and the operator
was not passed `--execute`.

## Diagnosis record: base-SHA replay

This section is the original diagnosis record, not the after-fix error-path proof. Its replay used
base SHA `c145b4599285969b43e40d0816071893d5090501`; full provenance remains in
`production-provenance.json`.

The scheduled workflow-token run emitted:

```json
{"action":"reconcile-parked","dry_run":false,"inventory_complete":true,"queue_pressure":"idle","inspected_targets":20,"terminal_targets":0,"repository_gone_targets":0,"resolved_targets":0,"open_targets":0,"recovered_targets":0,"skipped_targets":20}
```

The personal-token read-only replay emitted the exact contents of `read-only-summary.json`: all 20
targets were inspected, 1 was terminal, 19 were open, 5 fit the bounded recovery preview, and the
remaining 14 were skipped only by the recovery budget. There were no inspection failures, so
`skip_reasons` is empty.

## After-fix error-path trace

`run-error-trace.mjs` read the same immutable artifact (SHA-256
`1187c6042803b5ba98048d64157cb98a5399c1cbde76b69ce25f18dffe23b88f`), bound a real Node HTTP
listener to `127.0.0.1` on an ephemeral port, and launched the current source-tree operator as a
separate process with `GITHUB_API_URL` pointing at that listener. Both runs omitted `--execute`,
unset `GITHUB_TOKEN`, exposed no mutation route, and recorded only redacted request metadata.

All 20 issue lookups returned 403. `all-403-summary.json` contains this verbatim summary:

```json
{"action":"reconcile-parked","dry_run":true,"inventory_complete":true,"queue_pressure":"idle","inspected_targets":20,"terminal_targets":0,"repository_gone_targets":0,"resolved_targets":0,"open_targets":0,"recovered_targets":0,"skipped_targets":20,"skip_reasons":{"http_403":20},"skip_samples":[{"target":"steipete/codexbar#2367","reason":"parked review target check failed for steipete/codexbar#2367 with 403"},{"target":"steipete/codexbar#2407","reason":"parked review target check failed for steipete/codexbar#2407 with 403"},{"target":"steipete/codexbar#2469","reason":"parked review target check failed for steipete/codexbar#2469 with 403"}]}
```

The mixed scenario returned 200-open for the first two targets and 403 for the remaining 18.
Because the dry-run recovery preview rechecks open targets, the socket trace contains four 200 issue
responses for two unique targets. `mixed-summary.json` contains this verbatim summary:

```json
{"action":"reconcile-parked","dry_run":true,"inventory_complete":true,"queue_pressure":"idle","inspected_targets":20,"terminal_targets":0,"repository_gone_targets":0,"resolved_targets":0,"open_targets":2,"recovered_targets":2,"skipped_targets":18,"skip_reasons":{"http_403":18},"skip_samples":[{"target":"steipete/codexbar#2469","reason":"parked review target check failed for steipete/codexbar#2469 with 403"},{"target":"steipete/codexbar#2471","reason":"parked review target check failed for steipete/codexbar#2471 with 403"},{"target":"steipete/codexbar#2473","reason":"parked review target check failed for steipete/codexbar#2473 with 403"}]}
```

`after-fix-error-trace.jsonl` records the 46 loopback requests and response statuses.
`after-fix-error-trace-provenance.json` records the artifact identity, exact operator content hash,
command, transport, response mix, and proof limits.

## Gates

- `pnpm run build:all`: passed
- `pnpm run test:no-build`: 3,318 tests; 3,309 passed, 9 skipped, 0 failed
- `pnpm run lint`: passed
- `pnpm run format:check`: passed
- `pnpm run check:active-surface`: passed

Fresh-PR container proof used Crabbox `provider=aws`, lease `cbx_0fc9d2f49c92`
(`pearl-prawn-4739`), and run `run_2f53d8d972e6`. The clean PR 1117 checkout at
`8dd3a55bb774ec30fdc5a39fbf7957f53810863f` ran inside `node:24-bookworm` on Docker 29.7.1.
Corepack installed pinned pnpm 11.10.0. jq 1.8.1 was installed under `$HOME/.local/bin` only after
`jq-linux-amd64` verified against the official release checksum
`020468de7539ce70ef1bceaf7cde2e8c4f2ca6c3afb84642aabc5c97d9fc2a0d`. All 57 focused operator
tests passed in 11.2 seconds for that diagnosis-round head; Crabbox reported exit 0 and stopped the
lease automatically. Full machine-readable details are in `container-provenance.json`. The final
after-fix head receives a separate fresh-PR container run after push.

## Limits and Bay impact

This production observation proves the token-boundary diagnosis and the successful-target summary.
The focused operator tests cover per-target standard-reconcile discovery and recovery-revalidation
attribution, reason classification, bounded samples, credential and control-byte sanitization, and
output truncation. The replay did not mutate production queue state and cannot prove the production
Worker's signed list route beyond the immutable uploaded artifact.

OpenClaw Bay is unaffected. The change adds diagnostic fields to an operator-only JSON summary; it
does not change lifecycle publication, dashboard data, or the observer-only Bay surface.

---

### Overview (`docs/proof/parked-review-reconcile/README.md`)

# Parked review reconciliation proof

## Claim

The real local dashboard Worker and `ExactReviewQueue` Durable Object expose a bounded, signed
inventory for parked reviews. After the existing automatic recovery budget is genuinely exhausted,
the parked-review operator resolves a terminal target and re-enqueues an open target as a fresh
pending review with a reset recovery budget, while leaving a command-context target parked for its
maintainer-command obligations.

## Exercised surface

- Real `wrangler dev --local` Worker and Durable Object with disposable persistence
- Signed exact-review enqueue and parked-review operator routes
- The unchanged three-rung parked recovery alarm path (5/10/20 minutes, persisted 0.75-1.5x jitter)
- Built `scripts/exact-review-dead-letter-operator.mjs --action reconcile-parked --execute`
- A loopback GitHub stub for App installation tokens, live issue state, workflow state, and
  repository-dispatch rejection
- Full Wrangler process-tree stops, restart from the same Durable Object persistence, and a
  read-only DO schema-instantiation assertion

## Controlled scenario

Two ordinary open issues and one command-context review are enqueued through the signed Worker
route. The command uses the real legacy command intake shape: a pull-request item with
`sourceAction: "legacy_dispatch"`, command status marker, status comment id, and additional prompt.
`exactReviewQueueHasCommandContext` recognizes that stored decision. The loopback GitHub stub
returns the single-field HTTP 422 validation response that the production dispatcher classifies as
`permanent_rejection`, parking each item as `dispatch_rejected`. Wrangler alarms perform all three
automatic recoveries; every recovered item reaches the same real dispatch path and parks again.
The proof waits until all three inventory rows report `parked_recovery_attempts: 3` and the command
row reports `excluded_reason: "command_context"`.

The Worker process tree is then stopped. The proof opens Wrangler's disposable SQLite database only
to assert that the `exact_review_queue_parked_actions` table was instantiated; it never inserts,
updates, or deletes queue state. The Worker restarts against the same persistence with its normal
90-second enqueue debounce. The stub marks the ordinary terminal target and the command-context
target closed, then accepts dispatches. The real
operator classifies the targets, resolves the closed row with an audit note, fresh-recovers the open
ordinary row, and skips the command-context row before GitHub inspection. Direct signed resolve and
recover requests for that command row both report one skipped mutation. The proof observes the
ordinary recovered row as `pending` with `parked_recovery_attempts: 0` and the command-context row
unchanged as `parked` with `parked_recovery_attempts: 3`.

## Command and timing

Run from the repository root on Node 24 or newer with Docker/OrbStack available:

```bash
bash docs/proof/parked-review-reconcile/run-proof.sh
```

The recovery ladder is deliberately not shortened or faked. Its persisted jitter makes exhaustion
take 26.25-52.5 minutes; the script has a 60-minute hard deadline. Generated evidence is written to
`docs/proof/parked-review-reconcile/artifacts/` unless
`PARKED_REVIEW_RECONCILE_PROOF_OUTPUT` overrides it.

## Required observations

- The Durable Object is instantiated and the parked action-receipt table exists.
- All three rows are visible through the signed list route after exactly three automatic recoveries.
- The command-context row is flagged with `excluded_reason: "command_context"`.
- The operator inspects two targets, resolves one terminal target, and recovers one open target.
- The operator counts the excluded command-context target as skipped without inspecting it.
- Signed resolve and fresh-recover requests both refuse the command-context row.
- The terminal target has no queue item after reconciliation.
- The open target is pending with attempts and parked recovery attempts reset to zero.
- The final parked inventory contains only the unchanged command-context target.

## Limits and Bay impact

The GitHub service is a loopback behavioral stub; no production GitHub repository, Worker, secret,
comment, or workflow is contacted or mutated. The proof covers the real Worker/DO state machine,
HTTP signing, alarms, operator process, and persistence boundary, not GitHub's hosted implementation.
It exercises the initial command-review dispatch-rejection route. Terminal-finalization command
acknowledgements use their separate pending retry path and are intentionally outside this parking
scenario.
OpenClaw Bay is unaffected: it remains a public observer-only surface and gains no recovery, DLQ,
queue, workflow, deploy, or rollback action.

---

### Overview (`docs/proof/post-proof-accepted-baseline/README.md`)

# Accepted post-proof baseline: apply-path proof

## Claim and surface

A ClawSweeper acknowledgement update must not cause a repeated review of an unchanged PR.
The accepted timestamp is not sufficient by itself. A later contributor edit must still block
publication and close.

The proof runs `node dist/clawsweeper.js apply-decisions`, not the freshness function alone.
It uses the shipped CLI, report parser, source gate, coverage-proof runner, post-proof gate,
review-comment publisher, and PR close path. It uses the existing test helpers to supply a
stateful `gh` process and a controlled coverage-proof response. No product function is replaced.

## Fixture and scenario

The fixture is an old PR close proposal for `duplicate_or_superseded`. Its canonical PR is merged.
The review has a complete source revision, timeline revision, head SHA, and PR activity cursor.
The stored `updated_at` is `2026-05-01T00:00:00Z` (T0). The live PR and the acknowledgement
comment both have `updated_at` `2026-05-01T01:00:00Z` (T1). The acknowledgement has the exact
`clawsweeper-pr-ack:opened item=158915` marker and review-progress markers. These synthetic times
make the fixture old enough for the normal apply gates. The marker shape follows the incident at
<https://github.com/openclaw/openclaw/pull/158915>.

The fixture pre-seeds the managed rating label. Thus, a label-sync write cannot create an
additional apply-owned receipt and hide the regression. The driver asserts this condition.

Each revision runs three isolated cases:

1. **Acknowledgement only:** the live source and activity receipt match the stored review.
2. **Same-second title edit:** after coverage proof starts, the mock changes the title but keeps
   T1. The pre-apply gate has already accepted T1. The fresh structural receipt must reject the edit.
3. **Human comment after proof:** after coverage proof starts, the mock adds a contributor comment.
   Its timestamp is after the proof start. The PR still reports T1. Apply must reject the activity.

The mock records every `gh` request, including method, path, and sanitized arguments. It also
records all close and durable comment writes. Each run retains stdout, stderr, the stored review,
and the apply report. The driver asserts that rejected cases have no close or durable writes.

## Observed result

The base is `f3be2fcbbdad33596d1d3874d42340486cb339f2`. The candidate code is
`3d7cd274b6935ffa73e45ba57226ef8e20632ab9`. The proof-only commit does not change product code.

| Scenario                  | Revision  | `action_taken`                 | Drift log | Close writes | Durable writes |
| ------------------------- | --------- | ------------------------------ | --------- | ------------ | -------------- |
| Acknowledgement only      | Base      | `skipped_changed_since_review` | Yes       | 0            | 0              |
| Acknowledgement only      | Candidate | `closed`                       | No        | 1            | 1              |
| Same-second title edit    | Base      | `skipped_changed_since_review` | Yes       | 0            | 0              |
| Same-second title edit    | Candidate | `skipped_changed_since_review` | Yes       | 0            | 0              |
| Human comment after proof | Base      | `skipped_changed_since_review` | Yes       | 0            | 0              |
| Human comment after proof | Candidate | `skipped_changed_since_review` | Yes       | 0            | 0              |

Every blocked case reports `updated_at changed`. The human comment changes the structural
receipt, so it is rejected before the later non-automation-activity check. Every CLI process
exits 0: a conservative skip is a valid apply result.

See the [receipt](artifacts/receipt.json), [base results](artifacts/base/results.json),
and [candidate results](artifacts/candidate/results.json). Each result links its request trace.
The adjacent `service-responses.jsonl` records the PR and comment responses before and after
coverage proof starts. In the candidate title-edit case, the drift diagnostic has
`accepted_baseline: true` and `accepted_baseline_receipt_matches: false`. This shows that
the accepted timestamp alone did not authorize a durable publication or close.

The proof ran with Crabbox 0.74.0, provider `local-container`, image `node:24-bookworm`,
Node v24.21.0, pnpm 12.4.1, and lease `cbx_123bf98cfac9`. The receipt records the immutable
image ID, run ID, artifact hashes, and limits. The container has no home or credential mount.
Its only host mount is Crabbox's read-only bootstrap directory. Network access is used for
container setup and dependency installation; the apply process uses only local mock services.

## Command and environment

From the candidate checkout, create an archive of the base revision and transfer it to the
container. Then run:

```sh
crabbox run --provider local-container --id post-proof-1934 --no-hydrate --timing-json -- \
  bash docs/proof/post-proof-accepted-baseline/run-proof.sh \
  /tmp/post-proof-base.tar /tmp/post-proof-results
```

`run-proof.sh` builds both revisions and runs the same driver in each checkout. The base archive
must contain the complete source tree from `origin/main`. The driver uses temporary report and
closed directories, `--skip-dashboard`, and `--item-number 158915`. It does not use a GitHub token.

## Limits

This is controlled runtime evidence, not a live GitHub or model-quality test. GitHub reads and
writes terminate in a local mock process. The coverage-proof process returns a fixed allowed
result. The proof does not test GitHub timestamp precision, network failures, the hosted workflow,
or the semantic quality of a model decision. It proves the shipped apply path under the stated
source and activity transitions. No production item is changed.

OpenClaw Bay is not affected. This change does not change the queue, status, telemetry, or
dashboard data contract.

## Related timestamp-lag proof

The [owned-write timestamp-lag proof](owned-write-lag/README.md) extends this harness to cover
a durable review PATCH whose timestamp reaches the PR only after the first post-write item read.
Pass `owned-write-lag` as the third argument to `run-proof.sh` to run those cases.

---

### Overview (`docs/proof/pr-read-model-kind/README.md`)

# PR read-model identity proof

- Status: active controlled proof fixture
- Owner: ClawSweeper dashboard and queue maintainers
- Source of truth: `dashboard/github-webhook-read-model.ts`
- Base: `1e7c8d9981416ad8e230ab5b4987668053ed8841`
- Last verified source: `dashboard/github-webhook-read-model.ts` SHA-256
  `570d5058f0d66bfce739181886f8807b53fa11d35a93ffb45f174b24791b9086`
- Observed on Node 24.19.0: exact PR head reserved, drift refused, old rows classified as PRs, marker metadata preserved
- Update when: item projection, webhook merge, inventory, or reservation changes

After building on the qualified remote backend, run
`node docs/proof/pr-read-model-kind/run-proof.mjs`. Node 24+, Corepack, curl,
and pinned Wrangler 4.131.1 are required. The driver creates temporary workerd
SQLite state and an isolated Wrangler home, then deletes both on exit.

The fixture sends signed raw PR events into the actual read-model store and
consumes signed item responses through the actual runner client, inventory,
revision selector, and reservation command. It verifies PR heads, drift refusal,
old-row projection, marker metadata after a later raw update, placeholder kind,
and unchanged issue revision selection. Observations and source hashes go to stdout.

The GitHub head lookup and comment receiver are synthetic loopback endpoints;
issue digest calculation is stubbed, so the proof covers its selection only.
This proves the changed store-to-reserver contract, not production GitHub
publication, hosted workflow admission, or Cloudflare edge capacity. Worker
outbound requests are blocked. No production credentials or writes are used.
OpenClaw Bay's public observer contract is unchanged.

---

### Overview (`docs/proof/pr-review-once/README.md`)

# One automatic PR review after a quiet window

## Claim and exercised surface

Ordinary PRs receive their first automatic review after ten quiet minutes.
Source changes restart the window. A completed canonical PR answer suppresses
later automatic webhook and scheduled work, including after a Worker restart.
Explicit review requests and opted-in repair automation remain available.

The proof executes the production `ExactReviewQueue` and direct publication
store in workerd with persisted SQLite. A loopback HTTP fixture supplies GitHub
PR reads, installation tokens, and repository-dispatch responses. It exercises
the real queue admission, alarm, dispatch, claim, publication, and restart paths.

## Command and environment

Run from the source checkout with Node 24 or newer and a separate tool prefix
containing `wrangler@4.131.1` (Miniflare 5.20260911.0-alpha and workerd
1.20260911.1) and its esbuild dependency. Extract the previous implementation
into a temporary fixture to exercise its actual writer and pruning code:

```sh
git show adf080a6318b96e9665cc46de87f97641f3cfa23:dashboard/exact-review-direct-publication.ts > "$LEGACY_PUBLICATION_SOURCE"
node scripts/proof-pr-review-policy.mjs "$TOOL_PREFIX" "$FRESH_OUTPUT_DIR" "$LEGACY_PUBLICATION_SOURCE"
```

Executed on macOS arm64 with Node 26.7.0. AWS Crabbox source transfer failed;
the local container service subsequently became unavailable. Validation used
an isolated temporary source copy with its own frozen-lockfile dependencies.
No dependencies were installed in the shared checkout or managed worktree.

## Observed results

The checked-in [result.json](result.json) records a passing run and SHA-256
identities for all nine policy source files and the legacy fixture.

- Minute 0: enqueue succeeds; alarm holds the initial review until minute 10.
- Minute 10: an intervening body edit extends the hold to minute 20.
- Minute 20: exactly one dispatch occurs. Publishing the completed answer then
  rejects that old workflow's claim with `review_request_required`.
- After a fresh workerd instance opens the same SQLite store, synchronize,
  hot-intake, and normal-backfill events produce no additional dispatch.
- Failed and stale-source reports leave first-review admission available.
- Canonical archive/reopen mutations preserve completion provenance: a stale-source
  report remains eligible, while a completed answer still suppresses automatic work.
- The previous implementation writes and prunes legacy records. After a fresh
  Worker opens that database, unverified and already-pruned reports remain
  eligible. A verified report with retained completion provenance stays answered.
  Pruning first after upgrade also records that answer before deleting its receipt.
- An explicit request and an autofix opt-in each dispatch successfully.
- Removing the autofix label after dispatch rejects the delayed automatic claim.

Focused tests additionally cover push/revert activity between observations,
comment-only timestamps, legacy report seeding, failed replacements, tombstones,
and preservation of a newer explicit request when rejecting an old lease.

## Limits

GitHub responses and the clock are controlled fixtures. The proof does not call
a model, mutate a live PR, or establish deployment of the Worker. Source hashes
bind the result to the tested implementation; production deployment remains a
separate observable event.

---

### Overview (`docs/proof/proof-context/README.md`)

# Bounded primary-body producer proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

- Status: historical proof recipe/artifact, not an operator runbook
- Scope: raw primary issue/PR body and PR files through production hydration,
  compaction, and final review-prompt JSON; media discovery and complete-source
  freshness
- Source: retired `proof-context.ts` producer script,
  [shared fixture](../../../test/primary-body-fixture.ts), and
  [primary compactor](../../../src/clawsweeper-primary-body.ts)

From a checkout with Node 24 or newer and the pinned pnpm 11.10.0 installed:

```sh
pnpm run build
node scripts/e2e/proof-context.ts > proof-context-receipt.json
```

The default synthetic case contains 60,641 UTF-16 units: early supplemental
mock text, a later inert native-proof heading at offset 14,235, and an inert
HTTP/native-row trace at 19,562. The script executes the real
`collectItemContext` and final `reviewPrompt` path with locally supplied GitHub
transport; neither the compactor nor renderer is replaced. It shares fixture
wiring with the regression tests but runs as an ordinary executable, without
the test runner. Unexpected hydration capabilities fail closed.

The stdout JSON receipt records the current checkout HEAD, environment, source
and prompt hashes, exact retained ranges and excerpt hashes, omissions, and
serialized allocation. Both issue and PR representations must retain verbatim
excerpts within 12,000 serialized units per long body, including coverage and
indentation. An equal-length edit in omitted text must leave displayed evidence
unchanged while changing source revision, snapshot, content, and structural
identities. The default case edits the final source unit. Separate synthetic
media cases must produce zero supplemental runner calls, with one recording-only
prefix control call. PR patch-only cases cover a loopback fixture and harmless
prefix controls through the real collection and media-preparation owners. Each
must produce zero runner calls and no manifest or artifacts, while preserving
the compact patches in final prompt JSON. The same URL in the primary issue
body, PR body, or comment must still produce one recording-only call even when
also present in a patch. No runner call performs remote or loopback I/O.

Media fixture URLs are constructed from obvious parts at runtime, preserving
their assertion values without placing downloadable literals in this PR's
aggregate diff. This keeps existing reviewers safe before the patch-discovery
exclusion is deployed; it does not replace that production boundary.

An optional `--body-file path/to/body.md` reads authorized local text instead of
the synthetic body. It reports no file path or full body/trace bytes. Replay
requires a long body with an editable omitted range; recognized native-proof
and HTTP/native trace anchors must survive. Media checks always use synthetic
input. Do not commit private source bodies or prompts. The receipt identifies
HEAD but does not certify a clean working tree; rebuild and rerun after the
final commit before citing it as committed proof.

This is **input delivery and omission proof only**. The provider is a local
Node process, with no container image or lease. It does not invoke a model,
GitHub, cloud services, embedded scripts, or the original runtime described by
any saved body. Local GitHub transport is a fixture boundary, not live GitHub
integration proof. Verbatim excerpts do not establish source authenticity,
proof sufficiency, or a guaranteed reviewer verdict. Unrecognized or crowded
layouts can still omit material; coverage remains explicitly incomplete.
PR patches remain reviewer-only media inputs. No body-budget increase, extra
media fetch, proof-status/schema enum change, or weakened proof requirement is
part of this fix. OpenClaw Bay is unaffected: no observer fields, routes,
lifecycle states, or controls change.

---

### Overview (`docs/proof/publication-api-budget/README.md`)

# Publication quota request-budget proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

Claim: stop repeatedly calling an exhausted GitHub credential during publication
without reusing stale responses or changing publication/worker capacity.

Surface: the production GitHub runtime and retry executor, run in eight separate
publisher processes sharing the same batch observation and fallback-lock files.
The controlled fixture uses native HTTP on loopback and synthetic credentials.
An exhausted public read pool returns 403, one App fallback succeeds, and later
reads must defer. After the fixture expires the observations and changes the
source, permitted reads must observe the changed metadata and comments.

Command: `node scripts/e2e/publication-quota-budget.mjs` after `pnpm run build`.
The driver compares the checked-out base runtime with the changed runtime,
asserts equivalent deferred outcomes, counts actual loopback requests, and checks
fresh reads after reset. Its JSON result records the base and source hashes.

Measured on Crabbox provider `aws`, lease `cbx_ba682171e2d0`, Linux/Node 24.18.1,
image `ami-0461d919be7deb53c`. The [focused validation and proof run](https://crabbox.openclaw.ai/portal/runs/run_1ce115249f201d871658f100a5a62b15)
passed all 90 focused tests and the request-budget driver.

The [retained result](result.json) records 11 requests before the change versus
3 afterward: exhausted public reads dropped from 9 to 1, with one reset lookup
and one App fallback retained in both cases. All eight publisher outcomes remain
deferred. The changed runtime carries the authoritative reset across all eight
outcomes; the baseline replaces it with a fallback delay on later failures.
After reset, both versions make two fresh requests and observe the changed item
and comment bytes. No cached response substitutes for those fresh reads.

This establishes controlled runtime behavior, not production throughput or GitHub
quota accounting. Healthy-publication request counts are outside this claim.

OpenClaw Bay is unaffected: no public response fields, lifecycle meanings, or
observer-only behavior change. Existing v1 circuit-skip metrics record deferrals;
no synthetic wire-attempt or throttle observations are emitted.

---

### Overview (`docs/proof/publication-capacity-recovery/README.md`)

# Publication capacity recovery proof

This local proof runs the frozen main and candidate queue owners through signed
Worker HTTP routes in real Workerd with SQLite-backed Durable Objects.
It demonstrates ten post-cooldown published members, partial and completed
replays, stale fences, duplicate-envelope rejection, process restart, mixed quota
feedback, and SQL plus KV rollback after a late membership failure.

Run `node docs/proof/publication-capacity-recovery/run-proof.mjs` with
`CAPACITY_PROOF_BASELINE` pointing to the verified frozen-source fixture and
`CAPACITY_PROOF_WRANGLER` pointing to Wrangler 4.131.1. The native proof wrapper
pins source/install inputs and Workerd 1.20260911.1, denies external network,
and verifies owned process and socket cleanup before accepting the result.

The fixture supplies public-target admission, synthetic publication tuples, and
a controlled future clock. Its failure trigger aborts a real SQLite membership
write. Production queue and controller code are imported without replacement.
The baseline and candidate use the same fixture bytes. Results and bounded
request hashes are written under `.artifacts/publication-capacity-recovery`.

No live GitHub publication or production queue operation is performed. This
proves the canonical batch recovery invariant; it does not measure production
throughput or imply that legacy completions cannot recover the shared ceiling.
Bay remains an observer of the existing public capacity field.

---

### Overview (`docs/proof/publish-main-record-diff/README.md`)

# Publish-main record diff proof

- Status: proof for streaming the canonical tuple diff in publish-main
- Owner: ClawSweeper record-state maintainers
- Source: `src/repair/publish-main.ts` (`planCanonicalRecordTuples`)
- Update when: canonical tuple planning or record publication paths change

## Problem

Apply checkpoints publish `--path records/openclaw-openclaw`. To find the changed tuples, `planCanonicalRecordTuples` read every record file of the working tree and of the hydrated state tree into two Maps.

The review-record backfill made those trees large, and the result was two full copies of the repository's records in memory at once. Run https://github.com/openclaw/clawsweeper/actions/runs/38034255814 shows the failure. `apply-decisions` finished normally, then `node dist/repair/publish-main.js --path records/openclaw-openclaw` hit `Reached heap limit` within ten seconds. The apply lane therefore still failed after https://github.com/openclaw/clawsweeper/pull/1877 and https://github.com/openclaw/clawsweeper/pull/1880 (https://github.com/openclaw/clawsweeper/issues/1874).

## Change

Planning now collects paths only, with the same symlink and regular-file checks. It compares each file pair as it goes and keeps only the changed paths.

Changed tuples read their contents on demand through the existing containment-checked reader. Published tuples and their operations are unchanged.

## Command

```sh
pnpm run build:repair   # in both checkouts
node docs/proof/publish-main-record-diff/run-proof.mjs <base-checkout> <candidate-checkout> receipt.json
```

Each run executes `publish-child.mjs` with `--max-old-space-size=384`. The child calls the checkout's real `publishMainWithStateAppend` for `records/openclaw-openclaw`. The scenario has a source tree and a hydrated state tree of 1,600 items × 512 KiB each, about 800 MB per tree. Items 1 and 2 are updated and item 3 moves to `closed/`. A fixture queue accepts the posted tuples, and git fallback is forbidden.

## Observed

| Run | Commit | Result |
| --- | --- | --- |
| Base (main) | `a6d9984991` | `FATAL ERROR: Reached heap limit` (SIGABRT) |
| Candidate | `0cb88366bb` | `appended`; posted exactly `openclaw-openclaw/1`, `/2`, `/3`; peak heap 29 MiB; 0.7 s |

Environment: macOS arm64, Node 24.21.0. The full record is in [`receipt.json`](receipt.json).

`test/repair/publish-main.test.ts` adds a whole-repository case: 30 unchanged items, one modified, one moved to `closed/`, and one new. It expects exactly the three changed tuples, and it passes on both base and candidate, confirming identical publication behavior.

## Limits

Records and queue responses are synthetic. No production records, secrets, or GitHub writes are involved.

OpenClaw Bay is not affected: no public status, lifecycle, or projection field changes.

---

### Overview (`docs/proof/queue-policy-readmodel-extraction/README.md`)

# Queue policy and read-model extraction proof

## Claim

Moving exact-review decision/supersession policy into
\`dashboard/exact-review-decision.ts\` and queue statistics/Bay projection into
\`dashboard/exact-review-read-model.ts\` changes no queue decisions or public
dashboard responses.

## Exercised surface

- \`moved-body-identity.mjs\` parses the merge-base queue source and the
  candidate modules with TypeScript, extracts every moved function body from
  its opening brace through its closing brace, and requires exact byte equality.
- \`run-proof.mjs\` starts the real local Wrangler Worker for merge-base and
  candidate revisions, seeds six review items through the signed
  \`/internal/exact-review/enqueue\` route, then compares normalized
  \`/api/exact-review-queue\` and \`/api/status\` JSON bytes.
- Both revisions use independent SQLite-backed Durable Object state.

The committed \`moved-body-identity.json\` is the source-identity result. Runtime
artifacts are written to the ignored \`artifacts/\` directory.

## Run

From the repository root on Node 24 or newer:

\`\`\`bash
docs/proof/queue-policy-readmodel-extraction/run-proof.sh
\`\`\`

The script prints \`PROOF_RC=0\` after both routes compare byte-identically.

## Crabbox provenance

The proof in this directory passed unchanged at reviewed head
\`50a3749343b28b045e02722010aa91893c63a9f1\` inside a Docker-backed Crabbox
\`local-container\`. The run used a clean
\`--fresh-pr openclaw/clawsweeper#1124 --no-hydrate\` checkout, Crabbox CLI
\`0.38.3-5-g2a79805d\`, image \`node:24-bookworm\`, Docker 29.4.0 via
OrbStack, and lease \`cbx_f28414ea4f87\` (\`coral-lobster-07c4\`). Corepack
and checksum-verified jq 1.8.1 were installed under the unprivileged container
user's \`$HOME/.local/bin\`.

The full \`pnpm run check\` and the proof script passed. Crabbox reported
\`run_status: succeeded\`, \`exit_code: 0\`, and \`lease_stopped: true\`, with
9.0 seconds of checkout/sync, 299.5 seconds of command time, and 308.5 seconds
total. The verbatim proof result was \`PROOF_RC=0\`.

See the
[machine-readable container provenance](artifacts/crabbox-local-container-provenance.json)
and [redacted container stdout](artifacts/crabbox-local-container-stdout.log).

## Limits and OpenClaw Bay impact

This is a local real-Worker proof over synthetic pending reviews and a
deterministic loopback GitHub error stub. It does not contact GitHub, publish
records, acquire review leases, or mutate production.

The Crabbox run does not broaden those \`run-proof.sh\` limits. Its receipt
adds current-head, clean-checkout, container-image, toolchain, lease, timing,
and cleanup provenance for the same bounded scenario.

OpenClaw Bay is unaffected. This is an ownership-only move: Bay constants,
projection logic, response schema, and observer-only control boundary are
byte-identical.

---

### Overview (`docs/proof/r2-bundle-cache/README.md`)

# R2 exact-review bundle cache proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

The controlled behavior proof runs the production signed cache client against
`wrangler dev --local`, including the real Miniflare R2 and Durable Object
bindings, while a loopback HTTP server counts authoritative artifact requests.

Run it through the explicitly requested Docker-backed Crabbox provider:

```sh
proof_head="$(git rev-parse HEAD)"
proof_tree="$(git rev-parse HEAD^{tree})"
git cat-file -e "${proof_head}^{commit}"
git cat-file -e "${proof_tree}^{tree}"
../crabbox/bin/crabbox run \
  --provider local-container \
  --local-container-image node:24-bookworm \
  --no-hydrate \
  --timing-json \
  --script scripts/e2e/r2-bundle-cache-crabbox.sh \
  -- "$proof_head" "$proof_tree"
```

The script writes `.artifacts/r2-bundle-cache/proof.json`. Its static verifier
is:

```sh
jq -e '
  .r2.semantics == "wrangler-dev-local" and
  .first.source == "github" and .first.githubArtifactRequests == 1 and
  .second.source == "r2" and .second.githubArtifactRequests == 0 and
  .first.digest == .second.digest and
  .missingFallback.source == "github" and .missingFallback.githubArtifactRequests == 1 and
  .leaseMismatch.source == "github" and .leaseMismatch.githubArtifactRequests == 1 and
  .counted.repeatBefore == 1 and .counted.repeatAfter == 0 and
  .git.catFileCrossCheck == true
' .artifacts/r2-bundle-cache/proof.json
```

This proves the changed acquisition/cache protocol locally, including an
object-missing fallback and a lease-revision mismatch. It does not exercise the
deployed Cloudflare network or GitHub's hosted artifact service. OpenClaw Bay is
unaffected: this cache is internal data-plane state and exposes no observer or
control contract.

The final successful run is recorded in `receipt.json`. Verify the committed
receipt without dynamic inputs:

```sh
jq -e '
  .provider == "local-container" and
  .image == "node:24-bookworm" and
  .leaseStopped == true and
  .git.catFileCrossCheck == true and
  .counted.firstGithubArtifactRequests == 1 and
  .counted.repeatGithubArtifactRequestsAfter == 0 and
  .counted.missingObjectFallbackGithubArtifactRequests == 1 and
  .counted.leaseMismatchGithubArtifactRequests == 1 and
  .gates.result == "passed" and
  .gates.dashboardStrict == "passed"
' docs/proof/r2-bundle-cache/receipt.json
```

---

### Overview (`docs/proof/read-model-compression/README.md`)

# Read-model compression proof

Run from the repository root with pinned Miniflare, esbuild and Workerd available
through `PROOF_TOOL_ROOT` (a directory containing `package.json`):

```sh
PROOF_TOOL_ROOT=/path/to/runtime-tools node docs/proof/read-model-compression/run-proof.mjs
```

The local-only fixture archives frozen baseline
`d44a78ce5f214999b5cce854613319f9453989b9`, seeds its actual queue/SQLite owners,
then restarts the candidate against the same named Durable Object and files.
`PROOF_BASELINE_ARCHIVE` can supply that exact `git archive` when the remote
checkout has no Git objects. The runner reports its digest. No Cloudflare calls,
deployments, R2 objects or Node compatibility flag are used. Temporary source
and databases are removed on exit; results go to stdout.

Assertions cover five-table exact decoded bytes and metadata, large marker-bearing
comments, Unicode and historical fields, raw-before-activation behavior, bounded
passes, migration and completed-checkpoint restart, ordinary reads and digests,
placeholder retention, terminal facts and acknowledgement after conversion.
The result separately reports stored field bytes, decoded bytes, occupied SQLite
pages, native rows read, and wall time including fixture overhead. This synthetic
workload does not qualify production CPU, memory or throughput. Node tests cover
corruption, byte caps, concurrent CAS changes, rollback and signed operator calls.

---

### Overview (`docs/proof/readiness-privacy-fixture/README.md`)

# Gateway readiness privacy-fixture qualification

Status: historical proof for this exact fixture qualification. The policy owner is

`src/agent-input-scan-fixtures.ts`; the native entry point is
`src/agent-input-scan.ts`. Verified against ClawSweeper base
`4246312566ffd0832ed892857ccd10952e8034ca` with the candidate tuple addition.

## Claim and exercised surface

The existing host input gate may classify the explicitly approved synthetic URI
from [OpenClaw PR #152309](https://github.com/openclaw/openclaw/pull/152309) only when the native detector identity, decoder, both raw
value digests, complete source line, original path, regular-file mode, and committed
base/head references match. No scanner option, reviewed input, or other policy is
relaxed. The original OpenClaw fixture is unchanged.

## Native before/after proof

Target range:

- Base: `26c2f997d81b0745d0819ba803c185fde247b72d`
- Head: `876b4c34f16b46bb4cbff8569d6cb2ba39ee0e59`
- Source: [OpenClaw readiness test](https://github.com/openclaw/openclaw/blob/876b4c34f16b46bb4cbff8569d6cb2ba39ee0e59/test/helpers/openclaw-test-instance.test.ts#L2002)
- Source blob: `fb56a237c6d8f1f9a59cdb89072838e5ede881fe`

On Linux with Node 26.8.2, the repository's checksum-qualified native TruffleHog
3.97.4 and existing scanner owner ran with verification enabled:

```sh
node docs/proof/agent-input-scan-context/run-proof.mjs \
  <clean-openclaw-checkout> <base-sha> <head-sha> <receipt.json>
```

The unmodified policy refused the complete committed input set with two unknown
URI findings ([before](before.json)). The qualified policy admitted that same
range in all three repetitions ([first](after-1.json), [second](after-2.json),
[third](after-3.json)), retaining the exact source and introduced-patch witnesses.
Independent native scans of the unchanged source blob observed both PLAIN and
HTML variants with identical value and source-line identities; the retained
[source-only identity receipt](identities.json) records the PLAIN observation.

Thirty focused classifier tests pass, including twelve new regression cases for
this fixture. Positive controls cover Git-generated additions, removals and
unchanged context. Negative controls reject changed literals, complete lines,
paths, modes, uncommitted roles, verified findings, unsupported decoders, changes
to the surrounding synthetic-payload expression, and extra occurrences.

## Limits and update triggers

These scans use the complete canonical committed range and a controlled prompt;
they do not run a model or attest a hosted review. The historical hosted refusal
reported a PLAIN finding and a total of two findings, but did not preserve the
second finding's details; this proof does not reconstruct that old wire. A fresh
hosted review must scan its own complete source, prompt, schema, and other inputs.

No OpenClaw Bay, queue, status, or publication schema changes are involved. Re-run
this proof when the exact source line/value/path, scanner version, source-binding
contract, or host classification owner changes. Do not broaden the entry to make
a changed fixture pass.

---

### Overview (`docs/proof/receipt-based-freshness/README.md`)

# Receipt-based apply freshness proof

Historical evidence only: the one-off manual proof driver has been retired.
Commands below record the original run, not a supported current entrypoint.

- Status: historical proof artifact
- Owner: ClawSweeper publication maintainers
- Baseline: `openclaw/clawsweeper@cac974b3e1da900cac3e7480b91d02a36ca60163` (origin/main)
- Candidate: `openclaw/clawsweeper@349741921fb9c0002a45d5a1fea53bebfc32db85` (clean committed head)
- Update when: apply source freshness, durable review-version markers, review lease
  release, or the deferred batch re-apply path changes

## Claim

An exact-review producer that keeps a close proposal open syncs the durable review
comment, runs the close gates (`kept_open`), and releases its review lease by deleting the
lease comment, which moves the PR `updated_at`. When its direct publication is deferred,
the batch publisher re-applies the same review. Before this change that re-apply recorded
`skipped_changed_since_review` (`updated_at changed`) and requeued a full
`source_drift_requeue` review (openclaw/openclaw#143911, runs 36671559049 ->
36672608523 -> 36673368897, roughly every 23 minutes). After it, the re-apply accepts the
producer's receipt-backed writes and keeps the proposal open without a requeue or a
duplicate GitHub effect. A human comment, a new head, or a title edit after the producer
still blocks and requeues on both builds with zero close writes. The #1715 scenarios
(openclaw/openclaw#126549 and #158447) keep their recorded outcomes.

## Exercised surface and scenario

`scripts/e2e/apply-source-drift-final-effect.mjs` drives the compiled non-dry-run
`apply-decisions` CLI with the exact-event publication arguments of
`src/repair/publish-event-result.ts`, and ClawSweeper's own `update-review-status`
acknowledgement edits, through native `gh` (`http_unix_socket`) against a stateful
synthetic GitHub API. The API is seeded from read-only captures of each PR (PR, comments,
timeline, files, commits, checks, review-activity GraphQL, related items) and rewound to
the looping run's review snapshot. Capture restores the durable review comment's body at
that snapshot from its read-only GraphQL edit history (`userContentEdits`), so later
generations do not leak into the replay. The seeded review lease carries a live marker
window, so the apply adopts and releases it as production does.

For #143911 (revision-46 snapshot, review lease 5904434723 owned by
`github-run-36671559049-1`) each `batch-*` scenario runs, per build:

1. acknowledgement `reviewing`, review snapshot, report, acknowledgement `complete`;
2. the producer apply (phase `apply`);
3. an optional external change (`batch-human-comment`, `batch-new-head`,
   `batch-title-edit`);
4. the batch publisher re-apply of the same pre-apply review artifact (phase `batch`).

#126549 (`recorded` and `close-capable` records) and #158447 run the #1715 scenarios
`ack-only`, `human-comment`, `new-head`, and `title-edit` (steps 1-2 only).

## Command and environment

```bash
node scripts/e2e/apply-source-drift-final-effect.mjs capture --item <n> --out <seed-dir> --gh "$(command -v gh)"
node scripts/e2e/apply-source-drift-final-effect.mjs run --item <n> \
  --seed-dir <seed-dir> --baseline <origin/main checkout> --candidate <branch checkout> \
  --out <evidence-dir>
```

Node v24.21.0, gh 2.101.0 against the synthetic API, macOS, both checkouts built with
`pnpm run build:all`. Seeds were captured 2026-10-01 and are not committed (full public
PR captures):

| Seed | SHA-256 |
| --- | --- |
| `seed-143911.json` | `7287e4930f862d054930538fe74946a505db0c97da4b38d6208255bd08897efa` |
| `seed-126549.json` | `63342b6cd2a04d6d0e297908712f4964d2c48defc53af4c9a1ac695fc7f2582d` |
| `seed-158447.json` | `8bc5eb51659f9866a928c4038a2b4ce1251902748bdc16af461536fec420445d` |

## Observable result: #143911 deferred batch re-apply

| Scenario | Build | Producer apply | Batch re-apply | Requeue | Close writes |
| --- | --- | --- | --- | --- | --- |
| `batch-after-producer` | baseline | synced + `kept_open` | `skipped_changed_since_review: updated_at changed` | yes | 0 |
| `batch-after-producer` | candidate | synced + `kept_open` | `review_comment_synced` (metadata only, no PATCH) + `kept_open` | no | 0 |
| `batch-human-comment` | both | synced + `kept_open` | `skipped_changed_since_review: updated_at changed` | yes | 0 |
| `batch-new-head` | both | synced + `kept_open` | `skipped_changed_since_review: live PR head ... differs` | yes | 0 |
| `batch-title-edit` | both | synced + `kept_open` | `skipped_changed_since_review: updated_at changed` | yes | 0 |

The producer reproduces production's apply exactly: `review_comment_synced` plus
`kept_open: implemented-on-main close no longer has current GitHub
issue-to-fixing-pull-request provenance`, with GitHub effects `PATCH` durable comment
5616705068 and `DELETE` review lease 5904434723. Its event-apply disposition is `applied`
with no requeue, so the direct-publication planner accepts that shape.

The candidate batch re-apply's only GitHub effects are its own apply-lease create and
release, identical to the baseline batch; it makes no durable-comment PATCH, label edit,
or close request.

## Observable result: #1715 regression rerun

Baseline and candidate are identical in every scenario and match the outcomes #1715
recorded for its branch:

| Record | Scenario | Apply | Requeue | GitHub effects | Close writes |
| --- | --- | --- | --- | --- | --- |
| #126549 recorded | ack-only | synced + `kept_open` (paired closeout) | no | durable `PATCH`, lease `DELETE` | 0 |
| #126549 close-capable | ack-only | synced + `closed` (stalled unproven PR) | no | durable `PATCH`, closeout note `POST`, close, lease `DELETE` | 1 |
| #158447 recorded | ack-only | synced + `kept_open` (paired closeout) | no | `removeLabelsFromLabelable`, durable `PATCH`, lease `DELETE` | 0 |
| all three | human-comment | `skipped_changed_since_review: updated_at changed` | yes | lease `DELETE` only | 0 |
| all three | new-head | `skipped_changed_since_review: live PR head ... differs` | yes | none | 0 |
| all three | title-edit | `skipped_changed_since_review: updated_at changed` | yes | lease `DELETE` only | 0 |

One expected difference from #1715's recording: #1715 seeded a lease marker the apply
could not adopt, so each apply posted and deleted its own lease. This harness keeps the
seeded review lease live, so the apply adopts it and only deletes it, as the production
exact-review publisher does.

## Artifacts

- `receipt.json`: the three run summaries with seed SHA-256s and the local command path
  replaced by placeholders (SHA-256
  `e3c18c8d45dd9fef2321db8fd4bc38ff76c41493c22115f68dce6ae4ebc05f53`; raw summaries
  143911 `6e9ac39a7aff481238bb7b43c928130d0333df0c62e171991bfbdadc802ea15d`, 126549
  `c8fbeb91ee3c1ed7d5d5381255cdb289c8c4ea80038a8e346802d82511270350`, 158447
  `a1428aee6559420aeda658faa78e1e33dfa3827d4a6b2848b7a44b4ce743be02`).
- `traces/batch-after-producer-{baseline,candidate}.http-trace.jsonl`: every request of
  the headline #143911 scenario (SHA-256 `e9ff466d2db609c70fef2f5e5e80f108467ef2a8bd5b6fd3b7b4b828dce5d6ef`
  and `77602a8625c406493f763705e2c28fe81883f26859d502b0a2a8a83342bf0376`).
- #143911 control traces (not committed): human comment
  `26c8ae027b15fe1d7758342ec1bdd58de11df0d70920ccc30045fdb31ec943d3`, new head
  `28a0ea724f18058eff24a9a45dad3368d5ddd9f56c42b6df47d72fb7c2e6c405`, title edit
  `495219ad3543de519e4fa80aa0e103c31d234b020b3d9f00d228d4e06467ede3`, each identical on
  both builds.

## Limits

- The GitHub API is synthetic. It models `updated_at` and timeline effects of comment,
  label, title, push, and close writes; it does not model GitHub mention/subscription
  events, reactions, or the hosted rate limiter.
- The producer's direct publication POST and the batch publisher's queue claim and commit
  are not exercised here; the batch phase replays the batch publisher's apply step only.
- The released-lease receipt cannot see a comment deletion's time. It bounds the deletion
  to five minutes after the review generation's last recorded ClawSweeper write and
  relies on the complete activity receipt plus the no-non-automation-activity check for
  everything else.
- Review records are reconstructed from durable markers and run logs, as in #1715; the
  close-capable #126549 close reason is synthetic.

OpenClaw Bay is unaffected: no queue, status, telemetry, or dashboard data contract
changes.

---

### Overview (`docs/proof/reconcile-cap-class/README.md`)

# Recovery-cap skip-class proof

## Claim

The parked and standard dead-letter reconciliation summaries now distinguish open targets skipped
by the recovery ceiling as `recovery_cap`. When either path sees non-idle queue pressure and folds a
recoverable target into `skipped_targets`, it reports `recovery_deferred_pressure`. Existing
inspection failures retain their HTTP and timeout classes.

## Part 2 feasibility

Stopped as required: no cheap complete dispatch-to-claim transition source exists. Queue items keep
`claimedAt` only while they remain leased, so completed claims disappear from the active state.
Existing durable flow buckets count enqueue, completion, retry, and shed events; they do not count
claims, and there are no dispatching-phase entry or exit counters. Counting only active leased items
would undercount fast completions and could label a draining surge as zero progress. A correct
`claims_last_10m` would therefore require new claim-path bookkeeping, which this work order forbids.

`oldest_dispatching_key` already exists as
`handoff_health.phases.dispatching.oldest_key`. No queue, status-logic, dashboard, or Bay code changed.

## Red/green proof

On Node 24.19.0, the focused operator command was run before and after the implementation:

```text
node --test test/exact-review-dead-letter-operator.test.ts
```

The red run executed 59 tests: 56 passed and the three new assertions failed because parked
`recovery_cap`, standard `recovery_cap`, and standard `recovery_deferred_pressure` were absent. The
green run passed all 59 tests. The pre-existing bounded HTTP fixture remained green with
`http_403: 1` and `timeout: 3`. Machine-readable counts are in `test-evidence.json`.

## Read-only production replay

The immutable `parked-reviews.json` from scheduled run
https://github.com/openclaw/clawsweeper/actions/runs/31449984643, artifact `9085971968`, was replayed
against the current operator. Its SHA-256 is
`1187c6042803b5ba98048d64157cb98a5399c1cbde76b69ce25f18dffe23b88f`.

The replay used live GitHub target reads with the authenticated `gh` identity, a signed loopback
inventory route, idle loopback pressure, and no mutation route. It omitted `--execute` and emitted:

```json
{"action":"reconcile-parked","dry_run":true,"inventory_complete":true,"queue_pressure":"idle","inspected_targets":20,"terminal_targets":1,"repository_gone_targets":0,"resolved_targets":1,"open_targets":19,"recovered_targets":5,"skipped_targets":14,"skip_reasons":{"recovery_cap":14},"skip_samples":[]}
```

The exact output and provenance are in `production-replay-summary.json` and
`production-replay-provenance.json`. `run-production-replay.mjs` reproduces the read-only replay
while the artifact remains available.

## Gates

- `pnpm run build:all`: passed
- `pnpm run test:no-build`: 3,318 tests; 3,309 passed, 9 skipped, 0 failed
- `pnpm run lint`: passed
- `pnpm run format:check`: passed
- `pnpm run check:dashboard-queue-boundary`: passed
- `pnpm run check:active-surface`: passed

## Limits and Bay impact

The production proof exercises parked reconciliation; standard reconciliation classification is
covered by the red/green fixture. It does not mutate the queue or add handoff telemetry.

OpenClaw Bay is unaffected. Bay may continue to render the existing handoff status, but this
operator-only additive classification creates no status actions and Bay must not gain queue,
workflow, GitHub, DLQ, recovery, deploy, or rollback controls.

---

### Overview (`docs/proof/reconcile-throttle-resilience/README.md`)

# Reconcile throttle-resilience proof

Production run 31634514031-era evidence showed `inspected_targets=3`, `skipped_targets=125`, and `recovered_targets=0` after one `http_403` plus two attributed `not_inspected_abort` targets. At the same time, the `repository_actions` pool was under sustained pressure (`item_metadata` read throttle first=718, repeat=1197; roughly 6,000 `artifact_download` circuit skips) while the `target_app` pool was nearly idle.

The code investigation found that parked REST checks, standard REST checks, and batched GraphQL canonical discovery all selected `GITHUB_TOKEN`. In the scheduled workflow that variable was `${{ github.token }}`, the same repository Actions credential used by the prior-artifact download and stuck-run Actions API remediation. Round 1 moved those reads to one OpenClaw installation token, which would have failed every target owned outside that installation.

The owner decision preserves cross-owner recovery. The operator now reuses the Worker's canonical GitHub App plumbing—`githubAppCredentials`, `signGithubAppJwt`, `githubAppInstallationId`, and `createGithubAppTokenFor`—to mint a read-only contents/issues/pull-request token for each target owner. Successful tokens and setup-throttle rejections are cached per owner for the cycle, while `installation_missing` rejections are cached per repository so a selected-repositories installation can still reach an accessible sibling repository. GraphQL batches are owner-homogeneous. A genuinely missing or revoked installation is a per-target `installation_missing` skip with a bounded sample; it never aborts the cycle. Repository artifact and Actions-run operations remain on `${{ github.token }}`.

Round 4 closes the rollout boundary: the operator defaults target reads to `github-app` mode and validates the App ID/private-key pair synchronously at startup. A missing ID, missing key, or missing pair is a hard error naming exactly the absent field. The repository Actions token is usable for target reads only through the explicit `EXACT_REVIEW_TARGET_TOKEN_MODE=actions` opt-in. Both checked-in operator workflows select `github-app`, and the scheduled steps pass the referenced private-key secret; the repository currently exposes that secret name.

The original abort came from https://github.com/openclaw/clawsweeper/pull/973: complete canonical-alias discovery protected active sibling fences and bounded API usage before mutation. https://github.com/openclaw/clawsweeper/pull/1117 added honest per-target diagnostics while deliberately retaining that behavior. The new policy changes only GitHub-confirmed rate-limit or abuse 403s and all 429s: isolated target-read and App-setup throttles become per-target or per-owner skips, a successful target read resets the counter, and three consecutive throttled calls abort the remaining phase. A cached setup rejection may skip many targets or GraphQL batches but counts as the one GitHub call that was actually throttled. App-setup skips carry `github_throttled scope=app_setup` with the stage, owner, and status. Authorization failures, policy 403s, and every other non-throttle discovery failure still use the conservative abort path. The existing target, recovery, GraphQL batch, terminal-recheck, and inventory caps remain intact.

The real-behavior contract is in `behavior-contract.md`; the red/green record is in `red-green.md`. The final `run-proof.sh` execution used Docker-backed Crabbox `provider=local-container`, lease `cbx_2c2320c8c201` (`crimson-hermit-97fb`), and image `node:24-bookworm`; it passed 27/27 focused scenarios and stopped automatically. `receipt.json` binds tested code head `5a89572fa541de992d34afad7cf5d674208eccd0`, the proof harness, every executable input, and the sanitized transcripts by SHA-256. TruffleHog 3.96.0 found zero verified or unknown secrets.

---

--- METRICS ---
- Files Extracted: 107
- Estimated Token Budget: ~125474 tokens
- Canonical Reference: https://codewiki.google/github.com/openclaw/clawsweeper
