[luci] cache npm: exact [luci] step 1/5: export NPM_CONFIG_CACHE="$PWD/.npm-cache" [luci] step 1/5 done in 0s [luci] step 2/5: npm ci --prefer-offline npm warn deprecated node-domexception@1.0.0: Use your platform's native DOMException instead added 230 packages, and audited 231 packages in 10s 47 packages are looking for funding run `npm fund` for details found 0 vulnerabilities [luci] step 2/5 done in 11s [luci] step 3/5: npm run check > will@0.1.0 check > biome check src scripts web deploy rolldown.config.ts playwright.config.ts package.json tsconfig.json && tsc --noEmit Checked 79 files in 241ms. No fixes applied. [luci] step 3/5 done in 13s [luci] step 4/5: npm test > will@0.1.0 test > node --test src ✔ explicit fake wins even with a key (1.882781ms) ✔ no env at all falls back to fake (0.264818ms) ✔ key alone gives the real session (0.252941ms) ✔ explicit real without a key fails loudly (0.737572ms) ✔ explicit real with a key is real (0.292715ms) ✔ thinking level defaults to medium (0.834455ms) ✔ ZAI_THINKING_LEVEL overrides the default (0.445556ms) ✔ unknown ZAI_THINKING_LEVEL fails loudly (2.153026ms) ✔ wake queue persists across reopen; heartbeat coalesces; done compacts (17.972562ms) ✔ wake queue defer reorders wake with backoff (5.237818ms) {"ts":"2026-09-26T20:52:29.288Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ spool drains idempotently into the running service (5298.936816ms) ✔ agent state persists mutations atomically (4.860316ms) {"ts":"2026-09-26T20:52:36.761Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} {"ts":"2026-09-26T20:52:36.768Z","level":"warn","component":"agent","message":"running with a FAKE session (no model calls; set ZAI_API_KEY for real)"} {"ts":"2026-09-26T20:52:36.769Z","level":"warn","component":"agent","message":"worktree not ready","error":"worktree missing and no git url configured"} {"ts":"2026-09-26T20:52:36.846Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"} {"ts":"2026-09-26T20:52:37.926Z","level":"debug","component":"agent","message":"spool drained","events":2} {"ts":"2026-09-26T20:52:38.015Z","level":"info","component":"agent","message":"agent stopped cleanly"} ✔ end to end: mention reaches the resident session and readiness is healthy (6417.200406ms) ✔ chat turn completes, budget spent, wake removed (15.646047ms) ✔ boot context appears only on the first turn (5.491376ms) ✔ model failure retries with backoff, then defers after three attempts (3.969017ms) ✔ turn timeout enqueues exactly one recovery wake and completes the original (56.525273ms) ✔ budget cap blocks ordinary wakes but reserve admits recovery wakes (6.176693ms) ✔ storage stop pauses ordinary wakes, recovery continues (5.443534ms) ✔ system prompt is exactly the lexically ordered personality (6.050952ms) ✔ wake prompts render per-kind templates with facts (1.064545ms) ✔ facts block omits missing values instead of rendering undefined (0.407009ms) ✔ all coding tools are bound to the editable worktree (11.579446ms) ✔ worktree: clone, ff-only when clean, preserved when dirty or ahead (400.106196ms) ✔ readWorktreeState: fresh head and dirty flag without fetch or merge (134.113917ms) {"ts":"2026-09-26T20:52:52.091Z","level":"debug","component":"ciwatch","message":"ci poll","runs":1,"wakes":0} {"ts":"2026-09-26T20:52:52.099Z","level":"debug","component":"ciwatch","message":"ci poll","runs":2,"wakes":1} {"ts":"2026-09-26T20:52:52.102Z","level":"debug","component":"ciwatch","message":"ci poll","runs":2,"wakes":0} {"ts":"2026-09-26T20:52:52.105Z","level":"debug","component":"ciwatch","message":"ci poll","runs":3,"wakes":0} ✔ ci watch enqueues one failure wake per failed run of a tracked sha (65.169389ms) {"ts":"2026-09-26T20:52:52.239Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} {"ts":"2026-09-26T20:52:52.265Z","level":"info","component":"deploy","message":"deploy events imported","count":2} ✔ deploy events poll mirrors into service and wakes on failures only (5182.344902ms) {"ts":"2026-09-26T20:52:57.404Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ chat_send queues outbound; recall queries service; maintenance ops gated (5145.113104ms) {"ts":"2026-09-26T20:53:02.551Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} {"ts":"2026-09-26T20:53:02.568Z","level":"warn","component":"loop","message":"storage threshold transition","from":"ok","to":"warn"} ✔ storage watch: transitions emit deterministic outbox notice (5138.327042ms) ✔ readiness server reports 503 until local init completes (11.807513ms) ✔ fake telegram sanity (60.119468ms) {"ts":"2026-09-26T20:53:08.093Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} {"ts":"2026-09-26T20:53:08.104Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"} ✔ mention wakes, chatter archives without wake, other chats ignored (5218.208432ms) {"ts":"2026-09-26T20:53:13.291Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} {"ts":"2026-09-26T20:53:13.297Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"} ✔ media message downloads into service store and references digest (5163.614195ms) {"ts":"2026-09-26T20:53:18.451Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} {"ts":"2026-09-26T20:53:18.464Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"} ✔ /hide via reply tombstones deterministically without a model wake (5180.191265ms) {"ts":"2026-09-26T20:53:23.635Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ outbox delivers at-least-once and mirrors outbound to service (5143.505253ms) ✔ sums usage across assistant messages of one wake (2.815965ms) ✔ splits by provider/model and tolerates junk (0.492421ms) ✔ non-array input yields no rows (0.274968ms) {"ts":"2026-09-26T20:53:30.718Z","level":"warn","component":"zai","message":"zai retry","path":"/paas/v4/chat/completions","status":500,"attempt":1,"delay":500} ✔ rest client retries retryable failures (565.730939ms) ✔ rest client surfaces 4xx without retry (21.278003ms) {"ts":"2026-09-26T20:53:31.374Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ zai_analyze_media answers, caches by digest, second call is a hit (5191.641351ms) {"ts":"2026-09-26T20:53:36.556Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ zai_transcribe and zai_parse_document return explicit results (5181.725438ms) {"ts":"2026-09-26T20:53:41.747Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ generation tools store bytes and return digests; limits fail explicitly (8482.955341ms) {"ts":"2026-09-26T20:53:50.218Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ curated tool set carries stable names and one-line descriptions (5118.035723ms) {"ts":"2026-09-26T20:53:55.595Z","level":"info","component":"zai-mcp","message":"vision mcp connected"} ✔ mcp bridge lists and calls tools over stdio (408.71615ms) {"ts":"2026-09-26T20:53:56.061Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ healthz ok, index served, docs manifest served (8217.605064ms) {"ts":"2026-09-26T20:54:04.256Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ path traversal is rejected (5133.771228ms) {"ts":"2026-09-26T20:54:09.391Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ audit ingest -> timeline -> SSE replay with Last-Event-ID (5193.149964ms) {"ts":"2026-09-26T20:54:14.582Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ media upload, meta, public download round-trip (5149.899245ms) {"ts":"2026-09-26T20:54:19.733Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ chat ingest, hide via internal API, tombstone filters public chat (5139.294869ms) {"ts":"2026-09-26T20:54:24.870Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ status reports schema, counts and storage; recall works over HTTP (5134.990012ms) {"ts":"2026-09-26T20:54:30.004Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"} ✔ usage view aggregates turn_usage rows into daily cost (5124.322169ms) ✔ audit ingest is idempotent by event id and assigns seqs (12.978311ms) ✔ recall searches beyond the newest page in hot data and archives (39.252964ms) ✔ recall orders overlapping archives and late hot rows globally (35.324945ms) ✔ recall has identical Unicode case matching before and after archival (22.279522ms) ✔ recall tie ordering is limit-prefix consistent before and after archival (12.982412ms) ✔ chat ingest is idempotent and hide tombstones (3.997028ms) ✔ deployment events mirror idempotently (3.320414ms) ✔ media store is content-addressed and idempotent (5.639207ms) ✔ analysis cache upserts by (digest, capability, model, schemaVersion) (3.645182ms) ✔ archive cycle moves old audit rows exactly once and cold reads serve them (13.685891ms) ✔ crash between publish and delete does not duplicate rows (exactly once) (10.551236ms) ✔ archive cycle moves chat after one year and tombstones keep filtering (14.741575ms) ✔ quick check reports ok and jobs are recorded (5.78979ms) ✔ vacuum runs without error (3.447118ms) ✔ cost uses the price table per MTok (2.901307ms) ✔ unknown model keeps tokens but marks cost unavailable (0.498666ms) ✔ days are grouped by UTC date and sorted ascending (1.494601ms) ✔ projection extrapolates today across the remaining month (0.361944ms) ✔ projection is null without a priced day today (0.294986ms) ✔ ordinary calls stop at cap minus reserve (1.876501ms) ✔ recovery calls draw from the reserve only (0.299649ms) ✔ zero cap disables limiting (0.263133ms) ✔ state rolls over on a new day (1.885042ms) ✔ property: total allowed recovery calls per day equals reserve (25.7982ms) ✔ default budget exists and is sane (0.402683ms) ✔ cutoff subtracts hot days (1.998327ms) ✔ only rows strictly older than the cutoff archive (1.349258ms) ✔ rows group by month (0.378989ms) ✔ sidecar overlap selection skips non-overlapping segments (0.467886ms) ✔ property: every row lands in exactly one month group (17.304103ms) ✔ mention of the bot wakes (3.315912ms) ✔ reply to the bot wakes (0.438297ms) ✔ ordinary chatter never wakes (0.275792ms) ✔ mention inside a reply of someone else does not wake (0.389964ms) ✔ /hide via reply is deterministic, never wakes the model (0.387824ms) ✔ /hide with explicit id targets that id (0.446292ms) ✔ other commands wake (0.285228ms) ✔ caption mention on media wakes (0.400668ms) ✔ sender of the target or oliver may hide (0.389446ms) ✔ toTgMessage extracts largest photo and documents (1.834959ms) ✔ failure wakes outrank chat which outranks heartbeat (3.108301ms) ✔ FIFO inside a class (0.344475ms) ✔ deferred wakes are skipped until their time (0.348169ms) ✔ heartbeat coalescing predicate (0.440798ms) ✔ heartbeat hour is claimed at most once and never replayed (0.37637ms) ✔ property: ordering is stable sort by (priority, seq) (14.51246ms) ℹ tests 98 ℹ suites 0 ℹ pass 98 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 127982.473125 [luci] step 4/5 done in 128s [luci] step 5/5: npm run coverage > will@0.1.0 coverage > node --test --experimental-test-coverage --test-coverage-include='src/**/*.ts' "src/**/*.test.ts" "src/**/*.int.test.ts" 2>&1 | node scripts/coverage-ratchet.mjs coverage-ratchet: 91.4% >= floor 91.2% (ratchet raised, commit it) [luci] step 5/5 done in 127s