docs(readme): the examples demonstrate manifest shape, not recommended values - #201
Merged
Conversation
…d values The Examples section called the two shipped manifests "a good reference for a correct manifest". That reads as an endorsement of their VALUES, and one value is now in tension with guidance that just shipped: buzz-generator sets page.buzzBudgetPerGen: 10, which is also the platform fallback the canonical schema describes as "below almost any real generation". Reframe rather than edit the data. The examples are valuable precisely because they are copied verbatim from the shipping apps; changing the number would turn them into synthetic examples wearing a "copied from" label. And nobody has priced buzz-generator, so 10 is not established as wrong. So: keep the provenance, point at manifest SHAPE, and send the reader to the canonical schema's own field description for budget sizing. Note that notepad has no budget at all (it doesn't take the budgeted scope). Also make examples_test.go's comment honest about its reach: it asserts schema conformance, which 10 satisfies regardless of how it was sized. Deliberately NOT adding a heuristic budget threshold — any such check would have to guess at correct sizing per app and would fire on legitimately cheap apps. Docs-only plus one comment; no manifest values changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R7ZCxbgcsv3WfsSJrYdSCi
…pps are suspended Verified against the prod app_blocks table: buzz-generator AND notepad are both status=suspended, not approved. `approved` is a real state (9 apps hold it), so suspended is not a lifecycle default — neither example is a shipping app. They are dogfood apps, which is still exactly why their manifests are worth shipping as examples, but "shipping" is a claim the data does not support. Drop the word. Provenance (these are copied from real apps, not synthesised) is preserved and is what earns them their place. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R7ZCxbgcsv3WfsSJrYdSCi
ZacxDev
force-pushed
the
zach/examples-framing-not-values
branch
from
August 5, 2026 03:51
f1138c9 to
56025cf
Compare
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.
The tension
The
### Examplessection ofREADME.mdintroduced the two example manifests as"a good reference for a correct manifest".
One of them,
examples/buzz-generator.block.manifest.json, setspage.buzzBudgetPerGen: 10. Guidance that just shipped reframed that field: it is aper-generation safety ceiling against a malicious or compromised app draining the
viewer's Buzz — sized well above worst-case spend, not at an estimate of one run.
The canonical schema description (civitai#3629, now live at
https://civitai.com/schemas/app-block/v1.json) says so explicitly, and #199 moved thepage-moneyscaffold default 40 → 300.So
10sits under a heading that endorses it, with no context. A reader following theREADME to "a good reference for a correct manifest" cannot tell whether it is a
well-sized ceiling or an estimate.
What makes it look bad:
10is also the platform fallback used when the field isomitted — the one the canonical description calls "below almost any real
generation". A value indistinguishable from the unset default reads as unconsidered.
(Measurement later showed it is adequate for this particular cheap app — see below —
but a reader has no way to know that from the file.)
Why the value was deliberately NOT changed
Two independent reasons, either sufficient on its own:
civitai-block-*apps. That is the entire reason they earn their place — they arereal. Editing the number turns them into synthetic examples still wearing a
"copied from" label, which is a worse defect than the one being fixed.
10turns out to be RIGHT. This was priced during review rather than guessed —see below. A
buzz-generatorgeneration costs 3 Buzz, so10is a ~3.3×ceiling: correct in kind, if thin against the canonical "several times your expected
cost". Changing it was never warranted.
The fix is therefore to the framing, not the data. No manifest byte changed.
What
buzz-generatoractually costs — 3 Buzz (measured)Rather than assume, this got priced from two independent authorities that agree:
block_spend_attributionjoined toapp_blockshas exactly onerow for
buzz-generator:buzz_amount = 3,model_id 101055(SDXL 1.0),2026-06-24. Neighbouring SDXL-1.0 rows from other apps price at 2–3, corroborating.
the server fills 1024², Euler, 25 steps, quantity 1. The generic SD factor product
4 × (25/30) × 0.8 = 2.67 → ceil = 3. No base constant on this path.So the field is a ~3.3× ceiling over real cost — a correct ceiling, not the
estimate-shaped mistake it superficially resembles. This is precisely why the value was
not edited on a hunch: the number that looked wrong was fine.
It is still not a value to copy, which is what the new prose says — the right ceiling
is a function of your generation's cost, not this app's.
What the framing now says
shape: required fields,
$schemawiring, thepage/iframeblocks, and scopedeclarations with justifications.
buzzBudgetPerGenpointer that sends the reader to the canonicalschema's own field description rather than to this example's number, and states
plainly that the values here are those apps' own choices, not recommendations.
notepadhas no budget at all — verified: it declares onlyapps:storage:read/write, takes noai:write:budgetedscope, and has nobuzzBudgetPerGenkey. The caveat applies to exactly one of the two files, so theprose says which.
The pointer targets the published URL (already the
$schemavalue in both examples)rather than the CLI's vendored copy, deliberately — see the CI note below.
Second commit: "shipping" was inaccurate
Pricing the app turned up a separate defect in the sentence this PR originally set out
to preserve.
app_blocksin production says:buzz-generatornotepadapprovedis a real, populated state (9 of 21 app_blocks hold it), sosuspendedisnot a lifecycle default — neither example is a shipping app.
buzz-generatorhasone lifetime generation, run by its own author (
voided / self_spend).So "copied from the shipping
civitai-block-*apps" asserted more than is true.Second commit drops the word: "copied from the
civitai-block-*dogfood apps". Theprovenance point — these are real apps' manifests, not synthesised ones — is intact,
and is still the reason they earn their place.
What
examples_test.godoes and does not guaranteeThe README said the examples "validate clean (
examples_test.goasserts this so theclaim stays true)". True, but the test only reaches schema conformance —
10satisfies
exclusiveMinimum: 0perfectly happily. The test was guarding the syntax ofthe provenance claim while sitting directly under, and appearing to underwrite, a
quality claim it never touches.
Fixed in the prose: the sentence now says the assertion is "schema conformance only,
which says nothing about whether a value is well-sized." The test's own doc comment
gained a matching
SCOPE —paragraph.No heuristic budget test was added, on purpose. Any threshold that would flag
10has to guess at correct sizing per app, and would fire on legitimately cheap ones. The
right fix is that the prose stops claiming more than the test checks.
Confirmed there is no existing sizing check to lean on either:
internal/validate/warnings.gowarns only when
buzzBudgetPerGenis absent (or set without the budgeted scope) — alow-but-present value produces no warning. So a reader copying this example gets no
signal from tooling at all, which is exactly why the prose has to carry it.
Gates
go build ./...— clean.go test ./... -v -count=1— 1332=== RUN, 1330--- PASS, 2--- SKIP, 0--- FAILacross 16okpackages; nopanic: test timed out. Counted, not readfrom an exit code.
buzzBudgetPerGen: -5in an example makesTestExampleManifestsValidateCleanfail with this test's own error(
example notepad… should validate clean, got errors: [/page/buzzBudgetPerGen: exclusiveMinimum: got -5, want 0]), so its green is meaningful. Reverted.gofmt -l .clean,go vet ./...clean.Diff is docs-only plus one comment:
README.md(+11/−2) andexamples_test.go(+7, doc comment only — no assertion, control flow, or test data changed). No
.jsonunder
examples/was modified.Pre-existing CI red, unrelated to this PR
check canonical schema(scripts/check-canonical-schema.sh) currently fails onmain: the vendoredschema/app-block.manifest.schema.json(11,941 B) has driftedfrom the live canonical (13,196 B) because civitai#3629's rewritten
buzzBudgetPerGendescription shipped and the CLI has not re-vendored yet. The vendoredcopy still carries the old one-line "Optional per-generation Buzz budget…" text.
This branch touches only
README.mdandexamples_test.go, so it neither causes norfixes that. It is presumably what
.github/workflows/revendor-canonical-schema.ymlisfor. Flagging it so a red check here isn't misattributed — and it is a second reason the
new prose points at the published schema URL rather than the CLI's embedded copy,
which would currently hand the reader the stale wording.
Attribution is measured, not inferred.
schema-driftpassed onmainat2026-08-04T23:22:23Z(run 30959751797, commit8aab331). Re-running that exact jobon that exact unmodified commit at
2026-08-05T00:55Znow fails. Nothing in therepo changed between the two runs — the canonical schema served at
civitai.comdid,when civitai#3629 reached production. So the check is red on
mainright now,independent of this PR.
🤖 Generated with Claude Code
https://claude.ai/code/session_01R7ZCxbgcsv3WfsSJrYdSCi