Problem
The advanced flow ("stage with attach --branch while you work; the comment appears when the PR opens") has one silent failure mode: webhook auto-promotion only runs for repos already bound to a workspace, and staging alone never binds (binding implies proven write access, #297 — created only by a successful comment post, a promote, or uploads github link). In a never-bound repo, stage-only work silently no-ops at PR open. As this flow becomes the documented pitch (website/docs refresh in progress), the silent no-op is the one thing that would make it feel broken to a first-time user.
Proposal
attach --branch checks the repo's binding at stage time and prints one advisory line when the staged files won't auto-attach. No auto-binding — the security model stays intact; this only kills the surprise.
Server: a minimal read-only endpoint (or an extension of an existing one, if a fitting one exists) that answers "is repo bound, and is it mine?" for the calling workspace. To avoid cross-tenant information disclosure it must NOT name another owner: return only a tri-state, e.g. { binding: "self" | "other" | "none" }. Workspace-authed, files:read, read-only against github_repo_links (lenient lookup is fine here — an advisory must not 5xx on a D1 blip).
CLI: after a successful attach --branch upload, best-effort call the endpoint (bounded timeout, reuse timedExecRunner-style discipline for the HTTP call's budget; any failure → no warning). One stderr line:
none: note: staged, but <repo> isn't linked to your workspace yet — staged files only auto-attach on PR open for linked repos. Link it once with: uploads attach <file> (on any PR), or uploads github link. Zero-setup fallback after the PR opens: uploads attach --promote
other: note: staged, but <repo> is linked to a different workspace — these files won't auto-attach from this workspace.
self: no output.
Suppression: same switches as the #393 nudge (--quiet, UPLOADS_NO_NUDGE=1 env/config). JSON mode: additive hint field, same contract as #393 (absent when not firing).
Non-goals
- No auto-binding from staging.
- No change to webhook promotion or the binding model itself.
- No blocking: staging always succeeds regardless of binding state; this is advisory only.
Testing
Endpoint: tri-state responses (self/other/none), no owner name leakage in the other case, lenient on D1 error. CLI: warning fires per state, suppression switches, lookup failure → silent, stderr-only, JSON hint additive. Changeset: minor, @buildinternet/uploads only (plus nothing for apps/api — ignored package).
Related: #393 (nudge conventions), #297 (binding = proven write access), docs refresh using the two-tier framing.
Problem
The advanced flow ("stage with
attach --branchwhile you work; the comment appears when the PR opens") has one silent failure mode: webhook auto-promotion only runs for repos already bound to a workspace, and staging alone never binds (binding implies proven write access, #297 — created only by a successful comment post, a promote, oruploads github link). In a never-bound repo, stage-only work silently no-ops at PR open. As this flow becomes the documented pitch (website/docs refresh in progress), the silent no-op is the one thing that would make it feel broken to a first-time user.Proposal
attach --branchchecks the repo's binding at stage time and prints one advisory line when the staged files won't auto-attach. No auto-binding — the security model stays intact; this only kills the surprise.Server: a minimal read-only endpoint (or an extension of an existing one, if a fitting one exists) that answers "is
repobound, and is it mine?" for the calling workspace. To avoid cross-tenant information disclosure it must NOT name another owner: return only a tri-state, e.g.{ binding: "self" | "other" | "none" }. Workspace-authed,files:read, read-only againstgithub_repo_links(lenient lookup is fine here — an advisory must not 5xx on a D1 blip).CLI: after a successful
attach --branchupload, best-effort call the endpoint (bounded timeout, reusetimedExecRunner-style discipline for the HTTP call's budget; any failure → no warning). One stderr line:none:note: staged, but <repo> isn't linked to your workspace yet — staged files only auto-attach on PR open for linked repos. Link it once with: uploads attach <file> (on any PR), or uploads github link. Zero-setup fallback after the PR opens: uploads attach --promoteother:note: staged, but <repo> is linked to a different workspace — these files won't auto-attach from this workspace.self: no output.Suppression: same switches as the #393 nudge (
--quiet,UPLOADS_NO_NUDGE=1env/config). JSON mode: additivehintfield, same contract as #393 (absent when not firing).Non-goals
Testing
Endpoint: tri-state responses (self/other/none), no owner name leakage in the
othercase, lenient on D1 error. CLI: warning fires per state, suppression switches, lookup failure → silent, stderr-only, JSONhintadditive. Changeset: minor,@buildinternet/uploadsonly (plus nothing for apps/api — ignored package).Related: #393 (nudge conventions), #297 (binding = proven write access), docs refresh using the two-tier framing.