Files
pad/plugin
xarmian 403a6de19d docs(skill): structured bootstrap-failure branch + onboarding precondition in the embed source (BUG-2541) (#1100)
* docs(skill): structured bootstrap-failure branch + onboarding precondition in the embed source (BUG-2541)

`skills/pad/SKILL.md` — the //go:embed source `pad agent install` writes into
user projects — had TASK-2537's minimal safety note but not the structured
branch the plugin copy carries. Ports it, minus the Claude-Code-specific shell
advice (the embed source also serves Codex, Cursor, Windsurf, OpenCode and
pure-MCP agents with no shell at all), so it now names the two stderr
signatures as separate cases with opposite handling.

Also adds the Onboarding routing entry's missing precondition. It sent the
agent to load the onboard playbook, which lives IN a workspace — so on the
unlinked path `pad playbook show onboard` fails exactly the way bootstrap just
did, and the entry routed into a dead end.

Ride-along from the lead's citation sweep: the stale "hangs indefinitely / no
timeout" wording still shipped in plugin/skills/onboard/SKILL.md and
plugin/skills/pad/SKILL.md (two places). All three now carry the bounded
wording.

RE-VERIFIED RATHER THAN INHERITED, per this item's own requirement — and the
inherited correction needed one too:

- Read the code myself. First-admin setup is capped at 20m
  (bootstrap.go::bootstrapPollTimeout). The auth poll
  (cmd_auth.go::pollAndSaveCLIAuth) has NO wall-clock limit of its own: it
  exits only on ctx.Done, `approved`, or `expired`, and `continue`s past
  transient errors. So the ~5m bound is entirely the server-side session TTL
  (cli_auth_sessions.go::cliAuthSessionTTL) — if the server becomes
  unreachable after the session is created, it polls forever. "Bounded, not
  indefinite" is right for the ordinary case and wrong for that one; the skill
  text now says both. Filed separately.

- Observed it, not just read it. On a configured-but-unauthenticated HOME,
  `pad workspace init` printed the browser URL and was still waiting when a
  25s cap killed it. `pad auth whoami` returned in 0.106s in that state AND in
  the unconfigured one, with distinguishable output — the "fast, safe" claim
  the whole branch rests on.

- The exact stderr strings were wrong in both copies: the not-configured case
  has NO `Error:` prefix (`Pad is not configured. Run 'pad auth configure'
  first.`), only the unlinked one does. Corrected from captured output.

Verified through `pad agent install claude` into a scratch project and read
back off the installed file, not the diff.

Claude-Session: https://claude.ai/code/session_01QCMLhHQBrMHVML3YKdm4Cd

* docs(skill): `pad auth whoami` blocks in a TTY when unconfigured — qualify the claim (codex review)

Both plugin copies said `pad auth whoami` "never blocks waiting on input".
It does, in one state: `whoamiCmd` → `getConfiguredConfig()`, and on an
unconfigured machine that enters the interactive configure flow whenever
`canPromptForConfig()` is true — i.e. stdin AND stdout are both terminals
(configure.go:357). My own measurement (0.106s) was non-interactive, so it
could never have caught this; Codex found it by reading the call path.

The embed copy already had the right qualification ("in non-interactive use it
returns immediately"); this brings the two plugin copies in line and says why
the qualification is the operative one for an agent.

Codex's other finding — that the embed source's opening still frames `/pad` as
THE command, for surfaces with no slash commands — is real but pre-existing and
editorial rather than part of this port. Filed as BUG-2573. The auth-poll
timeout gap found while re-verifying the hang is BUG-2572.

Claude-Session: https://claude.ai/code/session_01QCMLhHQBrMHVML3YKdm4Cd

* docs(skill): `pad init` does not fail fast either — correct both plugin copies (codex round 2)

Both plugin copies told agents that in the configured-but-unauthenticated
state, `pad init` "fails fast" and merely "needs a TTY to complete" — offered
as the contrast to `pad workspace init`'s browser-poll block.

It is false. `cmd/pad/init.go`'s Step 4 calls `doBrowserLogin` with no TTY
guard when the server is already initialized but the client isn't
authenticated. Observed: on a configured-but-unauthenticated HOME, non-
interactive, `pad init` printed the same browser URL and was still waiting
when a 20s cap killed it — identical to `pad workspace init`.

That parenthetical was the one thing in the paragraph that could have made an
agent run a command instead of handing back, so it was the worst line to have
wrong. Both copies now say it is no safer as a probe.

Third claim in these three files this task that was wrong because it was
reasoned rather than run — the first two being "hangs indefinitely" (bounded,
mostly) and "whoami never blocks" (it prompts in a TTY).

Codex's other two round-2 findings are real but out of this port's scope and
filed: BUG-2574 (the plugin onboard skill inlines its own script instead of
loading the canonical onboard playbook) and BUG-2575 (plugin decompose entries
omit SPEC targets the embed source and playbook both support).

Claude-Session: https://claude.ai/code/session_01QCMLhHQBrMHVML3YKdm4Cd

* docs(skill): narrow the `pad init` claim to the state it is actually true in (codex round 3)

The previous commit replaced one over-broad claim with the opposite one. "Fails
fast" was wrong for the configured-but-unauthenticated case; "no safer as a
probe, blocks identically" is wrong for the genuinely-unconfigured one. Both
measured, non-TTY, same binary:

  unconfigured                  → 0.106s, "Error: Pad is not configured..."
  configured-but-unauthenticated → browser URL, still waiting at 20s

The instruction ("don't run it yourself") was right in both readings, so this
is the justification being wrong rather than the advice — which is exactly the
failure mode this whole item is about, and I reproduced it while fixing it.
Both plugin copies now say which state each behaviour belongs to.

Codex's other round-3 finding — that the plugin onboard skill gates its
recovery branch on `.pad.toml` being absent, so a STALE link skips it entirely
and dead-ends at the same bootstrap failure — is real and is the pre-link half
of the same skill's problem. Added to BUG-2574 rather than widened into this
port.

Claude-Session: https://claude.ai/code/session_01QCMLhHQBrMHVML3YKdm4Cd
2026-08-15 08:36:56 -04:00
..