Repository navigation
Conversation
|
Size Report
Startup median (7 runs, lower is better):
|
There was a problem hiding this comment.
1 issue found across 41 files
You’re at about 99% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/daemon-client/daemon-client-stop.ts">
<violation number="1" location="src/daemon-client/daemon-client-stop.ts:108">
P2: After a refused connection, this waits for the host process to exit. A host that keeps running after its runtime closed makes every such stop wait the full 30s, then report that the runtime may still be serving. Confirm the stop's answer for a closed runtime, or report the retained state directly.</violation>
</file>
5cf114c to
b3460e2
Compare
|
Rebased onto One owner per gap after the merge:
Not merged. Watching for the next pass. |
|
The Coverage job (unit-ci) fails at b3460e2, and it also failed on the previous head. The log excerpts stop before the vitest summary, so I could not name the failing test or threshold. This PR adds lifecycle suites that run in that job, so it may be related. Please find the failure in the full job log and fix it or say what causes it. Apart from the open stop-wait thread named at the end, I found no blocking code defect, and there are no conflicts. Not blocking, and you can take or leave these. (1) An unreadable or invalid The gross diff is +4064/-687, over the 2,500-line cap in I did not run The open inline thread on the stop wait (#3797 (comment)) still stands. The other review threads no longer apply and you can resolve them: r4306845790, r4306845794, r4306845798, r4306845809, r4306845813, r4306845820, r4306845823, r4306845825, r4306845831, r4306845836, r4306845840, r4306845843, r4306845852, r4306845854, r4306845858, r4306845861, r4306845865, r4306845868, r4306845870, r4306845878, r4306845884, r4306845890, r4306845893, r4306845897, r4306845902, r4306845904, r4306845906, r4306845912, r4306845916, r4306845920, r4306845922 and r4306845927. The code now handles each of these, and the comment-fix threads are already done. |
A runtime that runs inside another process cannot be stopped by signalling that process, so its registration now records who owns it and the runtime answers a stop for itself. `ownership: 'embedded' | 'detached'` is published in `daemon.json`, read back as the default `detached` by every reader, and decides three things: an idle timer never ends an embedded runtime, a shutdown request is answered only by an embedded runtime and a quiesce only by a detached one, and retiring an embedded record proves the lifetime is gone without signalling anything. Both requests are answered at one admission seam that shares the token check, the pid-plus-processStartTime fence, the answer-before-dispatch rule, and the runtime's one close owner. A shutdown drains work in hand rather than refusing it, and the close then answers the stop that asked for it through a bounded completion record written under the registration claim, before that claim is released.
What the registration now records lets a client tell whether it may end the process a state directory names, so nothing outside a host touches one it does not own. A managed client that finds an embedded runtime refuses with `daemon-owner-embedded` instead of replacing it, and a request timeout retires nothing for it or for a client pinned to one. `daemon stop` reaches such a runtime over its socket, waits for the completion record its own close writes, and reports what that close could not finish as warnings; a stop with no route to that socket is refused rather than falling back to a signal. `--clean` is refused for it, because that cleanup walks the owner's whole process tree and a host process runs more than the daemon. `daemonBinding` pins a client to one instance: its token, pid and process start time. The pin is compared before dispatch and never after, so a replaced or absent instance is a typed refusal and never a reason to start, replace, or redirect anything.
b3460e2 to
4f68cd7
Compare
|
Fixed the red What The cause was mine: The fix is the remedy the gate prescribes rather than a suppression: the write moved to The cubic thread on that test's mode assertion is resolved by the same move, in the honest direction: the contract test now plants a record as a fixture and says so, and the All 33 round-two threads are resolved. Each fix was already in the head, in Not merged. Watching for the next pass. |
|
The earlier gap is fixed. At 4f68cd7 all 20 checks pass, including Coverage, which failed at b3460e2 on the eager-closure probe for daemon-shutdown-report.ts. This push removes the host-kit/file import that caused it. The required evidence is now in place, and I did not run the embedded stop route or the timing case below myself. One problem remains in the stop path. A The cubic-dev-ai thread on this exact wait still holds, narrowed to retained closes: #3797 (comment). It resolves with the fix above or a reply that gives the reason. Not blocking: nothing in production produces embedded ownership until #3757, so only tests that start |
Summary
An embedder that keeps the runtime in its own process must say so where every other process looks: the registration. This adds
ownershipto the daemon record, makes every client path that could signal or replace a runtime respect it, and gives both stop paths one admission seam. Part of #3747. 43 files.close()— sohost.close()anddaemon stopproduce identical teardown. Nothing outside signals it: not a managed client, timeout recovery, a forced stop, or--clean(refused withdetails.reason: daemon_clean_not_detached).detached,embedded,unknown— and every decision that could signal a pid requires a provendetached. A record that is unreadable, or states an owner this build cannot recognize, answersunknownand is refused: retirement, takeover, timeout recovery,--clean, and both lifecycle requests.daemon quiesce(stop-if-idle) anddaemon_shutdown(drain) share one request builder, fence and admission check, so one owner cannot grant what the other refuses. The shipped quiesce wire shape is unchanged.daemon stopwaits on that record plus the instance's lifetime, and reports what the close could not finish as warnings.daemonBinding: { token, pid, processStartTime }and then dispatches only to it, with its token. That is the issue's requirement 4; it lands here because a host hands the pin back.daemon statusnames such a recordhost-owned, orowner-not-recognized;daemon stopstops it without signaling the host.Size: 1546 net production lines over 25 files, over the 700 threshold in
docs/agents/review.md. Two independent review rounds read this branch; this push answers round two (33 findings), all resolved on the threads.Layout: the admission seam sits in
daemon-idle-reap.ts(same leave judgement, one census), the completion envelope indaemon-shutdown-report.ts(the on-disk shutdown record pair). The eager-closure gate's remedy is a home in an already-evaluated module; renaming the first file is a follow-up (TODO(#3757)).Reconciled with #3795, which merged onto the same region. One owner per gap: its
settleWithinBudgetis the only bounded-shutdown helper here (the local copy this branch carried is gone), itsopenDaemonServersand startup rollback keep the listener-ownership rule, and its pending-platform-owner rule now also decides the completion record — a close that cannot release the holds because a platform owner is still running reportsretained, notreleased, because the registration really is still held.hasUnfinishedWork()covers abandoned requests and pending owners on both exits.Validation
Base
11de319aad, head4f68cd7607.pnpm check:affected --runpassed there withexactCommit=true: format, lint, typecheck, layering, fallow, build, vitest-related, command-docs, docs-links, docs-prose. Replay and web-smoke lanes are GitHub-authoritative or parked — CI owns them.Risks: no live device run, only CI lanes.
agent-device/hostlands next, soembeddedis unreachable from a published entrypoint yet.