Skip to content

feat: rename SUTANDO_PRIVATE_DIR → SUTANDO_MEMORY_DIR (closes #870) - #876

Merged
sonichi merged 1 commit into
mainfrom
feat/sutando-memory-dir-rename
May 19, 2026
Merged

sonichi merged 1 commit into
mainfrom
feat/sutando-memory-dir-rename

Conversation

@qingyun-wu

Copy link
Copy Markdown
Collaborator

Summary

  • Renames the Memory-space env var from SUTANDO_PRIVATE_DIR to SUTANDO_MEMORY_DIR so vocabulary matches the 3-space mental model (Code / State / Memory) ratified in docs: add workspace-design.md — 3-space model RFC (Code/State/Memory) #858 Decision 2.
  • One-release alias: SUTANDO_PRIVATE_DIR continues to work as a fallback, with a deprecation warning emitted to stderr on every read (cron / launchd miss startup-only warnings — every-read is intentional).
  • 10 Python + 5 TS unit tests cover precedence, legacy fallback, deprecation-on-every-read, and the both-set-prefer-new case.

What changed

New helper (single source of truth for the lookup):

  • Python — _memory_dir_env() in src/util_paths.py
  • TypeScript — memoryDirEnv() exported from src/util_paths.ts

Both return SUTANDO_MEMORY_DIR when set, else SUTANDO_PRIVATE_DIR with a DEPRECATION warning, else None/undefined.

Call-site updates:

  • src/util_paths.{py,ts} — personal_path() / personalPath() + shared_personal_path() / sharedPersonalPath() route through the helper.
  • src/inline-tools.ts — loadSkillManifestTools(), loadCoreDocumentedSkills(), and the open_file tool description.
  • src/voice-agent.ts — voice-context dynamic loader.
  • skills/phone-conversation/scripts/conversation-server.ts — inline personalPath() twin (kept inline to avoid pulling main repo's util_paths.ts through the skill's import surface).
  • src/session-handoff.sh — passes both env vars through to the python child.
  • Docs: CLAUDE.md, docs/workspace-contract.md, skills/MANIFEST.md.

Risk to existing users

None. Anyone with only SUTANDO_PRIVATE_DIR set:

  1. Keeps working — value still resolves correctly through the legacy path.
  2. Sees a one-line DEPRECATION warning on stderr per read.
  3. Can migrate at their own pace by renaming the env var in their shell rc / launchd plist / .env.

The legacy alias will be removed in the next release.

Test plan

  • python3 tests/util-paths-memory-dir.test.py — 10/10 pass
  • npx tsx --test tests/util-paths-memory-dir.test.ts — 5/5 pass
  • python3 tests/workspace-default.test.py — still 27/27 pass
  • npx tsc --noEmit clean
  • CI on the PR

Closes #870

🤖 Generated with Claude Code

@liususan091219 liususan091219 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid rename + deprecation alias pattern. Three notes:

1. Every-read deprecation warning may flood stderr in hot paths. The comment explicitly defends this ("cron environments miss startup-only warnings, so logging at every resolution is intentional"). Fair for cron — cron runs the script once per fire, so every-read is once-per-fire. But for long-running daemons (voice-agent, discord-bridge, telegram-bridge, slack-bridge) that call personalPath() / sharedPersonalPath() repeatedly, this becomes log spam. Suggest a module-level "warned-once-per-process" sentinel: still fires once per cron invocation (which is what cron needs), but doesn't flood the daemon logs. Two extra lines.

2. loadSkillManifestTools() resolves memoryDirEnv() at module-init time (in inline-tools.ts:1037ish) — fine as long as no test mutates process.env.SUTANDO_MEMORY_DIR between agent restarts, which I don't think any does. Just calling out the import-time read so it's a deliberate choice, not an accidental capture.

3. conversation-server.ts keeps its inline personalPath() twin with manually-duplicated deprecation-warn code. PR body acknowledges this is intentional (skill import-surface isolation). When/if hostLabel() logic shifts in #877 follow-ups, both sites need updates — worth a // keep in sync with src/util_paths.ts:hostLabel() comment over the inline twin to make the duplication discoverable.

Docs are thorough (CLAUDE.md / workspace-contract.md / MANIFEST.md all updated, 4 spots touched). 10 Py + 5 TS tests is right-sized for a rename + alias. LGTM net.

@vidhuUC vidhuUC left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE. Clean env rename with proper one-release backward compat. All the callsites I spot-checked (CLAUDE.md, workspace-contract.md, MANIFEST.md, conversation-server.ts) consistently use the new name with legacy fallthrough commentary. The pattern SUTANDO_MEMORY_DIR || SUTANDO_PRIVATE_DIR is applied uniformly. CI green.

Per workspace-design RFC #858 (Decision 2), the env var for the Memory
space is renamed from `SUTANDO_PRIVATE_DIR` to `SUTANDO_MEMORY_DIR` so the
vocabulary matches the 3-space mental model (Code / State / Memory).

One-release alias period:
- The new name `SUTANDO_MEMORY_DIR` is the canonical lookup.
- The old name `SUTANDO_PRIVATE_DIR` continues to work as a fallback.
- A deprecation warning fires to stderr on every read of the legacy var
  (not just at startup — cron / launchd environments would otherwise miss
  startup-only warnings and silently sit on the legacy name).

Resolution helper:
- Python: `_memory_dir_env()` in src/util_paths.py.
- TypeScript: `memoryDirEnv()` exported from src/util_paths.ts.
- Both: prefer the new var, fall back to the legacy one with the warning.

Call-site updates:
- src/util_paths.py — `_private_machine_dir()` + `shared_personal_path()` route through the helper.
- src/util_paths.ts — `personalPath()` + `sharedPersonalPath()` route through the helper.
- src/inline-tools.ts — `loadSkillManifestTools()` + `loadCoreDocumentedSkills()` + open_file doc text.
- src/voice-agent.ts — voice-context loader.
- skills/phone-conversation/scripts/conversation-server.ts — inline `personalPath()` twin.
- src/session-handoff.sh — passes both env vars through to the python child.
- Docs: CLAUDE.md, docs/workspace-contract.md, skills/MANIFEST.md.

Tests: 10 Python + 5 TS unit tests covering precedence, legacy fallback,
deprecation warning, and the every-read guard.

Zero existing-user breakage: anyone with only `SUTANDO_PRIVATE_DIR` set
keeps working through the deprecation window, sees the warning, and can
migrate by renaming the env var.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@qingyun-wu
qingyun-wu force-pushed the feat/sutando-memory-dir-rename branch from ced1ce6 to be885fa Compare May 19, 2026 18:01
@sonichi
sonichi merged commit 210dde3 into main May 19, 2026
2 checks passed
@sonichi
sonichi deleted the feat/sutando-memory-dir-rename branch May 19, 2026 19:08
qingyun-wu added a commit that referenced this pull request May 19, 2026
Plan-only document. Owner asked for a release-process + migration-framework
proposal in #dev. Sutando-Mini and I split it: Mini covers when-to-cut + tag
conventions; this doc covers what-goes-in + CHANGELOG culture + migration
framework + joint engine↔product coupling section.

270 lines covering:
1. CHANGELOG culture — 5 categories, author-curated + release-curator-pruned.
2. Migration framework — numbered migrations/NNNN-*.{sh,py},
   state/schema-version.json, idempotent startup-runner, 1-release
   backward-compat overlap (formalizes the ad-hoc #876 alias pattern),
   per-migration tempdir tests, 3-phase rollout.
3. Engine↔product coupling — Option A loose coupling (recommended) vs
   Option B lockstep. Engine = sonichi/sutando, Product = Sutando.app.
4. 4 open questions for owner.

Located under docs/ (parallel to docs/workspace-design.md's RFC pattern),
not notes/ (gitignored). Promotion to docs/release-process.md waits on
owner + Chi greenlight and Mini's companion proposal.

No code shipped. Plan only.
sonichi added a commit that referenced this pull request May 21, 2026
…906)

* docs: release process proposal (qingyun-sutando half)

Plan-only document. Owner asked for a release-process + migration-framework
proposal in #dev. Sutando-Mini and I split it: Mini covers when-to-cut + tag
conventions; this doc covers what-goes-in + CHANGELOG culture + migration
framework + joint engine↔product coupling section.

270 lines covering:
1. CHANGELOG culture — 5 categories, author-curated + release-curator-pruned.
2. Migration framework — numbered migrations/NNNN-*.{sh,py},
   state/schema-version.json, idempotent startup-runner, 1-release
   backward-compat overlap (formalizes the ad-hoc #876 alias pattern),
   per-migration tempdir tests, 3-phase rollout.
3. Engine↔product coupling — Option A loose coupling (recommended) vs
   Option B lockstep. Engine = sonichi/sutando, Product = Sutando.app.
4. 4 open questions for owner.

Located under docs/ (parallel to docs/workspace-design.md's RFC pattern),
not notes/ (gitignored). Promotion to docs/release-process.md waits on
owner + Chi greenlight and Mini's companion proposal.

No code shipped. Plan only.

* docs(rfc #906): add Overview + Motivations sections per owner ask

Owner asked in two consecutive Discord messages (task-1779223601794 +
task-1779223627953):
- "Update the RFC to include motivations"
- "Give an overview picture of what we are trying to do, why it matters"

Two new sections at the top of the proposal:

1. **Overview** — TL;DR framing. What (release process + migration
   framework), why it matters (rollback discipline, commercial pinning,
   silent-breakage prevention, bot coordination, continuous gate), what
   it does NOT try to do (time-based cadence, backward migrations, data
   re-encoding, engine-product lockstep), and the co-author split.

2. **Motivations** — 5 numbered motivations (M1-M5):
   - M1: named snapshots of known-good states
   - M2: state-format changes happen often, silently breaking users
   - M3: commercial deploys need a pin point
   - M4: two bots are coordinating, need a shared spec
   - M5: release process IS the migration-test framework

Plus an explicit **Non-goals** subsection listing what we're deliberately
NOT solving here (time cadence, backward migrations, etc.) — anchors
scope for future contributors.

No content change to Parts 1-2 or the joint section; just preamble that
explains why before the design pages dive in.

* docs(rfc): add Mini's half — when to cut + tag conventions

Half of the consolidated release-process RFC (#906). Covers:
- When to cut a release (feature-completion trigger, owner cuts the tag)
- SemVer vs CalVer (SemVer; engine-vX.Y.Z prefix)
- Tag on main vs release branch (tag on main; no release branch)
- Git tag vs GitHub Release (both — tag is anchor, Release is narrative)
- What to cut next (aligned with qingyun-sutando: cut v0.1.0 now,
  framework as v0.1.1)
- Explicit coupling table mapping every joint surface to the
  corresponding section in qingyun-sutando's half

Plan-only. No code shipped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(rfc #906): remove commercial framing — OSS readers may not be from AG2

Owner asked (task-1779223950387): "Remove the part about 'Commercial
pinning'. Remember OSS user may not care about commercial things as
they are not necessarily from Ag2 the company."

Changes:
- Overview "Commercial pinning" bullet → "Pinning for anyone building
  on top" (forks, downstream consumers, sister-node fleets — generic
  framing that includes but doesn't assume AG2-commercial users).
- M1 dropped "(commercial waitlist, OSS contributors, sister-node
  fleets)" parenthetical — just "users."
- Removed entire M3 "Commercial deploys need a pin point" motivation
  (was specifically about sutando.ag2.ai install instructions). M4/M5
  renumbered to M3/M4.
- Joint section's bottom bullet reworded: "Customer who hits a bug
  correlates ..." → "Anyone running the bundle who hits a bug ...
  Downstream consumers can pin install instructions to an engine tag."

Per memory feedback_internal_vs_public_docs.md — the sonichi/sutando
repo is PUBLIC; specific paths and commercial framings belong in
INTERNAL (#dev, workspace, owner DM), not in landed docs.

* docs(rfc #906): owner-quote line removed; M3 restored as downstream-pin-point (AG2-internal facing too)

Owner two follow-ups:

1. task-1779224091789: "Remove wordings like this — Owner (Chi)
   explicitly said 'Plan and make proposals first.'" — the preamble
   quote framing owner's instruction directly was leaking internal
   chatter into a public-repo doc. Replaced with neutral "This is half
   of a co-drafted proposal" framing.

2. task-1779224131237: "M3. Commercial deploys need a pin point —
   This is AG2 internal facing as well." — clarified that the doc
   serves both OSS contributors AND AG2-internal-facing audiences
   (sutando.ag2.ai, packaged bundles, commercial integrators). Restored
   as M3, generalized to "Pin points for downstream consumers and
   bundle deploys" — explicitly enumerates forks, sister-node fleets,
   Sutando.app, AG2-internal deploys, commercial integrators. M4/M5
   renumber accordingly (Two bots coordinating + release-process-is-
   migration-test).

Companion file `docs/release-process-proposal-mini.md` landed in
7d4f260 (Mini's half: when to cut + tag conventions). Both halves now
live on this PR's branch.

* docs(rfc #906): consolidated doc merging Mini's + qingyun-sutando's halves

Claimed the consolidation step in #dev bot-coord. Merges both source
files (both preserved on the branch as authorship record) into a single
review surface for Chi + Qingyun.

Structure:
- Top-of-doc overview + motivations + non-goals (combined from both).
- Part 1-4 from Mini (when to cut, SemVer + tag namespace, tag-on-main
  no release branch, git tag + GitHub Release + hard/soft gates).
- Part 5-6 from qingyun-sutando (CHANGELOG culture, migration framework
  with numbered migrations/state/runner/tests/phasing).
- Part 7 joint section (engine ↔ product coupling, Option A recommended).
- Part 8 "what to cut next" — both halves landed on (c): cut engine-v0.1.0
  now with manual migration notes, framework as v0.1.1.
- Coupling table verifying no double-coverage between the two halves.
- 5 consolidated open questions for owner (was 4 from each half; deduped
  + added Mini's signed-tags question).
- Next move: owner + Chi review, pick answers, then promote to
  docs/release-process.md + open implementation issues.

Source halves stay on the branch:
- docs/release-process-proposal-mini.md
- docs/release-process-proposal-qingyun-sutando.md

If owner greenlights, this consolidated doc moves to docs/release-process.md
and the two source files can be archived (or kept as authorship record).

No code shipped. Plan only.

* docs(rfc #906): integrate review-round resolutions

Integrates the 3 reviews on #906:
- Bassil (cold-review 2026-05-20 06:28) — 4-question picks aligned with
  Chi's later owner-pick; reinforces option (c) cut-now-with-manual-notes
  + framework as next-release primary payload.
- Lucy (review 11:31) — 3 implementation questions on the migration
  framework: multi-core race on schema-version.json, merge-order
  collision on migration numbers, health-check gate on fresh clone.
- Chi (sub-agent draft 19:28 + owner-pick 20:30) — final calls on
  3 open questions: bare v0.MINOR.PATCH (drop engine- prefix),
  working-state when-to-cut (not commit-count), unsigned tags for
  v0.1.x (signed deferred).

Concrete changes in the doc:
- Sweep `engine-vX.Y.Z` → bare `vX.Y.Z` everywhere (frontmatter
  status, body prose, schema-version.json example, alias timeline,
  coupling section, open-question text). 13 occurrences.
- Rewrite "Open questions for owner" as "RESOLVED 2026-05-20"
  section with each pick + reasoning (§§ 4a/4b for when-to-cut
  refinement + GPG deferral).
- §2.7 — replace cut-gate language with Chi's working-state
  framing + clarify health-check scope (tagging install, not
  fresh clone — addresses Lucy Q3).
- §2.8 (new) — Concurrency & ordering: resolve Lucy Q1
  (migrations run as pre-pool step in startup.sh, single-writer-
  by-construction; runner also called from resolve_workspace as
  idempotent fallback for manual sessions) and Q2 (number reserved
  at merge time, pre-merge CI check fails on collision, mirrors
  Rails/Alembic).
- Add "Future hardening" section gathering deferred items
  (signed tags, backward migrations, data re-encoding, PR-template
  migration checklist, docs/install.md fresh-install path,
  docs/release-process.md promotion).
- Rewrite "Next move" to reflect Chi's "mergeable" verdict + the
  Phase 1 framework PR sequence + cut v0.1.0 + workspace contract
  A/B as forcing function for migration 0002.
- Frontmatter: reviewers_integrated field naming the 3 reviews,
  status updated to "open questions resolved; pending merge",
  intro callout quoting Chi's mergeable line.

Plan-only doc — no code shipped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(rfc): sweep consolidated doc to reflect Chi's 2026-05-20 owner-picks

The qingyun-sutando half integrated the review-round decisions, but the
consolidated doc — the file that promotes to docs/release-process.md —
was never swept and still contradicted them. Chi's stated merge bar was
"once the RFC text reflects these, it's mergeable"; this makes it so.

- engine-vX.Y.Z → bare vX.Y.Z everywhere (decision 1).
- §2.2 rewritten: bare tag namespace, no engine- prefix; the namespace
  collision the prefix defended against doesn't exist (product ships
  from its own repo / tag line).
- Part 1.1: add the working-state precondition (decision 4a) — CI green,
  no release-blocker, no half-finished migration; quality gate not count.
- "Consolidated open questions" → "Consolidated decisions (resolved)"
  with all 5 answers recorded inline.
- "Next move" + coupling table + frontmatter status updated to reflect
  that nothing is owner-gated anymore.

Proposal files (mini / qingyun) left as the authorship record per the
consolidated doc's own header; the mini half still reads `engine-` —
flag if it should be swept too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(rfc): sweep mini proposal half to bare vX.Y.Z (consistency with #906 decisions)

Companion to e248cc6 (consolidated-doc sweep). The mini proposal half
still recommended the `engine-` tag prefix — the option the 2026-05-20
review round overrode. The qingyun-sutando half was already swept to
bare `vX.Y.Z`, so leaving the mini half unswept left the PR internally
inconsistent.

- engine-vX.Y.Z → bare vX.Y.Z throughout.
- §2.2 rewritten: records that this half's engine-prefix recommendation
  was overridden, states the resolved bare-vX.Y.Z decision + rationale.
- Coupling table + open-questions section marked resolved.

Per Chi's "up to you" call on whether to sweep the mini half. All three
release-process docs now consistent with the resolved decisions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Chi Wang <4250911+sonichi@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…#870) (sonichi#876)

Per workspace-design RFC sonichi#858 (Decision 2), the env var for the Memory
space is renamed from `SUTANDO_PRIVATE_DIR` to `SUTANDO_MEMORY_DIR` so the
vocabulary matches the 3-space mental model (Code / State / Memory).

One-release alias period:
- The new name `SUTANDO_MEMORY_DIR` is the canonical lookup.
- The old name `SUTANDO_PRIVATE_DIR` continues to work as a fallback.
- A deprecation warning fires to stderr on every read of the legacy var
  (not just at startup — cron / launchd environments would otherwise miss
  startup-only warnings and silently sit on the legacy name).

Resolution helper:
- Python: `_memory_dir_env()` in src/util_paths.py.
- TypeScript: `memoryDirEnv()` exported from src/util_paths.ts.
- Both: prefer the new var, fall back to the legacy one with the warning.

Call-site updates:
- src/util_paths.py — `_private_machine_dir()` + `shared_personal_path()` route through the helper.
- src/util_paths.ts — `personalPath()` + `sharedPersonalPath()` route through the helper.
- src/inline-tools.ts — `loadSkillManifestTools()` + `loadCoreDocumentedSkills()` + open_file doc text.
- src/voice-agent.ts — voice-context loader.
- skills/phone-conversation/scripts/conversation-server.ts — inline `personalPath()` twin.
- src/session-handoff.sh — passes both env vars through to the python child.
- Docs: CLAUDE.md, docs/workspace-contract.md, skills/MANIFEST.md.

Tests: 10 Python + 5 TS unit tests covering precedence, legacy fallback,
deprecation warning, and the every-read guard.

Zero existing-user breakage: anyone with only `SUTANDO_PRIVATE_DIR` set
keeps working through the deprecation window, sees the warning, and can
migrate by renaming the env var.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…onichi#906)

* docs: release process proposal (qingyun-sutando half)

Plan-only document. Owner asked for a release-process + migration-framework
proposal in #dev. Sutando-Mini and I split it: Mini covers when-to-cut + tag
conventions; this doc covers what-goes-in + CHANGELOG culture + migration
framework + joint engine↔product coupling section.

270 lines covering:
1. CHANGELOG culture — 5 categories, author-curated + release-curator-pruned.
2. Migration framework — numbered migrations/NNNN-*.{sh,py},
   state/schema-version.json, idempotent startup-runner, 1-release
   backward-compat overlap (formalizes the ad-hoc sonichi#876 alias pattern),
   per-migration tempdir tests, 3-phase rollout.
3. Engine↔product coupling — Option A loose coupling (recommended) vs
   Option B lockstep. Engine = sonichi/sutando, Product = Sutando.app.
4. 4 open questions for owner.

Located under docs/ (parallel to docs/workspace-design.md's RFC pattern),
not notes/ (gitignored). Promotion to docs/release-process.md waits on
owner + Chi greenlight and Mini's companion proposal.

No code shipped. Plan only.

* docs(rfc sonichi#906): add Overview + Motivations sections per owner ask

Owner asked in two consecutive Discord messages (task-1779223601794 +
task-1779223627953):
- "Update the RFC to include motivations"
- "Give an overview picture of what we are trying to do, why it matters"

Two new sections at the top of the proposal:

1. **Overview** — TL;DR framing. What (release process + migration
   framework), why it matters (rollback discipline, commercial pinning,
   silent-breakage prevention, bot coordination, continuous gate), what
   it does NOT try to do (time-based cadence, backward migrations, data
   re-encoding, engine-product lockstep), and the co-author split.

2. **Motivations** — 5 numbered motivations (M1-M5):
   - M1: named snapshots of known-good states
   - M2: state-format changes happen often, silently breaking users
   - M3: commercial deploys need a pin point
   - M4: two bots are coordinating, need a shared spec
   - M5: release process IS the migration-test framework

Plus an explicit **Non-goals** subsection listing what we're deliberately
NOT solving here (time cadence, backward migrations, etc.) — anchors
scope for future contributors.

No content change to Parts 1-2 or the joint section; just preamble that
explains why before the design pages dive in.

* docs(rfc): add Mini's half — when to cut + tag conventions

Half of the consolidated release-process RFC (sonichi#906). Covers:
- When to cut a release (feature-completion trigger, owner cuts the tag)
- SemVer vs CalVer (SemVer; engine-vX.Y.Z prefix)
- Tag on main vs release branch (tag on main; no release branch)
- Git tag vs GitHub Release (both — tag is anchor, Release is narrative)
- What to cut next (aligned with qingyun-sutando: cut v0.1.0 now,
  framework as v0.1.1)
- Explicit coupling table mapping every joint surface to the
  corresponding section in qingyun-sutando's half

Plan-only. No code shipped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(rfc sonichi#906): remove commercial framing — OSS readers may not be from AG2

Owner asked (task-1779223950387): "Remove the part about 'Commercial
pinning'. Remember OSS user may not care about commercial things as
they are not necessarily from Ag2 the company."

Changes:
- Overview "Commercial pinning" bullet → "Pinning for anyone building
  on top" (forks, downstream consumers, sister-node fleets — generic
  framing that includes but doesn't assume AG2-commercial users).
- M1 dropped "(commercial waitlist, OSS contributors, sister-node
  fleets)" parenthetical — just "users."
- Removed entire M3 "Commercial deploys need a pin point" motivation
  (was specifically about sutando.ag2.ai install instructions). M4/M5
  renumbered to M3/M4.
- Joint section's bottom bullet reworded: "Customer who hits a bug
  correlates ..." → "Anyone running the bundle who hits a bug ...
  Downstream consumers can pin install instructions to an engine tag."

Per memory feedback_internal_vs_public_docs.md — the sonichi/sutando
repo is PUBLIC; specific paths and commercial framings belong in
INTERNAL (#dev, workspace, owner DM), not in landed docs.

* docs(rfc sonichi#906): owner-quote line removed; M3 restored as downstream-pin-point (AG2-internal facing too)

Owner two follow-ups:

1. task-1779224091789: "Remove wordings like this — Owner (Chi)
   explicitly said 'Plan and make proposals first.'" — the preamble
   quote framing owner's instruction directly was leaking internal
   chatter into a public-repo doc. Replaced with neutral "This is half
   of a co-drafted proposal" framing.

2. task-1779224131237: "M3. Commercial deploys need a pin point —
   This is AG2 internal facing as well." — clarified that the doc
   serves both OSS contributors AND AG2-internal-facing audiences
   (sutando.ag2.ai, packaged bundles, commercial integrators). Restored
   as M3, generalized to "Pin points for downstream consumers and
   bundle deploys" — explicitly enumerates forks, sister-node fleets,
   Sutando.app, AG2-internal deploys, commercial integrators. M4/M5
   renumber accordingly (Two bots coordinating + release-process-is-
   migration-test).

Companion file `docs/release-process-proposal-mini.md` landed in
7d4f260 (Mini's half: when to cut + tag conventions). Both halves now
live on this PR's branch.

* docs(rfc sonichi#906): consolidated doc merging Mini's + qingyun-sutando's halves

Claimed the consolidation step in #dev bot-coord. Merges both source
files (both preserved on the branch as authorship record) into a single
review surface for Chi + Qingyun.

Structure:
- Top-of-doc overview + motivations + non-goals (combined from both).
- Part 1-4 from Mini (when to cut, SemVer + tag namespace, tag-on-main
  no release branch, git tag + GitHub Release + hard/soft gates).
- Part 5-6 from qingyun-sutando (CHANGELOG culture, migration framework
  with numbered migrations/state/runner/tests/phasing).
- Part 7 joint section (engine ↔ product coupling, Option A recommended).
- Part 8 "what to cut next" — both halves landed on (c): cut engine-v0.1.0
  now with manual migration notes, framework as v0.1.1.
- Coupling table verifying no double-coverage between the two halves.
- 5 consolidated open questions for owner (was 4 from each half; deduped
  + added Mini's signed-tags question).
- Next move: owner + Chi review, pick answers, then promote to
  docs/release-process.md + open implementation issues.

Source halves stay on the branch:
- docs/release-process-proposal-mini.md
- docs/release-process-proposal-qingyun-sutando.md

If owner greenlights, this consolidated doc moves to docs/release-process.md
and the two source files can be archived (or kept as authorship record).

No code shipped. Plan only.

* docs(rfc sonichi#906): integrate review-round resolutions

Integrates the 3 reviews on sonichi#906:
- Bassil (cold-review 2026-05-20 06:28) — 4-question picks aligned with
  Chi's later owner-pick; reinforces option (c) cut-now-with-manual-notes
  + framework as next-release primary payload.
- Lucy (review 11:31) — 3 implementation questions on the migration
  framework: multi-core race on schema-version.json, merge-order
  collision on migration numbers, health-check gate on fresh clone.
- Chi (sub-agent draft 19:28 + owner-pick 20:30) — final calls on
  3 open questions: bare v0.MINOR.PATCH (drop engine- prefix),
  working-state when-to-cut (not commit-count), unsigned tags for
  v0.1.x (signed deferred).

Concrete changes in the doc:
- Sweep `engine-vX.Y.Z` → bare `vX.Y.Z` everywhere (frontmatter
  status, body prose, schema-version.json example, alias timeline,
  coupling section, open-question text). 13 occurrences.
- Rewrite "Open questions for owner" as "RESOLVED 2026-05-20"
  section with each pick + reasoning (§§ 4a/4b for when-to-cut
  refinement + GPG deferral).
- §2.7 — replace cut-gate language with Chi's working-state
  framing + clarify health-check scope (tagging install, not
  fresh clone — addresses Lucy Q3).
- §2.8 (new) — Concurrency & ordering: resolve Lucy Q1
  (migrations run as pre-pool step in startup.sh, single-writer-
  by-construction; runner also called from resolve_workspace as
  idempotent fallback for manual sessions) and Q2 (number reserved
  at merge time, pre-merge CI check fails on collision, mirrors
  Rails/Alembic).
- Add "Future hardening" section gathering deferred items
  (signed tags, backward migrations, data re-encoding, PR-template
  migration checklist, docs/install.md fresh-install path,
  docs/release-process.md promotion).
- Rewrite "Next move" to reflect Chi's "mergeable" verdict + the
  Phase 1 framework PR sequence + cut v0.1.0 + workspace contract
  A/B as forcing function for migration 0002.
- Frontmatter: reviewers_integrated field naming the 3 reviews,
  status updated to "open questions resolved; pending merge",
  intro callout quoting Chi's mergeable line.

Plan-only doc — no code shipped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(rfc): sweep consolidated doc to reflect Chi's 2026-05-20 owner-picks

The qingyun-sutando half integrated the review-round decisions, but the
consolidated doc — the file that promotes to docs/release-process.md —
was never swept and still contradicted them. Chi's stated merge bar was
"once the RFC text reflects these, it's mergeable"; this makes it so.

- engine-vX.Y.Z → bare vX.Y.Z everywhere (decision 1).
- §2.2 rewritten: bare tag namespace, no engine- prefix; the namespace
  collision the prefix defended against doesn't exist (product ships
  from its own repo / tag line).
- Part 1.1: add the working-state precondition (decision 4a) — CI green,
  no release-blocker, no half-finished migration; quality gate not count.
- "Consolidated open questions" → "Consolidated decisions (resolved)"
  with all 5 answers recorded inline.
- "Next move" + coupling table + frontmatter status updated to reflect
  that nothing is owner-gated anymore.

Proposal files (mini / qingyun) left as the authorship record per the
consolidated doc's own header; the mini half still reads `engine-` —
flag if it should be swept too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(rfc): sweep mini proposal half to bare vX.Y.Z (consistency with sonichi#906 decisions)

Companion to e248cc6 (consolidated-doc sweep). The mini proposal half
still recommended the `engine-` tag prefix — the option the 2026-05-20
review round overrode. The qingyun-sutando half was already swept to
bare `vX.Y.Z`, so leaving the mini half unswept left the PR internally
inconsistent.

- engine-vX.Y.Z → bare vX.Y.Z throughout.
- §2.2 rewritten: records that this half's engine-prefix recommendation
  was overridden, states the resolved bare-vX.Y.Z decision + rationale.
- Coupling table + open-questions section marked resolved.

Per Chi's "up to you" call on whether to sweep the mini half. All three
release-process docs now consistent with the resolved decisions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Chi Wang <4250911+sonichi@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
qingyun-wu added a commit that referenced this pull request Jun 6, 2026
… 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>
qingyun-wu added a commit that referenced this pull request Jun 6, 2026
…mespace across resolvers, helpers, docs (8 commits) (#1490)

* fix(stage-readiness): modernize sync-age check to workspace-sync (drops 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>

* fix(agent-registry): modernize _workspace_resolve.py to delegate to M0 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>

* fix(submit-use-case): drop hardcoded `/Users/wangchi/.sutando/workspace/` 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>

* fix(workspace-resolver): drop legacy .sutando/workspace fallback (Mini 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>

* fix(sutando-app): drop hardcoded ~/.sutando/memory-sync/ candidate in 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>

* docs(workspace_default): refresh module docstrings to post-v0.8 contract (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>

* docs(config-templates): drop $SUTANDO_WORKSPACE + ~/.sutando/workspace/ 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>

* docs(code-comments): refresh 8 stale ~/.sutando/workspace comments to 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>

* test(workspace-default): update default-path assertion to match post-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>

* fix(watch-tasks-stream): drop legacy env-var + hardcoded ~/.sutando/workspace 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>

* docs(discord-voice): refresh _resolve_workspace docstring post-v0.8 (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>

* docs(memory-sync-refs): refresh 4 stale "memory-sync" references to workspace-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>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

workspace-design: rename SUTANDO_PRIVATE_DIR → SUTANDO_MEMORY_DIR

4 participants