From f87c489cb9aaca7432263d1adf829270c7a9d9c5 Mon Sep 17 00:00:00 2001 From: rldyourmnd Date: Fri, 11 Sep 2026 00:09:38 +0500 Subject: [PATCH] docs(contracts): state the offline limit of checkout removal `gds repository remove-checkout` is documented as a working lifecycle, and it cannot run against any ordinary checkout. Proving publication reads the remote ref; the mutation runner executes every Git command with `protocol.allow=never` and accepts only a locally resolvable URL, so any `https://` or `ssh://` origin is refused as GDS_WORKSPACE_REMOVE_UNSAFE with the message "network Git mutation is disabled before the live provider stage". That is the runner's offline stance, not a property of the checkout, and the message names the runner rather than the cause. Materialization already carries its local-only caveat one paragraph above; removal now carries its own, with the evidence a device-local retirement has to gather instead. ADR 0025 gains the price of its own accepted finding: because the complete relationship index demands an anchor on every boundary under the analysed root, one unanchored external checkout makes `gds repository delete` unusable for the whole tree. The documented escape is narrowing `--inventory-root`, which is sound because the planner stores it as `analysis_root` and apply reuses exactly that. Claude-Session: https://claude.ai/code/session_01CKXKXND4zAgWisTtatyTHX --- .serena/.auto_sync_head | 1 + .../0025-out-of-estate-external-workspace-root.md | 11 +++++++++++ docs/contracts/lifecycles-v1.md | 12 ++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 .serena/.auto_sync_head diff --git a/.serena/.auto_sync_head b/.serena/.auto_sync_head new file mode 100644 index 0000000..efbd4de --- /dev/null +++ b/.serena/.auto_sync_head @@ -0,0 +1 @@ +f8930197661c66eb037fb04b1d31ac043096a14f diff --git a/docs/adr/0025-out-of-estate-external-workspace-root.md b/docs/adr/0025-out-of-estate-external-workspace-root.md index ac49bbf..e01c3d2 100644 --- a/docs/adr/0025-out-of-estate-external-workspace-root.md +++ b/docs/adr/0025-out-of-estate-external-workspace-root.md @@ -50,6 +50,17 @@ implies GDS materializes there. outside every declared `workspace_root`, no placement finding (`GDS_WORKSPACE_PLACEMENT_DRIFT`, `GDS_WORKSPACE_ROOT_NOT_READY`) is produced and no bogus `expected_path` is computed. + + The accepted finding is not free, and this decision did not foresee its + price. The complete relationship index requires an anchor on **every** + boundary under the root it analyses, so a single external checkout under + `${HOME}/Developer` makes `gds repository delete` unusable for every + repository in the tree, not only for the external one. Narrowing + `--inventory-root` past the external root is the documented escape: the + planner stores the root it analysed as `analysis_root` and the apply path + reuses exactly that, so the narrowed scope is bound into the plan and the + approval. Narrow it only with independent evidence that the subject is a + leaf — no relationship and no consumer naming it in the full index. 5. Promotion out of `external` is an explicit estate change: it requires a new owner, an installation that can observe the account, and a selector — that is, transfer or adoption of the repository, never a local move alone. diff --git a/docs/contracts/lifecycles-v1.md b/docs/contracts/lifecycles-v1.md index 334668f..fbec14b 100644 --- a/docs/contracts/lifecycles-v1.md +++ b/docs/contracts/lifecycles-v1.md @@ -345,6 +345,18 @@ publication-proven checkout with no unsafe worktree state is atomically moved to deterministic device quarantine. Restoration requires a separate explicit plan. +Like materialization, removal is currently local-only. Proving publication +means reading the remote ref, the mutation runner runs every Git command with +`protocol.allow=never`, and the URL it accepts must resolve locally — so a +checkout whose `origin` is an ordinary `https://` or `ssh://` remote is refused +with `GDS_WORKSPACE_REMOVE_UNSAFE`, carrying the message `network Git mutation +is disabled before the live provider stage`. That is the offline stance of this +runner, not a property of the checkout, and the error names the runner rather +than the cause. Until the live provider stage lands, a device-local retirement +gathers the same evidence directly: clean status, `@{u}` neither ahead nor +behind, no stashes, no commits reachable only locally, and no tags the remote +does not have. + ## Portfolio planning ```text