docs(#260): document app list/view/pull, scope the anonymous-reads claim, add a TOC - #268
Merged
Conversation
…aim, add a TOC A blind dogfood run against v0.1.90-21-gf56aa72 (#260) found the docs asserting things the binary does not do, and a 1616-line README with no navigation. Four false claims and the navigation gap: A1. `app list`, `app view` and `app pull` are all in `civitai app --help` and were in NO README row. `app pull` is not minor — it is "the read side of git authoring" and carries a token-in-URL leakage hazard a README-only reader had no way to reach. All three now have rows, and `app pull` / the App store have sections carrying the real caveats. A2. "Reads are anonymous — no login needed" was false for `app list` and `app view`, which exit 3 with `no token configured`. The claim is now scoped to the public catalog, and the App-store commands are described as needing a credential in the README, the row, and root --help. A3. `app metrics` with no token said "run `civitai login`" — the ONE credential the full-scope analytics proc refuses (403). It now names the personal-API-key route and where to mint one, from a constant the command's own --help renders too. Still ErrUnauthorized-tagged (exit 3). A4. A mistyped flag printed a bare `unknown flag: --stict` with no next step, while a mistyped COMMAND already got `Run '… --help'`. The FlagErrorFunc now appends the help command for the command actually being parsed. Cobra's wording is appended to, never replaced; exit 2 is unchanged. B. A table of contents with verified anchors; the four essay-length table cells (generate 280w, dev-tunnel 222w, listing 124w, dev-token 105w) condensed to a summary plus a link, with the detail RELOCATED into sections rather than deleted. `civitai --help` now shows Usage and Available Commands BEFORE the ~60-line exit-code taxonomy. The exit-code section moved out of root's Long and into a help TEMPLATE gated on `{{if not .HasParent}}` (a template set on the root is otherwise inherited by every subcommand). Its TEXT is untouched and still generated from exitCodeDocs; the README's generated exit-code table is untouched. Guards: - TestREADMEAnchorLinksResolve — every `](#…)` target is a real heading. The slug algorithm is positive-controlled against eight anchors that already worked on github.com. Mutation-verified: an injected `#no-such-heading-zz` reddens it by name. - TestREADMETableOfContentsCoversEverySection — every `##` section is reachable from the TOC. - TestREADMECommandTableDocumentsEveryAppSubcommand — derived from the COBRA TREE, not a list. Mutation-verified: deleting the `app pull` row reddens it by name. - TestAppMetricsNoTokenNamesTheRouteThatWorks — errors.Is(ErrUnauthorized) for the exit code, specific substrings for the route, plus a check that the constant has not been collapsed into spendCredentialRoutes. - TestUnknownFlagNamesTheHelpCommandForThatCommand — errors.Is(ErrUsage), with a discriminating case that a root-hardcoded hint would fail. - TestRootHelpShowsUsageBeforeExitCodes asserts INDICES (both-present is satisfied by the broken order); TestSubcommandHelpDoesNotRepeatThe ExitCodeSection pins the template gate. TestReadmeDevTunnelRowMatchesTheCommandHelp now follows the row's own cross-reference into the section, so relocating detail out of a cell is a supported move and a broken link fails it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
golangci-lint's staticcheck ST1005 rejects an error string ending in punctuation, and the CI lint gate on this branch was red on exactly one issue: internal/cmd/root.go:214. Verified with the pinned linter (v2.12.2, matching .github/workflows/ci.yml): reproduced the identical ST1005 error on an unmodified checkout of this branch's tip, then confirmed 0 issues after the change. go build ./... clean and ./internal/cmd passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 7, 2026
Open
ZacxDev
added a commit
that referenced
this pull request
Aug 7, 2026
My README.md edits collided with #268 (which added a TOC and the app list/view/pull docs). Measured by exit code, not by grepping for markers: `git merge-tree --write-tree origin/main <ref>` exits 0 for the audited tip a4807f4 and 1 for my tip, so the conflict is mine and not pre-existing. Merged rather than rebased, deliberately: a rebase would rewrite a4807f4, which the PR must keep, and five sibling PRs are in flight against these same files. The conflict was one 3-row hunk of the command table where each side edited a DIFFERENT row — #268 rewrote `app dev-token` and `app dev-tunnel`, I rewrote `app validate`. Resolved row-by-row against the merge BASE rather than by picking a side: main's row wherever main changed it, mine wherever I changed it, with the resolver refusing outright if both had touched one row. Neither side's block was correct on its own. Verified on the MERGED tree, which is the tree that matters and the one neither side's review saw: make ci green — 18 packages ok, `--- FAIL` 0, `build failed` 0, timeout panics 0, gofmt clean — including the readme-nav, root-help-order and login-help guards main added while this branch was open. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four of the seven sub-items in the #260 dogfood umbrella, plus the navigation
work. The other three (
app_init.go's scaffold-validation and--fromleak;the icon/cover on-ramp) are elsewhere or blocked.
The false claims (issue #260 A1–A4)
These are not cosmetics — the docs asserted things the binary does not do.
A1 — three commands existed and the README documented none of them.
civitai app --helplistslist,viewandpull; the command-reference tablehad rows for none.
app pullis the significant one: its own--helpcalls it"the read side of git authoring", it lazily provisions a Forgejo identity, and it
carries a 10-line ⚠ SECURITY — TOKEN-IN-URL LEAKAGE warning. A README-only
reader did not know a git authoring path existed, let alone its hazards.
All three now have rows.
app pulland the App-store commands get sections; thesecurity warning is mirrored from the real
--helptext (both halves — theclone path persists the token to
.git/config, the sync path only exposes ittransiently in the git child's argv).
A2 — the README contradicted the binary on anonymous reads.
Reads are **anonymous** — nologinneededand root--help's "Reading is anonymous"were both false for
civitai app list/app view, which exit 3 withno token configured — … to browse the App store. Verified against the source(
newLoginGatedReaderininternal/cmd/apps.go), not assumed: the publicmodel/image/article commands genuinely are anonymous, and only these two store
reads are not. The claim is now scoped to the public catalog on all three
surfaces, and the App-store section says so at the top.
A3 —
app metricsrecommended a login that will be refused. The no-tokenbranch returned the generic
run 'civitai login'— the one credential thefull-scope analytics proc refuses with 403 — so following the CLI's own advice
landed the author on a second refusal. It now names the personal-API-key route
and where to mint one, from a constant
app metrics --helprenders too.A4 —
unknown flagoffered no next step.civitai app validate --stictprinted only
unknown flag: --stict, while an unknown command already saidRun '… --help'.SetFlagErrorFuncnow appends the help command for thecommand actually being parsed:
Navigation (issue #260 B)
generate(280 words / 1859 chars in onemarkdown column),
app dev-tunnel(222),app listing(124),app dev-token(105) — condensed to a one-line summary plus a link. Content was relocated,
not deleted:
generate's detail was already fully covered by## Generate;dev-tunnelgot a new section;dev-token's unique bits (--budget, themanifest-scope read) went into the Local dev loop section.
civitai --helpnow showsUsage:andAvailable Commands:before the~60-line exit-code taxonomy, which used to sit above the fold.
⚠ Reconciliation note for the exit-code work
The exit-code section moved out of root's
Longand into a helptemplate. Its text is untouched and still generated from
exitCodeDocs, andthe README's generated exit-code table is untouched — but
TestRootHelpExitCodesAreGeneratedhad to change from readingcmd.Longtoreading the rendered
--helpoutput (a strictly stronger assertion: it is whatthe user sees). If
exitcodes_doc.gois being edited concurrently, that is theone point of contact.
The
{{if not .HasParent}}gate is load-bearing: cobra'sHelpTemplate()walksup to the parent, so without it every subcommand help would grow a copy of the
root taxonomy.
TestSubcommandHelpDoesNotRepeatTheExitCodeSectionpins it.Guards
TestREADMEAnchorLinksResolve](#…)target is a heading that existsTestREADMEAnchorSlugMatchesKnownGitHubAnchorsTestREADMETableOfContentsCoversEverySection##section is reachable from the TOCTestREADMECommandTableDocumentsEveryAppSubcommandappsubcommand cannot ship undocumentedTestAppMetricsNoTokenNamesTheRouteThatWorkserrors.Is(civitai.ErrUnauthorized)for the exit code, the specific route substrings for the messageTestAppMetricsCredentialRouteIsNotTheSpendRoutespendCredentialRoutes, which would reintroduce the defectTestUnknownFlagNamesTheHelpCommandForThatCommanderrors.Is(ErrUsage), plus a case a root-hardcoded hint would failTestRootHelpShowsUsageBeforeExitCodesEvery exit-code assertion is
errors.Is, never message text (AGENTS item 7).Mutation results (each injected, watched red, reverted):
[x](#no-such-heading-zz)→TestREADMEAnchorLinksResolvefails,naming the dangling slug;
civitai app pulltable row →TestREADMECommandTableDocumentsEveryAppSubcommandfails, naming the command.TestReadmeDevTunnelRowMatchesTheCommandHelpwas widened to follow the row's owncross-reference into the section it links to, so relocating detail out of a table
cell is a supported move — and a broken link now fails it.
Gate
make cigreen. Counted fromgo test ./... -count=1 -v, not the exit code:2708
=== RUN, 2704--- PASS, 0--- FAIL, 4--- SKIP, 0build failed,0 timeout panics.
gofmt -s -l .clean over 299.gofiles.Behaviour verified against the built binary (
./bin/civitai), not only tests:the
--stictinvocation above,civitai app --helpcarrying zero copies of theexit-code block, and
civitai --helpshowingUsage:at line 32 withExit codes:after the flag list.🤖 Generated with Claude Code