fix: bare /config renders live state, not a frozen startup snapshot (gh #97) - #98
Merged
Merged
Conversation
#97) The full-table `/config` view printed `_resolved_config_report` — a string snapshotted at startup and never updated — while every other reader and setter uses the live `context`: `/config verbose on` sets `context["verbose"]`, `/config verbose` and `/status` read it back, and `/reset` mutates `context["config"]["configurable"]["thread_id"]`. So after `/verbose on` the table still showed `verbose = False [default]` even as `/status` said `on` and `/config verbose` said `True`, and after `/reset` it kept printing the pre-reset `thread_id`. The frozen string also carried a wrong SOURCE label — `[default]` for a value the user had overridden — so a user who set a value and re-ran `/config` to confirm saw it reported as unset and could conclude the set had silently failed. Bare `/config` now RE-RENDERS the one `describe()` diagnostic (the same renderer `--show-config` uses) from the `CodeConfig` resolved at startup, overlaid with live state: `verbose` from `context["verbose"]` (relabelled `[override]`, never `[default]`, when it differs from the resolved value) and the live `[configurable]` values (so a `/reset` thread_id shows through). Crucially it re-renders the startup-resolved cfg — whose per-field provenance is frozen — rather than RE-RESOLVING, so it still can't pick up the `LANGSTAGE_WORKSPACE_ROOT` that `apply_workspace()` self-publishes: the #64 fix holds and the no-mutation startup table stays byte-for-byte identical to `--show-config`. Same "two provenance views disagree" family as #64 / #66 / #79, now closed for the full `/config` table. `--show-config` is unaffected. Regression tests drive the real interactive loop: flip verbose (via `/verbose` and `/config verbose on`), then assert the bare `/config` table reflects it with an `[override]` source and agrees with `/status` and the single-key read; and a `/reset` test asserts the `[configurable]` thread_id tracks the reset. All three fail before the fix and pass after. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011HWCfJii6gXd3XL3Gq3W8B
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
In the interactive loop, the bare
/configfull-table view printed_resolved_config_report— a string snapshotted at startup and never updated — while every other reader and setter uses the livecontext. So after any runtime mutation the full table contradicted/status, the single-key/config <key>read, and even the✓ Set …line/configitself had just printed, and it carried a wrong source label ([default]for a value the user had actually overridden). Fixes #97.Repro A — verbose (was)
After
Repro B (thread_id) likewise: after
/reset, the bare/config[configurable]table now shows the new thread_id instead of the pre-reset one.What changed
Bare
/confignow re-renders the onedescribe()diagnostic (the same renderer--show-configuses) from theCodeConfigresolved at startup, overlaid with live state:verbosefromcontext["verbose"], relabelled[override](never[default]) when it differs from the resolved value;[configurable]values overlaid onto the startup key set, so a/resetthread_id shows through.Crucially it re-renders the startup-resolved cfg (whose per-field provenance is frozen) rather than re-resolving, so it still can't pick up the
LANGSTAGE_WORKSPACE_ROOTthatapply_workspace()self-publishes — the #64 fix holds and the no-mutation startup table stays byte-for-byte identical to--show-config. Same "two provenance views disagree" family as #64 / #66 / #79, now closed for the full/configtable. The non-interactive--show-configflag is unaffected.Tests
Three regression tests drive the real interactive loop (
CliRunner+ piped commands): flip verbose via/verboseand/config verbose onthen assert the bare/configtable showsTrue [override]and agrees with/status+ the single-key read; and a/resettest asserts the[configurable]thread_id tracks the reset. All three fail before the fix, pass after.Full suite: 146 passed (143 baseline + 3 new).
ruff check .andruff format --check .both clean.🤖 Generated with Claude Code
https://claude.ai/code/session_011HWCfJii6gXd3XL3Gq3W8B