Uh oh!
There was an error while loading. Please reload this page.
create-objectstack: converge scaffold docs on canonical host, drop last dead monorepo refs - #11191
Merged
Merged
Conversation
…op dead monorepo refs Fixes#10990: templates/AGENTS.md, blank/Dockerfile, blank/docker-compose.yml still pointed at objectstack.com (wrong domain) or the unratified docs.objectstack.ai alias; converge all three on the ruled canonical origin https://objectstack.ai. Fixes#11022: blank/README.md's last two monorepo-only references (ADR-0097, and an unlinked mention of skills/ 'in the ObjectStack framework repo') are rewritten self-contained, with the ADR-0097 line pointing at the public connectors doc and the skills line pointing at the followable 'npx skills add' form the scaffolder's own closing output already uses. Extends starter-comments-self-contained.test.ts (#10324) with the pin obligations both cards call for: assertion 4 pins host convergence via the same shippedFiles() walker (no other gate's population reaches these template files), and a fifth MONOREPO_ONLY pattern closes the prose-shaped hole the four syntactic patterns missed. The self-retiring EXCLUDED entry for blank/README.md is removed now that the file cites nothing monorepo-only.
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 2 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 8 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
…s carry blank/README.md's rewritten connectors and skills lines were unguarded by assertion 2: deleting the 'at boot' materialization clause or the 'npx skills add objectstack-ai/objectstack/skills' install command left assertions 1/3/4 all green, since none of them notice a fact quietly disappearing rather than an unfollowable reference reappearing. Add a blank/README.md entry to RATIONALE with one fact per rewritten line, matched loosely enough that rewording stays free.
This was referenced Aug 23, 2026
…age-test-inputs literal collector check:cross-package-test-inputs' flat literal collector matches ANY backtick/quote-wrapped repo-relative path anywhere in a file's text, including prose comments -- it cannot tell a real specifier from a mention. Three comments named scripts/check-published-readme-links.mjs in backticks while explaining why assertion 4 could not live in that gate, which the collector read as an escaping dependency and demanded a declared glob for. The test does not actually read that file (its host list is restated, not imported, exactly like assertion 3's candidate list already is), so the correct fix is to stop spelling the path, not to declare a false dependency -- this package's own entry in that gate's script documents the identical trade for a prior case (scripts/sync-template-versions.mjs while it was still only a mention: 'rewording ... into unquoted prose unforced a live radius'). Renamed the three sites to 'the published-readme-links gate' with no scripts/ prefix and no quoting.
os-elon
marked this pull request as ready for review
August 23, 2026 02:57
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
Fixes#10990
Fixes#11022
Premise check
Both cards' claimed line numbers and file states were re-measured against
origin/mainbefore editing, and both held:templates/AGENTS.md:99(objectstack.com),templates/blank/Dockerfile:10andtemplates/blank/docker-compose.yml:7(docs.objectstack.ai).CANONICAL_DOCS_ORIGIN = 'https://objectstack.ai'confirmed atscripts/check-published-readme-links.mjs:259.:77→:82,:134→:139), text matching verbatim.check:published-readme-links's population (publishedDocs()) walks each publishable package'sfilesarray.create-objectstack'sfilesis["dist", "README.md", "CHANGELOG.md"]—templates/AGENTS.mdlives undersrc/, never published as a top-level README.tsup.config.tsdoes copysrc/templates→dist/templateson build, so in principle a builtdist/templates/AGENTS.mdwould match thedistglob — butlint.yml'slintjob (which runs this gate) never buildscreate-objectstackbefore running it, sodist/doesn't exist there and the population is unaffected. Confirmed by running the gate on this tree:60 published markdown file(s)— matches its own documented census,create-objectstackabsent.Dockerfile/docker-compose.ymlaren't markdown regardless.See `AGENTS.md` for the full convention— re-verified, not a defect.packages/create-objectstack/src/index.tsreally doeswriteIfAbsent(path.join(targetDir, 'AGENTS.md'), rendered), and the scaffolded project sweep below shows it landing.No premise held wrong; nothing here needed a route change from the brief.
The fix
#10990 — converged all three lines on the ruled canonical origin (maintainer, 2026-08-21):
https://objectstack.ai/docs,https://objectstack.ai/docs/deployment/self-hosting×2. Each rewritten URL verified to resolve againstcontent/docsbefore committing (content/docs/index.mdx,content/docs/deployment/self-hosting.mdxboth exist).#11022 —
templates/blank/README.md, both lines rewritten self-contained per the #10324 style (state the fact, link a public page instead of an internal identifier)::82— dropped(ADR-0097), added a link tohttps://objectstack.ai/docs/automation/connectors(verified: covers connector materialization directly, and resolves viacontent/docs/automation/connectors.mdx).:139— dropped "in the ObjectStack framework repo" (unfollowable — a reader with only their own project has no path to it), replaced with the followable install form the scaffolder's own closing output already uses:`npx skills add objectstack-ai/objectstack/skills` (see `AGENTS.md`).AGENTS.mdis already established (line :102 above) as a file that really ships into the project, and it already documents this exact install command in full.Neither edit deletes the rationale each comment was carrying — both facts survive, reworded, with a resolvable pointer replacing the internal identifier.
Pin design
packages/create-objectstack/src/starter-comments-self-contained.test.ts(#10324) gets three changes:EXCLUDEDentry forblank/README.mddeleted. The retirement fired as designed: the file no longer cites anythingMONOREPO_ONLY, so it's scanned like every other shipped file (assertion 1) rather than staying silently exempt.A fifth
MONOREPO_ONLYpattern —/\bObjectStack (?:framework )?(?:mono)?repo\b/i— closes the hole flagged at claim time: the original four patterns are all syntactic identifiers (ADR id, issue number, script path, package path), and:139's "the ObjectStack framework repo" is the same defect class in prose form — nothing in the original four could have matched it. Deliberately scoped to the framework's own name next to a "repo" word, not the literal sentence, so a reword still gets caught; deliberately not a barerepo/monorepomatch, because this same template tree correctly calls the reader's own scaffolded project "a monorepo root" (blank/pnpm-workspace.yaml) — a true, self-contained, followable statement about a directory they do have. Verified against the whole shipped tree: exactly one hit, the line being fixed, both before and after — no false positives anywhere else in the 12 shipped files.A new assertion 4 — host convergence, driven by the same
shippedFiles()walker that already enumerates everything a scaffold ships. This is the pin create-objectstack templates: AGENTS.md links objectstack.com, Dockerfile/docker-compose.yml still use the docs.objectstack.ai alias #10990 had none of:check:published-readme-linksprescribes the same canonical origin but its population (publishable packages' published markdown) never reaches these template files (see premise-check section above). The host list is restated, not imported, fromcheck-published-readme-links.mjs'sDOCS_HOSTS/CANONICAL_DOCS_ORIGIN— the same cross-package-read-radius reason assertion 3's candidate list already gives for restating rather than importing. Swept the whole shipped tree for every host in that list before adding the assertion: zero occurrences outside the three lines this PR fixes.Reverse-verification (committed fix first, then reverted on top, restored via
git checkout HEAD --)objectstack.com/docs.objectstack.ai×2) → assertion 4 fails on exactly those 3 files, each error naming the exact offending host string (e.g.blank/Dockerfile cites "https://docs.objectstack.ai"). 31/34 tests still pass. Restored, green again (34/34).:82(ADR-0097) and:139(framework repo) together → assertion 1 fails onblank/README.md, first hit reported is the ADR pattern (loop order), confirming the existing pattern still catches its half.:139(kept:82fixed) → isolates the fifth pattern: assertion 1 fails onblank/README.mdwithcites a reference to the ObjectStack repo as an unlinked location ("ObjectStack framework repo")— proves the new pattern is what would have caught the hole the claim-time review flagged, not a coincidence of pattern-loop ordering. Restored, green again (34/34).PM review addendum — assertion 2 coverage for
blank/README.mdPM review flagged a real gap: assertion 2 (
RATIONALE, "the rationale survives") listed only#10324's two original files, so this PR's own two
blank/README.mdrewrites were unguarded —deleting the "materializes ... at boot" clause or the
npx skills add objectstack-ai/objectstack/skillsinstall command would leave assertions 1/3/4 all green (noADR id to find, no non-canonical host, every present URL still resolves) while the fact
disappeared. Exactly the failure mode the file's own header describes: "a one-way grep stays
green while the explanation is deleted."
Added a
blank/README.mdentry toRATIONALEwith one fact per rewritten line::82— that a provider-bound connector is materialized into a live, dispatchable connectorat boot (not written by hand):
/materializ\w*[^.]*?\bat\s+boot\b/i(the[^.]*?spansthe line wrap between "at" and "boot" in the source).
:139— the followable skills install command itself:/npx skills add objectstack-ai\/objectstack\/skills/i.Reverse-verification of both new legs (same method: commit fix, mutate on top, restore via
git checkout HEAD --):82's paragraph (kept it grammatical,reintroduced nothing unfollowable) → exactly 1 test fails, by name:
blank/README.md > still explains that a provider-bound connector is materialized into a live, dispatchable connector at boot (not written by hand). 35/36 other tests — includingassertions 1, 3, 4 and the other new leg — stayed green, confirming the exposure PM described
was real before this fix. Restored, green again (36/36).
npx skills add objectstack-ai/objectstack/skillsinstall command from:139(replaced with "the skills CLI", still true, still no unfollowable reference) →
exactly 1 test fails, by name:
blank/README.md > still explains the followable skills install command. Same 35/36-green pattern. Restored, green again (36/36).Full suite at the new HEAD (
cf9a767b36):pnpm --filter create-objectstack test—Test Files 13 passed (13)/Tests 160 passed (160)(158 → 160: the two new RATIONALE legs).pnpm --filter create-objectstack typecheck— clean. Re-ran the convention-triggered ratchetsthis test-file edit implicates (
check:query-options-erasure,check:type-check-coverage,check:engine-double-contract,check:where-matcher— all green, baselines unchanged) andcheck:type-check-debt --re-measureafter rebuilding the full workspace closure again(
turbo build, 70/70 tasks) — identical verdict to the first measurement:OK — 33 ledger entr(ies) re-measured ..., 1896 raw tsc error(s) total, none above its recorded number.check:nul-bytesand a manual control-byte scan of the diff stayed clean.CI-red fix —
check:cross-package-test-inputs(PM review, second pass)Lint & Repo Gatescame back red oncheck:cross-package-test-inputs: its flat literalcollector (
repoRelativeLiterals) matches ANY backtick/quote-wrapped repo-relative pathanywhere in a file's TEXT — prose included, no parsing — and my
RATIONALEaddendum commit'sprose named the published-readme-links gate's script path in backticks three times while
explaining why assertion 4 could not live there. The test does not actually read that file (the
host list is restated, not imported), so the flag was spurious — a real dependency was never
created.
Per PM's instruction, did not widen the package's declared globs — that would declare a
false dependency and invalidate the turbo cache on every unrelated
scripts/change for a readthat does not exist. Reworded all three sites to name the gate ("the published-readme-links
gate") without spelling or quoting its path — the same convention this file's own pre-existing
assertion-3 comment already uses for
check-docs-redirects.mjs("check-docs-redirects'pageCandidates", no backticks, no
scripts/prefix), and the same trade this package's OWNentry in
check-cross-package-test-inputs.mjs's ledger documents for a prior, structurallyidentical case (
sync-template-versions.mjs, while it was still only a mention: "rewording ...into unquoted prose unforced a live radius").
Verified:
pnpm check:cross-package-test-inputsnow printsOK: 13 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob(was previously failingwith
create-objectstack names path(s) no declared glob covers). Also ran every other stepstill queued behind the failing one in
lint.yml'slintjob (it aborts at first failure, soCI's report could not have surfaced a second failure past this one) — all ~20 remaining
check:*steps green:
check:live-db-isolation,check-ci-filter-parity(self-test + real),partition-test-shards --self-test,check-declaration-mirrors(self-test + real),check:examples-live-imports,check:test-source-alias,check:refd-timer-probe,check:type-source-resolution,check:published-files,check:engine-double-contract,check:where-matcher,check:kernel-hook-pairs,check:plugin-teardown-shape,check:resume-authority-declared,check:driver-memory-census,check:merge-driver,check:spec-parsed-alias,check:tenant-chokepoint,check:pnpm-filter-targets. Also re-rancheck:nul-bytes,check:published-readme-links(both unaffected, still green) and ESLintscoped to the changed file (clean, exit 0 — full-repo
pnpm lintwas not re-run locally; nothingin this diff is JS/TS logic, only comments). Full package suite reconfirmed at the new HEAD
(
f50d8b0eff): 160/160 tests, typecheck clean.Gap confirmed and filed:
dispatch-gates.mjsnever namedcheck:cross-package-test-inputsfor this diff at all — not matched, not convention-triggered, not unreachable — because the
gate's trigger (a test file's content gaining a new escaping read or a new quoted mention) is
identical in kind to the five gates already in the
'adds or edits a test file'convention list(
check:query-options-erasureetc.), but it isn't itself in that list. Filed unassigned as#11199 with the root cause and a suggested one-line fix (add it as a sixth entry in that
same convention-trigger kind); not fixed here because widening
dispatch-gates.mjsis unrelatedto this PR's own scope.
Gate verdicts (all at
d4bfa10cd4, first HEAD — see the two addenda above for thecf9a767b36/f50d8b0effre-runs)Package-scoped:
pnpm --filter create-objectstack build— clean (tsup + dts, exit 0)pnpm --filter create-objectstack test—Test Files 13 passed (13)/Tests 158 passed (158)pnpm --filter create-objectstack typecheck— clean, no output (exit 0)node scripts/pm/dispatch-gates.mjs(no paths — merge-base derived, 6 paths incl. the changeset) named these local gates, all run and green:pnpm check:changeset-gate-self-tests— ✓ (self-tests) + real-diff run:✓ No empty-frontmatter changeset introduced/✓ adds no declared-breaking changeset/✓ introduces no major bumppnpm check:objectui-changeset— ✓ self-test all checks passedpnpm check:slot-lookup— ✓ ratchet holds, no new sites, baseline unchangedpnpm check:template-version-sync— ✓ self-test 40 assertions (real check lives intemplate-version-stamps.test.ts, covered by the package test run above)pnpm check:test-source-alias— ✓ OK, 72 packages scannedpnpm check:type-source-resolution— ✓ OK, 77 packages scannednode scripts/check-ci-filter-parity.mjs—OK: all 86 declared cross-package glob(s) ... coverednode scripts/check-plugin-teardown-shape.mjs— ✓ 63 plugins, 0 known-unreachednode scripts/docs-audit/check-affected-docs.mjs— ✓ self-test 339 cases pass, exit 0Convention-triggered (test file added/edited):
pnpm check:query-options-erasure— ✓ ratchet holds,baseline key set verified against 2f93d0f53 (merge base): no files addedpnpm check:type-check-coverage— ✓ OK, 65/78 packages type-checked, unchanged from baselinepnpm check:type-check-debt --re-measure— built the full workspace closure first (pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*', 70/70 tasks, exit 0). An unbuilt-closure attempt was made first and correctly refused with--re-measure cannot run: 55 workspace dependenc(ies) ... have no built type entry point on disk(NOT MEASURED, not "not applicable"). After the build:check-type-check-coverage --re-measure: OK — 33 ledger entr(ies) re-measured in 207.7s, 1896 raw tsc error(s) total, none above its recorded number.(create-objectstackcarries no DEBT/TEST_DEBT ledger entry at all, consistent with its own cleantypecheckrun above.) Informational-only notes on 4 pre-existing, unrelated ledger entries with room to lower (plugin-approvals,runtime,plugin-auth,trigger-record-change) are untouched — out of this PR's scope, no regression.pnpm check:engine-double-contract— ✓ OK, 384 pinned / 133 DEBT / 2 exempt (unrelated to this diff — no fake-engine doubles touched)pnpm check:where-matcher— ✓ 281 matchers, 0 silently-wrong, baseline unchangedByte discipline:
node scripts/check-nul-bytes.mjsclean; manualgrep -naPcontrol-byte scan of the diff clean.CI e2e local-equivalent
packages/create-objectstack/**path-triggersScaffold E2E'sScaffold with repo distjob. Ran its local-equivalent by hand (network/docker unavailable in this container, so the install/build/boot/docker legs are out of reach here — CI covers those): built the CLI fromdist, scaffolded a real project (node bin/create-objectstack.js e2e-check-app --skip-install --skip-skills), then swept the generated project, not the template source. Every fixed line lands correctly in the output: canonical-host URLs inAGENTS.md/Dockerfile/docker-compose.yml, the rewritten connectors and skills lines inREADME.md; zero remainingobjectstack.com/docs.objectstack.ai/ADR-/ "framework repo" occurrences anywhere in the scaffolded tree. This is the same method #11022's card used to measure the original defect.Out of scope
Nothing found beyond the two cards' stated surface, except the dispatch-gates.mjs gap above (filed as #11199 — a tooling finding about this repo's PM dispatch machinery, unrelated to what #10990/#11022 ask for).
Generated by Claude Code