From 066de34489fd39eabdfe03f7acedbd35d2b96c97 Mon Sep 17 00:00:00 2001 From: Grant Whitmer Date: Tue, 11 Aug 2026 15:59:41 -0400 Subject: [PATCH] G5: fix version-count copy; record the u-system namespace finding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'There are 1 saved versions' is exactly the sloppiness the vocabulary law exists to catch. Copy is design material, not decoration. G5.9 records something the live test surfaced: a repo created through X-Service-Token lands in a 'u-system' namespace because the service caller has no identity of its own. Correct for /internal plumbing, WRONG for anything a person owns — the portal must pass an acting user and this cell must refuse to create a user-owned project without one. Until then service-created repos are ops artifacts, not customer data. Co-Authored-By: Claude Opus 5 --- DNA_STRAND_MASTER_PLAN.md | 7 +++++++ api/app/routes/repos.py | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/DNA_STRAND_MASTER_PLAN.md b/DNA_STRAND_MASTER_PLAN.md index 36a10fe..fff8d31 100644 --- a/DNA_STRAND_MASTER_PLAN.md +++ b/DNA_STRAND_MASTER_PLAN.md @@ -324,6 +324,13 @@ and landed in R2 at `lfs/34/2d/…`, with **no local `lfs/` directory on the hos - **G5.5** **Version history UI with one giant Undo.** Grandma-words throughout, and D-9 binds every string: "version", "save point", "restore" — **never "commit," never "a Git"** on this surface. - **G5.6** `POST /{id}/restore {version_seq}` — lossless, and itself a new version. **Undo is never destructive.** - **G5.7** Quota events double as storage-plan cross-sell hooks (§0.5). +- **G5.9** ⚠️ **Service callers need an on-behalf-of identity.** Verified live on + 2026-08-11: a repo created through `X-Service-Token` lands in a `u-system` + namespace, because the service caller has no identity of its own. That is + correct for `/internal/*` plumbing and **wrong for anything a person owns** — + the Cloud portal must pass the acting user, and this cell must refuse to + create a user-owned repo without one. Until then, service-created repos are + ops artifacts, not customer data. - **G5.8** *Accept — the strand's whole point in one test:* a Cloud folder is git-enabled, a second human is granted `writer`, that human edits a file through the portal, the owner restores the previous version, and **at no point does either user encounter the word "commit," "repo," "branch," or "Git."** ## Strand G6 — Git protocol surface diff --git a/api/app/routes/repos.py b/api/app/routes/repos.py index 76eb361..df7a533 100644 --- a/api/app/routes/repos.py +++ b/api/app/routes/repos.py @@ -291,8 +291,12 @@ async def list_versions( return { "versions": versions, "count": len(versions), + # "There are 1 saved versions" is the kind of sloppiness the vocabulary + # law exists to catch. Copy is design material, not decoration (I-9). "speak": ( - f"There are {len(versions)} saved versions of '{repo.display_name}'. " + f"'{repo.display_name}' has 1 saved version. You can go back to it." + if len(versions) == 1 + else f"'{repo.display_name}' has {len(versions)} saved versions. " "You can go back to any of them." if versions else f"'{repo.display_name}' is empty so far."