From c32288bd6b1aef4f6f5ca2546ecd860855302518 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 25 May 2026 11:34:35 +0900 Subject: [PATCH] =?UTF-8?q?docs(roadmap):=20add=20#693=20=E2=80=94=20claw-?= =?UTF-8?q?analog=20bootstrap=20phase=20parser=20silent=20unknown=20fallba?= =?UTF-8?q?ck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ROADMAP.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ROADMAP.md b/ROADMAP.md index 583d235c..9201c516 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -7524,3 +7524,13 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) **Required fix shape:** (a) Extend `system-prompt --help --output-format json` with structured fields: `usage:"claw system-prompt [--cwd ] [--date YYYY-MM-DD] [--output-format ]"`, `formats:["text","json"]`, `related:["claw doctor","claw dump-manifests"]`, `local_only:true`, `requires_credentials:false`, `requires_provider_request:false`, `mutates_workspace:false`, `output_fields:["kind","message","sections"]`, and `options:[{name:"--cwd", value_name:"PATH", type:"directory", required:false, validation:["exists","is_directory","no_newlines"], default:"current working directory"},{name:"--date", value_name:"YYYY-MM-DD", type:"date", required:false, validation:["iso8601_date","valid_calendar_date","no_newlines"], default:"current date"},{name:"--output-format", values:["text","json"]}]`. (b) Add `sections_schema` or at least `sections_field_semantics` so callers know whether `sections` is ordered and what each entry contains. (c) Derive option metadata from the parser/validator used by #99's eventual fix so help cannot claim validation that code does not enforce. (d) Keep `message` as human summary only. **Acceptance check:** `claw system-prompt --help --output-format json | jq -e '.command=="system-prompt" and .local_only==true and .requires_credentials==false and ([.output_fields[]] | index("message") and index("sections")) and ([.options[].name] | index("--cwd") and index("--date"))'` should pass; currently those structured fields are absent. Source: gaebal-gajae dogfood for the 2026-05-25 01:00 Clawhip nudge. 335. **`/session list --output-format json` session detail objects omit `created_at_ms`, forcing callers to parse the session ID string to recover creation time** — dogfooded 2026-04-29 by Jobdori on current main (`0f7578c`). Running `claw --output-format json --resume latest /session list` returns `session_details` objects with fields `["id", "lifecycle", "message_count", "path", "updated_at_ms"]` — `created_at_ms` is absent. The session ID (`session-1776891003038-0`) encodes a Unix millisecond timestamp as its second segment, so a caller can extract creation time by splitting on `-` and parsing index 1, but this is an undocumented implementation detail that can break if the ID format changes. Without a first-class `created_at_ms` field, a caller cannot: (a) compute session age (`now - created_at`), (b) distinguish a session created 30 seconds ago from one created 3 days ago (both may have `message_count=1`), (c) surface session age in monitoring dashboards without string-parsing hacks. **Required fix shape:** (a) add `created_at_ms` (Unix epoch milliseconds, same unit as `updated_at_ms`) to every `session_details` object; (b) derive it from the session JSONL `session_meta` event's `created_at` field (already written at creation time) or from the session ID timestamp as a fallback; (c) ensure `session_details` always has both `created_at_ms` and `updated_at_ms` so session age and idle time are computable from the JSON alone; (d) add regression coverage proving `session list --output-format json` always includes `created_at_ms`. **Why this matters:** session age is a key diagnostic field for monitoring, GC policies, and resume decisions; parsing the session ID string to recover creation time is a fragile workaround that couples callers to the ID generation implementation. Source: Jobdori live dogfood on mengmotaHost, claw-code `0f7578c`, 2026-04-29. + +## Pinpoint #693. `claw-analog` bootstrap-plan phase parser silently falls back to `"unknown"` — `lib.rs:1114` uses `.unwrap_or("unknown")` for phase field; unrecognized phases emit opaque kind instead of typed error + +**Surface.** `claw-analog` crate (`rust/crates/claw-analog/src/lib.rs:1114`): `let phase = v.get("phase").and_then(|x| x.as_str()).unwrap_or("unknown")` — any bootstrap-plan JSON event with a missing or unrecognized `phase` field silently degrades to `"unknown"` with no warning, no `kind` discriminator, and no structured hint. This is a third instance of the classifier-orphan pattern (#422, #463) now appearing in a freshly landed crate. + +**Why it matters.** `claw-analog` is the new diagnostic/analog harness crate merged in c8b44878. If bootstrap-plan phase names drift between runtime and analog (e.g., a phase renamed without updating the analog parser), all events from that phase silently become `"unknown"` — automation watching for specific phases (e.g., `"CliEntry"`, `"MainRuntime"`) will miss them with no error signal. + +**Required fix shape.** (a) Replace `.unwrap_or("unknown")` with an exhaustive match or typed `ParseError` that names the offending field and value; (b) add `kind:"unknown_bootstrap_phase"` with `received_value:string` to the structured error envelope; (c) add regression test asserting unrecognized phase emits a typed error, not silent `"unknown"` fallback. + +**Source.** Jobdori probe 2026-05-25 11:32 GMT+9 on main HEAD `c8b44878`. [SCOPE: ultraworkers/claw-code]