| cli.scaffold-first-run |
0 |
pass |
npm create objectstack@17.6.0 tasks-app exit 0 (installs + skills); os validate exit 0, os build exit 0 (dist/objectstack.json 2.2 KB); a second scaffold booted with os start (artifact auto-detected) → /api/v1/health 200, /api/v1/ready {"status":"ready","state":"running"} |
| cli.scaffold-first-run |
1 |
pass |
--help offers blank only; docs say the remote templates are retired; blank validates and builds |
| cli.scaffold-first-run |
2 |
pass |
healthy boot of a coherent scaffold (engines: { protocol: '^17' }), no protocol refusal |
| cli.scaffold-first-run |
3 |
pass |
installed set in .claude/skills/ = the 10 directories of the curated skills/ catalog exactly; no dogfood-verification or other internal skill present |
| cli.scaffold-first-run |
4 |
skipped |
no unhealthy boot occurred |
| cli.scaffold-console-first-paint |
0 |
pass |
pristine scaffold npx os validate exit 0 |
| cli.scaffold-console-first-paint |
1 |
pass |
/_console/ 200 text/html; screenshot (live, not attached): login form at /_console/login, then the home shell ("Build an app", "Your apps", Setup tile) |
| cli.scaffold-console-first-paint |
2 |
pass |
npm run dev -- -p 4310 → /_console/ 200; npx os dev --ui -p 4311 → /_console/ 200; both text/html |
| cli.scaffold-console-first-paint |
3 |
pass |
boot banner prints Dev admin: admin@objectos.ai / admin123; sign-in via the form lands on /_console/home; record created, action show/hide observed |
| cli.build-own-contract |
0 |
not-run |
human success path captured (exit 0, stats, Artifact: dist/objectstack.json (14.8 KB)); the --json success payload was not captured |
| cli.build-own-contract |
1 |
not-run |
no schema-shape break planted (the planted breaks were author-time rules) |
| cli.build-own-contract |
2 |
pass |
os build exit 1, ✗ Author-time rules failed (3 issues), each with rule: + at path (expression-invalid, object-reference-unknown, list-view-field-unknown), all three reported at once |
| cli.build-own-contract |
3 |
pass |
os build --json failure payload keys success, error, issues, warnings, conversions, success:false, 3 issues |
| cli.build-own-contract |
4 |
pass |
every observed exit was 0 or 1 across repeated runs |
| cli.build-own-contract |
5 |
pass |
the field-no-consumers warning prints and the build exits 0 with the artifact written |
| cli.dev-boot-contract |
0 |
pass |
health 200 within ~10 s, ready 200, /_console/ serves the login page |
| cli.dev-boot-contract |
1 |
not-run |
sign-in with the seeded credentials succeeded; the changed-password restart (idempotency) was not exercised |
| cli.dev-boot-contract |
2 |
pass |
nothing chosen → Database: file:/tmp/ns/tasks-app/.objectstack/data/objectstack.db, persistent across the session's restarts |
| cli.dev-boot-contract |
3–5 |
not-run |
--fresh, port shift and staleness block not exercised |
| cli.dev-boot-contract |
6 |
pass |
in a dir with no config: ✗ Config file not found … + Run in a directory with objectstack.config.ts, pass --artifact <path|url>, or run from the monorepo root., exit 1 |
| platform-core.console-login |
0 |
pass |
form sign-in → /_console/home, header + launcher, no sidebar |
| platform-core.console-login |
1–4 |
not-run |
reload / server-side expiry / wrong-password legs not exercised |
| cli.lint-severity-exit-contract |
0 |
pass |
human report groups Errors (3) ✗ / Warnings ⚠, each with rule id + path |
| cli.lint-severity-exit-contract |
1 |
pass |
3 errors → exit 1; warnings-only (green app) → exit 0 |
| cli.lint-severity-exit-contract |
3 |
pass |
the same three registry rule ids appear in os build and os lint on the same stack |
| cli.lint-severity-exit-contract |
2, 4–6 |
not-run |
--json, i18n fold, --fix, throwing config not exercised |
| cli.verify-verdict-exit-mapping |
0 |
pass |
statuses observed: verified, needs-fixture — both in the closed six (read from the JSON after stripping the log prefix, see finding below) |
| cli.verify-verdict-exit-mapping |
1 |
not-run |
only the zero side observed (hardFailures: 0, exit 0); no hard failure staged |
| cli.verify-verdict-exit-mapping |
2 |
pass |
a validation rule rejecting every insert → ~ tasks_app_project needs-fixture (app validation rejected the auto-record), summary 2 verified … 1 needs-fixture, exit 0 |
| cli.verify-verdict-exit-mapping |
3–4 |
not-run |
--rls ran green (3 PROVEN (3 consistent, 0 HOLES), per-persona line) but no hole was staged; posture leg not run |
| platform-core.marketplace-install-local-lifecycle |
0–1 |
not-run |
boot B (OS_CLOUD_URL=off) half only: runtime/config → installLocal:true, marketplace:false, GET /marketplace/install-local 200; boot A not run |
| platform-core.marketplace-install-local-lifecycle |
2 |
pass |
os package install ./dist/objectstack.json --runtime http://localhost:4320 → ✓ Package installed into the running kernel; GET /meta/app names tasks_app; POST /data/tasks_app_project 201 and read back. (What the install does NOT bring along is scored under the action gate item below and in the findings.) |
| platform-core.marketplace-install-local-lifecycle |
3 |
pass |
admin listing carries installedBy + storageDir; member listing 200 with the entry and without both; anonymous 401 |
| platform-core.marketplace-install-local-lifecycle |
4–6 |
not-run |
purge/reseed, full 4×3 door matrix, DELETE not exercised (member POST 403 / DELETE 403, anonymous POST 401 observed) |
| ai.mcp-http-surface |
3 |
pass |
anonymous POST /api/v1/mcp initialize → 401; bogus osk_ key → 401 |
| ai.mcp-http-surface |
4 |
pass |
keyed Streamable HTTP session: list_objects, describe_object, validate_expression, query_records, aggregate_records, get_record, create_record, update_record, delete_record, list_actions, run_action, resume_run |
| ai.mcp-http-surface |
0–2, 5 |
not-run |
opt-out boot, /mcp/skill, OAuth scope legs not exercised |
| ai.mcp-run-action-exposure-gate |
1 |
pass |
list_actions → exactly complete_task (the one ai.exposed action), with its ai.description |
| ai.mcp-run-action-exposure-gate |
2 |
fail |
on the runtime the app was INSTALLED into: run_action {actionName:'complete_task', recordId} → isError: true, No handler registered for action 'complete_task' on 'tasks_app_task'; record unchanged. Same call on the dev runtime and on the artifact-pinned runtime → {ok:true, …} and the record reads status: done, done: true. Reproduction below. |
| ai.mcp-run-action-exposure-gate |
3 |
pass |
[action-audit] MCP run_action 'complete_task' on 'tasks_app_task' — body executes TRUSTED (system-elevated context, RLS/FLS-bypassing) for user '…' |
| ai.mcp-run-action-exposure-gate |
0, 4 |
not-run |
the app declares no unexposed action; no sys_* action probed |
| identity-auth.api-key-ui-lifecycle |
0 |
pass |
Account → Connect an Agent → Create key → POST /api/v1/keys 201 with the raw key once; the panel says "copy it now, it will not be shown again"; GET /data/sys_api_key rows carry prefix and no key field |
| identity-auth.api-key-ui-lifecycle |
1 |
pass |
x-api-key on GET /data/tasks_app_task → 200 as the owner; MCP calls ran as the key's user (created_by = that user) |
| identity-auth.api-key-ui-lifecycle |
2 |
pass |
PATCH /data/sys_api_key/:id {revoked:true} 200 → next data call 401, MCP initialize 401 |
| identity-auth.api-key-ui-lifecycle |
3 |
pass |
{revoked:false} 200 → data call 200 |
| identity-auth.api-key-ui-lifecycle |
4–5 |
not-run |
mine-view scoping and the list screenshot not exercised |
| studio-authoring.first-run-loop |
all |
not-run |
step ⑥ was walked through metadata (allowed by the lane), not Studio |
| cli.dev-automigrate-policy |
all |
not-run |
path-level only: after adding priority, os dev printed ↻ recompiling … ✓ server restarted — the new build is live, the column was served and the five existing rows read back intact; the [schema-drift] auto-reconciled info line was not captured at the default log level |
Environment fingerprint
create-objectstack@17.6.0and every@objectstack/*resolved at17.6.0fromhttps://registry.npmjs.org/(dist-taglatest); 56@objectstack/*entries in the scaffold'snode_modules/.pnpm, all@17.6.0, zerolink:entries in itspnpm-lock.yaml617f25f8(the 17.6.0 version commit, per the release session)@objectstack/console@17.6.0(objectui pin31971ff1e28f, per the release session)executablePath=/opt/pw-browsers/chromium/tmp/ns/outside the repository, no workspace linkstasks-appdev runtimeos dev -p 4310(sqlitefile:<project>/.objectstack/data/objectstack.db, seeded dev admin); environment runtimesos startwithOS_CLOUD_URL=off:ops-env:4320 (catalog-less install target), empty kernel :4340 (hot-install repro), artifact-pinned :4350Scope
Selector: the path in
docs/NORTH-STAR.md(「唯一的度量,那条路」), walked end to end as a new developer reading only the published docs (content/docs/**) and CLI output, against the published 17.6.0 train. The items scored are the 「路上的功能点」 checklist items each step exercised, at these revisions:cli.scaffold-first-runr2 ·cli.scaffold-console-first-paintr2 ·cli.build-own-contractr3 ·cli.dev-boot-contractr3 ·platform-core.console-loginr4 ·cli.lint-severity-exit-contractr1 ·cli.verify-verdict-exit-mappingr1 ·platform-core.marketplace-install-local-lifecycler1 ·ai.mcp-http-surfacer2 ·ai.mcp-run-action-exposure-gater2 ·identity-auth.api-key-ui-lifecycler1 ·studio-authoring.first-run-loopr3 ·cli.dev-automigrate-policyr1Planned items: none in this selection.
The app built for the walk (
tasks-app, namespacetasks_app): a shared picklisttasks_app_work_statusused by two objects; objectstasks_app_projectandtasks_app_task(text, lookup → project, picklist select, date, number, boolean, textarea); a list view + a two-section form view; ascriptactioncomplete_taskwith an inlinebody,visible: 'record.done != true',ai.exposed: true; an activerecord_changeflowtask_completed_note(task after-update,record.status == 'done'→create_recordon the starter note object); a permission settasks_app_task_user(CRUD +readScope: 'org', no delete on project); an apptasks_appwith three nav entries.The path — per-step verdicts
npm create objectstack→ write metadatablanktemplate exists (the others are documented as retired). Generator defects noted below (they do not block a hand-written app).Complete Taskbutton runs, hides itself after completion (thevisiblepredicate), and the flow writes its note. Permission set proven both sides with a member persona.os validate/os build/os lint, each located and with a prescription; fixed → all green incl.objectstack verify --rls. Butobjectstack verifyitself prints✓ verify passed(exit 0) on the broken stack, andverify --jsonstdout is not parseable JSON.ai.mcp-run-action-exposure-gateclause 2 / NEG1: the documented community install (os package install ./dist/objectstack.json, no control plane) reports success, but the installed app'sscriptaction is not dispatchable from ANY door (REST 404, MCP "No handler registered"), whilelist_actionsadvertises it; hot install also leaves the flow trigger unbound and the permission set unprojected until a restart. Workaround used: the documented artifact-pinned boot (os start --artifact), on which every later step passes.tools/list= 12 tools,list_actionslistscomplete_task,create_record+run_action complete_taskcomplete a task, the flow fires, and the Console list shows it Done. Anonymous / bogus / revoked key → 401, restored key → 200.selectfield + one column + one form row; validate/lint green;os devrebuilt and restarted itself; the Console list shows Priority; existing rows, the action and the flow still work. Studio path not exercised.Per-clause verdicts
npm create objectstack@17.6.0 tasks-appexit 0 (installs + skills);os validateexit 0,os buildexit 0 (dist/objectstack.json2.2 KB); a second scaffold booted withos start(artifact auto-detected) →/api/v1/health200,/api/v1/ready{"status":"ready","state":"running"}--helpoffersblankonly; docs say the remote templates are retired;blankvalidates and buildsengines: { protocol: '^17' }), no protocol refusal.claude/skills/= the 10 directories of the curatedskills/catalog exactly; nodogfood-verificationor other internal skill presentnpx os validateexit 0/_console/200 text/html; screenshot (live, not attached): login form at/_console/login, then the home shell ("Build an app", "Your apps", Setup tile)npm run dev -- -p 4310→/_console/200;npx os dev --ui -p 4311→/_console/200; both text/htmlDev admin: admin@objectos.ai / admin123; sign-in via the form lands on/_console/home; record created, action show/hide observedArtifact: dist/objectstack.json (14.8 KB)); the--jsonsuccess payload was not capturedos buildexit 1,✗ Author-time rules failed (3 issues), each withrule:+atpath (expression-invalid,object-reference-unknown,list-view-field-unknown), all three reported at onceos build --jsonfailure payload keyssuccess, error, issues, warnings, conversions,success:false, 3 issuesfield-no-consumerswarning prints and the build exits 0 with the artifact written/_console/serves the login pageDatabase: file:/tmp/ns/tasks-app/.objectstack/data/objectstack.db, persistent across the session's restarts--fresh, port shift and staleness block not exercised✗ Config file not found …+Run in a directory with objectstack.config.ts, pass --artifact <path|url>, or run from the monorepo root., exit 1/_console/home, header + launcher, no sidebarErrors (3)✗ /Warnings⚠, each with rule id + pathos buildandos linton the same stack--json, i18n fold,--fix, throwing config not exercisedverified,needs-fixture— both in the closed six (read from the JSON after stripping the log prefix, see finding below)hardFailures: 0, exit 0); no hard failure staged~ tasks_app_project needs-fixture (app validation rejected the auto-record), summary2 verified … 1 needs-fixture, exit 0--rlsran green (3 PROVEN (3 consistent, 0 HOLES), per-persona line) but no hole was staged; posture leg not runOS_CLOUD_URL=off) half only:runtime/config→installLocal:true, marketplace:false,GET /marketplace/install-local200; boot A not runos package install ./dist/objectstack.json --runtime http://localhost:4320→✓ Package installed into the running kernel;GET /meta/appnamestasks_app;POST /data/tasks_app_project201 and read back. (What the install does NOT bring along is scored under the action gate item below and in the findings.)installedBy+storageDir; member listing 200 with the entry and without both; anonymous 401POST /api/v1/mcpinitialize → 401; bogusosk_key → 401list_objects, describe_object, validate_expression, query_records, aggregate_records, get_record, create_record, update_record, delete_record, list_actions, run_action, resume_run/mcp/skill, OAuth scope legs not exercisedlist_actions→ exactlycomplete_task(the oneai.exposedaction), with itsai.descriptionrun_action {actionName:'complete_task', recordId}→isError: true,No handler registered for action 'complete_task' on 'tasks_app_task'; record unchanged. Same call on the dev runtime and on the artifact-pinned runtime →{ok:true, …}and the record readsstatus: done, done: true. Reproduction below.[action-audit] MCP run_action 'complete_task' on 'tasks_app_task' — body executes TRUSTED (system-elevated context, RLS/FLS-bypassing) for user '…'sys_*action probedPOST /api/v1/keys201 with the raw key once; the panel says "copy it now, it will not be shown again";GET /data/sys_api_keyrows carryprefixand nokeyfieldx-api-keyonGET /data/tasks_app_task→ 200 as the owner; MCP calls ran as the key's user (created_by= that user)PATCH /data/sys_api_key/:id {revoked:true}200 → next data call 401, MCP initialize 401{revoked:false}200 → data call 200priority,os devprinted↻ recompiling … ✓ server restarted — the new build is live, the column was served and the five existing rows read back intact; the[schema-drift] auto-reconciledinfo line was not captured at the default log levelDerived item verdicts
Hand-off (not reached this run):
studio-authoring.first-run-loop(all clauses),cli.dev-automigrate-policy(all clauses), and the not-run clauses listed above.Reproduction rule for the fail
ai.mcp-run-action-exposure-gateclause 2, on an installed package (no authentication or authorization element; full recipe published):npm create objectstack@17.6.0 tasks-app; add ascriptaction with an inlinebodyandai: { exposed: true, description }on an app object (anybodythat updates the record — the docs' Path A example shape);npx os build.OS_CLOUD_URL=off npx os start -p 4340 --home ./home --auth-secret <32+ chars>;POST /api/v1/auth/sign-up/email(headerOrigin: http://localhost:4340) for the first owner.npx os package install ./dist/objectstack.json --runtime http://localhost:4340 --email … --password …→✓ Package installed into the running kernel.POST /api/v1/data/tasks_app_task {"name":"probe"}→ 201.POST /api/v1/actions/tasks_app_task/complete_task {"recordId":"<id>"}→ expected 200{success:true, data:{ok:true}}; actual404 {"code":"RESOURCE_NOT_FOUND","message":"Action 'complete_task' on object 'tasks_app_task' not found"}.POST /api/v1/keys; MCPlist_actions→ listscomplete_task; MCPrun_action {actionName:'complete_task', recordId}→ actualisError: true,No handler registered for action 'complete_task' on 'tasks_app_task'.npx os start -p 4350 --artifact <path>/dist/objectstack.json …→ step 5 answers{"success":true,"data":{"ok":true,…}}and the record readsstatus: done.Verify pass (RUNNER rule 7): a second, independent agent re-derived this verdict on fresh runtimes (:4461 install-local, :4462 artifact-pinned) from the steps above alone — CONFIRMED: REST 404
RESOURCE_NOT_FOUNDand MCPNo handler registered …on the installed runtime whilelist_actionslists the action; REST 200 and MCP{ok:true}on the artifact-pinned one.Findings outside the scored clauses (each extracted to its own card)
scriptaction bodies — the fail above (P0 of the path).doneright after install wrote no note (flow did not fire); after a restart (:4320) the same update writes it.sys_permission_setliststasks_app_task_useronly after a restart (/meta/permissionalready lists it), so an admin cannot grant the installed app's set until then. The CLI says nothing about a restart.objectstack verifypasses a stack the authoring gates refuse — with a dangling lookup target, a bare-referencevisiblepredicate and an unknown list column planted (validate/build/lint all exit 1),objectstack verifyprints3 verified … ✓ verify passed — no runtime failures, exit 0. NORTH-STAR defines done as "objectstack verifyis green"; the published docs (content/docs/deployment/cli.mdx) do not documentverifyat all.objectstack verify --jsonstdout is not a JSON document — ~329 lines ofINFOkernel log precede the payload on stdout, soverify --json > report.json(the item's own step 0) yields an unparseable file.os generatescaffolds fail the project's own gates —os g flow task_donewrites a start node ontasks_app_task_done(an object that does not exist) and reports✓ Reaches the stack; validate only warns.os g view taskwrites a view thatos lintrefuses (View "tasks_app_task" is missing a labelatviews[0].list.label, exit 1) and whosename/labelvalidate calls dead properties.os g action complete_task/os g app tasksderive the object from the NAME and refuse; there is no flag to target an existing object.Observations recorded, not extracted: the Console requests
GET /api/v1/usage/storageon every page and gets404 ENDPOINT_NOT_FOUNDon a community runtime; a plain member's Console requestsGET /data/sys_activityand gets 403 on home; the create form does not pre-select the picklist'sdefault: trueoption (the server applies it on insert);your-first-project.mdxsays the default template "runs on an in-memory driver" whileos devresolves a persistent SQLite file (the same page says so two sections later);runtime/configreportsaiStudio: trueon a communityos startboot (not followed up).Fixture gaps: none.
Generated by Claude Code