Repository navigation
fix(workspace-modernize): Path B sweep — drop .sutando/workspace namespace across resolvers, helpers, docs (8 commits) - #1490
Conversation
…ps SUTANDO_PRIVATE_DIR + legacy memory-sync fallbacks)
Owner flagged the stale `MEMORY_DIR` chain in `scripts/stage-readiness.sh`
2026-06-06 13:25Z (task-1780752348761):
```bash
MEMORY_DIR="${SUTANDO_MEMORY_DIR:-${SUTANDO_PRIVATE_DIR:-}}"
if [ -z "$MEMORY_DIR" ]; then
if [ -d "$HOME/.sutando/memory-sync" ]; then
MEMORY_DIR="$HOME/.sutando/memory-sync"
else
MEMORY_DIR="$HOME/.sutando-memory-sync"
fi
fi
```
Three legacy artifacts: (a) `SUTANDO_PRIVATE_DIR` deprecated alias
(#870; one-release honor window), (b) `~/.sutando/memory-sync/` pre-v0.3.0
clone path (sync-memory.sh is removed in v0.4.0), (c)
`~/.sutando-memory-sync/` pre-#870 alias.
Modernized: the workspace itself is the sync target as of v0.3.0
(`scripts/sync-workspace.sh`, PR #1445+) — check
`<workspace>/.git/FETCH_HEAD` mtime for freshness. Legacy
`~/.sutando/memory-sync/` retained as a fallback during the v0.3.x
deprecation window so hosts still on `sync-memory.sh` don't lose the
readiness signal; the warning hint includes a migrate-to-workspace-sync
nudge in the legacy path.
Drops `SUTANDO_PRIVATE_DIR` reference (#870's one-release window has
elapsed as of v0.3.0) and `~/.sutando-memory-sync/` (pre-#870).
Workspace resolution goes through the canonical M0 helper (no dead
else-branch fallback — script is already repo-coupled).
Smoke: stage-readiness.sh runs clean and reports
`workspace-sync last sync 33h ago — run 'bash scripts/sync-workspace.sh'`
on this MBP. Net -4 lines after dropping the legacy fork.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…0 helper Owner DM 2026-06-06 13:27Z (task-1780752451373 + task-1780752464055): the docstring still claimed `~/.sutando/workspace` was "the canonical default" and `$SUTANDO_WORKSPACE` was honored. Both wrong post-#1440 / v0.8 — canonical default is `<repo>/workspace/` and the env var is no longer honored for resolution. The module previously re-implemented its own 3-step resolver (env-var, .env-file walk-up, hardcoded `~/.sutando/workspace` default) — all three steps are obsolete post-v0.8. Replaced with a thin delegate that walks up to find `scripts/sutando-config.sh` and shells out to the canonical M0 helper, so this script can never drift from the resolver contract again. The walk-up logic (5-level realpath() bounded walk) is retained because the symlinks-into-the-repo concern still applies (when invoked via `~/.claude/skills/agent-registry/...`). Symptom of the prior bug was silent-data-loss-equivalent: registry writes to wrong dir while readers look at the right one. Smoke: resolves correctly to `/Users/qingyunwu/Documents/github/sutando/workspace` on this MBP. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ce/` Chi-fleet probe (post-#1440) Owner DM 2026-06-06 13:28Z (task-1780752526451 + task-1780752549313: "Why this is still not fixed?"): three sites in the submit-use-case skill still referenced `/Users/wangchi/.sutando/workspace/` as Chi's fleet-detection signal. Pre-#1440 that path existed on Chi's hosts; post-#1440 the workspace is in-repo (`<repo>/workspace/`), so the path-existence probe always returns false and the fleet-detection silently broke. 3 sites updated: - `skills/submit-use-case/scripts/submit_use_case.py` — `is_chi_fleet()` drops the `Path("/Users/wangchi/.sutando/workspace").exists()` check; retains the `SUTANDO_FLEET_OWNER=chi` env signal (Chi sets this once per host in `.env`, no longer needs the path probe). - `skills/submit-use-case/SKILL.md` L59 — prose updated to match. - `skills/submit-use-case/README.md` L64 — same. If Chi-fleet auto-detection regresses (the env var isn't set on a host that used to be detected via the path), the user can re-enable by setting `SUTANDO_FLEET_OWNER=chi` in their `.env` — same setup documented in the README. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
37e5540 to
c5962e4
Compare
…i opinion-requested Path B) Per Mini's #design opinion 2026-06-06 14:42Z + owner's "go ahead with B" 14:44Z: post-v0.8 (#1440) the legacy `.sutando/workspace/` namespace should be fully retired from production resolution, not just from the documented contract. Three sites updated in this commit (the Tier 1+2 contract-bearing changes — Tier 3+ doc-comment sweep to follow): - `src/sutando_config.py:344-352` — no-config-no-repo-root last-ditch fallback now `~/sutando-workspace/` instead of `~/.sutando/workspace/`. Preserves the safety net for ad-hoc invocations outside a checkout while fully dropping the deprecated `.sutando/` namespace. - `src/Sutando/SutandoConfig.swift:228-236` — same change, Swift side. Mirrors Python intentionally per the cross-language contract. - `src/session-handoff.sh:38-49` — drop the `$SUTANDO_WORKSPACE`-aware defensive fallback entirely. Post-v0.8 the env var is no longer honored for workspace resolution; if the M0 helper isn't reachable via either of the two probed paths, fail loud rather than risk writing `session-state.md` to the wrong workspace via the deprecated env value. CI lint `--diff` clean. Smoke: `bash scripts/sutando-config.sh workspace` still resolves correctly to `<repo>/workspace/` on this MBP. Stand: Mini's scope-expansion caveat noted — there's a follow-up sweep of resolver-module docstrings (workspace_default.{py,ts}) + ~9 stale code-comment sites + config.json.example templates to land in subsequent commits before this PR is ready for review. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… resolveAxReadPath (Path B sweep) Owner DM 2026-06-06 14:46Z (task-1780757193114): `src/Sutando/main.swift:1492` had a hardcoded `~/.sutando/memory-sync/skills/personal-deictic/ax-read` candidate path in `resolveAxReadPath()`. That was the pre-v0.3.0 default-private location — `sync-memory.sh`'s rsync target. Post-v0.3.0 (#1440 + the sync-workspace.sh flow), the legacy `.sutando/memory-sync/` clone is deprecated (removed in v0.4.0). Dropped the hardcoded candidate; kept the `$SUTANDO_MEMORY_DIR` + `$SUTANDO_PRIVATE_DIR` env lookups (canonical + legacy alias #876) + the public-repo `<repo>/skills/context-drop/ax-read` fallback. Net behavior on a host whose `$SUTANDO_MEMORY_DIR` is set: identical. On a host where neither env var is set: now falls straight to the public-repo binary instead of probing a deprecated path that's guaranteed not to exist post-migration. Updated the resolution-order doc comment to match + added a v0.3.0 deprecation note. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…act (Path B sweep Tier 3)
`src/workspace_default.{py,ts}` are the historic resolver wrappers; their
module docstrings still described the pre-v0.8 contract ($SUTANDO_WORKSPACE
honored, ~/.sutando/workspace/ as fallback). Per Mini's opinion-requested
B reading + owner directive 2026-06-06: rewrite to match the actual
post-#1440 contract.
- `src/workspace_default.py:1-32` — module docstring now describes the
M0 helper chain (`sutando.config.local.json` → `<repo>/workspace/`),
notes the env-var is no longer honored, points readers at
`src.sutando_config.resolve_workspace` as the canonical entry point,
and explains that `default_workspace_dir` is a test-only export.
- `src/workspace_default.py:23` — `_DEFAULT_SUBPATH` updated from
`(".sutando", "workspace")` to `("sutando-workspace",)`. Matches the
new `~/sutando-workspace/` last-ditch fallback in `sutando_config.py`.
- `src/workspace_default.py:46` — `default_workspace_dir()` docstring
rewritten to clarify it returns the post-v0.8 fallback, NOT the
production default.
- `src/workspace_default.ts:1-22` — module docstring refreshed with the
same content, TS-flavored.
- `src/workspace_default.ts:24-45` — `resolveWorkspace()` docstring
rewritten: drops the "$SUTANDO_WORKSPACE env var (legacy escape
hatch; warn once)" claim, notes the env-var is no longer honored,
describes the warn-and-ignore + auto-migrate behavior.
Behavior change: callers using `default_workspace_dir()` for the
no-config-no-repo-root fallback now get `~/sutando-workspace/` instead
of `~/.sutando/workspace/`. Tests use this via `patch.object(...)` so
they're unaffected by the underlying path change.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e/ from skill examples (Path B Tier 5) Owner DM 2026-06-06 14:50Z (task-1780757426171): the `_comment` field in `skills/phone-conversation/config.json.example` (and the sibling `skills/discord-voice/config.json.example`) still described the pre-v0.8 contract: "lives at \$SUTANDO_WORKSPACE/config/foo.json (default ~/.sutando/workspace/config/foo.json)". Both wrong post-#1440. Rewrote to point at the canonical resolver: "<workspace>/config/foo.json (the workspace resolves via `bash scripts/sutando-config.sh workspace`, default <repo>/workspace/)". Drops both the deprecated env-var mention and the deprecated `.sutando/` namespace fallback in one stroke. These are user-facing template files copied into the workspace on first run — getting the prose right matters because the `_comment` field is what a user reads when they open the live config to edit it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… post-v0.8 contract (Path B Tier 4) Path B sweep round-up for the 8 code-comment sites where the prose still described the pre-v0.8 contract: - `skills/call-diagnostics/scripts/diagnose.py:38` — "(~/.sutando/workspace)" → "post-v0.8 default `<repo>/workspace/`" - `src/archive-stale-results.py:37-38` — "$SUTANDO_WORKSPACE (default ~/.sutando/workspace/)" → "the resolved workspace (post-v0.8 default `<repo>/workspace/`)" - `src/inline-tools.ts:659-661` — "$SUTANDO_WORKSPACE/state/ (default ~/.sutando/workspace/state/)" → "<workspace>/state/ (default <repo>/workspace/ post-v0.8)" - `src/web-client.ts:3108-3113` — same shape as inline-tools - `src/util_paths.py:65-66` — docstring updated: "canonical default (~/.sutando/workspace/)" → "post-v0.8 canonical default (<repo>/workspace/)"; notes $SUTANDO_WORKSPACE no longer honored - `src/util_paths.ts:13-18` — same shape - `src/health-check.py:847-850` — "~/.sutando/workspace/notes" → "<workspace>/notes"; v0.8 default note - `src/voice-agent.ts:19, 99-100` — header env-doc + inline comment both refreshed Pure prose; no behavior change. CI lint --diff clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
.sutando/workspace namespace across resolvers, helpers, docs (8 commits)
…v0.8 sutando-workspace (Path B sweep)
CI test failure on `f7f5ce7`: `test_default_is_dot_sutando_workspace_under_home`
expected `default_workspace_dir()` to return `~/.sutando/workspace/`. Per the
B sweep's `_DEFAULT_SUBPATH` change (`(".sutando", "workspace")` →
`("sutando-workspace",)`), the function now returns `~/sutando-workspace/`.
Renamed the test method to match the new behavior; updated all three
assertion lines + the equality-on-full-path; added a docstring tying the
test to the post-v0.8 contract.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…orkspace fallbacks (Path B sweep) Owner DM 2026-06-06 14:57Z (task-1780757867862): `src/watch-tasks-stream.sh` had a 4-tier fallback chain for both TASKS_DIR and STATE_DIR — positional arg → M0 helper → `$SUTANDO_WORKSPACE` env → hardcoded `$HOME/.sutando/workspace/`. Post-v0.8 (#1440 + Mini opinion-requested 2026-06-06) the env-var path is no longer honored and the `.sutando/workspace/` namespace is retired. Replaced both blocks with a single-path resolver: M0 helper required, fail-loud if not reachable. Matches the contract change applied to `session-handoff.sh` earlier in this PR. Also removed `src/watch-tasks-stream.sh` from the lint `ALLOWED` regex in `scripts/lint-workspace-resolution.sh` — the file no longer needs a defense-in-depth exemption now that the legacy paths are gone. Behavior change: a host where the sutando checkout is broken/incomplete will now error visibly with "cannot resolve workspace" instead of silently watching `~/.sutando/workspace/tasks/` (which would be empty post-migration and produce no events — owner DMs would land silently in the bridges' workspace dir). This matches the divergence-prevention rationale in the surrounding comment, but enforces it strictly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Path B sweep tail)
`skills/discord-voice/scripts/join_trigger.py:46` had a docstring still
describing the pre-v0.8 resolver chain ("$SUTANDO_WORKSPACE env, else
~/.sutando/workspace/"). Refreshed to point at the canonical helper +
note the env-var is no longer honored post-v0.8. Behavior unchanged —
this is the docstring only; the actual code already prefers the helper.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0f9e625 to
e3500f8
Compare
…orkspace-sync (Path B sweep cont'd)
Owner DM 2026-06-06 15:08Z (task-1780758535617): grep for "memory-sync"
turned up 19 files. 4 had stale references that should now point at the
v0.3.0 canonical workspace-sync flow + deprecation note:
- `README.md:218` — multi-machine sync row pointed at deleted
`docs/memory-sync.md` and recommended `sync-memory.sh` as primary path.
Updated to: vault config + `sync-workspace.sh --init`, with link to
`docs/workspace-sync.md`; called out the v0.4.0 sync-memory.sh removal.
- `skills/relay/SKILL.md:33` — "Sync via the existing memory-sync engine"
→ "Sync via the workspace-sync engine (`scripts/sync-workspace.sh`)";
added deprecation note.
- `skills/catchup-after-startup/SKILL.md:57` — "across multiple cores
via memory-sync" → "via workspace-sync".
- `docs/state-sync-allowlist.md:171` — link to deleted `docs/memory-sync.md`
→ `docs/workspace-sync.md` (with note that it's canonical as of v0.3.0).
Remaining 15 of 19 are either (a) intentional historical / deprecation
prose (CHANGELOG.md, scripts/sync-memory.sh, scripts/sync-workspace.sh
--migrate-from-legacy block, docs/workspace-sync.md deprecation section,
tests/sync-{memory,workspace}-migration.test.sh), (b) already addressed
in this PR (stage-readiness.sh, main.swift), or (c) describing a real
concept that's separate from the legacy clone (skills/MANIFEST.md,
context-drop/Package.swift, health-check.py legacy-path lookup,
inline-tools.ts skills location, workspace_default.py symlink comment,
sutando-migrate.sh conflict-resolution comment, schedule-crons example
narrative).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
@cla-assistant check |
john-the-dev
left a comment
There was a problem hiding this comment.
Reviewed the workspace-modernize Path B sweep.
What I checked:
workspace_default.py:_DEFAULT_SUBPATHcorrectly updated from('.sutando', 'workspace')to('sutando-workspace',)for the post-v0.8 fallback.default_workspace_dir()docstring accurately scopes it to tests + ad-hoc; production callers route throughsutando_config.resolve_workspace. Sound.workspace_default.ts: Resolution order in both the module docstring and theresolveWorkspace()JSDoc now correctly drops$SUTANDO_WORKSPACEas step 1. Wrapper preserved for callsite compatibility — no callers need changes. Sound.util_paths.py/util_paths.ts: Comments updated to reflect post-v0.8 resolution. No behavioral changes, just doc drift fixed. Good.stage-readiness.sh: Legacy$SUTANDO_PRIVATE_DIR/~/.sutando/memory-sync//~/.sutando-memory-sync/chain replaced with\<workspace\>/.git/FETCH_HEADmtime. Correct — workspace is the sync target post-v0.3.0.
Dependency verified: PR #1478 (per-source migration sentinels) is merged (2026-06-06T03:26Z) — the auto-migration path this PR relies on is live.
Risk check: $SUTANDO_WORKSPACE is not set in the local .env — clean migration path, no legacy re-migration loop risk.
One question for the author: util_paths.py comment says '$SUTANDO_WORKSPACE is no longer honored for resolution per #1440' — is src/sutando_config.py already merged with #1440, or is that a forward reference to a follow-on PR? Worth confirming the import chain is complete before merging.
Overall: clean doc+config sweep, no behavioral regressions visible, dependency satisfied. Approve-worthy pending confirmation on the #1440 import.
john-the-dev
left a comment
There was a problem hiding this comment.
Reviewed the workspace-modernize Path B sweep.
What I checked:
workspace_default.py:_DEFAULT_SUBPATHcorrectly updated to('sutando-workspace',)for the post-v0.8 fallback.default_workspace_dir()docstring accurately scopes it to tests + ad-hoc. Sound.workspace_default.ts: Resolution order in both docstring andresolveWorkspace()JSDoc drops$SUTANDO_WORKSPACEas step 1 correctly. Wrapper preserved for callsite compat. Sound.util_paths.py/util_paths.ts: Comments updated to reflect post-v0.8 resolution. No behavioral changes.stage-readiness.sh: Legacy$SUTANDO_PRIVATE_DIR/~/.sutando/memory-sync//~/.sutando-memory-sync/chain replaced with<workspace>/.git/FETCH_HEADmtime. Correct — workspace is the sync target post-v0.3.0.
Dependency verified: PR #1478 (per-source migration sentinels) merged 2026-06-06T03:26Z — the auto-migration path is live.
Risk check: $SUTANDO_WORKSPACE not set in local .env — clean migration, no re-migrate loop risk.
One question: util_paths.py comment says "$SUTANDO_WORKSPACE is no longer honored per #1440" — is src/sutando_config.py already merged with #1440, or a follow-on? Worth confirming the import chain is complete before merging.
Overall: clean doc+config sweep, no behavioral regressions visible, dependency satisfied. Approve-worthy pending #1440 import confirmation.
john-the-dev
left a comment
There was a problem hiding this comment.
Reviewed the workspace-modernize Path B sweep.
workspace_default.py: _DEFAULT_SUBPATH correctly updated to ('sutando-workspace',) for the post-v0.8 fallback. default_workspace_dir() docstring accurately scopes it to tests + ad-hoc. Sound.
workspace_default.ts: Resolution order drops SUTANDO_WORKSPACE as step 1 correctly. Wrapper preserved for callsite compat. Sound.
util_paths.py / util_paths.ts: Comments updated to reflect post-v0.8 resolution. No behavioral changes.
stage-readiness.sh: Legacy SUTANDO_PRIVATE_DIR / ~/.sutando/memory-sync / ~/.sutando-memory-sync chain replaced with workspace .git/FETCH_HEAD mtime. Correct - workspace is the sync target post-v0.3.0.
Dependency verified: PR #1478 (per-source migration sentinels) merged 2026-06-06T03:26Z - auto-migration path is live.
Risk check: SUTANDO_WORKSPACE not set in local .env - clean migration, no re-migrate loop risk.
One question for author: util_paths.py comment says SUTANDO_WORKSPACE is no longer honored per #1440 - is src/sutando_config.py already merged with #1440, or is that a forward reference to a follow-on PR? Worth confirming the import chain is complete before merging.
Overall: clean doc+config sweep, no behavioral regressions visible, dependency satisfied. Approve-worthy pending #1440 import confirmation.
|
@john-the-dev — thanks for the careful review. Confirming the import chain is complete: The Lucy + Mini + Pro already approved earlier today (Mini's LGTM at 14:58Z: "findings: none blocking"). Holding for owner merge. |
Summary
Owner-flagged dead-fallback chain in
scripts/stage-readiness.sh2026-06-06 13:25Z. The script's section 8 (sync-age check) was reading from$SUTANDO_PRIVATE_DIR→~/.sutando/memory-sync/→~/.sutando-memory-sync/— three legacy artifacts from the pre-v0.3.0 world.Modernization
The workspace itself is the sync target as of v0.3.0 (
scripts/sync-workspace.sh, PR #1445+). Freshness now comes from<workspace>/.git/FETCH_HEADmtime. Legacy~/.sutando/memory-sync/clone retained as a one-release fallback during the v0.3.xsync-memory.shdeprecation window (removed in v0.4.0); the warning hint in the legacy path includes a migrate-to-workspace-sync nudge.What's dropped
SUTANDO_PRIVATE_DIRenv-var reference — workspace-design: rename SUTANDO_PRIVATE_DIR → SUTANDO_MEMORY_DIR #870's one-release honor window has elapsed as of v0.3.0.~/.sutando-memory-sync/pre-workspace-design: rename SUTANDO_PRIVATE_DIR → SUTANDO_MEMORY_DIR #870 path — older fleet hosts had this; their next sync auto-migrates anyway.What's preserved
scripts/sutando-config.sh workspace) — no dead else-branch fallback (script is repo-coupled).~/.sutando/memory-sync/fallback for v0.3.x hosts still onsync-memory.sh—$SUTANDO_MEMORY_DIRenv override honored for that path.Smoke
CI lint
--diffclean — no new workspace-resolution anti-patterns introduced.Stats
1 file, +18/-22 (net -4 after the legacy fork collapses).
🤖 Generated with Claude Code