LUCIRUNSDOCSPUBLIC CI
Run summary

Run passed.

1 passed.

will / validate

··
Result output · validate
[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 12s

47 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New major version of npm available! 11.19.1 -> 12.1.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.1.0
npm notice To update run: npm install -g npm@12.1.0
npm notice
[luci] step 2/5 done in 12s
[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 254ms. 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.886997ms)
✔ no env at all falls back to fake (0.251474ms)
✔ key alone gives the real session (0.246772ms)
✔ explicit real without a key fails loudly (0.723847ms)
✔ explicit real with a key is real (0.376149ms)
✔ thinking level defaults to medium (0.836221ms)
✔ ZAI_THINKING_LEVEL overrides the default (1.482313ms)
✔ unknown ZAI_THINKING_LEVEL fails loudly (0.36989ms)
✔ wake queue persists across reopen; heartbeat coalesces; done compacts (21.199953ms)
✔ wake queue defer reorders wake with backoff (5.031119ms)
{"ts":"2026-09-26T18:23:52.514Z","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 (5225.389944ms)
✔ agent state persists mutations atomically (5.242979ms)
{"ts":"2026-09-26T18:23:59.528Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:23:59.539Z","level":"warn","component":"agent","message":"running with a FAKE session (no model calls; set ZAI_API_KEY for real)"}
{"ts":"2026-09-26T18:23:59.541Z","level":"warn","component":"agent","message":"worktree not ready","error":"worktree missing and no git url configured"}
{"ts":"2026-09-26T18:23:59.622Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"}
{"ts":"2026-09-26T18:24:00.667Z","level":"debug","component":"agent","message":"spool drained","events":2}
{"ts":"2026-09-26T18:24:00.685Z","level":"info","component":"agent","message":"agent stopped cleanly"}
✔ end to end: mention reaches the resident session and readiness is healthy (6312.758916ms)
✔ chat turn completes, budget spent, wake removed (16.659453ms)
✔ boot context appears only on the first turn (5.031754ms)
✔ model failure retries with backoff, then defers after three attempts (4.72128ms)
✔ turn timeout enqueues exactly one recovery wake and completes the original (54.513089ms)
✔ budget cap blocks ordinary wakes but reserve admits recovery wakes (5.936494ms)
✔ storage stop pauses ordinary wakes, recovery continues (5.547586ms)
✔ system prompt is exactly the lexically ordered personality (7.150412ms)
✔ wake prompts render per-kind templates with facts (1.222971ms)
✔ facts block omits missing values instead of rendering undefined (0.575121ms)
✔ all coding tools are bound to the editable worktree (12.804626ms)
✔ worktree: clone, ff-only when clean, preserved when dirty or ahead (413.658609ms)
✔ readWorktreeState: fresh head and dirty flag without fetch or merge (142.511564ms)
{"ts":"2026-09-26T18:24:14.854Z","level":"debug","component":"ciwatch","message":"ci poll","runs":1,"wakes":0}
{"ts":"2026-09-26T18:24:14.861Z","level":"debug","component":"ciwatch","message":"ci poll","runs":2,"wakes":1}
{"ts":"2026-09-26T18:24:14.864Z","level":"debug","component":"ciwatch","message":"ci poll","runs":2,"wakes":0}
{"ts":"2026-09-26T18:24:14.867Z","level":"debug","component":"ciwatch","message":"ci poll","runs":3,"wakes":0}
✔ ci watch enqueues one failure wake per failed run of a tracked sha (78.0007ms)
{"ts":"2026-09-26T18:24:15.005Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:15.029Z","level":"info","component":"deploy","message":"deploy events imported","count":2}
✔ deploy events poll mirrors into service and wakes on failures only (5178.546605ms)
{"ts":"2026-09-26T18:24:20.163Z","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.631063ms)
{"ts":"2026-09-26T18:24:25.305Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:25.323Z","level":"warn","component":"loop","message":"storage threshold transition","from":"ok","to":"warn"}
✔ storage watch: transitions emit deterministic outbox notice (5133.776469ms)
✔ readiness server reports 503 until local init completes (12.325887ms)
✔ fake telegram sanity (73.568783ms)
{"ts":"2026-09-26T18:24:30.852Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:30.865Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"}
✔ mention wakes, chatter archives without wake, other chats ignored (5222.235422ms)
{"ts":"2026-09-26T18:24:36.052Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:36.063Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"}
✔ media message downloads into service store and references digest (5186.680427ms)
{"ts":"2026-09-26T18:24:41.238Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:41.250Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"}
✔ /hide via reply tombstones deterministically without a model wake (5181.738389ms)
{"ts":"2026-09-26T18:24:46.419Z","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 (5151.372896ms)
✔ sums usage across assistant messages of one wake (2.878462ms)
✔ splits by provider/model and tolerates junk (0.445457ms)
✔ non-array input yields no rows (0.295385ms)
{"ts":"2026-09-26T18:24:53.534Z","level":"warn","component":"zai","message":"zai retry","path":"/paas/v4/chat/completions","status":500,"attempt":1,"delay":500}
✔ rest client retries retryable failures (568.360751ms)
✔ rest client surfaces 4xx without retry (22.071119ms)
{"ts":"2026-09-26T18:24:54.194Z","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 (5225.655787ms)
{"ts":"2026-09-26T18:24:59.407Z","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 (5179.005369ms)
{"ts":"2026-09-26T18:25:04.589Z","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 (8583.312071ms)
{"ts":"2026-09-26T18:25:13.168Z","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 (5119.815672ms)
{"ts":"2026-09-26T18:25:18.550Z","level":"info","component":"zai-mcp","message":"vision mcp connected"}
✔ mcp bridge lists and calls tools over stdio (414.052204ms)
{"ts":"2026-09-26T18:25:19.033Z","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 (8213.30259ms)
{"ts":"2026-09-26T18:25:27.220Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
✔ path traversal is rejected (5130.710694ms)
{"ts":"2026-09-26T18:25:32.350Z","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 (5188.990778ms)
{"ts":"2026-09-26T18:25:37.541Z","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 (5151.403957ms)
{"ts":"2026-09-26T18:25:42.690Z","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 (5137.120827ms)
{"ts":"2026-09-26T18:25:47.827Z","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 (5133.509008ms)
{"ts":"2026-09-26T18:25:52.962Z","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 (5127.683087ms)
✔ audit ingest is idempotent by event id and assigns seqs (13.241916ms)
✔ recall searches beyond the newest page in hot data and archives (42.602749ms)
✔ recall orders overlapping archives and late hot rows globally (34.76768ms)
✔ recall has identical Unicode case matching before and after archival (20.606272ms)
✔ recall tie ordering is limit-prefix consistent before and after archival (17.892851ms)
✔ chat ingest is idempotent and hide tombstones (4.247599ms)
✔ deployment events mirror idempotently (3.473117ms)
✔ media store is content-addressed and idempotent (6.252955ms)
✔ analysis cache upserts by (digest, capability, model, schemaVersion) (3.677647ms)
✔ archive cycle moves old audit rows exactly once and cold reads serve them (15.201827ms)
✔ crash between publish and delete does not duplicate rows (exactly once) (10.655795ms)
✔ archive cycle moves chat after one year and tombstones keep filtering (13.886585ms)
✔ quick check reports ok and jobs are recorded (6.283457ms)
✔ vacuum runs without error (3.596612ms)
✔ cost uses the price table per MTok (2.892687ms)
✔ unknown model keeps tokens but marks cost unavailable (0.404859ms)
✔ days are grouped by UTC date and sorted ascending (1.42021ms)
✔ projection extrapolates today across the remaining month (0.353101ms)
✔ projection is null without a priced day today (0.293452ms)
✔ ordinary calls stop at cap minus reserve (1.930197ms)
✔ recovery calls draw from the reserve only (0.302383ms)
✔ zero cap disables limiting (0.264704ms)
✔ state rolls over on a new day (1.711774ms)
✔ property: total allowed recovery calls per day equals reserve (21.081551ms)
✔ default budget exists and is sane (0.45875ms)
✔ cutoff subtracts hot days (1.957867ms)
✔ only rows strictly older than the cutoff archive (1.336741ms)
✔ rows group by month (0.372895ms)
✔ sidecar overlap selection skips non-overlapping segments (0.458101ms)
✔ property: every row lands in exactly one month group (17.695844ms)
✔ mention of the bot wakes (3.149147ms)
✔ reply to the bot wakes (0.337815ms)
✔ ordinary chatter never wakes (0.296243ms)
✔ mention inside a reply of someone else does not wake (0.292435ms)
✔ /hide via reply is deterministic, never wakes the model (0.41696ms)
✔ /hide with explicit id targets that id (0.323465ms)
✔ other commands wake (0.284294ms)
✔ caption mention on media wakes (2.000375ms)
✔ sender of the target or oliver may hide (0.37393ms)
✔ toTgMessage extracts largest photo and documents (0.75972ms)
✔ failure wakes outrank chat which outranks heartbeat (3.119631ms)
✔ FIFO inside a class (0.335128ms)
✔ deferred wakes are skipped until their time (0.333484ms)
✔ heartbeat coalescing predicate (0.450892ms)
✔ heartbeat hour is claimed at most once and never replayed (0.350913ms)
✔ property: ordering is stable sort by (priority, seq) (15.047649ms)
ℹ tests 98
ℹ suites 0
ℹ pass 98
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 127583.854668
[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

Complete raw log

Passed · 1 executions
PASSEDvalidate4m

Execution configuration

Imagedocker.io/library/node:26

Matrixnone

Triggerpush

Commands

export NPM_CONFIG_CACHE="$PWD/.npm-cache"
npm ci --prefer-offline
npm run check
npm test
npm run coverage
Job source · .ci/validate.kdl
job "validate" {
image "docker.io/library/node:26"trigger {
push {
branch "trunk"branch "feature/**"		}	}cache "npm" {
path ".npm-cache"key {
file "package-lock.json"		}	}run "export NPM_CONFIG_CACHE=\"$PWD/.npm-cache\""run "npm ci --prefer-offline"run "npm run check"run "npm test"run "npm run coverage"}
step timing
StepCommandTime
1/5export NPM_CONFIG_CACHE="$PWD/.npm-cache"0s
2/5npm ci --prefer-offline12s
3/5npm run check13s
4/5npm test128s
5/5npm run coverage127s

Complete raw log

Log tail
[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 12s

47 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New major version of npm available! 11.19.1 -> 12.1.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.1.0
npm notice To update run: npm install -g npm@12.1.0
npm notice
[luci] step 2/5 done in 12s
[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 254ms. 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.886997ms)
✔ no env at all falls back to fake (0.251474ms)
✔ key alone gives the real session (0.246772ms)
✔ explicit real without a key fails loudly (0.723847ms)
✔ explicit real with a key is real (0.376149ms)
✔ thinking level defaults to medium (0.836221ms)
✔ ZAI_THINKING_LEVEL overrides the default (1.482313ms)
✔ unknown ZAI_THINKING_LEVEL fails loudly (0.36989ms)
✔ wake queue persists across reopen; heartbeat coalesces; done compacts (21.199953ms)
✔ wake queue defer reorders wake with backoff (5.031119ms)
{"ts":"2026-09-26T18:23:52.514Z","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 (5225.389944ms)
✔ agent state persists mutations atomically (5.242979ms)
{"ts":"2026-09-26T18:23:59.528Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:23:59.539Z","level":"warn","component":"agent","message":"running with a FAKE session (no model calls; set ZAI_API_KEY for real)"}
{"ts":"2026-09-26T18:23:59.541Z","level":"warn","component":"agent","message":"worktree not ready","error":"worktree missing and no git url configured"}
{"ts":"2026-09-26T18:23:59.622Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"}
{"ts":"2026-09-26T18:24:00.667Z","level":"debug","component":"agent","message":"spool drained","events":2}
{"ts":"2026-09-26T18:24:00.685Z","level":"info","component":"agent","message":"agent stopped cleanly"}
✔ end to end: mention reaches the resident session and readiness is healthy (6312.758916ms)
✔ chat turn completes, budget spent, wake removed (16.659453ms)
✔ boot context appears only on the first turn (5.031754ms)
✔ model failure retries with backoff, then defers after three attempts (4.72128ms)
✔ turn timeout enqueues exactly one recovery wake and completes the original (54.513089ms)
✔ budget cap blocks ordinary wakes but reserve admits recovery wakes (5.936494ms)
✔ storage stop pauses ordinary wakes, recovery continues (5.547586ms)
✔ system prompt is exactly the lexically ordered personality (7.150412ms)
✔ wake prompts render per-kind templates with facts (1.222971ms)
✔ facts block omits missing values instead of rendering undefined (0.575121ms)
✔ all coding tools are bound to the editable worktree (12.804626ms)
✔ worktree: clone, ff-only when clean, preserved when dirty or ahead (413.658609ms)
✔ readWorktreeState: fresh head and dirty flag without fetch or merge (142.511564ms)
{"ts":"2026-09-26T18:24:14.854Z","level":"debug","component":"ciwatch","message":"ci poll","runs":1,"wakes":0}
{"ts":"2026-09-26T18:24:14.861Z","level":"debug","component":"ciwatch","message":"ci poll","runs":2,"wakes":1}
{"ts":"2026-09-26T18:24:14.864Z","level":"debug","component":"ciwatch","message":"ci poll","runs":2,"wakes":0}
{"ts":"2026-09-26T18:24:14.867Z","level":"debug","component":"ciwatch","message":"ci poll","runs":3,"wakes":0}
✔ ci watch enqueues one failure wake per failed run of a tracked sha (78.0007ms)
{"ts":"2026-09-26T18:24:15.005Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:15.029Z","level":"info","component":"deploy","message":"deploy events imported","count":2}
✔ deploy events poll mirrors into service and wakes on failures only (5178.546605ms)
{"ts":"2026-09-26T18:24:20.163Z","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.631063ms)
{"ts":"2026-09-26T18:24:25.305Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:25.323Z","level":"warn","component":"loop","message":"storage threshold transition","from":"ok","to":"warn"}
✔ storage watch: transitions emit deterministic outbox notice (5133.776469ms)
✔ readiness server reports 503 until local init completes (12.325887ms)
✔ fake telegram sanity (73.568783ms)
{"ts":"2026-09-26T18:24:30.852Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:30.865Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"}
✔ mention wakes, chatter archives without wake, other chats ignored (5222.235422ms)
{"ts":"2026-09-26T18:24:36.052Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:36.063Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"}
✔ media message downloads into service store and references digest (5186.680427ms)
{"ts":"2026-09-26T18:24:41.238Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
{"ts":"2026-09-26T18:24:41.250Z","level":"info","component":"telegram","message":"bot identified","username":"will_bot"}
✔ /hide via reply tombstones deterministically without a model wake (5181.738389ms)
{"ts":"2026-09-26T18:24:46.419Z","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 (5151.372896ms)
✔ sums usage across assistant messages of one wake (2.878462ms)
✔ splits by provider/model and tolerates junk (0.445457ms)
✔ non-array input yields no rows (0.295385ms)
{"ts":"2026-09-26T18:24:53.534Z","level":"warn","component":"zai","message":"zai retry","path":"/paas/v4/chat/completions","status":500,"attempt":1,"delay":500}
✔ rest client retries retryable failures (568.360751ms)
✔ rest client surfaces 4xx without retry (22.071119ms)
{"ts":"2026-09-26T18:24:54.194Z","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 (5225.655787ms)
{"ts":"2026-09-26T18:24:59.407Z","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 (5179.005369ms)
{"ts":"2026-09-26T18:25:04.589Z","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 (8583.312071ms)
{"ts":"2026-09-26T18:25:13.168Z","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 (5119.815672ms)
{"ts":"2026-09-26T18:25:18.550Z","level":"info","component":"zai-mcp","message":"vision mcp connected"}
✔ mcp bridge lists and calls tools over stdio (414.052204ms)
{"ts":"2026-09-26T18:25:19.033Z","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 (8213.30259ms)
{"ts":"2026-09-26T18:25:27.220Z","level":"info","component":"service","message":"service listening","public":"127.0.0.1:0","internal":"127.0.0.1:0"}
✔ path traversal is rejected (5130.710694ms)
{"ts":"2026-09-26T18:25:32.350Z","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 (5188.990778ms)
{"ts":"2026-09-26T18:25:37.541Z","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 (5151.403957ms)
{"ts":"2026-09-26T18:25:42.690Z","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 (5137.120827ms)
{"ts":"2026-09-26T18:25:47.827Z","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 (5133.509008ms)
{"ts":"2026-09-26T18:25:52.962Z","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 (5127.683087ms)
✔ audit ingest is idempotent by event id and assigns seqs (13.241916ms)
✔ recall searches beyond the newest page in hot data and archives (42.602749ms)
✔ recall orders overlapping archives and late hot rows globally (34.76768ms)
✔ recall has identical Unicode case matching before and after archival (20.606272ms)
✔ recall tie ordering is limit-prefix consistent before and after archival (17.892851ms)
✔ chat ingest is idempotent and hide tombstones (4.247599ms)
✔ deployment events mirror idempotently (3.473117ms)
✔ media store is content-addressed and idempotent (6.252955ms)
✔ analysis cache upserts by (digest, capability, model, schemaVersion) (3.677647ms)
✔ archive cycle moves old audit rows exactly once and cold reads serve them (15.201827ms)
✔ crash between publish and delete does not duplicate rows (exactly once) (10.655795ms)
✔ archive cycle moves chat after one year and tombstones keep filtering (13.886585ms)
✔ quick check reports ok and jobs are recorded (6.283457ms)
✔ vacuum runs without error (3.596612ms)
✔ cost uses the price table per MTok (2.892687ms)
✔ unknown model keeps tokens but marks cost unavailable (0.404859ms)
✔ days are grouped by UTC date and sorted ascending (1.42021ms)
✔ projection extrapolates today across the remaining month (0.353101ms)
✔ projection is null without a priced day today (0.293452ms)
✔ ordinary calls stop at cap minus reserve (1.930197ms)
✔ recovery calls draw from the reserve only (0.302383ms)
✔ zero cap disables limiting (0.264704ms)
✔ state rolls over on a new day (1.711774ms)
✔ property: total allowed recovery calls per day equals reserve (21.081551ms)
✔ default budget exists and is sane (0.45875ms)
✔ cutoff subtracts hot days (1.957867ms)
✔ only rows strictly older than the cutoff archive (1.336741ms)
✔ rows group by month (0.372895ms)
✔ sidecar overlap selection skips non-overlapping segments (0.458101ms)
✔ property: every row lands in exactly one month group (17.695844ms)
✔ mention of the bot wakes (3.149147ms)
✔ reply to the bot wakes (0.337815ms)
✔ ordinary chatter never wakes (0.296243ms)
✔ mention inside a reply of someone else does not wake (0.292435ms)
✔ /hide via reply is deterministic, never wakes the model (0.41696ms)
✔ /hide with explicit id targets that id (0.323465ms)
✔ other commands wake (0.284294ms)
✔ caption mention on media wakes (2.000375ms)
✔ sender of the target or oliver may hide (0.37393ms)
✔ toTgMessage extracts largest photo and documents (0.75972ms)
✔ failure wakes outrank chat which outranks heartbeat (3.119631ms)
✔ FIFO inside a class (0.335128ms)
✔ deferred wakes are skipped until their time (0.333484ms)
✔ heartbeat coalescing predicate (0.450892ms)
✔ heartbeat hour is claimed at most once and never replayed (0.350913ms)
✔ property: ordering is stable sort by (priority, seq) (15.047649ms)
ℹ tests 98
ℹ suites 0
ℹ pass 98
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 127583.854668
[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
Continue in CLI

Nushell command · read-only.

luci log dogim-vumop-parup-lakaz 001

Local Luci data access required · no execution.

All configuration at this revision
browser.kdl @ f524
// Browser e2e tier: runs only when web/ or service routes change (path-filtered).
// Requires playwright browsers in the job image; enable after the browser
// runner image exists (Luci extension item, see deploy/contract.md).
job "browser" {
  image "mcr.microsoft.com/playwright:v1.58.0-noble"
  trigger {
    push {
      branch "trunk"
      include "web/**"
      include "src/service/**"
    }
  }
  cache "npm" {
    path ".npm-cache"
    key {
      file "package-lock.json"
    }
  }
  run "export NPM_CONFIG_CACHE=\"$PWD/.npm-cache\""
  run "npm ci --prefer-offline"
  run "npm run build"
  run "npm run test:browser"
}
canary.kdl @ f524
// Scheduled ZAI canary (non-deploying). Manual-only until ZAI_API_KEY is
// configured as a Luci secret; flip to a schedule "..." trigger then.
job "canary" {
  image "docker.io/library/node:26-slim"
  secret "ZAI_API_KEY" env="ZAI_API_KEY"
  cache "npm" {
    path ".npm-cache"
    key {
      file "package-lock.json"
    }
  }
  run "export NPM_CONFIG_CACHE=\"$PWD/.npm-cache\""
  run "npm ci --prefer-offline"
  run "npm run canary"
}
validate.kdl @ f524
job "validate" {
  image "docker.io/library/node:26"
  trigger {
    push {
      branch "trunk"
      branch "feature/**"
    }
  }
  cache "npm" {
    path ".npm-cache"
    key {
      file "package-lock.json"
    }
  }
  run "export NPM_CONFIG_CACHE=\"$PWD/.npm-cache\""
  run "npm ci --prefer-offline"
  run "npm run check"
  run "npm test"
  run "npm run coverage"
}