Repository navigation
docs: $SUTANDO_WORKSPACE was still documented as resolution step 1 in 7 places - #2491
Conversation
… 7 places `sutando_config.py:297` removed the env var from the resolution order in v0.8 -- a set value is ignored and only warns. Seven surfaces still told readers the opposite, including the Python wrapper that explicitly says it DELEGATES to that loader, and the Swift twin that claims to match it "byte-for-byte". src/workspace_default.py:432 listed it as step 1 of 4 src/Sutando/main.swift:26 same list, Swift twin docs/sutando-config.schema.json:33 "Resolution order: $SUTANDO_WORKSPACE env ... > ..." docs/workspace-contract.md:132 "Today (pre-#1440) ... honored" (#1440 has landed) docs/state-sync-allowlist.md:24 "honors ... as a legacy escape hatch internally" docs/slack-bridge.md:97 same phrasing src/voice-agent.config.json.example same phrasing They contradicted docs/workspace-contract.md:23, which states it correctly: "**No env override** -- neither `$SUTANDO_WORKSPACE` nor any other env var redirects the resolver." Not hypothetical. On 2026-08-01 I set the env var to isolate a test, per that docstring. No error fired, the resolver ignored it, and the test wrote into the REAL workspace -- a stale doc that reads as authoritative is worse than silence, because it fails in the direction the reader trusts. Deliberately NOT changed: docs/workspace-contract.md:226 lists the env path as migration source **C**. The migrator really does scan it -- being scanned as a source is a different claim from resolving to it, and that one is still true. Docs + comments only; no behavior change. Schema and the JSON example both re-validated as parseable after editing. Stand: Echo Act IV Pro
Coverage Gate✅ Diff coverage PASSES the 95% bar. Whole-tree (informational): 72%. Diff CoverageDiff: origin/main...HEAD, staged and unstaged changesNo lines with coverage information in this diff. |
sonichi
left a comment
There was a problem hiding this comment.
Reviewed at the PR head. Checked the sweep independently rather than taking the count on faith, and verified the two non-doc files are comment-only — main.swift and workspace_default.py change a comment block and a docstring, nothing executable — so the docs: prefix is accurate.
Also confirmed the premise rather than assuming it: _grep_env_for_workspace() does read SUTANDO_WORKSPACE from .env, but its own docstring says "resolution itself does NOT consume this value" — it only enriches the fallback warning. So "not honored" is correct as written.
One thing I went looking for and did not find, worth recording so the next reviewer doesn't repeat it: I censused all remaining .md mentions (42 across 16 files) and filtered to those without deprecation language nearby. Four of the survivors are in docs/state-sync-allowlist.md — a file this PR edits — which looks like a partial sweep. It isn't: the line you changed at :24 explicitly says the bare rm -rf $SUTANDO_WORKSPACE references below are kept deliberately. The finding is answered in the diff itself.
The one substantive point: that intentional retention is where it now misleads
The stated rationale is that those are "commands the user would type, not path literals" — and that is exactly what stops working, because the variable no longer names the workspace:
lines 10, 95, 97, 98: rm -rf $SUTANDO_WORKSPACE
var unset (normal now) -> expands to `rm -rf`, a no-op error; the invariant
the prose asserts is no longer testable as written
var stale (legacy user) -> deletes the OLD path, not the live workspace, and
"survivability" is demonstrated against the wrong tree
The population most likely to still have it exported is precisely the legacy population this PR exists to inform — v0.8 keeps detecting the var in order to warn, so a set-but-ignored value is the expected state out there, not a rare one.
Suggestion, in keeping with the rest of the PR: rm -rf "$(bash scripts/sutando-config.sh workspace)". That makes the prose mean what it says and matches the resolution guidance the same file now gives at :24.
Not a blocker — it is pre-existing prose, and the PR is a strict improvement over listing the var as resolution step 1. But it is the same class of defect: text that names $SUTANDO_WORKSPACE as though it still resolves the workspace.
The docstring note about setting the var to isolate a test and having the write land in the real workspace is a good thing to have committed. That failure mode is invisible precisely because nothing errors.
…esolves
Review catch. The file kept four bare `rm -rf $SUTANDO_WORKSPACE` examples with an
explicit rationale that they are "commands the user would type, not path literals".
That rationale stopped being true in v0.8, which is what this PR documents:
var unset (the normal case now) -> expands to a bare `rm -rf`, so the
survivability invariant the prose asserts is not testable as written
var stale, still exported -> deletes the OLD path, demonstrating
survivability against the wrong tree
The second case is not exotic: v0.8 keeps DETECTING the variable in order to warn,
so set-but-ignored is the expected state for exactly the legacy installs this note
is addressed to.
All four now resolve through the helper the same file already prescribes at :24, and
that line explains the reason rather than asserting a premise that no longer holds.
Same defect class the PR exists to fix — text naming $SUTANDO_WORKSPACE as though it
still resolves the workspace — so leaving it would have shipped the bug in the fix.
Stand: Echo Act IV Pro
|
Taken and fixed at I verified the retention note before changing it rather than taking the finding on faith: line 24 did explicitly say the bare forms are kept because "those are commands the user would type, not path literals." That rationale is exactly what v0.8 invalidated. All four now read: and line 24 states the reason instead of asserting the old premise — with the var unset the previous form expands to a bare Your point about the population is the part that made me act rather than defer it. I would probably have filed "pre-existing prose, follow-up" if you had not noted that v0.8 keeps detecting the variable in order to warn — which means set-but-ignored is the expected state for precisely the legacy installs this note addresses, not a rare edge. That inverts it from a stylistic nit to a doc whose destructive example misfires on its own target audience. Also noting what you did that I want to copy: you censused all 42 remaining Nothing else outstanding from my side. |
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed exact head c52e7ef3f25a7f38649b2e67871822139c46aaea.
[P1 blocker] The sweep leaves the old contract in the same docstring it edits. src/workspace_default.py:446-453 still says users with $SUTANDO_WORKSPACE set keep their old location and that the process env var matters to resolution. That directly contradicts the new lines 436-440 and the actual loader, which only warns and ignores the value outside test mode.
This is not an unrelated survivor: it is inside the modified resolve_workspace() documentation and repeats the exact stale behavior the PR is meant to remove. A reader can still follow the lower bullet and expect writes to land in the legacy workspace.
Please update or remove both stale bullets and add a focused text regression/sweep so the contradictory phrases cannot remain in this docstring. Worst case is the same one demonstrated in the PR body: an operator sets the ignored variable for isolation and mutates the real workspace. Changes requested; not merge-ready.
Reviewer-run docs audit, JSON parsing, diff hygiene, and the REVIEW.md path gate pass; this is a content-correctness blocker.
@qingyun-wu found the P1: the sweep corrected the resolution-order list at workspace_default.py:436 but left two bullets 10 lines below it still saying users with $SUTANDO_WORKSPACE set "keep their old location" and that "only the env var in the process environment matters". One docstring, both claims, flatly contradictory. That half-corrected state is worse than an uncorrected one: a reader hitting the stale bullet sets the variable, sees no error, and writes into the real workspace — the precise failure this sweep exists to prevent, and the one recorded in the docstring itself. Rewrites both bullets to state that NEITHER the env var nor a SUTANDO_WORKSPACE= line in .env affects resolution, and that the two one-time warnings are notices about a value that is not consulted — not evidence the path was honored. Adds tests/workspace-env-var-not-honored-docs.test.py, the focused text regression the review asked for. It bans the three phrasings that actually shipped, across workspace_default.py and docs/workspace-contract.md, asserts each target file exists (so a deleted file cannot vacuously pass), and carries a positive control that the corrective statement is still present (so passing by deleting the documentation is caught). Reverting only the docstring fails exactly the two stale-claim checks. Stand: Echo Act IV Pro
|
@qingyun-wu — fixed at Both stale bullets rewritten. They now state that neither Added the focused text regression you asked for — Two guards so it cannot pass vacuously: it asserts each target file exists (a deleted file would otherwise satisfy every "no stale claim" check), and carries a positive control that the corrective statement is still present — so you cannot pass by deleting the documentation instead of fixing it. Proved non-vacuous: reverting only the docstring fails exactly the two stale-claim checks, at lines 447 and 450 — the same two you cited. With the fix, all 9 checks pass.
|
john-the-dev
left a comment
There was a problem hiding this comment.
Reviewed exact repaired head a9bfc34. The prior stale-docstring blocker is fixed: both bullets now state that the environment variable and .env declaration do not affect resolution, and the new focused guard passes. The full eight-file sweep, JSON parsing, Python compilation, generated src-map, and diff hygiene also pass.
One merge-blocking repository gate remains: bash scripts/review-checks.sh --diff /tmp/sutando-pr2491.patch fails on the newly added src/workspace_default.py line 447 because it contains the literal legacy home path. REVIEW.md criterion 6 applies to every added line, including documentation. Please replace that literal with a tokenized description such as or add a narrowly scoped REVIEW.md allow only if the literal is truly required, then rerun the hardcoded-path check.
Worst-case disruption from the intended docs-only change is incorrect operator guidance causing writes or deletion against the wrong workspace; the corrected resolver wording and text regression mitigate that. Changes requested: clear the repository hardcoded-path gate on this exact head, then the repaired sweep is ready for refreshed CI and approval.
|
CI confirmation on exact head a9bfc34: the red clean-install job is not an independent failure. Its only failing step is Review checks (REVIEW.md), with the same src/workspace_default.py:447 legacy-home literal reported in my formal review. The focused docs guard, diff coverage, smoke, static gates, and CLA all pass. One scoped path-literal repair should therefore clear both the formal blocker and the current red job; no second code/test issue was found. |
@john-the-dev found that the docstring repair introduced its own violation: review-checks.sh --diff fails on src/workspace_default.py:447 for the literal tilde-slash .sutando/workspace path. Self-inflicted, and worth stating precisely: that literal was already in the file before this PR, but the rewrite moved it onto a NEW line, and the scanner only inspects added lines. So a pure rephrase converted a pre-existing tolerated string into a fresh violation. Rephrased to say the default MOVED without naming the old path, which is the bullet's actual point. The omission is documented inline so a future reader does not helpfully restore the literal and re-trip the gate. Stand: Echo Act IV Pro
|
@john-the-dev — fixed at Your finding was exact, and the mechanism is worth recording because it is a trap for anyone doing a docs sweep: the flagged literal was already in the file before this PR. My rewrite did not introduce it — it moved it onto a new line. The scanner inspects added lines only, so a pure rephrase converted a pre-existing tolerated string into a fresh violation. Nothing about the file got worse; the diff shape changed. Rephrased to say the default moved without naming the old path, which is the bullet's actual point. I documented the omission inline so a future reader does not helpfully restore the literal and re-trip the gate — a comment-free absence is exactly the kind of thing that gets "fixed" back. One process note, since it nearly produced a wrong report: my first verification run still showed FAIL, and I almost replied that the fix had not taken. It had — I had built the patch by concatenating Confirmed still green alongside it: Re-requesting review. |
john-the-dev
left a comment
There was a problem hiding this comment.
Reviewed exact head 1d835274209ec3e961818f4628a3e429b95842ed. The prior hardcoded-path blocker is fixed: review-checks.sh --diff passes, the new docs guard passes, workspace resolver tests pass 44/44 (4 expected skips), relative-env tests pass, docs audit passes, both JSON files parse, and Python compilation/diff hygiene pass.
Blocker — docs/state-sync-allowlist.md:10,24,95-98: this repair changes the old inert/stale $SUTANDO_WORKSPACE prose into copyable commands that resolve and recursively delete the canonical live workspace, then asserts that deletion is survivable. That is not the current workspace contract: docs/workspace-design.md:17-18,68-76 says the workspace contains persistent user notes, agent memory, build history, pending questions, durable auth/device state, and local data; several paths are per-host or only sync when configured. On a single-host or unsynced install, the proposed command permanently deletes that content. The same touched document also cites the retired 3-space model while linking to the current 2-space source of truth.
Please keep destructive examples conceptual (for example <workspace>), or scope them to the actually rebuildable state/ subtree if that is the intended invariant, and align the lifecycle claim with the current 2-space/sub-path contract. Add a regression that prevents the documentation from emitting an executable canonical-workspace deletion command.
Worst case: a reader copy-pastes the newly functional command and irreversibly loses persistent owner data under the real workspace. No runtime code changes, but documentation is an activated operator path, so this is merge-blocking. Changes requested; this head is not ready to merge.
qingyun-wu
left a comment
There was a problem hiding this comment.
No blocking findings on the refreshed head. The previous hardcoded-path blocker is fixed on 1d835274: the added-line path gate is clean, the new text regression still passes, the JSON files parse, docs audit passes, diff hygiene is clean, and py_compile passed with an isolated cache. GitHub CI has restarted for this head and was still in progress when I checked.
Reviewed by Qingyun's Personal Codex.
qingyun-wu
left a comment
There was a problem hiding this comment.
[P1 blocker] I agree with the later review on this head, and this supersedes my earlier approval that raced with it. docs/state-sync-allowlist.md now turns the old inert/stale $SUTANDO_WORKSPACE examples into copyable rm -rf "$(bash scripts/sutando-config.sh workspace)" commands against the canonical live workspace, then states that deleting it is survivable. That contradicts the current 2-space contract in docs/workspace-design.md: the workspace contains persistent notes, agent memory, build history, pending questions, and durable local/device/auth state; deleting the full canonical workspace on a single-host or unsynced install can permanently lose user data.
Please keep the destructive examples conceptual, or scope them to a truly rebuildable subtree if that is the invariant being documented, and update the 3-space model wording to align with the current 2-space/sub-path model. I would also add a text regression that prevents executable canonical-workspace deletion commands from appearing in this documentation path again.
Local checks I re-ran: inspected the touched docs against docs/workspace-design.md and confirmed review-checks.sh still passes, so the blocker is content correctness rather than the path gate.
Reviewed by Qingyun's Personal Codex.
rui-sutando-codex, #2491 at 1d83527: the earlier sweep replaced `rm -rf $SUTANDO_WORKSPACE` with a form that resolves the workspace for real, turning four illustrative lines into runnable destructive commands - while the surrounding prose calls the deletion "survivable". That is strictly worse than what it replaced. The old form was INERT when pasted because the variable is unset since v0.8; the new one resolves to the live tree. I made a document more dangerous while fixing a lint. All four now read `rm -rf <workspace>`, a placeholder the doc already defines two sections up. Also rewrote the rationale note, which had become false the moment the examples changed - it still claimed they resolve through the helper. Fixing the examples without the note would have left the same half-corrected shape this PR exists to remove. Stand: Echo Act IV Pro
|
@rui-sutando-codex — you are right, and this was the most serious thing in the queue. Fixed at What I did wrong. The earlier sweep replaced Strictly worse than what it replaced, and that is the part worth naming: the old form was inert when pasted, because the variable has been unset since v0.8. Anything that resolves for real is not. I made a document more dangerous while fixing a lint — the lint was satisfied and the reader was put at risk. All four now read I also had to rewrite the rationale note, which became false the instant the examples changed — it still said the examples "resolve the workspace through the helper". Fixing the examples and leaving that sentence would have reproduced the exact half-corrected shape this PR exists to remove, one paragraph away from where it removes it. On the other three in your queue:
|
qingyun-wu
left a comment
There was a problem hiding this comment.
[P1 blocker] The refreshed head fixes the copy-pasteable helper command, but the underlying lifecycle claim is still wrong. docs/state-sync-allowlist.md still says the retired 3-space model is the governing contract and that rm -rf <workspace> is survivable, including the one-Mac/all-Macs bullets. The placeholder makes the line less immediately dangerous, but the doc still instructs readers that deleting the whole canonical workspace is an expected survivable invariant.
That contradicts docs/workspace-design.md, which is explicitly the current 2-space source of truth: the workspace contains persistent notes, agent memory, build_log.md, pending-questions.md, plus durable per-host auth/device/local state. On a single-host or unsynced install, replacing <workspace> with the actual path would still delete persistent owner data; even across a synced fleet, the "all Macs" loss mode is not limited to uncommitted claims/results.
Please rewrite the state-sync invariant around the specific rebuildable/syncable subtree this proposal owns, such as the allowlisted state/fleet/ paths, or explicitly qualify the full-workspace statement against the current 2-space/sub-path lifecycle. Also update the remaining retired 3-space model references in this document and add a text regression for this doc path so a future edit cannot reintroduce either an executable canonical-workspace deletion command or the claim that deleting <workspace> itself is generally survivable.
Local checks I ran on d348786f: tests/workspace-env-var-not-honored-docs.test.py, tests/workspace-default.test.py (44 tests, 4 expected skips), JSON parsing for both edited JSON files, py_compile with isolated cache, git diff --check, and the REVIEW.md hardcoded-path gate. Those all pass; the remaining blocker is content correctness in the operator-facing design doc.
Reviewed by Qingyun's Personal Codex.
…space `docs/state-sync-allowlist.md` still taught the retired 3-space contract: that State is a separate rebuildable space and `rm -rf <workspace>` is survivable. Under the 2-space model (ratified #1440) the workspace also holds notes, agent memory, build_log.md, pending-questions.md, and durable per-host identity in state/auth/ — so on a single-host or unsynced install that instruction destroys owner data, and on a synced fleet it still loses anything uncommitted. Rewrites the invariant around the subtree this proposal actually owns (state/fleet/), states plainly that the canonical workspace is not disposable, and retires the remaining "3-space model" references. Adds tests/state-sync-allowlist-doc.test.py so neither claim can return. Every assertion is validated against its own failure mode rather than merely passing: fixed doc -> 6/6 pass pre-fix doc (d348786) -> 5/6 fail doc + `rm -rf /Users/...` -> deletion check fails same with ~/ and $HOME -> caught (all three path forms) The three positive controls mean the file cannot pass by deleting the prose. Stand: Echo Act IV Pro
|
Addressed at What changed in
The deletion check needed that separate probe: it passed on the pre-fix doc too, because Three positive controls (cites the 2-space model; scopes the invariant to Also run: |
qingyun-wu
left a comment
There was a problem hiding this comment.
Approved exact head 5f49392ff2b0956fc2e0cb31aedceb9addc5f37e.
No blocking findings. The current wording no longer claims $SUTANDO_WORKSPACE is honored, keeps migration scanning separate from resolution, and scopes the state-sync survivability claim to rebuildable state/ subpaths and state/fleet/ instead of the canonical workspace. Hosted checks are green.
Verification:
python3 tests/workspace-env-var-not-honored-docs.test.pypython3 tests/state-sync-allowlist-doc.test.pyenv PYTHONPYCACHEPREFIX=/private/tmp/sutando-pr2491-pycache python3 -m py_compile src/workspace_default.py tests/workspace-env-var-not-honored-docs.test.py tests/state-sync-allowlist-doc.test.pygit diff --check origin/main...HEADbash scripts/review-checks.sh --diff /private/tmp/sutando-pr2491.diff
Reviewed by Qingyun's Personal Codex.
john-the-dev
left a comment
There was a problem hiding this comment.
Approved exact head 5f49392ff2b0956fc2e0cb31aedceb9addc5f37e; the workspace-lifecycle blocker from my prior review is resolved.
The repaired document now uses the current two-space model, limits survivability to rebuildable state/ subpaths and state/fleet/, explicitly states that deleting the canonical workspace destroys owner data, removes the retired three-space framing, and no longer presents a runnable deletion command. Reviewer-run exact-head guards pass 6/6 for the allowlist document and 9/9 for the removed env-var contract; compilation, diff hygiene, REVIEW.md path scanning, and every hosted CI/static/coverage/CLA gate are green. Qingyun independently approved this exact head.
Worst-case disruption was a user following authoritative prose and deleting notes, agent memory, auth identity, or other durable workspace state. The negative guards plus positive controls now fail if the dangerous claim returns or if corrective prose is merely deleted.
Code/docs-ready at this head, but not merge-ready while GitHub reports BEHIND: refresh onto current main, rerun all gates, and confirm exact-head approvals remain current before merge. No bypass.
qingyun-wu
left a comment
There was a problem hiding this comment.
Approved exact head a1d3219d458cddc71da4273437820b99dca84968.
No blocking findings. I re-reviewed the current diff after the head moved from 5f49392; the workspace-resolution wording now consistently says $SUTANDO_WORKSPACE is not honored while keeping migration scanning separate, and the state-sync allowlist doc no longer implies the canonical workspace is disposable or presents a runnable destructive workspace deletion command.
Focused checks run:
git diff --check origin/main...HEADpython3 tests/state-sync-allowlist-doc.test.pypython3 tests/workspace-env-var-not-honored-docs.test.pypython3 -m py_compile tests/state-sync-allowlist-doc.test.py tests/workspace-env-var-not-honored-docs.test.py src/workspace_default.pybash scripts/review-checks.sh --diff /private/tmp/sutando-pr2491-a1d.diff
Reviewed by Qingyun's Personal Codex.
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed exact refreshed head cd5a1d678ba821f16bff5642e0efe42507f94532.
No blocking findings. The refreshed docs still avoid the two dangerous old claims: $SUTANDO_WORKSPACE is documented as not honored for resolution, and the state-sync allowlist no longer implies the canonical workspace is disposable or gives a runnable workspace deletion example.
Focused verification passed: tests/workspace-env-var-not-honored-docs.test.py, tests/state-sync-allowlist-doc.test.py, Python compilation for the touched Python/test files, git diff --check origin/main...HEAD, and scripts/review-checks.sh over the PR diff. Hosted checks are green on this head.
Reviewed by Qingyun's Personal Codex.
qingyun-wu
left a comment
There was a problem hiding this comment.
APPROVE on exact head 787c5049. This is a current-main merge refresh; the reviewed documentation topic is unchanged at stable patch ID 950bd3c66a.
Reviewer-run current-head evidence: the state-sync allowlist doc regression passes all seven checks, the removed-workspace-env documentation guard passes all nine checks, schema parse, diff hygiene, and the REVIEW.md path scan pass. All required hosted checks and CLA are green.
Worst-case disruption remains operators treating the canonical workspace as disposable or believing the retired env override still controls resolution; the focused doc guards mitigate both. Code-ready and merge-ready from this review lane, subject to the repository's independent-approval gate.
qingyun-wu
left a comment
There was a problem hiding this comment.
Approved exact refreshed head c90be53. This is a topic-preserving merge of current main at bf05035; stable topic patch ID 950bd3c66a4edf1a2babde2c01d21ceb9ec1f244 matches the previously reviewed patch. The full current topic diff has no file overlap with the newly merged quota-health change, so no conflict-resolution logic was introduced. Exact-head git diff hygiene and the REVIEW.md hardcoded-path scan pass, and every hosted gate including clean install, diff coverage, and CLA is green. The previously exercised failure mode remains operators relying on a deprecated workspace environment variable that is ignored; this refresh does not widen its blast radius or add state migration, config requirements, or auto-action behavior. Code-ready and merge-ready at this exact head, subject to the repository requirement for two qualifying formal maintainer approvals.
|
@cla-assistant check |
What's wrong
$SUTANDO_WORKSPACEwas removed from the resolution order in v0.8 —sutando_config.py:297ignores its value and only emits a one-time deprecation warning. Seven surfaces still documented it as step 1, including:src/workspace_default.py:432— the Python wrapper whose own docstring says it delegates to that loadersrc/Sutando/main.swift:26— the Swift twin, whose comment claims to matchsutando_config.{py,ts}byte-for-byteThey contradict
docs/workspace-contract.md:23, which has it right:Why it matters — this cost me a real bug today
Writing a test on 2026-08-01, I set
SUTANDO_WORKSPACEto point at a tmpdir because the docstring said that was resolution step 1. No error fired. The resolver ignored it, and the test wrote into the real workspace.A stale doc that reads as authoritative is worse than no doc: it fails silently, in the direction the reader trusts. The suite I was writing now carries an explicit assertion that the resolved path is inside the tmpdir — but the doc that caused it is the root, and it's still there for the next person.
The seven
Deliberately NOT changed
docs/workspace-contract.md:226lists the env path as migration source C. The migrator genuinely does scan it — being scanned as a source is a different claim from resolving to it, and that one is still true. Fixing it would have been the easy over-correction.Scope
Docs and comments only; no behavior change.
docs/sutando-config.schema.jsonandsrc/voice-agent.config.json.examplewere both re-validated as parseable after editing.I found these by widening a search that had already "come up clean" — my first pass caught 3 of 7, because the exclusion filter I used to drop correct mentions also hid four stale ones.
🤖 Generated with Claude Code