Repository navigation
fix(create-objectstack,cli,docs): make the third-party onboarding path actually work on the current release - #2907
Merged
Conversation
… guides Evaluated the docs from an external (npm-consumer) developer's perspective: the getting-started section had no hands-on scaffold-to-API tutorial that doesn't assume an AI agent or the monorepo, and the deployment section had no self-hosting guide (only Vercel as a concrete target). - getting-started/your-first-project: scaffold via create-objectstack, generated layout and package surface, dev server, REST calls, manual model edits, validate gate, artifact build - deployment/self-hosting: systemd, Docker (multi-stage), Docker Compose with Postgres, required secrets (OS_AUTH_SECRET/OS_SECRET_KEY), health and readiness probes, reverse-proxy wiring, multi-node notes - create-objectstack README: replace stale template list (minimal-api/full-stack/plugin) with the real registry (blank + remote todo/compliance/content/contracts/procurement) and document --skip-skills and the identity-rewrite behavior - nav meta.json + cross-links from section indexes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Em3ky9uu6zw2cYzVhqCij2
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Em3ky9uu6zw2cYzVhqCij2
…le grammar) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Em3ky9uu6zw2cYzVhqCij2
…h actually work on the current release Verified the published npm onboarding flow end-to-end as an external user (npx create-objectstack@latest → install → validate → dev → REST → build → os start) and fixed everything that broke: - create-objectstack: the bundled blank template pinned ^6.0.0 while the registry publishes 14.x, so fresh projects installed a framework eight majors behind the docs. Template bumped to the current API (Field.longText → Field.textarea, drop the removed api.rest config key, declare sharingModel per ADR-0090) and the scaffolder now rewrites every @objectstack/* range in the generated package.json to its own release version, so generated projects track the registry even if the committed template drifts. Consistency tests ratchet the template major and the README template table against the TEMPLATES registry. - cli: os validate now runs the ADR-0090 D7 security posture check — previously a stack passed validate and then failed the identical gate in os build, breaking validate's documented same-gates contract. - docs: quick-start / build-with-claude-code / your-first-project examples updated to the current field API + explicit sharingModel; the tutorial's curl flow now includes the seeded dev-admin sign-in that the data API requires; cli.mdx names npm create objectstack as the recommended scaffolder with os init for plugin/bare-config cases. - deployment: new Backup & Restore guide (state inventory incl. the OS_SECRET_KEY escrow trap, per-driver recipes, restore drill); Kubernetes reference manifests in self-hosting; ready-to-copy Docker packaging in examples/docker linked from the guide. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Em3ky9uu6zw2cYzVhqCij2
…merged to main as 04ce2db)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 19 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Em3ky9uu6zw2cYzVhqCij2
os-zhuang
marked this pull request as ready for review
July 14, 2026 09:21
…on warnings alongside conversion notices Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Em3ky9uu6zw2cYzVhqCij2
os-zhuang
added a commit
that referenced
this pull request
Jul 14, 2026
…-time template dep sync (#2912) Close the remaining template-staleness gaps behind #2907 (fixes #2908): a scaffold-local PR job that scaffolds with the repo-built dist and runs the generated project end-to-end (install → validate → build → boot → health probes → docker build/run of examples/docker), a nightly registry canary running npx create-objectstack@latest across every template as a real first-run user, and scripts/sync-template-versions.mjs chained into the root version script so a release can never ship the blank template pinning a stale @objectstack/* range.
This was referenced Aug 16, 2026
Merged
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Aug 17, 2026
…ge-tag cannot misfire (objectstack-ai#9102) * feat(scripts): sync docs image tags at version time so the gate cannot misfire `check:docs-image-tag` (objectstack-ai#9018) pins the docs' concrete image/CLI tags to `packages/cli`'s version, so a bump reddens it until the doc surfaces move. The red could not land on the change that caused it: `changeset version` bumps the version on a release PR that gets no CI (changesets/action opens it with the default GITHUB_TOKEN, per sync-template-versions.mjs's own header), so the bump merged green and the gate reddened on the next ordinary PR, naming files that author never touched. Adds scripts/sync-docs-image-tags.mjs to the root `version` chain, beside the two sync scripts already there -- the shape this repo chose for the identical drift class in objectstack-ai#2907. It imports SURFACES, PATTERNS, VERSION_SOURCE, extractOccurrences and checkSurfaces from the gate, so the rewriter and the gate read one list and its verdict IS the gate's. Version-time sync only: no publish, no tag, no Version Packages PR (objectstack-ai#6170). check-docs-image-tag.mjs gains an entry-point guard and exports VERSION_SOURCE. Both additive: importing it previously ran main() and exited the process, which made its exports unusable by the one consumer they were added for. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011RB4waLuNbdruCo6X9oobm * test(scripts): name the inert-rewriter failure instead of crashing on it An ablation that made rewriteText inert died of a TypeError indexing an empty `changed` array, two limbs before the byte-identity control ran. Optional chaining so the self-test REPORTS the inert case by name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011RB4waLuNbdruCo6X9oobm --------- Co-authored-by: Claude <noreply@anthropic.com>
hotlong
pushed a commit
that referenced
this pull request
Sep 4, 2026
…#15332) `content/docs/releases/index.mdx` ends each major's entry with a status parenthetical — "(current series: 17.2.0, released 2026-08-23)". That sentence is derived data: the newest GA of a major is already readable from `packages/spec/CHANGELOG.md`, which is where check-release-section-coverage reads it from to produce its finding. Kept by hand, it went stale on three consecutive minors (#10232, #11649, and this one), each caught after the fact. The gate that names it cannot fire on the change that causes it: the version commit is opened by changesets/action with the default GITHUB_TOKEN and gets no CI, and lint.yml runs the gate without `--strict`, where a finding is advisory and the job is green by design. Only release-coverage-patrol.yml passes `--strict`, and a standing patrol is an after-the-fact reader by construction. Adds scripts/sync-release-index-currency.mjs to the root `version` chain, beside the three sync scripts already there — the shape this repo chose for the identical drift class in #2907 and #9064 (e569cac). It imports INDEX_PATH, SPEC_CHANGELOG, the scope predicate, the entry and status lookups and the verdict from check-release-section-coverage.mjs, so the rewriter and the gate read one contract and the rewriter's verdict IS the gate's. It rewrites exactly one shape, `current series: <x.y.z>, released <date>`, and refuses the ones that need a human sentence — a "final release:" claim a newer minor contradicts, an entry with no status field — which then reach the gate's own words and stop the run. Assertion 1 (a published minor has a section) is never consulted here: a rewriter cannot write curated prose, and hard-failing the version lane on unwritten prose would wedge it for a debt the release did not create. release.yml's post-version shape assertion and cut-rc.yml's staging allowlist both resolve the surface from `syncedPaths()` at run time, joining the two lists they already resolve on the same terms — a fourth literal would be a fourth contract. Measured: without that third list the post-version validation rejects content/docs/releases/index.mdx as "outside the reviewed surface", which is the treadmill guard doing its job. The index line itself was fixed by running the stamper, not by hand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m
This was referenced Sep 5, 2026
os-litant
added a commit
that referenced
this pull request
Sep 5, 2026
…w declarations in the CI filter-parity pin Two review findings from PR #15974. 1. The head reddened `check-ci-filter-parity --self-test`: the pre-#10015 rollback now uncovers 21 globs, not 19. Measured, the delta is exactly the two `content/docs` pages this branch declared for `@objectstack/cli` (troubleshooting.mdx, getting-started/index.mdx) — an origin/main control yields 19 with an empty symmetric difference otherwise. Both are recorded by name, the way the pin's own comment prescribes for #14824's three, rather than the count merely being bumped. 2. The shipped history claim was wrong. `dbb54e12f0c` (2026-05-25) added the bundled template at `^5.3.0`, not `^6.0.0`; `eaff01425b7` (#2907, 2026-07-14) moved it to `^6.0.0` and recorded no reasoning about TypeScript — in that same one-file diff the five `@objectstack/*` ranges move `^6.0.0` to `^14.0.0` while the `typescript` line moves onto the `^6.0.0` they are vacating. So the three-value split is 53 days old, not 102, and the two-value split is 210 (the changeset said 211). Corrected in init.ts, create.ts, the pin's header and the changeset, which now agree. A dated provenance claim written into source comments is exactly the restated fact nothing checks that this card exists to close; shipping a wrong one inside the fix would have been self-refuting. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 9, 2026
…d os create stop restating the tsconfig and the devtool ranges (objectstack-ai#15974) * refactor(cli): extract the restated scaffold emission policy into one module `os init` and `os create` each restated the third-party ranges and the `tsconfig.json` an emitted project carries. Measured on the tree, the TypeScript range was written in six places across three scaffolders and had split into three values (`^5.3.0` / `^5.8.0` / `^6.0.0`); vitest into two. Both CLI scaffolders now read one definition per value. Surviving values: `^5.3.0` for TypeScript (the floor two live doc pages already state) and `^4.0.0` for vitest (no recorded decision for either; `^4.0.18` claimed a patch-level floor nothing justifies). Neither changes what an emitted project installs — `^5.3.0` and `^5.8.0` both resolve to typescript 5.9.3, `^4.0.0` and `^4.0.18` both to vitest 4.1.11. `create-objectstack`'s `^6.0.0` is deliberately untouched: it cannot import from `@objectstack/cli` (the dependency edge runs the other way), and unifying it would change what a scaffolded project installs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N * test(cli): pin the shared scaffold emission policy across all five emissions Both ends of every expectation are derived — from the renderers, from the other scaffolder, or from the doc pages that already state the TypeScript floor — so a transcription cannot go green on a half-edited tree. `os init` writes its `tsconfig.json` inside `run()`, so that half is measured by driving the real command into a throwaway directory and reading the bytes off disk; an exported renderer nobody calls would pass every in-process assertion. The two doc pages the floor case reads are declared in `scripts/cross-package-test-inputs.mjs` and mirrored into `turbo.json`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N * chore(changeset): record the scaffold emission policy extraction Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N * fix(cli): correct the shipped provenance claim, and record the two new declarations in the CI filter-parity pin Two review findings from PR objectstack-ai#15974. 1. The head reddened `check-ci-filter-parity --self-test`: the pre-objectstack-ai#10015 rollback now uncovers 21 globs, not 19. Measured, the delta is exactly the two `content/docs` pages this branch declared for `@objectstack/cli` (troubleshooting.mdx, getting-started/index.mdx) — an origin/main control yields 19 with an empty symmetric difference otherwise. Both are recorded by name, the way the pin's own comment prescribes for objectstack-ai#14824's three, rather than the count merely being bumped. 2. The shipped history claim was wrong. `dbb54e12f0c` (2026-05-25) added the bundled template at `^5.3.0`, not `^6.0.0`; `eaff01425b7` (objectstack-ai#2907, 2026-07-14) moved it to `^6.0.0` and recorded no reasoning about TypeScript — in that same one-file diff the five `@objectstack/*` ranges move `^6.0.0` to `^14.0.0` while the `typescript` line moves onto the `^6.0.0` they are vacating. So the three-value split is 53 days old, not 102, and the two-value split is 210 (the changeset said 211). Corrected in init.ts, create.ts, the pin's header and the changeset, which now agree. A dated provenance claim written into source comments is exactly the restated fact nothing checks that this card exists to close; shipping a wrong one inside the fix would have been self-refuting. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 9, 2026
…objectstack-ai#15332) (objectstack-ai#15392) * fix(docs): stamp the release index's "current series" at version time (objectstack-ai#15332) `content/docs/releases/index.mdx` ends each major's entry with a status parenthetical — "(current series: 17.2.0, released 2026-08-23)". That sentence is derived data: the newest GA of a major is already readable from `packages/spec/CHANGELOG.md`, which is where check-release-section-coverage reads it from to produce its finding. Kept by hand, it went stale on three consecutive minors (objectstack-ai#10232, objectstack-ai#11649, and this one), each caught after the fact. The gate that names it cannot fire on the change that causes it: the version commit is opened by changesets/action with the default GITHUB_TOKEN and gets no CI, and lint.yml runs the gate without `--strict`, where a finding is advisory and the job is green by design. Only release-coverage-patrol.yml passes `--strict`, and a standing patrol is an after-the-fact reader by construction. Adds scripts/sync-release-index-currency.mjs to the root `version` chain, beside the three sync scripts already there — the shape this repo chose for the identical drift class in objectstack-ai#2907 and objectstack-ai#9064 (e569cac). It imports INDEX_PATH, SPEC_CHANGELOG, the scope predicate, the entry and status lookups and the verdict from check-release-section-coverage.mjs, so the rewriter and the gate read one contract and the rewriter's verdict IS the gate's. It rewrites exactly one shape, `current series: <x.y.z>, released <date>`, and refuses the ones that need a human sentence — a "final release:" claim a newer minor contradicts, an entry with no status field — which then reach the gate's own words and stop the run. Assertion 1 (a published minor has a section) is never consulted here: a rewriter cannot write curated prose, and hard-failing the version lane on unwritten prose would wedge it for a debt the release did not create. release.yml's post-version shape assertion and cut-rc.yml's staging allowlist both resolve the surface from `syncedPaths()` at run time, joining the two lists they already resolve on the same terms — a fourth literal would be a fourth contract. Measured: without that third list the post-version validation rejects content/docs/releases/index.mdx as "outside the reviewed surface", which is the treadmill guard doing its job. The index line itself was fixed by running the stamper, not by hand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m * ci(lint): run the release-index rewriter's self-test at PR time (objectstack-ai#15332) Third version-time rewriter, third self-test step, beside the two already in this job (check:docs-image-tag-sync, check:template-version-sync). Two gates require a PR-time caller, and both name this family: check-self-test-wired ("a script CI runs that ships a --self-test must have that self-test run by CI"), and dispatch-gates' "a deferred pair defers the LEAD, not the load break" — a family no every-PR workflow runs leaves its import edges unwatched at PR time, so a change breaking the module load of check-release-section-coverage.mjs would not redden the PR that made it. With release.yml as the only caller that self-test was 2-of-1382 RED naming check:release-index-currency-sync.⚠️ Not the --strict promotion, and it cannot become one: this step runs only --self-test, whose cases are string fixtures. It never reads the live index for currency and never reads a release page, so no corpus state can red it. The advisory, non-strict `Release section-coverage guard` step is untouched — this diff is 44 insertions and 0 deletions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UHvF5hyiZjnCyExFnfQB8m --------- Co-authored-by: Claude <noreply@anthropic.com>
This branch was successfully deployed
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.
背景
#2899 合并后,按建议对 npm 入门路径做了真实的端到端验证(以外部用户身份:
npx create-objectstack@latest→ install → validate → dev → REST → build →os start),发现入门路径在当前发布版上实际是坏的,并顺藤摸瓜修复了一个 CLI 门禁缺口。验证发现的问题与修复
create-objectstack(核心问题)
^6.0.0,而 npm 上所有包已发布到 14.7.0 —— 实测新项目装到 6.9.0。Field.longText已移除 → 改为Field.textarea;api: { rest: ... }不再是defineStack的合法键(REST 已默认开启)→ 移除;sharingModel被 ADR-0090 安全姿态门禁拦截 → 显式声明'private'。修复策略(双保险):模板字面量更新到
^14.0.0+ 当前 API;同时脚手架在生成时把package.json里所有@objectstack/*区间改写为^<自身版本>(全家桶 lockstep 发版,恒可解析)——即使模板字面量再次漂移,生成的项目也跟随当前发布版。新增一致性测试棘轮:模板依赖 major 必须等于包自身 major;README 模板表必须与TEMPLATES注册表一致(正是 #2899 发现的两类腐化)。修复后全流程在 14.7.0 上实测跑通:scaffold → tsc/validate ✓ → dev 启动 → 登录 seeded admin → REST 增查 ✓ →
os build→os start+ health/ready ✓。@objectstack/cli
os validate缺 ADR-0090 D7 安全姿态检查:同一份 stackvalidate放行、os build拒绝(例如缺sharingModel的自定义对象),违背 cli.mdx 声明的 "validate 与 compile/build 同门禁(只是不产出物)" 契约。已把validateSecurityPosture对齐进 validate(error 拦截、advisory 警告、--json一致)。CLI 全部 489 个测试通过;补丁后实测:缺 sharingModel 时 validate 拦截,声明后通过。文档
quick-start/build-with-claude-code/your-first-project的示例更新到当前字段 API,并补上显式sharingModel(含"读对象要看什么"清单项)。your-first-project的 curl 流程加入 seeded dev-admin 登录步骤(14.x 数据 API 默认要求会话)——原裸 curl 实测返回unauthenticated。cli.mdx收敛双脚手架口径:npm create objectstack@latest为推荐入口,os init定位 plugin 骨架 / 裸配置场景。部署板块补齐
OS_SECRET_KEY托管陷阱——没有它的数据库备份是不完整备份)、按驱动的备份方法、恢复演练步骤(对应 production-readiness 清单要求)。self-hosting新增 Kubernetes 参考 manifests(探针接已验证的/api/v1/health、/api/v1/ready)。examples/docker/:可直接复制进脚手架项目的 Dockerfile / compose / .dockerignore,与 self-hosting 文档互链。验证
npm create objectstack(本地构建的 dist)冒烟:生成项目依赖为^14.7.0、textarea、sharingModel、无 api 块 ✓pnpm --filter create-objectstack test(4 个新测试)✓;--filter @objectstack/cli test(489)✓check-role-word/check-doc-authoring✓;docs 站完整构建 ✓;ESLint ✓examples/docker的镜像构建未在本会话执行(容器内无 docker daemon);Dockerfile 内容与已在裸机验证的npm ci → os build → os start流程一一对应。分支说明:
claude/third-party-dev-docs-0t5256按规范从最新 main 重建;一个-s ours合并结点用于接续被 GitHub 删除前的旧分支引用,不影响 diff。🤖 Generated with Claude Code
https://claude.ai/code/session_01Em3ky9uu6zw2cYzVhqCij2
Generated by Claude Code