Skip to content

feat: add ExecApprovalsStore write path and wire coordinator side effects - #526

Merged
shanselman merged 10 commits into
openclaw:mainfrom
AlexAlves87:feat/exec-approvals-write-path
Jun 21, 2026
Merged

feat: add ExecApprovalsStore write path and wire coordinator side effects#526
shanselman merged 10 commits into
openclaw:mainfrom
AlexAlves87:feat/exec-approvals-write-path

Conversation

@AlexAlves87

@AlexAlves87 AlexAlves87 commented May 23, 2026

Copy link
Copy Markdown
Contributor

What

Adds the write path to ExecApprovalsStore and wires the two side-effect calls into ExecApprovalsCoordinator, closing the persistence loop for the exec approvals V2 pipeline.

Store — new public API:

  • AddAllowlistEntryAsync(agentId, pattern) — persists a new allowlist entry after an AllowAlways prompt decision. Deduplicates on write (OrdinalIgnoreCase). Returns true if the entry is present after the call (added or already there), false on empty pattern or I/O failure. New entries carry {id, pattern}; lastUsedAt is stamped later by RecordAllowlistUseAsync on first successful use (matches macOS parity).
  • RecordAllowlistUseAsync(agentId, pattern, resolvedPath) — updates lastUsedAt and lastResolvedPath for every matching entry after a final allow. No command text is persisted. Returns false if pattern not found or on I/O failure.

Store — private infrastructure:

  • UpdateFileAsync(mutate) — load → mutate → atomic save, serialized by the existing SemaphoreSlim. Never throws. Refuses to overwrite a malformed file. Handles transient IOException on the atomic move as a degraded path: logs Warn, no retry.

Coordinator — side effects wired:

  • RecordAllowlistUsageAsync fires on both allow exit points: the pass1 pre-approved branch and the post-pass2 branch. Both are required to cover the common allowlist-satisfied case.
  • PersistAllowlistEntriesAsync fires only after pass2 = Allow and followupDecision == AllowAlways, strictly outside the _promptLock block.
  • Each side effect is wrapped in its own independent best-effort try/catch so a failure in one does not skip the other and cannot flip an already-decided allow into InternalError.

Not wired in production yet: the coordinator is still not referenced in any production src/ file. The ProductionWiring_CoordinatorNotReferencedInSrc test remains green.

Design notes

Side effects fire strictly after the final allow decision is confirmed — not before the second evaluator pass. This is a deliberate structural safety choice: the guarantee is structural rather than relying on proof that Evaluate(context, AllowAlways) always produces Allow.

Pattern validation in AddAllowlistEntryAsync is non-empty only, matching macOS parity. Basename-only patterns are inert at match time but not rejected at persist time.

No command text reaches disk. lastUsedAt (Unix ms) and lastResolvedPath provide sufficient operational metadata without exposing tokens or secrets embedded in command arguments.

Testing

2252 OpenClaw.Shared tests passing, 0 failures (head da0b255). Build: 0 warnings, 0 errors (TreatWarningsAsErrors clean).

Store tests cover: success paths, dedup, not-found, malformed-file refusal, I/O failure degradation on both mutators, concurrency (5 concurrent writes produce a single entry), round-trip JSON validation, and a regression guard asserting lastUsedCommand is absent from the persisted file.

Coordinator tests cover: AllowAlways persistence, non-allowlist security guard, duplicate pattern dedup, allowlist usage recording, allowlist-not-satisfied guard, pass1 pre-approved path, and fallback path with allowlist satisfied.

Real behavior proof

End-to-end coordinator/store runtime proof using real filesystem I/O (test RuntimeProof_AllowAlways_PersistsAndRecordsLastUsed in tests/OpenClaw.Shared.Tests/ExecApprovalsCoordinatorTests.cs).

Scope clarification: this is slice runtime proof, not full production runtime proof. The coordinator is intentionally not wired in production yet. A follow-up production wiring slice connects the coordinator, and the WinUI prompt dialog is a separate slice after that. UI-driven proof against the live app is only meaningful once those land.

Reproduce locally:

dotnet test tests/OpenClaw.Shared.Tests/OpenClaw.Shared.Tests.csproj   --filter "FullyQualifiedName~RuntimeProof_AllowAlways_PersistsAndRecordsLastUsed"   --logger "console;verbosity=detailed" --nologo

Captured output — current head (da0b255), lastUsedCommand absent:

=== Initial exec-approvals.json ===
{"version":1,"agents":{"main":{"security":"allowlist","ask":"always"}}}

=== After AllowAlways (correlationId=proof-1) ===
{
  "version": 1,
  "agents": {
    "main": {
      "security": "allowlist",
      "ask": "always",
      "allowlist": [
        {
          "id": "ffdb6291-0c5d-4b96-bf44-4bc48367d73c",
          "pattern": "C:\WINDOWS\system32\cmd.EXE"
        }
      ]
    }
  }
}

=== After allowlist hit (correlationId=proof-2) ===
{
  "version": 1,
  "agents": {
    "main": {
      "security": "allowlist",
      "ask": "always",
      "allowlist": [
        {
          "id": "ffdb6291-0c5d-4b96-bf44-4bc48367d73c",
          "pattern": "C:\WINDOWS\system32\cmd.EXE",
          "lastUsedAt": 1781830269056,
          "lastResolvedPath": "C:\WINDOWS\system32\cmd.EXE"
        }
      ]
    }
  }
}

The entry id is identical between the two invocations, proving on-disk dedup. lastUsedAt and lastResolvedPath appear only after the second invocation, proving RecordAllowlistUseAsync fires on the allowlist-hit path. No lastUsedCommand field is present at any stage.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed June 18, 2026, 9:09 PM ET / 01:09 UTC.

Summary
The branch adds ExecApprovalsStore allowlist write/usage APIs, removes persisted command text from allowlist entries, wires coordinator allow-side side effects, and expands shared tests with filesystem-backed runtime proof.

Reproducibility: not applicable. This is a feature PR adding an internal exec-approvals write path, so the relevant evidence is PR-head code review and the contributor's filesystem-backed runtime proof rather than reproducing a current-main bug.

Review metrics: 3 noteworthy metrics.

  • Diff size: 15 files, +800/-56. The PR is a substantial exec-approvals persistence slice rather than a small isolated edit.
  • Persisted policy surface: 2 write APIs added, 1 persisted command-text field removed. The branch changes what OpenClaw writes to exec-approvals.json and what sensitive metadata is retained.
  • Validation state: 2 successful, 2 skipped, 4 in progress. The latest GitHub check rollup had not completed when reviewed, so merge should still wait for normal validation.

Root-cause cluster
Relationship: canonical
Canonical: #526
Summary: This PR is the active canonical write-path branch; the earlier closed PR is superseded, and the merged migration PR is adjacent state-dir work that this branch now preserves.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Let the current head's required validation finish before merge.
  • Have a maintainer explicitly accept the persisted exec-approvals metadata behavior.

Risk before merge

  • [P1] Merging changes persisted exec-approvals.json semantics: future writes drop existing lastUsedCommand metadata and start updating lastUsedAt/lastResolvedPath best-effort.
  • [P1] The change sits inside the local exec approval security boundary, and production coordinator/UI wiring is still deferred, so maintainers need to accept this as an internal slice before full app proof exists.
  • [P1] Required GitHub validation for the latest head was still running during review; maintainers should wait for the normal build/test gate before merge.

Maintainer options:

  1. Merge after validation and policy review (recommended)
    Wait for the current head's required checks and explicitly accept the stored-metadata behavior before landing this internal exec-approvals slice.
  2. Defer until production wiring proof
    Pause this PR if maintainers want allowlist persistence reviewed together with the live coordinator and prompt UI integration.
  3. Request a narrower storage contract change
    Ask for a follow-up revision only if maintainers want a different migration or metadata-retention contract for existing exec-approvals files.

Next step before merge

  • [P2] There is no narrow automation-safe repair finding; the remaining action is maintainer review of the compatibility and security-policy persistence behavior plus normal validation completion.

Security
Cleared: No concrete remaining command-text persistence or supply-chain issue was found, though the diff remains security-boundary-sensitive because it changes exec approval persistence.

Review details

Best possible solution:

Land the internal write-path slice after maintainer acceptance of the persisted policy change and green required validation, while preserving the no-command-text and migration-before-write behavior.

Do we have a high-confidence way to reproduce the issue?

Not applicable. This is a feature PR adding an internal exec-approvals write path, so the relevant evidence is PR-head code review and the contributor's filesystem-backed runtime proof rather than reproducing a current-main bug.

Is this the best way to solve the issue?

Yes, broadly. The store/coordinator ownership boundary matches the existing pipeline, and the latest head addresses the earlier command-text and side-effect isolation concerns; remaining work is maintainer acceptance of the security-policy persistence slice and completed validation.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against c0514bd2d026.

Label changes

Label justifications:

  • P2: This is a normal-priority exec approval persistence improvement with bounded blast radius because production wiring remains deferred.
  • merge-risk: 🚨 compatibility: The PR changes persisted exec-approvals.json write behavior and removes an existing metadata field on future writes.
  • merge-risk: 🚨 security-boundary: The PR changes allowlist persistence and side effects in the local exec approval security path.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes copied terminal output from a filesystem-backed coordinator/store runtime proof showing persistence, usage recording, deduplication, and absence of lastUsedCommand; the latest merge commit only added tests in this slice.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied terminal output from a filesystem-backed coordinator/store runtime proof showing persistence, usage recording, deduplication, and absence of lastUsedCommand; the latest merge commit only added tests in this slice.
Evidence reviewed

What I checked:

Likely related people:

  • AlexAlves87: Git blame and -S history show this person introduced the current exec-approvals store/coordinator areas that this PR extends, and they authored the active branch. (role: feature owner / prior area contributor; confidence: high; commits: b175439fbfd4, a4f106c7d09c, 12416d282a23; files: src/OpenClaw.Shared/ExecApprovals/ExecApprovalsStore.cs, src/OpenClaw.Shared/ExecApprovals/ExecApprovalsCoordinator.cs, tests/OpenClaw.Shared.Tests/ExecApprovalsStoreTests.cs)
  • vincentkoc: Merged PR history shows this person changed the custom state-dir migration behavior that this PR now preserves before any store write. (role: recent adjacent contributor; confidence: medium; commits: 913ba4e8f504; files: src/OpenClaw.Shared/ExecApprovals/ExecApprovalsStore.cs, tests/OpenClaw.Shared.Tests/ExecApprovalsStoreTests.cs)
  • shanselman: The PR discussion shows this person raised the command-text and side-effect isolation concerns, and git history shows adjacent hardening work in the area. (role: reviewer / adjacent hardening contributor; confidence: medium; commits: d23f8ca50013; files: src/OpenClaw.Shared/ExecApprovals/ExecApprovalsStore.cs, src/OpenClaw.Shared/ExecApprovals/ExecApprovalsCoordinator.cs)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels May 23, 2026
@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown

ClawSweeper PR egg

✨ Hatched: 🌱 uncommon Clockwork Patch Peep

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🌱 uncommon.
Trait: sniffs out flaky tests.
Image traits: location flaky test forest; accessory little merge flag; palette rose quartz and slate; mood sleepy but ready; pose peeking out from the egg shell; shell glossy opal shell; lighting warm desk-lamp glow; background gentle dashboard dots.
Share on X: post this hatch
Copy: My PR egg hatched a 🌱 uncommon Clockwork Patch Peep in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@AlexAlves87

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 🔁 re-review loop A fresh ClawSweeper review was explicitly requested after the latest review. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 23, 2026
@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@AlexAlves87

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 🔁 re-review loop A fresh ClawSweeper review was explicitly requested after the latest review. labels May 26, 2026
@shanselman

Copy link
Copy Markdown
Collaborator

First-pass triage: holding this one rather than merging.

A dual-model review found enough security-boundary/correctness risk that I don’t think it clears the quick-merge bar yet:

  • Potentially sensitive full command text appears to be persisted in exec-approvals.json usage metadata (lastUsedCommand). That can leak tokens/secrets embedded in command arguments.
  • Approval-store side effects are wired into Allow paths; if the side-effect wrapper throws unexpectedly, an already-approved command could be reported as denied.

Suggested follow-up: avoid persisting full command text (or store only a redacted/structured summary), and wrap approval metadata side effects so they log/fail-soft without changing the approval decision.

@AlexAlves87

Copy link
Copy Markdown
Contributor Author

Both findings addressed in the latest commit (90b36db):

1. lastUsedCommand removed. The field is gone from ExecAllowlistEntry and the command parameter is dropped from RecordAllowlistUseAsync. Only lastUsedAt and lastResolvedPath are persisted — no command text reaches disk. A DoesNotContain("lastUsedCommand") assertion in the store round-trip test acts as a regression guard.

2. Side effects isolated. Each side effect (PersistAllowlistEntriesAsync, RecordAllowlistUsageAsync) is now wrapped in its own independent best-effort try/catch in both the pre-approved (pass1) and post-prompt paths. A failure in one does not skip the other and cannot flip an already-decided allow into InternalError.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. and removed proof: sufficient Contributor real behavior proof is sufficient. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 7, 2026
…ation

lastUsedCommand persisted the full command text in exec-approvals.json,
leaking tokens or secrets embedded in command arguments. Remove the field
from ExecAllowlistEntry and the command parameter from RecordAllowlistUseAsync;
lastUsedAt and lastResolvedPath provide sufficient operational metadata.

Approval-store side effects (PersistAllowlistEntriesAsync, RecordAllowlistUsageAsync)
were unguarded, so an unexpected exception could cause an already-approved command
to be reported as InternalError. Each side effect in both the pre-approved (pass1)
and post-prompt (step 8) paths is now wrapped in its own best-effort try/catch so
a failure in one does not skip the other and never flips an allow to a deny.

Add DoesNotContain("lastUsedCommand") assertion to the store round-trip test
as a regression guard against accidental reintroduction of the field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AlexAlves87
AlexAlves87 force-pushed the feat/exec-approvals-write-path branch from df28407 to ad4021d Compare June 7, 2026 20:43
@clawsweeper clawsweeper Bot added status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 7, 2026
AlexAlves87 and others added 2 commits June 12, 2026 07:04
…-write-path

# Conflicts:
#	tests/OpenClaw.Shared.Tests/ExecApprovalsStoreTests.cs
UpdateFileAsync loaded the target file directly, so with a custom state
dir configured a write could create a fresh exec-approvals.json at the
target path while an unmigrated legacy file still existed. That would
permanently block TryMigrateLegacyFile and silently orphan the legacy
configuration. Mirror EnsureFileAsync: run migration first and refuse
to write when the legacy file is unreadable (Blocked), consistent with
the existing fail-closed read semantics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 12, 2026
@AlexAlves87

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 12, 2026

Copy link
Copy Markdown

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 12, 2026
@AlexAlves87

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper clawsweeper Bot added proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 19, 2026
Conflict in ExecApprovalsStoreTests.cs: upstream added two tilde-expansion
tests (ResolveAsync_TildeOnlyStateDir, ResolveAsync_TildePrefixedOpenClawHome)
at the same point where the write-path tests end. Both blocks kept.
@shanselman
shanselman merged commit cfca9f5 into openclaw:main Jun 21, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. merge-risk: 🚨 security-boundary 🚨 Merging this PR could weaken sandboxing, authorization, credentials, or sensitive data. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants