Skip to content

docs(create-objectstack): say that the blank starter ships no app - #10507

Merged
os-elon merged 1 commit into
mainfrom
claude/issue-10317-blank-template-ships-no-app
Aug 21, 2026
Merged

docs(create-objectstack): say that the blank starter ships no app#10507
os-elon merged 1 commit into
mainfrom
claude/issue-10317-blank-template-ships-no-app

Conversation

@os-elon

Copy link
Copy Markdown
Collaborator

Part of #10317. Verified at 1776d515c.

That card is two defects wearing one title, with opposite fixes — (a) the template is
right and the README lies, or (b) the README is right and the template is incomplete.
This PR implements (a), and only after measuring. It deliberately does not implement (b);
the evidence below is why, and the remaining product call is left to the maintainer.

What actually renders — measured, not predicted

Scaffolded with the real CLI, installed against the published 17.1.0 packages, booted with
objectstack dev --ui, signed in as the seeded dev admin:

create-objectstack my-app -t blank -> src/ contains objects/ and nothing else
GET /api/v1/meta/app -> 200 items: [setup, account] (2, both platform)
GET /api/v1/data/my_app_note -> 200 {"records":[],"total":0}

The symptom the card describes is real: the scaffolder's own object is live over REST for the
whole session and sits in no app's navigation. (The card said "Your apps 1"; at head it is 2 —
account has since joined setup. The count is stale, the substance is not: zero of them
come from the scaffolded project.)

Why (a) — the template is deliberately empty

Not a taste call. Four independent readings agree:

  1. The template's own stated purpose.template-registry.ts describes blank as
    "Minimal starter — one object, REST API, ready to extend" — the promise names REST, not
    the Console.
  2. What init offers alongside it.os init has three templates — app, plugin,
    empty. All three write src/objects/ only. The one literally described as
    "Full application with objects" ships no *.app.ts either.
  3. The sibling templates. There are none — the five remote content templates are retired,
    so blank is the sole template. Anything added here ships into every project ever
    scaffolded, forever.
  4. History. No *.app.ts has ever existed under packages/create-objectstack/src/templates/**.
    (b) would be adding something new, not restoring something lost.

And README.md:69 does not say what the card reads it as saying. It is step 3 of a
three-step loop whose step 2 has the agent author the ticket object, the Resolve action,
an "Open tickets" list view and a Support nav group. "The Console renders the real app" is a
claim about what you build in step 2 — not about the scaffolder's output. The generated
template README never promised a Console either: it says "a clean slate for building" and
already lists "Add a view or app" under Next steps.

So the card's headline premise — the README promises the opposite — does not hold, and (b)
would be unrequested scope in every blank project forever.

What was actually broken, and what this changes

The real defect is the half both readings agree on, and it is the one the card names in its own
"Adjacent gap" section: nothing the newcomer can reach says an app is the missing piece
while pnpm dev prints ➜ Console: http://localhost:3000/_console/ on every boot. The product
sends them to a screen and never explains it.

This PR adds one section to the generated README.md naming the Console path, the consequence,
and src/apps/*.app.ts as the remedy. Documentation only — no change to what the scaffolder
writes into src/.

Reverse verification

Runtime, from real scaffold-and-boot runs — proving the instruction this PR ships is true.
One *.app.ts added to the scaffolded project (not to the template), rebooted:

GET /api/v1/meta/app
before2setup, account
after3my_app_main, setup, account

The project app carries nav_notes → objectName: my_app_note. The empty src/apps/ is the
entire cause and an app is the entire remedy — exactly what the new README section now says.

The test. Reverting only the README to origin/main and re-running the new file:

× discloses that no app means no Console navigation
AssertionError: README must name the Console path:
expected '# Blank Starter\n\nMinimal ObjectStac…' to match /\/_console\//
Test Files 1 failed (1) · 4 tests | 1 failed

The three tree/vacuity assertions stayed green — the failure is the disclosure, which is the
predicted direction. The README was then restored from the commit and confirmed byte-identical.

The assertion is bidirectional on purpose: the template's tree decides which README claim is
required, so if someone later adds an app to the template, the stale "ships no app" sentence
fails rather than sitting green on a claim that has become false.

Gates

Re-derived with node scripts/pm/dispatch-gates.mjs (no path arguments) after the final commit,
on a clean tree — committed 3, working tree 0, untracked 0. The dispatch brief named no gate
family; all of these are newly derived.
Each line below is the gate's own verdict.

GateVerdict
check:changeset-gate-self-tests✓ check-empty-changeset --self-test: 118 assertions over real temp git repos
check:objectui-changeset✓ objectui-range --self-test: all checks passed
check:slot-lookup✓ slot-lookup ratchet holds: 107 unswept site(s) in 25 file(s), none new
check:template-version-sync✓ sync-template-versions --self-test: 40 assertions over temp fixtures
check-adr-0087-registration.mjs✓ this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen).
check-changeset-no-major.mjs✓ This diff introduces no 'major' bump.
check-empty-changeset.mjs✓ No empty-frontmatter changeset introduced by this diff (1 declaring changeset(s) added).
docs-audit/check-affected-docs.mjs✓ affected-docs self-test: 262 cases pass.

Convention-triggered by adding a test file:

GateVerdict
check:query-options-erasure✓ query-options-erasure ratchet holds: 67 unswept non-test site(s) in 17 file(s), none new
check:engine-double-contractcheck-engine-double-contract: OK — 340 pinned, 133 in the DEBT ledger, 2 exempt.
check:where-matcher✓ where-matcher conformance holds: 266 matcher(s) discovered … 0 silently-wrong … none new.
check:type-check-coveragecheck-type-check-coverage: OK — 64/77 workspace packages type-checked (plus the root), 13 in the DEBT ledger, 1 exempt.

Plus check:nul-bytescheck-nul-bytes: OK (scanned 6145 text file(s) … no raw ASCII control bytes).
and pnpm --filter create-objectstack typecheck && … testTest Files 8 passed (8) · Tests 88 passed (88).

One family declared NOT MEASURED locally: check:type-check-debt. Its --re-measure path
refuses on this worktree — "55 workspace dependenc(ies) of the ledgered packages have no built
type entry point on disk"
— and that refusal means not-measured, never not-applicable. It needs
a full 77-package turbo run build, and the shared verify lock had two agents queued behind me,
so holding it for that was disproportionate to a three-file documentation change. What bounds the
risk: create-objectstack carries no ledger entry in either DEBT or TEST_DEBT, and
--re-measure only re-runs tsc for ledger entries, so a new test file here cannot move a ledger
number. The half my change could move — the structural one, a test file no tsc program reaches —
ran green above, and the file is provably inside the package's program (tsconfig.json is
include: ["src"], excluding only src/templates, and the package typecheck passes with the file
present). CI runs the family regardless.

Fences

Deliberately left open

This PR is scoped with Part of deliberately, so that #10317 stays open on merge. Two things
it raises are not settled here:

  1. The (b) product call. My recommendation is no — do not ship an app in blank, on the
    four readings above. That is a recommendation, not a ruling, and it is the maintainer's to make.
  2. The os validate silence the card flags — filed separately as [finding] os validate drops the whole UI: row at zero apps, so a project with no navigable UI reads identically to one that was never asked #10504, unassigned. Measured
    there: at zero apps the UI: row is not printed as 0, it is absent, so "no navigable UI"
    and "this summary does not report on UI" read identically. That lives in packages/cli, outside
    this card's file fence. Note the measurement also argues against the card's suggested shape: a
    warning would fire on every clean scaffold, since zero apps is the intended blank state — a
    printed UI: 0 Apps is the cheaper reading.

Generated by Claude Code


Generated by Claude Code

Scaffolded with the real CLI against published 17.1.0 packages and booted
with `objectstack dev --ui`: `GET /api/v1/meta/app` returns two items, both
platform apps (setup, account), while `GET /api/v1/data/my_app_note` serves
the scaffolded object for the whole session. The object is live and simply
has no route into Console navigation.
That is deliberate. `blank` is described in the registry as "Minimal starter
— one object, REST API, ready to extend"; all three `os init` templates ship
`src/objects/` only, including the one described as "Full application with
objects"; and no `*.app.ts` has ever existed under `src/templates/**` in this
repo's history. Apps are what the agent authors in step 2 of the root
README's loop, not what the scaffolder pre-writes into every project.
What was missing is the disclosure: `pnpm dev` prints the Console URL on
every boot, and nothing the newcomer could reach explained why their object
is not there. Adds a "The Console" section to the generated README naming the
path, the consequence and `src/apps/*.app.ts` as the remedy, plus a
bidirectional test — the template's own tree decides which README claim is
required, so adding an app later cannot leave a stale "ships no app" green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019bmVFqoQPq63zhKrxdYG1r
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/create-objectstack/src/templates/blank/README.md) — pages documenting those are invisible to this run

Coarse fallback — 1 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json b20c8d2fa42af17a7b4367866f3120f354da37a6packageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Aug 21, 2026
@os-elon
os-elon marked this pull request as ready for review August 21, 2026 02:01
@os-elon
os-elon added this pull request to the merge queueAug 21, 2026
Merged via the queue into main with commit 3a3f209Aug 21, 2026
30 checks passed
@os-elon
os-elon deleted the claude/issue-10317-blank-template-ships-no-app branch August 21, 2026 02:26
os-elon pushed a commit that referenced this pull request Aug 21, 2026
Backs the three `src/templates/blank/` files out of this PR. They are the
declared surface of #10321, which was promoted into sweep anchor #10353 —
a queued card with its own PR contract ("zero changes outside the six
items", one closing line per member). Sweeping them here would have left
that member half-delivered by a PR that never named it, and `blank/README.md`
is also touched by the open PR #10507.
The canonical host is settled now, so #10321's open question ("dev states
which and why") has an answer; that is recorded on the anchor rather than
acted on here. The gate does not read these files — they are outside the
published-doc population — so nothing goes red by leaving them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GawRwpD44VwBDVy3hs77AX
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-elon@claude