From d625a301ece2aca6eadf992fb03804ddc83bfa98 Mon Sep 17 00:00:00 2001 From: "@permadeath.com" Date: Tue, 25 Aug 2026 12:22:41 -0400 Subject: [PATCH] docs(stack): drop claims this repository never established MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The architecture notes said Tangled's web resubmit cannot correlate a multi-commit round. What is actually in core at e4eb96e9 is an accessor that answers only for single-patch rounds and that nothing calls — which settles nothing about the web, so the note now says that instead. Also out: an incident that never happened, odds nobody measured, and a claim about how Graphite stores stack membership that was never read. --- TODO.md | 4 ++-- docs/architecture.md | 9 ++++++--- src/cmd/stack/marks.rs | 12 +++++------- src/cmd/stack/write.rs | 19 ++++++++----------- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/TODO.md b/TODO.md index 7a31339..e6f8807 100644 --- a/TODO.md +++ b/TODO.md @@ -1248,8 +1248,8 @@ agents file five pull requests for one change. first cut inferred them — any branch whose tip fell in the range — and that is wrong in a working repository: `git branch backup` before a rebase, or an abandoned worktree's branch, silently re-cut the stack. - Every comparable tool declares membership rather than guessing at it - (`gh stack add`, Graphite's branch metadata). With no marks left, the + `gh stack` reaches the same shape from the other side: a stack is + `init`ed and its layers `add`ed, never guessed at. With no marks left, the cuts come back out of the records' change-id headers, so a fresh clone still reconciles - [x] `atgc stack rebase` and `atgc stack sync`. Marks live in git, so they diff --git a/docs/architecture.md b/docs/architecture.md index bb474ac..3af0437 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -86,9 +86,12 @@ Those headers are the whole of stack identity. `stack resubmit` matches a record to a run when any of the run's ids is one the record already claimed, which is what lets a member survive an amend anywhere inside it — and what lets the grouping be re-derived from the records instead of re-stated by the -caller. The appview reads a round's change-id only from a single-commit -round, so a member of several is one Tangled's own web resubmit cannot -correlate; atgc's can, and `stack resubmit` is the command for those stacks. +caller. What the *appview* does with them is less settled than it looks: its +accessor for a submission's change-id (`PullSubmission.ChangeId`, read at +core `e4eb96e9`) answers only for a round holding exactly one patch, and +nothing in the appview calls it. So whether the web can correlate a +multi-commit round is not something this repository has established. atgc's +reconcile does not go through it either way. A branch that is one change from bottom to top is not a stack: it is one pull request holding every commit, and `pr create` is its command. diff --git a/src/cmd/stack/marks.rs b/src/cmd/stack/marks.rs index 7c516fa..9c3019a 100644 --- a/src/cmd/stack/marks.rs +++ b/src/cmd/stack/marks.rs @@ -6,13 +6,11 @@ //! the name into the checkout's git config, and only recorded names are read //! back. That indirection is the whole point of this module. //! -//! It was not always so. The first cut of this feature treated any branch -//! whose tip landed in the range as a mark, which reads well in a demo and is -//! wrong in a working repository: `git branch backup` before a risky rebase, -//! an abandoned worktree branch, a colleague's branch checked out last week — -//! each of them silently re-cuts the stack, and nothing says so. Every other -//! tool in this space declares membership rather than inferring it (`gh stack -//! add`, Graphite's branch metadata), for exactly this reason. +//! Recorded rather than inferred, because inferring it is wrong in a working +//! repository: `git branch backup` before a risky rebase lands in the range +//! too, and a stack that silently re-cut itself around it would say nothing. +//! `gh stack` reaches the same shape from the other direction — a stack is +//! `init`ed and layers `add`ed, never guessed at. //! //! The record is per-branch and multivalued: `branch..atgcMark`, in //! the same namespace git keeps `branch..description` in. It lives in diff --git a/src/cmd/stack/write.rs b/src/cmd/stack/write.rs index 7ef8ad2..a57acde 100644 --- a/src/cmd/stack/write.rs +++ b/src/cmd/stack/write.rs @@ -1003,9 +1003,8 @@ fn label_of(cut: &Cut, index: usize) -> String { } /// How a plan line names the commits behind a member: the sha for the -/// ordinary one, and the run's ends plus a count when it carries several. -/// A member of five commits printed as one sha was the plan reading as a -/// plan for one commit. +/// ordinary one, and the run's ends plus a count when it carries several, +/// since one sha alone reads as a member of one commit. fn describe_commits(p: &Planned) -> String { match p.commits() { 1 => format!("commit {}", p.short()), @@ -1161,12 +1160,10 @@ fn one_group_per_commit(total: usize) -> Groups { /// How many commits an unmarked branch may stack one-per-commit before /// `create` stops to ask. /// -/// Three is the largest number that still reads as a deliberate series -/// rather than an accident: the jj workflow these commands grew out of opens -/// a pull per change, and two or three of those is an ordinary stack. Above -/// it, the odds that somebody meant "one pull request per commit" fall off a -/// cliff, and the cost of guessing wrong is a pile of records to close by -/// hand. +/// Three is a judgement call, not a measurement: two or three single-commit +/// pulls is an ordinary jj-shaped stack, and past that the cost of guessing +/// wrong — a pile of records to close by hand — outweighs the cost of +/// asking. const UNMARKED_LIMIT: usize = 3; /// Whether this checkout still wants the unmarked-branch question. @@ -2628,8 +2625,8 @@ pub(in crate::cmd) struct SyncedJson { /// The halves stay available on their own — a conflict during the rebase /// leaves work to do before any reconcile makes sense, and an amend that /// needs no rebase needs no fetch either — but neither is the verb to reach -/// for by default, and every comparable tool says so: `gh stack sync` and -/// Graphite's `gt sync` are the same pairing behind one word. +/// for by default. `gh stack sync` and Graphite's `gt sync` pair the same +/// two behind one word. /// /// Stops after the rebase if the rebase stopped. A reconcile planned against /// a half-rebased branch would be a plan for a branch that does not exist -- 2.51.2