Compare commits

...

5 Commits

Author SHA1 Message Date
YeonGyu-Kim
c1b6d0d067 docs(roadmap): add #372 — status workspace missing git_commit, git_remote_url, git_ahead_behind 2026-04-30 09:32:53 +09:00
Bellman
8e24f3049e Merge pull request #2901 from ultraworkers/docs/roadmap-354-memory-list-hangs
docs(roadmap): add #354 — memory json help/list hangs
2026-04-30 09:30:57 +09:00
Yeachan-Heo
71d8e7b925 Document memory JSON help/list hang
Constraint: ROADMAP-only dogfood follow-up for 00:00 nudge on rebuilt claw git_sha 19947545

Rejected: implementation change to memory command dispatch; request was one concrete follow-up if no backlog item
Confidence: high after bounded memory list samples plus memory help bounded sanity also hung
Scope-risk: narrow
Directive: Switch from plugin lifecycle repetition to memory command introspection clawability
Tested: cargo run --manifest-path rust/Cargo.toml --bin claw -- version --output-format json; timeout 8 ./rust/target/debug/claw memory list --output-format json samples; timeout 8 ./rust/target/debug/claw memory help --output-format json; git diff --check; scripts/fmt.sh --check
Not-tested: runtime behavior change, because this commit only documents the gap
2026-04-30 00:02:58 +00:00
Bellman
19947545e2 Merge pull request #2899 from ultraworkers/docs/roadmap-353-plugins-uninstall-stderr-only
docs(roadmap): add #353 — plugins uninstall json error is stderr-only
2026-04-30 09:01:02 +09:00
Yeachan-Heo
f7b2d8d6fe Document plugins uninstall JSON stderr-only not-found
Constraint: ROADMAP-only dogfood follow-up for 23:30 nudge on rebuilt claw git_sha 6f92e54d

Rejected: implementation change to plugin lifecycle uninstall; request was one concrete follow-up if no backlog item
Confidence: high after repeated bounded samples plus prompt list sanity check
Scope-risk: narrow
Directive: Replaces invalid hang PR #2897 with verified stderr-only JSON-mode gap
Tested: cargo run --manifest-path rust/Cargo.toml --bin claw -- version --output-format json; repeated timeout 8 ./rust/target/debug/claw plugins uninstall does-not-exist --output-format json; timeout 8 ./rust/target/debug/claw plugins list --output-format json; git diff --check; scripts/fmt.sh --check
Not-tested: runtime behavior change, because this commit only documents the gap
2026-04-29 23:31:56 +00:00

View File

@@ -6292,3 +6292,7 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed)
350. **Top-level `plugins enable <missing-plugin> --output-format json` hangs with zero stdout/stderr instead of returning a typed plugin-not-found or unsupported-target response** — dogfooded 2026-04-29 for the 22:00 nudge on current `origin/main` / rebuilt `./rust/target/debug/claw` with embedded `git_sha` `ee44ff98`. After rebuilding and verifying the binary provenance, repeated bounded runs of `timeout 8 ./rust/target/debug/claw plugins enable does-not-exist --output-format json` exited `124` with `stdout=0` and `stderr=0`; a third sample was still stuck until killed. In the same rebuilt binary, `plugins list --output-format json` returned promptly with the known plugin inventory payload, proving the plugin top-level surface is reachable and narrowing the hang to missing-plugin lifecycle mutation. This is distinct from #348's prose-only list inventory and #349's unsupported `plugins show` success-shaped JSON: #350 covers a supported lifecycle verb (`enable`) against an absent target, where the CLI should be able to fail fast before any plugin runtime work. **Required fix shape:** (a) validate the target plugin against the discovered/configured inventory before invoking enable-side effects; (b) return bounded stdout JSON such as `kind:"plugin"`, `action:"enable"`, `status:"not_found"` or `kind:"error"`, `code:"plugin_not_found"`, `plugin`, and optional `available_plugins[]`; (c) add internal timeout/diagnostic metadata for plugin lifecycle operations so registry or hook stalls do not produce silent zero-byte hangs; (d) add regression coverage proving `plugins enable does-not-exist --output-format json` returns a typed JSON outcome within a deterministic budget and does not mutate plugin state. **Why this matters:** enable/disable/update/uninstall are destructive control-plane actions. A missing or stale plugin name must fail safely and machine-readably; otherwise claws cannot preflight plugin lifecycle operations, distinguish typo from loader deadlock, or recover without killing a hung process. Source: gaebal-gajae dogfood follow-up for the 22:00 nudge on rebuilt `./rust/target/debug/claw` `ee44ff98`.
351. **Top-level `plugins disable <missing-plugin> --output-format json` sends the JSON error envelope to stderr only, leaving stdout empty** — dogfooded 2026-04-29 for the 22:30 nudge on current `origin/main` / rebuilt `./rust/target/debug/claw` with embedded `git_sha` `0f9e8915`. After rebuilding and verifying the binary provenance, repeated bounded runs of `timeout 8 ./rust/target/debug/claw plugins disable does-not-exist --output-format json` exited `1` with `stdout=0` and `stderr=113`; stderr contained JSON (`{"error":"plugin `does-not-exist` is not installed or discoverable","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, proving the plugin command surface is reachable. This is distinct from #350's missing-target `plugins enable` zero-byte timeout: the disable path fails fast, but its JSON-mode error envelope is routed to stderr and uses generic `kind:"unknown"`/`type:"error"` instead of a plugin-specific stdout outcome. **Required fix shape:** (a) define and consistently document whether JSON mode emits machine-readable envelopes on stdout, stderr, or both for nonzero exits; (b) return a plugin-specific typed error with `kind:"plugin"` or `domain:"plugin"`, `action:"disable"`, `status:"not_found"` or `code:"plugin_not_found"`, `plugin`, and optional `available_plugins[]`; (c) keep stdout/stderr placement consistent across plugin lifecycle verbs so callers do not need per-action stream heuristics; (d) add regression coverage proving `plugins disable does-not-exist --output-format json` produces a typed plugin-not-found JSON contract on the documented stream. **Why this matters:** disable is a recovery/control-plane operation. A stale plugin name should be a structured, domain-specific not-found result on a predictable stream; otherwise claws that read stdout JSON for normal responses and stderr for human diagnostics must special-case this lifecycle failure. Source: gaebal-gajae dogfood follow-up for the 22:30 nudge on rebuilt `./rust/target/debug/claw` `0f9e8915`; invalid hang PR #2891 was closed after repeated bounded repros returned exit 1 with JSON on stderr.
352. **Top-level `plugins update <missing-plugin> --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 <missing-plugin> --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: "<sha>"` (full or short); (b) add `git_remote_url: "<url>"` (or `null` if no remote configured); (c) add `git_ahead: <int>` and `git_behind: <int>` (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.