Skip to content

test(qualification): close greenfield Phase 0 - #391

Open
mira-2026 wants to merge 4 commits into
mira/greenfield-rewrite-gateway-verifierfrom
mira/greenfield-rewrite-qualification-closure
Open

test(qualification): close greenfield Phase 0#391
mira-2026 wants to merge 4 commits into
mira/greenfield-rewrite-gateway-verifierfrom
mira/greenfield-rewrite-qualification-closure

Conversation

@mira-2026

@mira-2026 mira-2026 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • close all eight mandatory Phase 0 qualification spikes on the exact audited Bun canary
  • add executable frontend/endpoint parity inventories and a hash-pinned OpenClaw 2026.7.2-beta.7 protocol/source audit
  • qualify compiler-first frontend builds, TanStack Query Collections, multiprocess SQLite/outbox behavior, 150 ms chat batching, raw RFC 6455 fragmentation, complete shutdown, and capped resource budgets
  • move qualification cleanup and production listener shutdown orchestration onto the existing Effect-owned runtime with bounded deadlines, cancellation, tagged failures, and deterministic force escalation
  • harden reviewed fixture/source reads against races, enforce fail-closed route-tree and CSP accounting, and close every first-head CodeQL/CodeRabbit finding and nitpick
  • update the greenfield blueprint, progress ledger, delivery policy, generated runtime docs, and exact legacy endpoint inventory

Architecture and delivery boundaries

  • Bun revision 17d6843606d76620cb55d31424d7fb0aed51c367 is qualification evidence, not a new repository-wide runtime pin.
  • Synchronous SQLite transaction callbacks, Valibot parsing, hashing, and deterministic state calculations remain plain TypeScript.
  • No greenfield production cutover, credential mutation, service restart, or lower-stack change is included.
  • This PR is based directly on locked PR feat(security): add native Gateway credential verification #390 at f1a66709a07ba45f853d18070de6ff92ae956183.

Verification

  • bun install --frozen-lockfile
  • installed Bun qualification: 151 tests, 758 assertions, 0 failures across 31 files
  • exact candidate qualification: 151 tests, 758 assertions, 0 failures across 31 files
  • bun run typecheck:qualification
  • bun run typecheck:server
  • bun run test:server: 836 tests, 3340 assertions, 0 failures
  • bun run test:server:docs: 13 tests, 291 assertions, 0 failures
  • bun run test:server:tooling
  • bun run docs:check
  • bun run db:check
  • bun run lint
  • bun run format:check
  • bun run build:frontend
  • bun run test:frontend:coverage: 705 tests, 4493 assertions, 0 failures
  • bun run build:backend
  • bun run test:backend:coverage: 738 tests, 4769 assertions, 0 failures
  • exact-candidate cgroup resource matrix: all six scenarios passed with no memory cap/OOM events, memory pressure, leaked processes, transient units, cgroups, or temporary state
  • final independent adversarial code audit after all review fixes: READY, no remaining findings or nitpicks

@mira-2026
mira-2026 requested a review from rajohan as a code owner August 6, 2026 05:01
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added health and readiness probes, dashboard settings, expanded logging, Docker management, and pull-request stack documentation.
    • Improved frontend build validation, chat responsiveness, resource controls, data delivery, shutdown handling, and connection cleanup.
    • Added stronger route, protocol, file, and source consistency validation.
  • Documentation

    • Updated rewrite progress, architecture decisions, implementation plans, and delivery evidence.
  • Bug Fixes

    • Corrected frontend build plugin ordering and pinned database package versions.
    • Improved graceful shutdown escalation, deadlines, and error handling.

Walkthrough

This PR adds qualification workflows for frontend builds, chat batching, OpenClaw parity, SQLite outbox behavior, resource budgets, shutdown, and WebSocket protocols. It also adds Effect-based lifecycle management, coordinated server shutdown, exact dependency pins, build-plugin ordering, and architecture documentation updates.

Changes

Qualification and runtime changes

Layer / File(s) Summary
Frontend, browser, and chat qualification
qualification/browser/*, qualification/build/*, qualification/chat/*
Adds TanStack Query collection qualification, Bun frontend build checks, deterministic chat batching, and supporting fixtures.
Effect lifecycle and shutdown coordination
qualification/test/*, qualification/resources/*, qualification/shutdown/*, src/server/platform/runtime/*, src/app/server.ts
Adds scoped cleanup, SSE resources, shutdown services, WAL-backed shutdown state, and coordinated graceful-to-forced listener shutdown.
WebSocket protocol qualification
qualification/websocket/*
Adds RFC 6455 framing fixtures, native WebSocket observation, fragmented UTF-8 cases, close handling, limits, and cleanup tests.
Outbox and resource-budget qualification
qualification/outbox/*, qualification/budgets/*
Adds SQLite outbox storage, multiprocess recovery checks, systemd resource policies, cgroup evidence, bounded workloads, and CLI runners.
Source parity inventories
qualification/parity/*, scripts/qualification/legacyBackendRouteProbe.ts
Adds strict route and endpoint fixtures, source extraction, legacy route probing, reviewed comparisons, target accounting, and candidate generation.
OpenClaw source audit
qualification/openclaw/*
Adds strict schemas, versioned fixtures, artifact hashing, source-contract extraction, reviewed comparisons, candidate writing, and CLI tests.
Documentation and integration
docs/*, bunfig.toml, package.json, scripts/frontendBuild.ts
Updates endpoint and rewrite documentation, pins TanStack packages, and places the React Compiler plugin before Tailwind.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: area: frontend, area: backend

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description provides a detailed summary and verification results but omits the required behavior, risk, deployment, and reviewer-notes sections. Add the missing template sections and document behavior/regression coverage, risk review, deployment needs, rollback, and reviewer focus.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely identifies the main change: closing the greenfield Phase 0 qualification work.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mira-2026 mira-2026 changed the title mira/greenfield rewrite qualification closure test(qualification): close greenfield Phase 0 Aug 6, 2026
@mira-2026 mira-2026 added type: tests Adds or updates automated tests/coverage area: ci CI, test runners, workflow checks, and release gates area: openclaw OpenClaw gateway/API integration and runtime behavior labels Aug 6, 2026
@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Comment thread qualification/build/frontendBuildQualification.ts Fixed
Comment thread qualification/openclaw/reviewedFixtures.ts Fixed
Comment thread qualification/openclaw/sourceAudit.ts Fixed
Comment thread qualification/parity/legacyBackendRouteInventory.ts Fixed
Comment thread qualification/parity/reviewedParityInventory.ts Fixed
Comment thread qualification/parity/sourceParityInventory.ts Fixed
Comment thread qualification/parity/parityInventorySchemas.ts Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (13)
qualification/parity/parityInventory.test.ts-98-103 (1)

98-103: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Give this parity test a timeout above the probe budget.

loadLegacyBackendRouteIdentities waits on Bun.spawnSync with a 5000 ms subprocess timeout, while Bun tests also default to 5000 ms. Add an explicit test timeout larger than 5000 ms so probe failures can surface instead of being masked by a test timeout.

♻️ Proposed change
-    test("accounts for every executable backend route and documented row exactly once", async () => {
+    test("accounts for every executable backend route and documented row exactly once", async () => {
             ).toHaveLength(0);
-    });
+    }, 20_000);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/parity/parityInventory.test.ts` around lines 98 - 103, Set an
explicit timeout greater than 5000 ms on the test named “accounts for every
executable backend route and documented row exactly once,” ensuring the
loadLegacyBackendRouteIdentities probe can reach its timeout and report failures
without the test runner timing out first.
qualification/openclaw/sourceAudit.ts-1016-1020 (1)

1016-1020: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Bind promptChars: 4000 to a source marker.

promptChars is emitted by the reviewer, but no marker in the installed OpenClaw artifacts ties it to the source. Add the OpenClaw constant or literal that sets the bounded task prompt length to the relevant task protocol/handler assertion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/openclaw/sourceAudit.ts` around lines 1016 - 1020, Update the
OpenClaw source-audit assertion around promptVisibility to include the source
marker for the constant or literal that sets the bounded task prompt length to
4000. Bind promptChars to the relevant task protocol or handler assertion,
preserving the existing visibility flags and value.
qualification/budgets/resourceBudgetPolicy.test.ts-217-220 (1)

217-220: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Test unitCollected separately.

This case changes cgroupRemoved, not unitCollected. It duplicates the cgroup cleanup condition and does not verify that assessResourceBudgetEvidence rejects an uncollected unit.

Proposed fix
             [
-                "unit was not collected",
+                "cgroup was not removed",
                 (candidate) => {
                     candidate.cgroupRemoved = false;
                 },
             ],
+            [
+                "unit was not collected",
+                (candidate) => {
+                    candidate.unitCollected = false;
+                },
+            ],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/budgets/resourceBudgetPolicy.test.ts` around lines 217 - 220,
Update the test case around the “unit was not collected” candidate mutation so
it sets unitCollected to false instead of cgroupRemoved. Keep cgroup cleanup
coverage in its separate test and ensure this case verifies that
assessResourceBudgetEvidence rejects an uncollected unit.
qualification/budgets/resourceBudgetOrchestration.ts-406-447 (1)

406-447: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Check the launcher exit code before reading the unit report.

readResult runs at Line 418, inside the scope. The launcher exit-code check runs at Line 432, after the scope closes.

If the launcher fails, the unit writes no report. readResult then fails first with "Resource-budget unit did not write a report". The diagnostic block at Lines 433-439, which carries the launcher stderr and stdout, never executes. The operator sees a missing-report error instead of the actual launch failure.

Move the exit-code check into the scope, directly after runBoundedProcess.

🐛 Proposed fix to surface the launcher failure first
         const completed = yield* Effect.scoped(
             Effect.gen(function* () {
                 yield* transientUnitResource(command);
                 const limits = resourceBudgetPolicy.scenarios[scenarioId].limits;
                 const launcher = yield* runBoundedProcess(
                     command.argv,
                     command.environment,
                     resourceBudgetPolicy.launcherOutputMaxBytes,
                     limits.outerDeadlineMs,
                     "run-transient-unit",
                     scenarioId
                 );
+                if (launcher.exitCode !== 0) {
+                    const diagnostic = [launcher.stderr.trim(), launcher.stdout.trim()]
+                        .filter((value) => value.length > 0)
+                        .join("\n")
+                        .slice(0, 16 * 1024);
+                    return yield* Effect.fail(
+                        new ResourceBudgetOrchestrationError({
+                            cause: diagnostic,
+                            operation: "transient-unit-exit",
+                            scenarioId,
+                        })
+                    );
+                }
                 const report = yield* readResult(command);
                 return { launcher, report };
             })
         );
         const [unitCollected, cgroupRemoved] = yield* Effect.all(
             [unitIsCollected(command), cgroupIsRemoved(cgroupPath)] as const,
             { concurrency: "unbounded" }
         );
-        const evidence: ResourceBudgetScenarioEvidence = {
+        return {
             cgroupRemoved,
             launcherExitCode: completed.launcher.exitCode,
             report: completed.report,
             unitCollected,
-        };
-        if (completed.launcher.exitCode !== 0) {
-            const diagnostic = [
-                completed.launcher.stderr.trim(),
-                completed.launcher.stdout.trim(),
-            ]
-                .filter((value) => value.length > 0)
-                .join("\n")
-                .slice(0, 16 * 1024);
-            return yield* Effect.fail(
-                new ResourceBudgetOrchestrationError({
-                    cause: diagnostic,
-                    operation: "transient-unit-exit",
-                    scenarioId,
-                })
-            );
-        }
-        return evidence;
+        } satisfies ResourceBudgetScenarioEvidence;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/budgets/resourceBudgetOrchestration.ts` around lines 406 - 447,
Move the launcher exit-code validation into the Effect.scoped generator
immediately after runBoundedProcess and before readResult. Preserve the existing
diagnostic construction and ResourceBudgetOrchestrationError with operation
"transient-unit-exit", and return the completed launcher/report only when the
launcher succeeds.
qualification/outbox/sqliteOutboxQualification.test.ts-74-86 (1)

74-86: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

The sentinel error is swallowed by its own catch, and the competing transaction leaks.

If competingWriter.run("BEGIN IMMEDIATE") succeeds, the code throws "Competing writer unexpectedly acquired WAL lock". The adjacent catch receives that same Error. classifyQualificationSqliteError then returns undefined because the value has no SQLITE_ code. The assertion at Line 99 still fails, but the reported cause becomes "received undefined" instead of the explicit sentinel message.

On that path competingWriter also stays inside an open BEGIN IMMEDIATE transaction. The finally block rolls back only writer.

Track the acquisition outside the catch and roll back both connections.

🐛 Proposed fix for the sentinel and the leaked transaction
                     const contention = yield* Effect.sync(() => {
                         writer.run("BEGIN IMMEDIATE");
+                        let competingWriterAcquired = false;
                         try {
                             competingWriter.run("BEGIN IMMEDIATE");
-                            throw new Error(
-                                "Competing writer unexpectedly acquired WAL lock"
-                            );
+                            competingWriterAcquired = true;
+                            return undefined;
                         } catch (error) {
                             return classifyQualificationSqliteError(error);
                         } finally {
+                            if (competingWriterAcquired) competingWriter.run("ROLLBACK");
                             writer.run("ROLLBACK");
                         }
                     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/outbox/sqliteOutboxQualification.test.ts` around lines 74 - 86,
Update the contention logic in the Effect.sync block to track whether
competingWriter.run("BEGIN IMMEDIATE") succeeds, only classify errors from the
competing transaction attempt, and preserve the explicit sentinel error for
unexpected lock acquisition. In the finally block, roll back writer and also
roll back competingWriter when it successfully began a transaction.
qualification/budgets/resourceBudgetUnit.ts-430-439 (1)

430-439: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

The reported limits use unchecked casts on finalCgroup and a hardcoded oomGroup.

Two problems exist in the limits block.

First, cpuQuotaMicros, memoryHighBytes, memoryMaxBytes, memorySwapMaxBytes, and pidsMax are typed as number | "max". The guard at Lines 365-378 validated initialCgroup, not finalCgroup. The as number casts therefore suppress the union without any runtime check. If a final read returns "max", writeReport serializes the string. parseResourceBudgetUnitReport in qualification/budgets/resourceBudgetPolicy.ts then rejects the report with a Valibot error, so the orchestrator reports a parse failure instead of a cgroup-policy failure.

Second, oomGroup: true is a literal. assertObservedLimits checks !observed.oomGroup at Line 298 of qualification/budgets/resourceBudgetPolicy.ts, and the schema uses v.literal(true). Both checks are therefore tautological for the final state.

Validate the final limits in the unit, and carry the observed oomGroup value.

🐛 Proposed fix to validate the final cgroup limits
+        if (
+            finalCgroup.cpuQuotaMicros === "max" ||
+            finalCgroup.memoryHighBytes === "max" ||
+            finalCgroup.memoryMaxBytes === "max" ||
+            finalCgroup.memorySwapMaxBytes === "max" ||
+            finalCgroup.pidsMax === "max" ||
+            !finalCgroup.oomGroup
+        ) {
+            return yield* Effect.fail(
+                new ResourceBudgetUnitError({ operation: "verify-final-cgroup-policy" })
+            );
+        }
         const report: ResourceBudgetUnitReport = {
@@
             limits: {
                 cpuPeriodMicros: finalCgroup.cpuPeriodMicros,
-                cpuQuotaMicros: finalCgroup.cpuQuotaMicros as number,
-                memoryHighBytes: finalCgroup.memoryHighBytes as number,
-                memoryMaxBytes: finalCgroup.memoryMaxBytes as number,
-                memorySwapMaxBytes: finalCgroup.memorySwapMaxBytes as number,
-                oomGroup: true,
-                pidsMax: finalCgroup.pidsMax as number,
+                cpuQuotaMicros: finalCgroup.cpuQuotaMicros,
+                memoryHighBytes: finalCgroup.memoryHighBytes,
+                memoryMaxBytes: finalCgroup.memoryMaxBytes,
+                memorySwapMaxBytes: finalCgroup.memorySwapMaxBytes,
+                oomGroup: finalCgroup.oomGroup,
+                pidsMax: finalCgroup.pidsMax,
             },

The explicit === "max" comparisons narrow each union, so the casts become unnecessary.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/budgets/resourceBudgetUnit.ts` around lines 430 - 439, Update
the limits construction around finalCgroup to validate the final values rather
than relying on casts: explicitly reject or handle "max" for cpuQuotaMicros,
memoryHighBytes, memoryMaxBytes, memorySwapMaxBytes, and pidsMax so the reported
fields remain numeric. Replace the hardcoded oomGroup: true with the observed
finalCgroup.oomGroup value, preserving schema and assertObservedLimits
validation.
qualification/build/frontendBuildQualification.test.ts-12-12 (1)

12-12: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert production hashed assets are present

The .every(...) assertion passes on an empty filtered array, so this check does not prove that any .css/.js output is hash-busted. Assert production.outputPaths contains at least one production asset before checking the hashedAssetPattern.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/build/frontendBuildQualification.test.ts` at line 12, Update
the production asset assertion using hashedAssetPattern to first verify that
production.outputPaths contains at least one matching CSS or JavaScript asset,
then apply the existing hash-pattern validation so an empty filtered array
cannot pass.
qualification/build/frontendBuildQualification.test.ts-70-81 (1)

70-81: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Make the React Compiler assertion depend on the unminified output.

buildQualificationFrontend runs production with minify: true, and the compiler imports the cache function locally before calling it. Minification can rename that local binding, so useMemoCache is not a stable production-bundle marker. Assert the compiler ran against the unminified development bundle, or assert a stable specifier such as the compiler-runtime import string.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/build/frontendBuildQualification.test.ts` around lines 70 - 81,
Update the React Compiler assertion in the frontend build qualification test to
inspect unminified development output or a stable compiler-runtime import
specifier instead of requiring the production bundle to contain the local name
“useMemoCache”. Keep the stylesheet assertion unchanged and ensure the test
still verifies that the compiler ran.
qualification/chat/chatBatchingModel.ts-123-127 (1)

123-127: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Compute the p95 rank with integer arithmetic.

Math.ceil(sorted.length * 0.95) is affected by binary floating-point representation. 0.95 is not exact, so 20 * 0.95 evaluates to 19.000000000000004 and Math.ceil returns 20. The function then returns the maximum value instead of the 95th percentile. The same drift occurs for other lengths that are multiples of 20.

p95CommitDelayMs is published in the evidence artifact by qualification/chat/runChatBatchingQualification.ts, so the reported value is overstated for those trace lengths.

🐛 Proposed fix
 function percentile95(values: readonly number[]): number {
     if (values.length === 0) return 0;
     const sorted = values.toSorted((left, right) => left - right);
-    return sorted[Math.ceil(sorted.length * 0.95) - 1] ?? 0;
+    return sorted[Math.ceil((sorted.length * 95) / 100) - 1] ?? 0;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/chat/chatBatchingModel.ts` around lines 123 - 127, Update
percentile95 to calculate the 95th-percentile rank using integer arithmetic
rather than multiplying by the floating-point literal 0.95; preserve the
existing empty-input fallback, sorted ordering, and zero-based indexing while
ensuring lengths divisible by 20 select the 19th-ranked value instead of the
maximum.
qualification/chat/chatBatchingQualification.ts-68-77 (1)

68-77: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

The thinking guard cannot fail; assert the stream instead.

fixtureEvent at line 37 already filters on candidate.kind === kind and throws when no event matches. Line 75 therefore tests a condition that is always false, and the error message at line 76 does not describe what is actually verified.

thinking is bound to the first agent-delta in completed-tool-run, not to an event whose stream is "thinking". The reviewed fixture happens to order the thinking delta first. If a future reviewed fixture reorders that scenario, thinking silently becomes an assistant-stream template and payloadBytes is computed from the wrong template, while this guard still passes.

Select thinking by stream and assert it, matching how assistant is selected.

🐛 Proposed fix
     const throttleMs = fixture.streamingPolicy.deltaThrottleMs;
-    const thinking = fixtureEvent(fixture, "completed-tool-run", "agent-delta");
-    const assistant = fixture.syntheticScenarios
+    const agentDeltaForStream = (stream: "assistant" | "thinking") =>
+        fixture.syntheticScenarios
             .flatMap(({ events }) => events)
             .find(
                 (event): event is Extract<SyntheticChatEvent, { kind: "agent-delta" }> =>
-                event.kind === "agent-delta" && event.stream === "assistant"
+                    event.kind === "agent-delta" && event.stream === stream
             );
-    if (thinking.kind !== "agent-delta" || assistant === undefined) {
+    const thinking = agentDeltaForStream("thinking");
+    const assistant = agentDeltaForStream("assistant");
+    if (thinking === undefined || assistant === undefined) {
         throw new Error("Reviewed chat fixture lacks both coalesced agent streams");
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/chat/chatBatchingQualification.ts` around lines 68 - 77, Update
the thinking event selection in the fixture validation to require both kind
"agent-delta" and stream "thinking", rather than relying on fixtureEvent’s first
matching event. Preserve the assistant selection, and change the guard/error to
assert that the thinking and assistant stream-specific events are both present
before computing payloadBytes.
qualification/shutdown/shutdownService.ts-166-168 (1)

166-168: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

The process-group evidence is not established by the code. The qualification reports and documents a detached process group, but grandchildProcessResource in qualification/shutdown/shutdownServiceResources.ts spawns with detached: false, and stopGrandchild signals a single pid. One decision resolves both sites: either create a real process group and signal it, or stop claiming one.

  • qualification/shutdown/shutdownService.ts#L166-L168: either establish group leadership before reporting processGroupId, or rename the field to reflect that it carries the service pid.
  • docs/architecture/greenfield-rewrite/progress.md#L618-L625: replace "ends the detached process group" with wording that matches the single-child SIGTERM-then-SIGKILL reaping that the code performs.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/shutdown/shutdownService.ts` around lines 166 - 168, Align the
reported process-group evidence with the implemented single-process behavior: in
qualification/shutdown/shutdownService.ts at lines 166-168, rename
processGroupId to represent the service pid unless group leadership is
explicitly established; in docs/architecture/greenfield-rewrite/progress.md at
lines 618-625, replace the claim that a detached process group is ended with
wording describing single-child SIGTERM-then-SIGKILL reaping.
qualification/shutdown/shutdownServiceResources.ts-430-465 (1)

430-465: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

A failed handshake leaks the open WebSocket.

fail removes the listeners and resumes with a failure. It never closes socket. The socket stays in CONNECTING or OPEN on the gateway-non-text-frame, gateway-transport-error, and gateway-protocol-error paths. gatewaySocketResource acquires through openGatewaySocket, so a failed acquisition produces no resource and registers no finalizer. The socket then survives until the process exits.

The interrupt canceler at Line 469 already performs the correct close. Reuse it in fail.

🐛 Proposed fix to close the socket on handshake failure
+            const closeSocket = () => {
+                if (
+                    socket.readyState === WebSocket.CONNECTING ||
+                    socket.readyState === WebSocket.OPEN
+                ) {
+                    socket.close(1000, "qualification handshake failed");
+                }
+            };
             const fail = (operation: string, cause?: unknown) => {
                 if (settled) return;
                 settled = true;
                 removeListeners();
+                closeSocket();
                 resume(
                     Effect.fail(
                         new ShutdownQualificationResourceError({ cause, operation })
                     )
                 );
             };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/shutdown/shutdownServiceResources.ts` around lines 430 - 465,
Update the handshake failure handler fail in gatewaySocketResource to close the
WebSocket before resuming with failure. Reuse the existing interrupt canceler’s
socket-close behavior rather than duplicating a different cleanup path, while
preserving listener removal and ShutdownQualificationResourceError reporting.
qualification/shutdown/shutdownGrandchild.ts-1-3 (1)

1-3: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the grandchild alive with an explicit handle.

Effect.never keeps the fiber scheduled, but this uses raw Effect.runPromise instead of a platform runtime that supports SIGTERM. If the runtime handle is not guaranteed after Effect 4 refactor, replace this with Effect.sleep for a long duration or an explicit interval.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/shutdown/shutdownGrandchild.ts` around lines 1 - 3, Update the
grandchild’s top-level Effect execution around Effect.runPromise so its
long-running lifecycle is retained through an explicit runtime handle that
supports SIGTERM. If that handle is unavailable after the Effect 4 refactor,
replace Effect.never with a sufficiently long Effect.sleep or an explicit
interval while preserving the process’s alive behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@qualification/budgets/runSafeChildCancellationEvidence.ts`:
- Around line 5-10: Update the validation around
interruptedShutdownQualification to fail when
report.processGroupMembersWhileReady.length is zero, ensuring the evidence
confirms a child process existed before interruption. Preserve the existing
post-interruption and stopped-status checks in the same error path.

In `@qualification/outbox/sqliteOutboxProtocol.ts`:
- Line 4: Align countSchema with the maximum count produced by runDrainCommand:
either reduce the drain loop’s permitted total to the protocol bound or increase
validation to cover the full possible drain result. Ensure successful drain
statuses remain accepted by readStatus.

In `@qualification/shutdown/completeShutdownQualification.test.ts`:
- Around line 60-61: Set explicit Bun timeout values on the tests invoking
completeShutdownQualification and interruptedShutdownQualification, using a
duration greater than each qualification’s total operation budget and
process-spawning overhead. Update both test declarations while preserving their
existing assertions and qualification behavior.

In `@qualification/shutdown/completeShutdownQualification.ts`:
- Around line 254-273: Update
qualification/shutdown/completeShutdownQualification.ts:254-273 in fetchResponse
to acquire the Response body within the enclosing scope and register
response.body?.cancel() as its release finalizer, ensuring callers at 523, 534,
and 566 cannot leak connections. Also update
qualification/shutdown/completeShutdownQualification.ts:334-356 to explicitly
cancel the reader when opening-event validation fails, because the
Effect.acquireRelease cleanup does not run when acquisition fails.
- Around line 159-181: Update the early-exit branch in stopServiceProcess so an
already-exited child still invokes killProcessGroup(child.pid) before
completing. Preserve the existing graceful shutdown and timeout flow for running
children, and ensure the detached process group is reaped in both exitCode and
signalCode cases.

In `@qualification/shutdown/shutdownIdleHttpConnection.ts`:
- Around line 90-105: Update the response handling in the idle HTTP
qualification to parse the headers after headerEnd, extract Content-Length, and
wait until headerEnd + 4 + contentLength bytes are available before settling.
Keep the existing status validation, then pause the socket and resume only after
the complete readiness response body has been consumed.

In `@src/app/server.ts`:
- Around line 150-162: Update the shutdownListener error path in the stopPromise
callback to specifically handle ApplicationListenerStopTimeoutError before
disposing the application runtime: mark readiness unavailable and record that
listener shutdown did not complete so the process supervisor can escalate
termination. Preserve primaryErrorAfterCleanup for other errors and do not
dispose before recording this state.

In `@src/server/platform/runtime/applicationRuntime.ts`:
- Around line 112-155: Ensure gracefulShutdownTimeoutMs represents one total
shutdown budget rather than applying independently to the graceful wait,
boundedForceListenerStop, and awaitGracefulListenerSettlement; derive each later
timeout from the remaining deadline while preserving the existing timeout errors
and shutdown sequence. Update the ApplicationListenerShutdownOptions
documentation to state the single-budget semantics.

---

Minor comments:
In `@qualification/budgets/resourceBudgetOrchestration.ts`:
- Around line 406-447: Move the launcher exit-code validation into the
Effect.scoped generator immediately after runBoundedProcess and before
readResult. Preserve the existing diagnostic construction and
ResourceBudgetOrchestrationError with operation "transient-unit-exit", and
return the completed launcher/report only when the launcher succeeds.

In `@qualification/budgets/resourceBudgetPolicy.test.ts`:
- Around line 217-220: Update the test case around the “unit was not collected”
candidate mutation so it sets unitCollected to false instead of cgroupRemoved.
Keep cgroup cleanup coverage in its separate test and ensure this case verifies
that assessResourceBudgetEvidence rejects an uncollected unit.

In `@qualification/budgets/resourceBudgetUnit.ts`:
- Around line 430-439: Update the limits construction around finalCgroup to
validate the final values rather than relying on casts: explicitly reject or
handle "max" for cpuQuotaMicros, memoryHighBytes, memoryMaxBytes,
memorySwapMaxBytes, and pidsMax so the reported fields remain numeric. Replace
the hardcoded oomGroup: true with the observed finalCgroup.oomGroup value,
preserving schema and assertObservedLimits validation.

In `@qualification/build/frontendBuildQualification.test.ts`:
- Line 12: Update the production asset assertion using hashedAssetPattern to
first verify that production.outputPaths contains at least one matching CSS or
JavaScript asset, then apply the existing hash-pattern validation so an empty
filtered array cannot pass.
- Around line 70-81: Update the React Compiler assertion in the frontend build
qualification test to inspect unminified development output or a stable
compiler-runtime import specifier instead of requiring the production bundle to
contain the local name “useMemoCache”. Keep the stylesheet assertion unchanged
and ensure the test still verifies that the compiler ran.

In `@qualification/chat/chatBatchingModel.ts`:
- Around line 123-127: Update percentile95 to calculate the 95th-percentile rank
using integer arithmetic rather than multiplying by the floating-point literal
0.95; preserve the existing empty-input fallback, sorted ordering, and
zero-based indexing while ensuring lengths divisible by 20 select the
19th-ranked value instead of the maximum.

In `@qualification/chat/chatBatchingQualification.ts`:
- Around line 68-77: Update the thinking event selection in the fixture
validation to require both kind "agent-delta" and stream "thinking", rather than
relying on fixtureEvent’s first matching event. Preserve the assistant
selection, and change the guard/error to assert that the thinking and assistant
stream-specific events are both present before computing payloadBytes.

In `@qualification/openclaw/sourceAudit.ts`:
- Around line 1016-1020: Update the OpenClaw source-audit assertion around
promptVisibility to include the source marker for the constant or literal that
sets the bounded task prompt length to 4000. Bind promptChars to the relevant
task protocol or handler assertion, preserving the existing visibility flags and
value.

In `@qualification/outbox/sqliteOutboxQualification.test.ts`:
- Around line 74-86: Update the contention logic in the Effect.sync block to
track whether competingWriter.run("BEGIN IMMEDIATE") succeeds, only classify
errors from the competing transaction attempt, and preserve the explicit
sentinel error for unexpected lock acquisition. In the finally block, roll back
writer and also roll back competingWriter when it successfully began a
transaction.

In `@qualification/parity/parityInventory.test.ts`:
- Around line 98-103: Set an explicit timeout greater than 5000 ms on the test
named “accounts for every executable backend route and documented row exactly
once,” ensuring the loadLegacyBackendRouteIdentities probe can reach its timeout
and report failures without the test runner timing out first.

In `@qualification/shutdown/shutdownGrandchild.ts`:
- Around line 1-3: Update the grandchild’s top-level Effect execution around
Effect.runPromise so its long-running lifecycle is retained through an explicit
runtime handle that supports SIGTERM. If that handle is unavailable after the
Effect 4 refactor, replace Effect.never with a sufficiently long Effect.sleep or
an explicit interval while preserving the process’s alive behavior.

In `@qualification/shutdown/shutdownService.ts`:
- Around line 166-168: Align the reported process-group evidence with the
implemented single-process behavior: in
qualification/shutdown/shutdownService.ts at lines 166-168, rename
processGroupId to represent the service pid unless group leadership is
explicitly established; in docs/architecture/greenfield-rewrite/progress.md at
lines 618-625, replace the claim that a detached process group is ended with
wording describing single-child SIGTERM-then-SIGKILL reaping.

In `@qualification/shutdown/shutdownServiceResources.ts`:
- Around line 430-465: Update the handshake failure handler fail in
gatewaySocketResource to close the WebSocket before resuming with failure. Reuse
the existing interrupt canceler’s socket-close behavior rather than duplicating
a different cleanup path, while preserving listener removal and
ShutdownQualificationResourceError reporting.

---

Nitpick comments:
In `@docs/architecture/greenfield-rewrite/progress.md`:
- Around line 631-642: Update the final scenario label in the table to
“Child-process cancel” so it matches the corresponding row in the other
architecture document, without changing its measurements or table structure.

In `@docs/architecture/greenfield-rewrite/runtime-and-delivery.md`:
- Around line 90-101: Remove the duplicated resource matrix table from the
runtime-and-delivery document and replace it with a reference link to the
authoritative measurements in the progress record. Preserve the surrounding
statement about passing resource checks and direct readers to the existing
resource matrix section in progress.md.

In `@package.json`:
- Around line 59-61: The manifest lacks a direct pin for `@tanstack/db`. In
package.json lines 59-61, add the `@tanstack/db` version pin at 0.6.17 or an
equivalent Bun override alongside the existing TanStack pins; in
qualification/browser/queryCollectionAdapter.test.ts lines 203-210, keep the
version assertion and update its expected value whenever the manifest pin
changes.

In `@qualification/browser/queryCollectionAdapter.test.ts`:
- Around line 231-256: Update readInstalledVersions() to resolve each
package.json through the adapter test’s module-resolution context instead of
constructing URLs from ../../node_modules. Use the resolver to locate the
installed copy under the test scope’s `@tanstack` packages, then read and validate
its version as before.

In `@qualification/budgets/resourceBudgetOrchestration.ts`:
- Around line 79-85: Update requiredExecutable and its callers in
resourceBudgetQualification to return failures through the declared Effect error
channel instead of throwing plain Error values. Convert missing or non-absolute
executable results into ResourceBudgetOrchestrationError, preserving the
existing ResourceBudgetOrchestrationDeadlineError behavior and allowing callers
to handle the failure with Effect.catchTag.

In `@qualification/budgets/resourceBudgetPolicy.ts`:
- Around line 6-18: Update resourceBudgetUnitNamePattern to derive its scenario
alternation from resourceBudgetScenarioIds instead of repeating literal ids,
while preserving the existing resource-budget unit-name format and matching
behavior. Ensure the pattern is initialized after resourceBudgetScenarioIds is
declared and remains compatible with createResourceBudgetUnitName and
assertResourceBudgetUnitName.

In `@qualification/build/frontendBuildQualification.ts`:
- Around line 26-28: Update qualificationFrontendEntrypoint to resolve the
fixture path relative to import.meta.dir rather than process.cwd(), while
preserving the existing qualification/build/fixtures/frontend/index.html
location.

In `@qualification/build/runFrontendBuildQualification.ts`:
- Around line 33-49: Update the metrics validation in the build qualification
flow after readFile to parse the JSON content and compare the parsed
formatVersion value to 1, replacing the formatted substring check in the
existing metrics.includes condition. Preserve the existing error message and all
other validation checks.

In `@qualification/chat/chatBatchingModel.ts`:
- Line 225: Update maximumCommitDelayMs in simulateChatBatching to compute the
maximum commit delay with reduce instead of spreading commitDelays into
Math.max, while preserving the existing zero fallback for empty or non-positive
values and supporting arbitrarily large traces.

In `@qualification/chat/chatBatchingQualification.ts`:
- Around line 139-151: In the rejection-reason construction, define separate
named constants for the visual-delay and crash-window bounds using the
corresponding metrics fields maximumAdditionalVisualDelayMs and
maximumCrashWindowMs, then use each constant for its matching reason condition.
Keep the existing scheduled-transaction bound and reason unchanged.

In `@qualification/openclaw/reviewedFixtures.ts`:
- Around line 209-229: Refactor the existence check around stat(outputDirectory)
to use an explicit existence flag rather than throwing and identifying the
sentinel via error.message. Set the flag when stat succeeds, handle only ENOENT
as the absent-directory case, and throw the “OpenClaw audit output directory
already exists” error after the try/catch when the flag indicates the directory
exists.

In `@qualification/openclaw/sourceAudit.test.ts`:
- Around line 429-450: Extend the source-audit tests around
parseSourceAuditCliArguments to cover the --output= argument mode, and add a
companion case that calls writeOpenClawAuditCandidate twice with the same output
directory, asserting the second call rejects with the existing-directory
refusal. Preserve the current coverage and use the existing audit fixture/setup
symbols.
- Around line 361-367: Update the test around loadReviewedOpenClawFixtures to
assert its rejected promise directly with Bun’s rejection matcher, checking that
the error message contains “hash mismatch for chat.json”; remove the try/catch
and self-thrown sentinel so a successful resolution cannot be mistaken for the
expected failure.

In `@qualification/outbox/sqliteOutboxQualification.ts`:
- Around line 213-241: Update claimAndTerminateChild to capture the child’s
required signal value within the Effect.scoped block and return that value with
status instead of returning the released QualificationChildProcess handle.
Adjust the call site and report field to read the captured signal directly,
preserving the existing post-kill behavior.

In `@qualification/parity/parityFixtureCandidate.ts`:
- Around line 39-59: Extract the shared greenfield projection and sorting logic
from buildGreenfieldContractFixtureCandidate and
assertGreenfieldRegistryMatchesReviewed into one exported helper, and have both
callers use it so procedures and rawHttp remain byte-identical. Move the related
ProcedureContractCandidate, RawHttpContractCandidate, ProcedureContractIdentity,
and RawHttpContractIdentity types into the shared module, preserving the
existing method compatibility between the union and string declarations.

In `@qualification/parity/parityInventory.test.ts`:
- Around line 31-40: Tighten the countByPhase parameter type to use the exported
EndpointTarget and frontend route target fixture types from
parityInventorySchemas.ts instead of an anonymous object shape. Preserve the
existing reviewed-removal filtering and phase counting while ensuring schema
changes produce compile-time failures.

In `@qualification/parity/parityInventorySchemas.ts`:
- Around line 191-194: Export a named constant for the reviewed endpoint row
count from the schema module, and replace the hard-coded 157 in the parity
schema validation and parityInventory test with that shared constant. Update the
relevant imports so both the validation message/check and test expectations use
the single exported value.

In `@qualification/parity/reviewedParityInventory.ts`:
- Around line 37-39: Update canonicalJson to serialize objects with
deterministically sorted keys, so parity comparisons depend on values rather
than insertion order. Reuse or move the existing compareStrings helper as
needed, ensuring it is declared before canonicalJson or otherwise available when
serialization occurs; preserve the current formatted JSON output and trailing
newline.

In `@qualification/parity/sourceParityInventory.test.ts`:
- Around line 22-44: Generalize withModifiedRouter to accept the relative source
path to mutate instead of always using paritySourcePaths.router. Update its
temporary-file mutation logic and callers so rejection tests can modify the
navigation, route-module, and preload source files, then add rejection coverage
for the corresponding extractNavigationEntries, extractRouteModules, and
extractPreloadEntries guards while preserving existing router tests.

In `@qualification/resources/sseMemoryScenario.ts`:
- Around line 174-177: Optionally move scope creation into the per-round flow
surrounding consumer creation, so each round uses and closes its own Effect
scope before the next begins. Update the cleanup logic to close that round’s
scope and remove the now-redundant closeConsumers call, while preserving
consumer cleanup and memory assertions.

In `@qualification/shutdown/shutdownProtocol.ts`:
- Around line 134-157: Update createGatewayConnectRequest to include the
validated nonce in the connect request’s authentication parameters, and extend
gatewayConnectParametersSchema to accept and validate the same nonce field.
Ensure the generated fixture request echoes the challenge so the handshake is
bound to the original nonce.

In `@qualification/shutdown/shutdownService.ts`:
- Around line 305-311: Update the top-level catch around parseCommand and
runService to bind the thrown error, then include its diagnostic details when
writing the failure to process.stderr; preserve the existing failure message and
exitCode assignment while retaining the tagged error and stack information.

In `@qualification/shutdown/shutdownServiceResources.test.ts`:
- Around line 93-126: The existing memoization test does not exercise SSE
controller teardown because it mocks Bun.serve. Add a separate test that starts
applicationServerResource with a real listener, opens /api/events, verifies an
SSE connection is registered, calls close(), and asserts sseConnectionCount
returns to zero; keep the existing memoization assertions unchanged.

In `@qualification/websocket/nativeWebSocketQualification.test.ts`:
- Around line 366-393: Reduce or remove the fixed 1200-millisecond sleep in the
test around observeNativeWebSocket. Since the effect has already completed and
attempts is updated only by the injected WebSocket factory, verify the
no-reconnect behavior immediately or use a shorter wait sufficient to observe
the released socket state while preserving the attempts assertion.

In `@qualification/websocket/nativeWebSocketQualification.ts`:
- Around line 314-333: Document the port-reuse race in
closedLoopbackWebSocketUrl: add a comment explaining that listener.stop(true)
runs before the caller connects, allowing concurrent tests or the OS to reuse
the ephemeral port and invalidate refusal expectations. Do not change the
existing acquire/use/release behavior.

In `@qualification/websocket/rawWebSocketProtocol.ts`:
- Around line 142-145: Update createUpgradeResponse at the createHash("sha1")
call with an inline static-analysis suppression that references RFC 6455 §4.2.2
and explains SHA-1 is required for the WebSocket Sec-WebSocket-Accept protocol
value. Keep the hashing implementation unchanged.
- Around line 5-8: Export maximumFixtureOutboundBytes from
rawWebSocketProtocol.ts and update nativeWebSocketQualification.test.ts to
import and use that constant in the evidence.sentBytes assertion instead of
duplicating the 128 * 1024 literal, keeping the test synchronized with the
fixture limit.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0843f828-0ab0-46c8-a09c-c281e7b3c872

📥 Commits

Reviewing files that changed from the base of the PR and between f1a6670 and fe82291.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock and included by **/*
  • docs/generated/packages-and-runtime.md is excluded by !**/generated/** and included by **/*
📒 Files selected for processing (84)
  • bunfig.toml
  • docs/api/endpoints.md
  • docs/architecture/greenfield-rewrite.md
  • docs/architecture/greenfield-rewrite/application-architecture.md
  • docs/architecture/greenfield-rewrite/implementation-plan.md
  • docs/architecture/greenfield-rewrite/progress.md
  • docs/architecture/greenfield-rewrite/runtime-and-delivery.md
  • package.json
  • qualification/browser/queryCollectionAdapter.test.ts
  • qualification/browser/queryCollectionAdapter.ts
  • qualification/budgets/resourceBudgetCommand.ts
  • qualification/budgets/resourceBudgetOrchestration.test.ts
  • qualification/budgets/resourceBudgetOrchestration.ts
  • qualification/budgets/resourceBudgetPolicy.test.ts
  • qualification/budgets/resourceBudgetPolicy.ts
  • qualification/budgets/resourceBudgetUnit.ts
  • qualification/budgets/runResourceBudgetEvidence.ts
  • qualification/budgets/runSafeChildCancellationEvidence.ts
  • qualification/build/fixtures/frontend/index.html
  • qualification/build/fixtures/frontend/src/LazyPanel.tsx
  • qualification/build/fixtures/frontend/src/QualificationApp.tsx
  • qualification/build/fixtures/frontend/src/index.css
  • qualification/build/fixtures/frontend/src/main.tsx
  • qualification/build/frontendBuildQualification.test.ts
  • qualification/build/frontendBuildQualification.ts
  • qualification/build/runFrontendBuildQualification.ts
  • qualification/chat/chatBatching.test.ts
  • qualification/chat/chatBatchingModel.ts
  • qualification/chat/chatBatchingQualification.ts
  • qualification/chat/runChatBatchingQualification.ts
  • qualification/openclaw/fixtures/2026.7.2-beta.7/agents.json
  • qualification/openclaw/fixtures/2026.7.2-beta.7/chat.json
  • qualification/openclaw/fixtures/2026.7.2-beta.7/cron.json
  • qualification/openclaw/fixtures/2026.7.2-beta.7/gateway.json
  • qualification/openclaw/fixtures/2026.7.2-beta.7/manifest.json
  • qualification/openclaw/fixtures/2026.7.2-beta.7/sessions.json
  • qualification/openclaw/fixtures/2026.7.2-beta.7/tasks.json
  • qualification/openclaw/reviewedFixtures.ts
  • qualification/openclaw/runSourceAudit.ts
  • qualification/openclaw/sourceAudit.test.ts
  • qualification/openclaw/sourceAudit.ts
  • qualification/openclaw/sourceAuditSchemas.ts
  • qualification/outbox/runSqliteOutboxEvidence.ts
  • qualification/outbox/sqliteOutboxChild.ts
  • qualification/outbox/sqliteOutboxProtocol.ts
  • qualification/outbox/sqliteOutboxQualification.test.ts
  • qualification/outbox/sqliteOutboxQualification.ts
  • qualification/outbox/sqliteOutboxStore.ts
  • qualification/parity/fixtures/frontend-routes.json
  • qualification/parity/fixtures/greenfield-contracts.json
  • qualification/parity/fixtures/legacy-endpoints.json
  • qualification/parity/legacyBackendRouteInventory.ts
  • qualification/parity/parityFixtureCandidate.ts
  • qualification/parity/parityInventory.test.ts
  • qualification/parity/parityInventorySchemas.ts
  • qualification/parity/reviewedParityInventory.ts
  • qualification/parity/sourceParityInventory.test.ts
  • qualification/parity/sourceParityInventory.ts
  • qualification/resources/pausedTlsSseClient.test.ts
  • qualification/resources/pausedTlsSseClient.ts
  • qualification/resources/sseMemoryScenario.ts
  • qualification/shutdown/completeShutdownQualification.test.ts
  • qualification/shutdown/completeShutdownQualification.ts
  • qualification/shutdown/runCompleteShutdownEvidence.ts
  • qualification/shutdown/shutdownDatabase.ts
  • qualification/shutdown/shutdownGrandchild.ts
  • qualification/shutdown/shutdownIdleHttpConnection.ts
  • qualification/shutdown/shutdownProtocol.ts
  • qualification/shutdown/shutdownService.ts
  • qualification/shutdown/shutdownServiceResources.test.ts
  • qualification/shutdown/shutdownServiceResources.ts
  • qualification/test/asyncCleanupStack.test.ts
  • qualification/test/asyncCleanupStack.ts
  • qualification/websocket/nativeWebSocketQualification.test.ts
  • qualification/websocket/nativeWebSocketQualification.ts
  • qualification/websocket/rawWebSocketFixture.ts
  • qualification/websocket/rawWebSocketProtocol.ts
  • scripts/frontendBuild.ts
  • scripts/qualification/legacyBackendRouteProbe.ts
  • src/app/server.ts
  • src/server/platform/runtime/applicationRuntime.test.ts
  • src/server/platform/runtime/applicationRuntime.ts
  • src/server/test/support/requestContext.ts
  • src/server/test/system/serverShutdown.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Analyze JavaScript and TypeScript
🧰 Additional context used
🪛 ast-grep (0.45.0)
qualification/websocket/rawWebSocketProtocol.ts

[warning] 142-142: Do not use weak hash functions (MD5/SHA1)
Context: createHash("sha1")
Note: [CWE-328] Use of Weak Hash.

(insecure-hash-typescript)


[warning] 142-142: Avoid SHA1 security protocol
Context: createHash("sha1")
Note: [CWE-327] Use of a Broken or Risky Cryptographic Algorithm (SHA-1).

(avoid-crypto-sha1-typescript)

qualification/openclaw/sourceAudit.ts

[warning] 279-279: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(const ${name} = ([^;]+);, "u")
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

🪛 LanguageTool
docs/architecture/greenfield-rewrite/progress.md

[style] ~610-~610: Using “real” as an adverb is considered informal. Consider using “really” or “very”.
Context: ...er/writer and writer/writer behavior, real busy/locked classification, no-gap/no-d...

(REAL_REALLY)

docs/architecture/greenfield-rewrite.md

[style] ~5-~5: Consider using “incomplete” to avoid wordiness.
Context: ...ed, > hardening, and cutover phases are not complete. The rewrite is built beside the curren...

(NOT_ABLE_PREMIUM)

docs/architecture/greenfield-rewrite/implementation-plan.md

[style] ~102-~102: Using “real” as an adverb is considered informal. Consider using “really” or “very”.
Context: ...ox without gaps or duplicates, classify real busy/locked outcomes, and recover an ...

(REAL_REALLY)

Comment thread qualification/budgets/runSafeChildCancellationEvidence.ts
Comment thread qualification/outbox/sqliteOutboxProtocol.ts Outdated
Comment thread qualification/shutdown/completeShutdownQualification.test.ts
Comment thread qualification/shutdown/completeShutdownQualification.ts
Comment thread qualification/shutdown/completeShutdownQualification.ts
Comment thread qualification/shutdown/shutdownIdleHttpConnection.ts
Comment thread src/app/server.ts
Comment thread src/server/platform/runtime/applicationRuntime.ts
Comment thread qualification/files/boundedFile.ts Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/server.ts (1)

148-167: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

A failed stop is memoized, so a later stop(true) cannot escalate.

Line 150 memoizes stopPromise on the first call, including when shutdownListener rejects. A supervisor that first calls stop() and then escalates with stop(true) aborts forceStopController at Line 149, but the memoized rejected promise is returned without re-entering shutdownListener. The abort signal is never observed, no forced listener stop runs, and dispose() never runs.

Either clear the memo on rejection so an escalation can retry, or document that a listener-stop failure is terminal and require the supervisor to kill the process.

🐛 Proposed fix to allow one escalation retry
             stop(force = false) {
                 if (force) forceStopController.abort();
                 stopPromise ??= (async () => {
                     try {
                         await options.applicationRuntime.shutdownListener({
                             forceSignal: forceStopController.signal,
                             gracefulShutdownTimeoutMs,
                             stop: (forceListener) => server.stop(forceListener),
                         });
                     } catch (error) {
                         // A listener-stop rejection cannot prove that no request can still enter
                         // the runtime. Withdraw readiness and preserve process services for the
                         // supervisor's terminal containment instead of disposing them underneath
                         // a potentially live listener.
                         options.readiness.markUnavailable();
+                        // Release the memo so a forced escalation can retry the listener stop.
+                        stopPromise = undefined;
                         throw error;
                     }
                     await options.applicationRuntime.dispose();
                 })();
                 return stopPromise;
             },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/server.ts` around lines 148 - 167, Update the stop method’s
stopPromise lifecycle so a shutdownListener rejection does not permanently
memoize the failed attempt: clear or reset stopPromise in the rejection path
before propagating the error, allowing a later stop(true) call to re-enter
shutdownListener with the already-aborted forceStopController signal and then
dispose successfully. Preserve promise memoization for successful shutdown and
concurrent callers.
🧹 Nitpick comments (4)
qualification/shutdown/shutdownServiceResources.ts (1)

368-397: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the challenge nonce into one constant.

Line 375 and Line 391 repeat the literal "shutdown-qualification-nonce". If one site changes, the handler rejects every connect request and closes with 1008. The failure looks like a client defect, not a fixture defect. Bind the value once and use it at both sites.

♻️ Proposed refactor
+const gatewayChallengeNonce = "shutdown-qualification-nonce";
+
 export function gatewayFixtureResource(): Effect.Effect<
-                                if (
-                                    request.params.nonce !==
-                                    "shutdown-qualification-nonce"
-                                ) {
+                                if (request.params.nonce !== gatewayChallengeNonce) {
                                     throw new Error(
                                         "Gateway connect request did not echo its challenge"
                                     );
                                 }
                                     payload: {
-                                        nonce: "shutdown-qualification-nonce",
+                                        nonce: gatewayChallengeNonce,
                                         ts: 1_786_000_000_000,
                                     },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/shutdown/shutdownServiceResources.ts` around lines 368 - 397,
Define a single constant for the shutdown qualification nonce in the surrounding
setup, then replace both the request validation comparison and the challenge
payload’s duplicated "shutdown-qualification-nonce" literal with that constant.
Keep the existing connect handling and close behavior unchanged.
qualification/files/boundedFile.ts (2)

125-143: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Preserve the original failure cause.

The catch at Line 125 discards the caught value. Every failure then surfaces as the same invalidMessage with no cause. A qualification failure is undiagnosable: an allowed-root violation, an EACCES, and a hook rejection are indistinguishable. Attach the original error as cause. String(error) does not render cause, so the redaction assertions in qualification/files/boundedFile.test.ts (Lines 145, 167, 189) still hold.

♻️ Proposed refactor
-function invalidFileState(message: string): Error {
-    return new Error(message);
+function invalidFileState(message: string, cause?: unknown): Error {
+    return cause === undefined ? new Error(message) : new Error(message, { cause });
 }
     let result: Buffer | undefined;
-    let failed = false;
+    let failed = false;
+    let failureCause: unknown;
     try {
         // ...
         result = buffer.subarray(0, bytesRead);
-    } catch {
-        failed = true;
+    } catch (error) {
+        failed = true;
+        failureCause = error;
     }
 
     if (pathFile) {
         try {
             await pathFile.close();
-        } catch {
-            failed = true;
+        } catch (error) {
+            failed = true;
+            failureCause ??= error;
         }
     }
     if (file) {
         try {
             await file.close();
-        } catch {
-            failed = true;
+        } catch (error) {
+            failed = true;
+            failureCause ??= error;
         }
     }
-    if (failed || !result) throw invalidFileState(invalidMessage);
+    if (failed || !result) throw invalidFileState(invalidMessage, failureCause);
     return result;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/files/boundedFile.ts` around lines 125 - 143, Preserve the
caught qualification error in the main try/catch around bounded-file validation
instead of discarding it. Pass that original error as the cause when
constructing invalidFileState(invalidMessage), while keeping cleanup failures
and existing redaction behavior unchanged.

83-86: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the procfs dependency, or the reader fails closed on every non-Linux host.

Line 83 and Line 113 resolve /proc/self/fd/${fd}. That path exists only on Linux. On macOS the realpath call rejects, the catch at Line 125 records the failure, and every call throws invalidMessage. A developer then sees a containment violation instead of an unsupported platform. State the Linux requirement in the JSDoc, or detect process.platform and throw a distinct error.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/files/boundedFile.ts` around lines 83 - 86, Document the
Linux-only procfs requirement in the JSDoc for the bounded-file reader and its
use of /proc/self/fd via realpath, so unsupported platforms are clearly
identified rather than reported as containment violations. Anchor the
documentation to the reader function containing the descriptorPath resolution
and the corresponding resolution near the second descriptor check; do not alter
containment behavior.
qualification/build/frontendBuildQualification.test.ts (1)

113-138: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the rejection reason for each HTML sample.

The loop only asserts that some Error is thrown. One overly broad rule inside assertSelfHostedFrontendHtml would satisfy all 14 samples. The test would then keep passing after a specific CSP rule regresses. Pair each sample with its expected message fragment.

♻️ Proposed refactor
-            for (const html of [
-                '<script type="module" src="/assets/app.js">inline()</script>',
-                '<script type="module" src="/assets/app.js"></script><script>inline()</script >',
+            for (const [html, expected] of [
+                [
+                    '<script type="module" src="/assets/app.js">inline()</script>',
+                    "inline script",
+                ],
+                [
+                    '<script type="module" src="/assets/app.js"></script><script>inline()</script >',
+                    "inline script",
+                ],
                 // ... remaining samples paired with their expected message fragment
-            ]) {
+            ] as const) {
                 await writeFile(indexPath, html, "utf8");
                 let rejected = false;
                 try {
                     await assertSelfHostedFrontendHtml(indexPath);
                 } catch (error) {
                     rejected = true;
                     expect(error).toBeInstanceOf(Error);
+                    expect((error as Error).message).toContain(expected);
                 }
                 expect(rejected).toBeTrue();
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@qualification/build/frontendBuildQualification.test.ts` around lines 113 -
138, Update the HTML samples in the test around assertSelfHostedFrontendHtml to
pair each input with its expected rejection-message fragment, then assert the
caught Error message contains that fragment for every case. Preserve the
existing rejection assertion while ensuring each sample validates the specific
rule it is intended to exercise.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@qualification/openclaw/sourceAudit.test.ts`:
- Around line 365-367: Await both rejection assertions in
qualification/openclaw/sourceAudit.test.ts at lines 365-367 and 425-427: the
assertion around loadReviewedOpenClawFixtures must await the "hash mismatch for
chat.json" rejection, and the assertion around writeOpenClawAuditCandidate must
await the "output directory already exists" rejection.

---

Outside diff comments:
In `@src/app/server.ts`:
- Around line 148-167: Update the stop method’s stopPromise lifecycle so a
shutdownListener rejection does not permanently memoize the failed attempt:
clear or reset stopPromise in the rejection path before propagating the error,
allowing a later stop(true) call to re-enter shutdownListener with the
already-aborted forceStopController signal and then dispose successfully.
Preserve promise memoization for successful shutdown and concurrent callers.

---

Nitpick comments:
In `@qualification/build/frontendBuildQualification.test.ts`:
- Around line 113-138: Update the HTML samples in the test around
assertSelfHostedFrontendHtml to pair each input with its expected
rejection-message fragment, then assert the caught Error message contains that
fragment for every case. Preserve the existing rejection assertion while
ensuring each sample validates the specific rule it is intended to exercise.

In `@qualification/files/boundedFile.ts`:
- Around line 125-143: Preserve the caught qualification error in the main
try/catch around bounded-file validation instead of discarding it. Pass that
original error as the cause when constructing invalidFileState(invalidMessage),
while keeping cleanup failures and existing redaction behavior unchanged.
- Around line 83-86: Document the Linux-only procfs requirement in the JSDoc for
the bounded-file reader and its use of /proc/self/fd via realpath, so
unsupported platforms are clearly identified rather than reported as containment
violations. Anchor the documentation to the reader function containing the
descriptorPath resolution and the corresponding resolution near the second
descriptor check; do not alter containment behavior.

In `@qualification/shutdown/shutdownServiceResources.ts`:
- Around line 368-397: Define a single constant for the shutdown qualification
nonce in the surrounding setup, then replace both the request validation
comparison and the challenge payload’s duplicated "shutdown-qualification-nonce"
literal with that constant. Keep the existing connect handling and close
behavior unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 35dfca3d-04da-4c85-9712-0a879a630a08

📥 Commits

Reviewing files that changed from the base of the PR and between fe82291 and 169136e.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock and included by **/*
  • docs/generated/packages-and-runtime.md is excluded by !**/generated/** and included by **/*
📒 Files selected for processing (51)
  • docs/architecture/greenfield-rewrite.md
  • docs/architecture/greenfield-rewrite/application-architecture.md
  • docs/architecture/greenfield-rewrite/implementation-plan.md
  • docs/architecture/greenfield-rewrite/progress.md
  • docs/architecture/greenfield-rewrite/runtime-and-delivery.md
  • package.json
  • qualification/browser/queryCollectionAdapter.test.ts
  • qualification/budgets/resourceBudgetOrchestration.ts
  • qualification/budgets/resourceBudgetPolicy.test.ts
  • qualification/budgets/resourceBudgetPolicy.ts
  • qualification/budgets/resourceBudgetUnit.ts
  • qualification/budgets/runSafeChildCancellationEvidence.ts
  • qualification/build/frontendBuildQualification.test.ts
  • qualification/build/frontendBuildQualification.ts
  • qualification/build/runFrontendBuildQualification.ts
  • qualification/chat/chatBatchingModel.ts
  • qualification/chat/chatBatchingQualification.ts
  • qualification/files/boundedFile.test.ts
  • qualification/files/boundedFile.ts
  • qualification/openclaw/fixtures/2026.7.2-beta.7/manifest.json
  • qualification/openclaw/reviewedFixtures.ts
  • qualification/openclaw/sourceAudit.test.ts
  • qualification/openclaw/sourceAudit.ts
  • qualification/openclaw/sourceAuditSchemas.ts
  • qualification/outbox/sqliteOutboxChild.ts
  • qualification/outbox/sqliteOutboxProtocol.ts
  • qualification/outbox/sqliteOutboxQualification.test.ts
  • qualification/outbox/sqliteOutboxQualification.ts
  • qualification/parity/legacyBackendRouteInventory.ts
  • qualification/parity/parityFixtureCandidate.ts
  • qualification/parity/parityInventory.test.ts
  • qualification/parity/parityInventorySchemas.ts
  • qualification/parity/reviewedParityInventory.ts
  • qualification/parity/sourceParityInventory.test.ts
  • qualification/parity/sourceParityInventory.ts
  • qualification/resources/sseMemoryScenario.ts
  • qualification/shutdown/completeShutdownQualification.test.ts
  • qualification/shutdown/completeShutdownQualification.ts
  • qualification/shutdown/shutdownGrandchild.ts
  • qualification/shutdown/shutdownIdleHttpConnection.ts
  • qualification/shutdown/shutdownProtocol.ts
  • qualification/shutdown/shutdownService.ts
  • qualification/shutdown/shutdownServiceResources.test.ts
  • qualification/shutdown/shutdownServiceResources.ts
  • qualification/websocket/nativeWebSocketQualification.test.ts
  • qualification/websocket/nativeWebSocketQualification.ts
  • qualification/websocket/rawWebSocketProtocol.ts
  • src/app/server.ts
  • src/server/platform/runtime/applicationRuntime.test.ts
  • src/server/platform/runtime/applicationRuntime.ts
  • src/server/test/system/serverShutdown.test.ts
🚧 Files skipped from review as they are similar to previous changes (30)
  • package.json
  • qualification/outbox/sqliteOutboxChild.ts
  • qualification/parity/legacyBackendRouteInventory.ts
  • docs/architecture/greenfield-rewrite/implementation-plan.md
  • qualification/openclaw/reviewedFixtures.ts
  • qualification/outbox/sqliteOutboxProtocol.ts
  • qualification/shutdown/shutdownProtocol.ts
  • qualification/budgets/runSafeChildCancellationEvidence.ts
  • qualification/websocket/nativeWebSocketQualification.ts
  • qualification/parity/parityInventorySchemas.ts
  • qualification/budgets/resourceBudgetUnit.ts
  • qualification/shutdown/shutdownService.ts
  • qualification/openclaw/fixtures/2026.7.2-beta.7/manifest.json
  • qualification/outbox/sqliteOutboxQualification.ts
  • qualification/openclaw/sourceAuditSchemas.ts
  • qualification/parity/parityInventory.test.ts
  • src/server/platform/runtime/applicationRuntime.ts
  • qualification/budgets/resourceBudgetPolicy.ts
  • qualification/build/runFrontendBuildQualification.ts
  • qualification/parity/reviewedParityInventory.ts
  • docs/architecture/greenfield-rewrite.md
  • docs/architecture/greenfield-rewrite/application-architecture.md
  • qualification/build/frontendBuildQualification.ts
  • qualification/websocket/nativeWebSocketQualification.test.ts
  • docs/architecture/greenfield-rewrite/progress.md
  • qualification/chat/chatBatchingModel.ts
  • qualification/openclaw/sourceAudit.ts
  • src/server/test/system/serverShutdown.test.ts
  • qualification/chat/chatBatchingQualification.ts
  • qualification/outbox/sqliteOutboxQualification.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Analyze JavaScript and TypeScript
🧰 Additional context used
🪛 ast-grep (0.45.0)
qualification/websocket/rawWebSocketProtocol.ts

[warning] 144-144: Do not use weak hash functions (MD5/SHA1)
Context: createHash("sha1")
Note: [CWE-328] Use of Weak Hash.

(insecure-hash-typescript)


[warning] 144-144: Avoid SHA1 security protocol
Context: createHash("sha1")
Note: [CWE-327] Use of a Broken or Risky Cryptographic Algorithm (SHA-1).

(avoid-crypto-sha1-typescript)

🪛 GitHub Check: CodeQL
qualification/files/boundedFile.ts

[failure] 109-112: Potential file system race condition
The file may have changed since it was checked.

🔇 Additional comments (30)
qualification/websocket/rawWebSocketProtocol.ts (8)

1-12: 🎯 Functional Correctness

Verify the fixture budget invariant.

asBoundedPayload limits payload bytes, but frame headers add 2, 4, or 10 bytes. Confirm that oversizedQualificationMessageBytes exceeds the application message limit while the encoded frame remains within maximumRawWebSocketFixtureOutboundBytes. Otherwise, oversized-text can throw during fixture construction or produce an over-budget frame.

Also applies to: 46-55, 326-343


13-44: 🗄️ Data Integrity & Integration

Verify the exported protocol contracts against their consumers.

Confirm that every RawWebSocketScenario member has a matching createScenarioBytes branch. Confirm that all result-interface fields have compatible producers and consumers in the WebSocket qualification tests.


57-112: 🎯 Functional Correctness

Verify RFC 6455 control-frame validation.

Confirm that encodeServerFrame rejects reserved opcodes, non-final control frames, and control payloads larger than 125 bytes. Confirm that encodeServerCloseFrame rejects reserved close codes and enforces the 123-byte UTF-8 reason limit.


142-158: LGTM!


114-141: 🎯 Functional Correctness

Verify upgrade parsing at the HTTP/WebSocket boundary.

Confirm that header names and token values use the required case-insensitive matching. Reject malformed or ambiguous duplicate headers. Confirm that the parser enforces the handshake-size limit and preserves every byte after \r\n\r\n.

Also applies to: 161-193


195-255: 🩺 Stability & Availability

Verify safe 64-bit length handling.

Confirm that lengths with the high bit set are rejected. Confirm that values above the configured budget are rejected before allocation or slicing. Do not convert an untrusted 64-bit length to an unsafe number before these checks. Also confirm that incomplete frame suffixes are retained without dropping bytes.


257-286: 🎯 Functional Correctness

Verify fragmented UTF-8 evidence at the byte level.

Confirm that concatenating the fragment bytes reproduces the complete UTF-8 sequence. Confirm that the first frame uses the text opcode, continuation frames use opcode 0x00, and only the final frame sets FIN.


335-337: 🎯 Functional Correctness

Confirm that silent may send a ping.

createScenarioBytes("silent") emits a WebSocket ping. This is not wire-level silence and can trigger a pong or reset an idle timer. If the qualification requires no inbound bytes, return an empty buffer or use a separate control-frame scenario.

docs/architecture/greenfield-rewrite/runtime-and-delivery.md (2)

136-141: LGTM!


91-94: 📐 Maintainability & Code Quality

No changes needed.

qualification/budgets/resourceBudgetPolicy.test.ts (1)

217-227: LGTM!

qualification/build/frontendBuildQualification.test.ts (1)

39-62: LGTM!

qualification/files/boundedFile.test.ts (1)

1-275: LGTM!

qualification/openclaw/sourceAudit.test.ts (1)

144-147: LGTM!

Also applies to: 432-442

qualification/shutdown/shutdownServiceResources.test.ts (1)

5-8: LGTM!

Also applies to: 17-24, 141-179

qualification/shutdown/shutdownServiceResources.ts (1)

438-456: LGTM!

Also applies to: 486-489

src/app/server.ts (1)

9-9: LGTM!

Also applies to: 70-70

qualification/shutdown/shutdownGrandchild.ts (1)

3-6: 🩺 Stability & Availability

No change needed for Effect.sleep(oneDayMs).

Effect 4 beta still accepts bare millisecond numbers in DurationInput.

qualification/shutdown/completeShutdownQualification.test.ts (2)

167-167: The explicit 60_000 ms and 30_000 ms per-test timeouts resolve the earlier finding about the 5000 ms Bun default for these process-spawning qualifications.

Also applies to: 181-181


43-48: 🩺 Stability & Availability

Confirm TestClock handoff behavior before changing this test.

Deferred.succeed(cancelStarted, undefined) can complete before cancelShutdownStreamBeforeDeadline registers its 25 ms timeout. If this Effect version advances time only for already-suspended fibers, TestClock.adjust(25) can run before the child fiber is scheduled, leaving no timeout to fire and causing Fiber.join to wait. Move Deferred.succeed after the cancellation effect is started if needed.

qualification/shutdown/completeShutdownQualification.ts (2)

189-191: The already-exited branch now calls killProcessGroup(child.pid), which resolves the earlier finding about the surviving detached grandchild.


105-128: LGTM!

Also applies to: 292-306, 370-398

qualification/shutdown/shutdownIdleHttpConnection.ts (1)

92-127: The handler now parses Content-Length and resumes only after headerEnd + 4 + contentLength bytes arrive, which resolves the earlier finding about measuring a connection with an unconsumed in-flight response.

qualification/budgets/resourceBudgetOrchestration.ts (1)

79-99: LGTM!

Also applies to: 433-445, 454-459, 477-490

qualification/parity/parityFixtureCandidate.ts (1)

17-32: LGTM!

Also applies to: 34-65, 77-91

qualification/parity/sourceParityInventory.test.ts (1)

22-45: LGTM!

Also applies to: 152-236

qualification/parity/sourceParityInventory.ts (1)

61-65: LGTM!

Also applies to: 236-311, 322-323, 517-524

src/server/platform/runtime/applicationRuntime.test.ts (1)

166-209: LGTM!

qualification/resources/sseMemoryScenario.ts (1)

184-208: 🩺 Stability & Availability

No change needed. Effect 4 Scope.make("parallel") and Scope.provide(roundScope)(consumerResource) match the declared API.

qualification/browser/queryCollectionAdapter.test.ts (1)

240-244: 📐 Maintainability & Code Quality

Package metadata exports are present.

All four pinned TanStack packages expose ./package.json as an explicit export entry, so Bun.resolveSync(${packageName}/package.json, import.meta.dir) should not fail due to missing subpath exports.

Comment thread qualification/openclaw/sourceAudit.test.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI, test runners, workflow checks, and release gates area: openclaw OpenClaw gateway/API integration and runtime behavior type: tests Adds or updates automated tests/coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants