From c1b6d0d067dba760527c581c5d56496dc3782380 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 30 Apr 2026 09:32:53 +0900 Subject: [PATCH] =?UTF-8?q?docs(roadmap):=20add=20#372=20=E2=80=94=20statu?= =?UTF-8?q?s=20workspace=20missing=20git=5Fcommit,=20git=5Fremote=5Furl,?= =?UTF-8?q?=20git=5Fahead=5Fbehind?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ROADMAP.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ROADMAP.md b/ROADMAP.md index 29eaf800..efd6500a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -6294,3 +6294,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) 352. **Top-level `plugins update --output-format json` sends a generic JSON error envelope to stderr only, leaving stdout empty** — dogfooded 2026-04-29 for the 23:00 nudge on current `origin/main` / rebuilt `./rust/target/debug/claw` with embedded `git_sha` `5eb1d7d8`. After rebuilding and verifying the binary provenance, repeated bounded runs of `timeout 8 ./rust/target/debug/claw plugins update does-not-exist --output-format json` exited `1` with `stdout=0` and `stderr=97`; stderr contained JSON (`{"error":"plugin `does-not-exist` is not installed","hint":null,"kind":"unknown","type":"error"}`), but stdout was empty. In the same rebuilt binary, `plugins list --output-format json` returned stdout JSON promptly with the known plugin inventory payload. This is distinct from #350's missing-target `plugins enable` zero-byte timeout and parallel to #351's `plugins disable` stderr-only JSON envelope: update fails fast, but the JSON-mode error lives on stderr only and uses generic `kind:"unknown"`/`type:"error"` instead of a plugin-specific not-found contract. **Required fix shape:** (a) define and consistently document stdout/stderr placement for JSON-mode lifecycle errors; (b) return a plugin-specific typed error with `kind:"plugin"` or `domain:"plugin"`, `action:"update"`, `status:"not_found"` or `code:"plugin_not_found"`, `plugin`, and optional `available_plugins[]`; (c) share missing-target error-envelope behavior across disable/update/uninstall and reconcile it with enable's timeout path; (d) add regression coverage proving `plugins update does-not-exist --output-format json` produces a typed plugin-not-found JSON contract on the documented stream. **Why this matters:** update is a maintenance/control-plane operation often run in automation. A stale plugin name should produce a predictable, domain-specific not-found result, not require callers to special-case stderr-only generic error envelopes after explicitly requesting JSON. Source: gaebal-gajae dogfood follow-up for the 23:00 nudge on rebuilt `./rust/target/debug/claw` `5eb1d7d8`; invalid hang PR #2894 was closed after repeated bounded repros returned exit 1 with JSON on stderr. 353. **Top-level `plugins uninstall --output-format json` sends a generic JSON error envelope to stderr only, leaving stdout empty** — dogfooded 2026-04-29 for the 23:30 nudge on current `origin/main` / rebuilt `./rust/target/debug/claw` with embedded `git_sha` `6f92e54d`. After rebuilding and verifying the binary provenance, repeated bounded runs of `timeout 8 ./rust/target/debug/claw plugins uninstall does-not-exist --output-format json` exited `1` with `stdout=0` and `stderr=97`; stderr contained JSON (`{"error":"plugin `does-not-exist` is not installed","hint":null,"kind":"unknown","type":"error"}`), but stdout was empty. In the same rebuilt binary, `plugins list --output-format json` returned stdout JSON promptly with the known plugin inventory payload. This is distinct from #350's missing-target `plugins enable` zero-byte timeout and parallel to #351/#352 for disable/update: uninstall fails fast, but the JSON-mode error lives on stderr only and uses generic `kind:"unknown"`/`type:"error"` instead of a plugin-specific not-found contract. **Required fix shape:** (a) define and consistently document stdout/stderr placement for JSON-mode lifecycle errors; (b) return a plugin-specific typed error with `kind:"plugin"` or `domain:"plugin"`, `action:"uninstall"`, `status:"not_found"` or `code:"plugin_not_found"`, `plugin`, and optional `available_plugins[]`; (c) share missing-target error-envelope behavior across disable/update/uninstall and reconcile it with enable's timeout path; (d) add regression coverage proving `plugins uninstall does-not-exist --output-format json` produces a typed plugin-not-found JSON contract on the documented stream. **Why this matters:** uninstall is the most destructive plugin lifecycle action. A stale plugin name should produce a predictable, domain-specific not-found result before cleanup hooks or loader work, not require callers to special-case stderr-only generic error envelopes after explicitly requesting JSON. Source: gaebal-gajae dogfood follow-up for the 23:30 nudge on rebuilt `./rust/target/debug/claw` `6f92e54d`; invalid hang PR #2897 was closed after repeated bounded repros returned exit 1 with JSON on stderr. 354. **Top-level `memory list` and `memory help` with `--output-format json` hang with zero stdout/stderr instead of returning bounded memory inventory/help or a typed unavailable response** — dogfooded 2026-04-30 for the 00:00 nudge on current `origin/main` / rebuilt `./rust/target/debug/claw` with embedded `git_sha` `19947545`. After rebuilding and verifying the binary provenance, bounded runs of `timeout 8 ./rust/target/debug/claw memory list --output-format json` produced `stdout=0` and `stderr=0`; the first sample exited `124` and the second sample was still stuck until killed. A follow-up sanity check of `timeout 8 ./rust/target/debug/claw memory help --output-format json` also exited `124` with `stdout=0` and `stderr=0`, so the issue is broader than list inventory: even the memory help path can hang silently in JSON mode. This is distinct from prior plugin lifecycle stream/status items: the affected surface is memory command introspection, where claws need safe local help/inventory before reading or mutating memory. **Required fix shape:** (a) make `memory help` and `memory list --output-format json` return bounded local JSON without requiring external/authenticated backing store availability; (b) return stdout JSON with `kind:"memory"`, `action:"help"|"list"`, `status`, usage or `entries[]`, source/provenance, counts, and truncation metadata; (c) if credentials/config/backing store are missing or slow, return a typed JSON unavailable/config/timeout error instead of hanging; (d) add regression coverage proving both `memory help --output-format json` and `memory list --output-format json` return machine-readable outcomes within a deterministic budget. **Why this matters:** memory is a core clawability surface. If even help/list can hang silently with no bytes, agents cannot tell whether memory is empty, unavailable, remote-auth blocked, or deadlocked, and any higher-level recall/debug flow stalls at the first introspection step. Source: gaebal-gajae dogfood follow-up for the 00:00 nudge on rebuilt `./rust/target/debug/claw` `19947545`. + +372. **`/status --output-format json` workspace object is missing `git_commit`, `git_remote_url`, and `git_ahead_behind` fields; only `git_branch` and `git_state` (a prose dirty-state string) are provided** — dogfooded 2026-04-30 by Jobdori on `8e24f304`. Running `/status --output-format json` with a git repo active returns workspace keys: `['changed_files','cwd','discovered_config_files','git_branch','git_state','git_state','loaded_config_files','memory_file_count','project_root','session','session_id','session_lifecycle','staged_files','unstaged_files','untracked_files']`. `git_commit` (current HEAD SHA), `git_remote_url`, and `git_ahead_behind` are absent. `git_state` is a prose string `"dirty · 4 files · 4 untracked"` — not structured. An orchestrator cannot determine: (a) which exact commit is checked out without a separate `git rev-parse HEAD` call; (b) whether the local branch is ahead/behind its upstream without a separate `git status -sb` call; (c) the remote repository URL without a separate `git remote get-url origin` call. All three are standard git workspace properties available without network access. **Required fix shape:** (a) add `git_commit: ""` (full or short); (b) add `git_remote_url: ""` (or `null` if no remote configured); (c) add `git_ahead: ` and `git_behind: ` (or combined `git_ahead_behind: {ahead, behind}`) relative to the tracking branch; (d) split `git_state` prose into structured fields: `git_is_dirty: bool`, `git_changed_count: int`, `git_untracked_count: int`; (e) add regression coverage confirming `git_commit` is non-null in a git workspace. Source: Jobdori live dogfood, mengmotaHost, `8e24f304`, 2026-04-30.