feat: add durable capability-service managed runs - #510
Merged
Conversation
`pnpm lint:security` failed with three errors, which blocks the push gate and every downstream CI tier. - sub-agent-runner: the archival promise is assigned once and only read from its own settle callback, so it is a `const`. - setup-cross-session-runtime: the delivery surface captures the chunk store before the dead-letter queue backing it is built. The late binding becomes an explicit holder assigned once, rather than a `let` that the rule cannot express. - cross-session-sender: settling the announcement reservation threw from a `finally`, which discards the outcome it replaces. The precedence is deliberate — an unsettled reservation strands durable ownership no retry can reconcile — so it is preserved exactly and raised from ordinary control flow instead, where it is visible. Adds a characterization test for release-failure-over-a-completed-send, the settlement path that had no coverage, alongside the existing cancellation-failure test that already pinned the error path.
Five of the seven gate failures on this branch, none of which were caused by the work itself outrunning its own tests. Stale tests — both asserted contracts this branch replaced: - The cross-session announce test still expected the raw `sendToChannel` path. Announcements now go only through the recoverable boundary, which fail-closes when it is unwired, so the test wires that boundary and additionally pins that the raw port stays unused. - The sub-agent auto-archive test advanced timers synchronously. The sweep awaits replay-guard retirement before removing the run, so the advance now drains those continuations. Gates: - Audit-stamps for the two wide announcement types. Both are legitimately wide: the dead-letter row carries whichever evidence the failing send reached, and the queue options are injectable capabilities rather than data. - The five delivery-recovery port types are structurally satisfiable, so implementers match their shape without importing the name and the consumer scan sees no importer. Tracked in the public API policy beside the OutwardSendLedgerPort precedent. - Regenerated the web contract artifacts.
The setup-cross-session/ tree carries a 600-line per-file cap; three files had grown past it. Each split follows a seam the code already had rather than cutting to hit a number. - Reservation identity (does a stored reservation describe the same operation we are about to send?) moves out of recoverable delivery as two pure functions. - The governed delivery shapes move to a types module, so wiring that only names them does not pull in the send implementation. - The composition root sheds three cohesive pieces: retirement-producer state resolution, sub-agent result processing (condenser, caster, full-output store), and the parent announcement rewrite. The result type moves out too, so the wiring barrel does not depend on the builder. No behavior change. The subdirectory gate passes and the 2415 daemon wiring tests are unchanged.
Two files past the 1000-line production cap, each split at a seam that was already there. - Sub-agent failure notification is the LLM-free path: no model is available to phrase the message, so the text is built directly. It shares nothing with the result processing around it beyond the announce key, so it moves whole. - Graph resume rehydrates a run that outlived its process. It is guard code before it is restore code — re-parsing the record, re-validating topology against the stored execution order, unwinding the announcement reservation on every abort path — and it reads as such on its own. The coordinator internals it drives are now named in an explicit context rather than captured implicitly. No behavior change; 1195 graph and spawn tests unchanged.
…he cap Three extractions, each along a boundary the code already respected. - Announcement sanitization is a display boundary: it decides what reads as the agent's own words rather than as plumbing. It touches no batcher state. - A single delivery attempt draws on the strongest boundary the caller actually wired, falling back through governed, receipt-aware, and plain sends. Each fallback is a real downgrade in what can be proven after the send, so the order is fixed. It captured only the deps and the admission signal, which are now parameters. - The dead-letter record shapes and their validators move together. The JSONL file is the trust boundary — rows outlive restarts, can be hand-edited, and drift across versions — so every stored row is re-validated on the way in, and the comparators that decide whether a row still describes the caller's operation belong beside the shapes they compare. No behavior change; 1264 orchestrator tests unchanged.
…ages The queue had grown to 3396 lines in a single factory closure — one function holding sixty inner closures over a shared record set. It is now 833 lines plus seven stage modules, split by lifecycle rather than by size. The record set moves first. Six reassigned array bindings become one `DeadLetterRecordStore`, because persistence is all-or-nothing: every record kind is rewritten to the same JSONL file in one atomic replace, so they are already read and swapped together. Stages then take a named context instead of closing over the factory. Function members forward at call time, so a stage can be constructed before the stages it calls into exist — the call graph between them is genuinely cyclic (drain settles decisions, decisions release producers, promotion re-enters drain) and no ordering makes it acyclic. Each stage keeps its own concern: storage (lazy idempotent load, atomic rewrite), governed drain (ledger adjudication, park-don't-guess on an ambiguous send), serial drain (ordering as the substitute for receipts), delivery attempts (unknown as a real outcome), decisions, reservations, producer promotion. Function bodies are unchanged — each stage destructures the context back into the names its code already used. 1264 orchestrator tests and the file-size gate confirm it.
Each extracted stage started from the source file's whole import list, so most modules carried names they never used, plus a few type aliases that moved to the shared context. `lint:security` treats an unused binding as an error, which fails the push gate and every CI tier behind it.
The splits left three source-level import cycles and one file the coverage gate could not pair with a test. - The record-store type lived in the queue module the stages import, so every stage pointed back at it. It belongs with the context that hands it to them, and moves there. - The failure-notification module reached back into the runner for its deps type, while the runner already reaches it through the result processor. It now states the four capabilities it uses structurally. - The cross-session result type is a result declaration, not a wiring stage, so it no longer carries the `setup-` prefix that puts it under the setup-file coverage invariant.
Adds coverage for paths the queue's existing suite never drove: an unreadable store refusing every durable operation, an unwritable store refusing to acknowledge an admission it could not persist, chunked ledgerless replay at its attempt ceiling and against an unresolved prior send, terminal-store quarantine of unreadable layout, retirement-intent validation, and producer promotion across a restart. Raises cross-session statement coverage from 80.76% to 82.13%.
…efusals Adds cancellation coverage for an enqueue waiting on capacity, an already-abandoned caller, and a producer reservation blocked on producer capacity; plus governed-drain refusals where the ledger lookup is unreadable, its begin is refused, or it already holds a terminal decision.
A release bump on the default branch only touches the packages that exist there. A package added on a feature branch has nothing for the merge to conflict on, so it silently keeps its pre-bump version while every sibling moves — a drift no textual merge can surface, and one the release preflight missed because it compared the tag against the umbrella manifest alone. Assert both layers: every packages/* manifest agrees with the umbrella, and the preflight rejects a tag that disagrees with any workspace package. The preflight case runs against a synthetic workspace in a temp dir so it proves the script's real behavior without mutating this repo's manifests.
The preflight compared the release tag against the umbrella manifest alone, so a package left behind at an older version published silently — the drift reached the tarball via bundledDependencies and surfaced at publish time rather than in any local build. Read every packages/* manifest and fail on the first disagreement, naming the package and its path so the offender is fixable without a manual sweep. The release steps in AGENTS.md and CLAUDE.md hardcoded a package count that was already stale and re-drifts whenever a package is added; state the invariant over packages/* instead and cite the gates that now enforce it.
Bundled skills auto-seed into every deployment's data directory at boot, so a capability-service companion's opt-in skill shipped there reaches unrelated deployments that do not run that service. The companion repository owns it and the operator installs it into one selected agent workspace.
The bundled-skill tree auto-seeds into every deployment's data directory at boot, so the DevCrew liaison skill reached deployments that run no capability service and cannot call a single tool it describes. The companion repository owns that skill; an operator copies it into the one agent workspace configured for the service. Live campaign targets now name the companion release as its source so they keep installing it explicitly rather than relying on seeding.
The reducer already treats heartbeat freshness as an input and the record carries lastHeartbeatAtMs, but nothing writes it, so a service that stopped reporting is indistinguishable from one that never had to. Liveness must move forward only, belong to the owning service instance, and stop at a terminal run.
Adds the store mutation the reducer's heartbeat inputs were already written against. A beat advances only forward, belongs only to the owning service instance, and is refused once the run is terminal, so a stalled or departed service cannot present itself as current.
A service can report and can go quiet, but the wire has no way for it to say it is still alive between reports, so the reducer's freshness inputs can never be supplied. Liveness carries identifiers and one observation time — never run state, which would become a second unsequenced path around report ingestion.
Closes the seam the reducer was already written against: a service could report and could go quiet, but had no way to say it still held a run in between, so heartbeat freshness never had a source and a departed service looked the same as a healthy idle one. The observation is advisory and bounded against the host clock. A future-dated beat is refused rather than trusted, because accepting one would both overstate freshness now and make every honest later beat look stale. makeHost's optional dependencies are now named rather than positional: a caller that passed undefined past the defaulted session callback silently disabled the handshake its own assertions depended on.
The coordinator required a heartbeat from every service while nothing wrote one, so in production every reduction resolved to unknown; these tests stayed green only because the fixture record carried a hand-set beat. A service that never requested the health scope cannot satisfy the requirement and must not be held to it.
Every reduction demanded a heartbeat while nothing wrote one, so in production a managed run could never leave unknown and therefore never reach succeeded. The coordinator tests hid it: their fixture record carried a hand-set beat that no real code path produced. The obligation now comes from the definition's declared scopes, which is where the rest of the host's per-run requirements already live. A service that never requested the health scope has no way to send a beat and is no longer held to one; a service that did is held at unknown until it reports. Both resolvers now read the planned definition through one helper instead of repeating the instance-to-definition lookup.
The host can bind and abandon a preparation but has no way to ask a running service to stop, so an operator cancel has nothing to send. Cancellation names the run and the host's reason only: how the service disposes of work the host cannot see stays a domain decision it reports, not one the host dictates.
An operator cancel must persist the host's decision before it notifies the service, and must stay cancelled when the service is unreachable: the authority record is the host's, and a service that is down does not get to veto it.
Adds the wire method and its caller together: the host could bind and abandon a preparation but had no way to ask a running service to stop, so an operator cancel had nothing to send. The transition commits before the service is notified and stands even when the socket is down. The reducer already ranks a host-recorded cancellation above every later report, so reporting failure because the service was unreachable would contradict the record the operator can already read.
The platform had no way for an operator to see an installed service, list the runs it owns, explain why one is stuck, or cancel it — the only diagnosis path was the companion product's own CLI, which is the other half of the picture. Both groups are admin-only with no agent route, so an installed service cannot enumerate its siblings and a model turn cannot cancel a question another principal is waiting on. Capabilities that have not shipped are carried as explicitly unavailable rather than omitted, so a caller cannot render an absent custody or process view as a healthy empty one.
The scoped list is what a service or a conversation uses and it must never see another principal's work. An operator fleet view is a different caller class, so it gets its own named method with its own discriminator — the shape listRecoverable already established — rather than an optional scope on the scoped path, which would let an omitted scope quietly become a cross-tenant read.
An operator fleet view cannot use the scoped list, which is bound to one tenant, agent, principal, and conversation by design. Rather than making that scope optional — where an omitted scope silently becomes a cross-tenant read — these are separate methods behind the same explicit discriminator listRecoverable already uses, so reaching another principal's work requires naming that you are administering the host. The attention read deliberately includes settled records: an operator asking why a run is stuck needs the resolved and cancelled ones too.
A fleet row must carry no service-authored content, a capped page must say it was capped, an unshipped capability must be labelled rather than omitted, and a missing run must read as not found rather than an empty successful row.
Implements the eight admin-only methods the contracts declared: cross-run list, run detail, a deterministic explain, host-authority cancel, installed-instance views, and the attention records runs are blocked on. Until now the only way to diagnose external work was the companion product's own CLI, which is the domain half; this is the host half — whether authority bound, whether policy and the capability snapshot resolved, which host records the run holds, and whether the service is still alive. The explain verdict is deterministic over the durable record and orders causes so the outer fault wins: a missing instance outranks a liveness gap, which outranks a run merely waiting, because repairing the outer one is what makes the inner symptom go away. Three gates shaped the result rather than being worked around. The shared context type moved to its own module because a handler file may not import another handler file. Two files crossed the size cap, so the outbound run commands and the cross-scope reads were split out along the seams the terminal-event sender already established. And "fleet" is a retired domain term here, so the vocabulary is cross-run and summary throughout.
Register retry spawning as a fresh serialized persistence transition so delayed timers cannot append work to an already-drained continuation collector.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
The bridge keeps only text content from an MCP tool result, so a server that returns a screenshot leaves the agent with "Tool returned no text content" and no image. Pin the expected behavior: sanitized image parts after the text, a runtime-authored untrusted-output notice, content-free drop reporting, and a visible notice instead of a silent drop when no image policy is configured.
…model Route `image` content blocks from MCP tool results through the same sharp-backed sanitizer browser screenshots use, consider at most four blocks per call (bounding sanitizer work, not just kept output), keep text first, and prefix a runtime-authored notice that the frames are untrusted tool output. Every dropped block — sanitizer rejection, limit, unreadable data, or no policy — is reported content-free and named in the result so the agent never mistakes a dropped frame for an empty result. The daemon wires the policy through a small helper so the composition root stays under the file-size cap and the errorKind literal resolves for the log-payload gate. Documented under "Image results" in the MCP guide.
The public-command test reaches the fixture host through two nested
package-manager processes, so the spawned child is the `pnpm` wrapper
rather than the host itself. A SIGTERM sent to that wrapper is not
forwarded to its grandchild on every platform: on Linux the wrapper died
by signal and the assertion read that disposition as the host's exit,
failing the sharded unit job with `{ code: null, signal: 'SIGTERM' }`
while the same test passed on macOS.
Signal the process group so the host itself receives SIGTERM, and assert
the contract the host owns — its handler removes the credential and closes
the socket — rather than the wrapper's incidental exit disposition. A host
that is killed outright leaves both files behind, so their removal is what
proves the graceful shutdown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Ship the
release/1.0.64-prepbranch intomain: 840 commits carrying durable capability-service managed runs, the capability-service protocol bundle and fixtures, dead-letter delivery resilience, durable terminal attachment relays across worker replacement, and the 1.0.64 version bump across all 17 workspace packages.Also included (merged into this branch via #511): the MCP tool bridge no longer drops
imageresult blocks, so a server returning a screenshot reaches the model sanitized and bounded instead of collapsing to "Tool returned no text content".The three review findings listed under Risk Assessment below are closed by commits pushed after that section was written:
capability-service-protocol-fixture-host-entry.ts:81— omitsmanaged_run_group+approval_receiptscopesea4b6d0afix(daemon): align executable fixture scopescapability-service-protocol-fixture-server.test.ts:692— asserts raw package-script strings5fd56604test(protocol): exercise public fixture commandstest/architecture/capability-service-protocol-bundle.test.ts:135— matches command strings without executing5fd56604test(protocol): exercise public fixture commandsRelated Issue
N/A: release-integration PR. Each constituent change carries its own rationale in its commit; no single tracking issue covers the branch.
Type of Change
Checklist
pnpm validate— green in CI on this head, and as the local pre-push hook)N/Areason aboveRED Test Proof
This is a release-integration PR: the RED proof for each behavior lives in its own test-first commit on the branch (the
test(...)commit preceding eachfix(...)commit — e.g.b8fcc9e8/bb1db89a,3eeac39d/e8c9daac,c9ab419b/a21c058e).Captured directly for the most recent addition, run at the test-only commit before its production patch:
After the production patch:
Test Files 2 passed (2),Tests 88 passed (88).Intent
Ship release/1.0.64-prep after the completed full unit, integration, E2E, clean-build, and local review passes. Preserve the atomic managed-run admission fixes, corrected capability-service contracts and fixtures, dead-letter resilience already merged into the release branch, and durable terminal attachment relays across worker replacement. Create a PR targeting the repository default branch, drive all findings and CI to green, merge the PR, then clean up the merged release branch and only other refs proven disposable. Do not add Co-Authored-By trailers.
What Changed
Risk Assessment
🚨 High: A required cross-language fixture path remains unreachable through the standalone host, and two newly added tests rely on prohibited source-content assertions rather than the public commands.
Testing
The supplied broad validation baseline was supplemented with focused protocol, admission, dead-letter, relay, and retirement tests plus four executable/persisted-state artifacts; the only local integration retry limitation was absent clean-build
distoutput, covered by equivalent source-level execution and the supplied completed integration baseline, and all observed behavior passed. This is backend/protocol work, so visual UI evidence is not applicable.Evidence: Full-scope capability-service handshake
Evidence: Atomic managed-run admission state
Evidence: Dead-letter retry and recovery state
Evidence: Durable attachment relay across worker replacement
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
packages/capability-service-sdk/src/methods.ts:555- The required criterion “Preserve … corrected capability-service contracts and fixtures” is not met: the method catalog and production senders advertisemanagedRunGroups.activateandmanagedRunGroups.abandon, but this aggregate omits both request schemas. The cross-language fixture server therefore rejects valid group-control frames asinvalid_params. Add both schemas to the aggregate and enforce catalog-to-union parity.packages/daemon/src/__tests__/capability-service-protocol-fixture-server.ts:144- The same fixture criterion is contradicted here:managedRuns.heartbeatandmanagedRunGroups.getHostRolluphave no dispatch or response-validation cases. A valid request falls throughdispatch, which returns the request itself, while this default returns the nonempty method string as a truthy validation result, causing a malformed request-shaped response. Implement both response paths with their schemas and add their semantic fixture targets.packages/orchestrator/src/cross-session/announcement-dead-letter-terminal-decision.ts:340- The persisted retirement validator accepts atool_resultproducer without its required nonemptyoperationId, unlike the shared validator. Because JSON hashing omits the absent field, a malformed record can still have a matching ID; recovery then cannot match or remove its handoff, leaving an uncommitted producer active indefinitely or stale state after commit. ReuseisAnnouncementRetirementProducer()at this deserialization boundary.🔧 Fix: Align capability protocol parity and retirement validation
3 errors still open:
packages/daemon/src/__tests__/capability-service-protocol-fixture-host-entry.ts:81- The required criterion “Preserve … corrected capability-service contracts and fixtures” remains contradicted by the standalone fixture entry: it omitsmanaged_run_groupandapproval_receipt, causing those canonical requests to returnprecondition_failed. Its preparation sets also omitexternal-run_group-member-a, so the published valid group activation returnsinvalid_params. Enable the canonical scopes/references and exercise those requests through the standalone process.packages/daemon/src/__tests__/capability-service-protocol-fixture-server.test.ts:692- This added process test asserts raw package-script strings, then bypasses both scripts by spawning the TypeScript entry directly. It can pass while the publicpnpm capability-service-fixture-hostcommand is broken. Invoke the real package-script entry and assert its readiness and request behavior instead.test/architecture/capability-service-protocol-bundle.test.ts:135- This added test only readspackage.jsonand matches raw command strings/substrings, contrary to the test-quality rule; it does not prove either command executes. Exercise the real drift-check command and the generator against an isolated output instead.🔧 **Test** - 1 issue found → auto-fixed ✅
packages/daemon/src/__tests__/capability-service-protocol-fixture-host-entry.ts:81- The standalone cross-language fixture host is out of parity with the committed valid protocol fixture. A real handshake requesting all nine valid scopes returnsprecondition_failedbecauseactiveScopesomitsmanaged_run_groupandapproval_receipt. Add those scopes and extend the process-level test to exercise the complete valid handshake.pnpm exec vitest run src/managed-run-store.test.ts src/managed-run-group-store.test.ts --testNamePattern='admits one concurrent run when the service capacity is one|shares atomic service capacity with single-run admission'frompackages/memorypnpm exec vitest run packages/capability-service-sdk/src/contract-revision.test.tspnpm exec vitest run src/__tests__/capability-service-protocol-fixture-host.test.ts src/__tests__/capability-service-protocol-fixture-server.test.tsfrompackages/daemonpnpm exec vitest run src/tools/builtin/terminal-driver/terminal-durable-attachment-relay.test.tsfrompackages/skillspnpm exec vitest run src/cross-session/announcement-dead-letter.test.ts src/cross-session/announcement-dead-letter-terminal-decision.test.ts --testNamePattern='enqueue persists entry to JSONL file|drain retries delivery via sendToChannel|drain emits announcement:dead_letter_delivered on success|loads the durable count before the first health observation after restart|retires replay guards only when their producer completion retires|rejects malformed terminal decision and retirement record shapes'frompackages/orchestratorDaemon coordinator tests initially encountered missing ignored@comis/memory/dist; retried successfully withpnpm exec vitest run --config /var/folders/w_/w1lk_fns7nqcjkp2n3512g8c0000gn/T/no-mistakes-evidence/01M0VRAYQ3316K74DZ91J83THA/daemon-source-alias.vitest.mjs src/wiring/managed-run-activation-coordinator.test.ts src/wiring/managed-run-group-activation-coordinator.test.ts src/wiring/managed-run-report-bridge.test.ts --testNamePattern='admits a run below the concurrency cap and refuses one at the cap|rejects a group whose members exceed service capacity|admits only one of two concurrent reports at a one-report ceiling|returns the original sequence when a rate-limited client retries an accepted report'Executable fixture-host Unix-socket check covering handshake,managedRuns.receiveAttentionResponse,managedRuns.release, and cleanupExecutable full valid-scope handshake againstcapability-service-protocol-fixture-host-entry.tsReal detached relay check: worker exit → helper survival → socket round trip → helper retirementReal SQLite/JSONL check: capacity-one managed-run admission and dead-letter recovery through queue replacementgit log --format='%B' 56c47590d3e25e148a28a4b0009d09ef96e0195f..97034295ae05ea965b54a28ce6250830d008b54d | rg -n '^Co-Authored-By:'found no forbidden trailers🔧 Fix: Align executable fixture scopes with protocol
✅ Re-checked - no issues remain.
Accepted the supplied baseline of completed full unit, integration, E2E, clean-build, and local-review passes.pnpm exec vitest run packages/daemon/src/__tests__/capability-service-protocol-fixture-server.test.ts packages/capability-service-sdk/src/contract-revision.test.ts packages/memory/src/managed-run-store.test.ts packages/memory/src/managed-run-group-store.test.ts packages/skills/src/tools/builtin/terminal-driver/terminal-durable-attachment-relay.test.ts -t 'runs as a test-only process|accepts one canonical request for every advertised method|classifies report replay before applying atomic rate admission|admits one concurrent run when the service capacity is one|shares atomic service capacity with single-run admission|launches a detached session-bound helper and transfers attachment authority over stdin'pnpm exec vitest run packages/orchestrator/src/cross-session/announcement-dead-letter.test.ts packages/daemon/src/__tests__/capability-service-protocol-fixture-server.test.ts -t 'drain retries delivery via sendToChannel|drain emits announcement:dead_letter_delivered on success|binds a 0600 Unix socket and strictly dispatches the closed pinned methods'pnpm exec vitest run packages/orchestrator/src/cross-session/announcement-dead-letter-terminal-decision.test.ts -t 'rejects malformed terminal decision and retirement record shapes'pnpm exec vitest run --config test/vitest.config.ts test/integration/resilience-e2e-dead-letter.test.ts -t 'failed delivery -> enqueue -> drain retry -> successful delivery -> dead_letter_delivered event'(setup-only import failure because this isolated worktree lacks daemon/orchestratordist; covered by the supplied integration baseline plus source-mapped checks).Manual executable fixture-host JSON-RPC handshake requesting all nine scopes, including socket/credential permissions, secret non-disclosure, and shutdown cleanup.Manual SQLite concurrent single/group admission at capacity one, inspecting the resulting durable authority rows.Manual JSONL dead-letter lifecycle through persistence, rejected retry retention, accepted recovery, cleanup, and emitted events.Manual detached attachment-relay lifecycle using separate original and replacement worker processes, followed by clean retirement.Parsed all evidence artifacts, checked testing-process cleanup and worktree state, and rangit log --format='%B' 56c47590d3e25e148a28a4b0009d09ef96e0195f..HEAD | rg -i '^Co-Authored-By:'.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.