Skip to content

QA run · platform-core (27/34) · 5b14b7f3 · 2026-10-19 · 21 PASS / 4 PARTIAL / 2 FAIL / 0 BLOCKED / 7 NOT-RUN #24557

Closed as not planned

Description

@objectstack-fleet

QA run record for selector area:platform-core (bare area platform-core in the title for the roll-up), 18.0 release sweep, plan B (Tier 1 + Tier 2 driven, Tier 3 deferred). Text only — no screenshots; reproduction rules below.

Environment fingerprint

  • framework: 5b14b7f3ad8e2e0786d228772f473d07b36b2477 (objectstack-ai/objectstack, pinned — no pull)
  • console: vendored objectui build stamped 4016370af3c9c9dafec2bc5299afd8e8079701b8 (= .objectui-sha), built with pnpm objectui:build; objectui-only pins run in a checkout at that same sha
  • app: examples/app-showcase, canonical boot OS_PORT=P objectstack dev --ui --seed-admin -p P -d file:RUN/data.db with per-item OS_HOME / OS_STORAGE_LOCAL_ROOT; package-installing items booted from a scratch copy outside the repo
  • ports: each runner its own range (41100–42319), one file DB per item; seed: stock showcase (132 rows) + --seed-admin
  • run window: 2026-10-19 12:26–13:45 UTC; host: 4 vCPU / 15 GB container shared by up to 7 parallel runners (load average peaked ~40; two boots timed out under load and were re-run serially — no verdict rests on a starved run)
  • runner: one dispatching session + parallel runner sub-agents (not sequential); every persona identity proven server-side (GET /auth/get-session) before each cell

Scope

Selector area:platform-core → 34 runnable items (node scripts/checklist-select.mjs area:platform-core --json). No planned items; none hidden as blocked. The 4 unpinned P0 items (boot-health, seed-integrity, console-login, builtin-apps-nav-render) are also driven by the separate priority:P0 gate card — independent second judgement by design.

item priority surface revision tier method item verdict
platform-core.boot-health P0 mixed 7 2 manual browser+API PASS
platform-core.seed-integrity P0 api 3 2 manual API PASS
platform-core.console-login P0 browser 4 2 manual browser+API PASS
platform-core.nav-surfaces-render P0 browser 6 1 pin (incl. objectui pins at the pin sha) + browser PASS
platform-core.metadata-registry-serving P1 api 2 1 Tier 1 pin + live legs PASS
platform-core.metadata-authoring-roundtrip P1 mixed 3 1 Tier 1 pin + live legs / pin (incl. objectui pins at the pin sha) + browser PASS
platform-core.builtin-apps-nav-render P0 browser 6 2 manual browser+API PASS
platform-core.settings-hub-roundtrip P1 mixed 4 2 manual browser+API PASS
platform-core.package-lifecycle-enable-disable P1 mixed 1 2 manual browser+API FAIL
platform-core.notification-center P1 mixed 2 2 manual browser+API PASS
platform-core.shell-nav-personalization P2 browser 4 3 deferred NOT-RUN
platform-core.app-management-toggle P2 mixed 3 3 deferred NOT-RUN
platform-core.docs-audience-gate P1 api 1 2 manual API PARTIAL
platform-core.interrupted-migration-boot-report P2 mixed 2 1 Tier 1 pin + live legs PASS
platform-core.manifest-install-contract P1 api 3 2 manual API PASS
platform-core.activation-ledger-registration-home P1 api 5 1 Tier 1 pin + live legs PASS
platform-core.activation-ledger-row-contract P2 api 4 1 Tier 1 pin + live legs PASS
platform-core.packaged-object-extend-only P2 api 2 3 deferred NOT-RUN
platform-core.marketplace-install-local-lifecycle P1 api 4 2 manual API PASS
platform-core.marketplace-console-honesty P2 browser 5 3 deferred NOT-RUN
platform-core.runtime-config-boot-read P1 api 1 2 manual API PASS
platform-core.docs-portal-render P1 browser 2 2 manual browser+API PASS
platform-core.url-overlay-contract P1 browser 1 1 pin (incl. objectui pins at the pin sha) + browser PASS
platform-core.keyboard-shortcut-surface P2 browser 4 3 deferred NOT-RUN
platform-core.home-admin-cluster-links P1 browser 3 2 manual browser+API PASS
platform-core.lifecycle-retention-sweep P1 mixed 4 1 Tier 1 pin + live legs PASS
platform-core.seed-mode-matrix P1 api 2 2 manual API PASS
platform-core.theme-mode-persistence P2 browser 2 3 deferred NOT-RUN
platform-core.console-installability-indicators P2 browser 1 3 deferred NOT-RUN
platform-core.settings-audit-secret-fingerprint P1 api 2 1 Tier 1 pin + live legs PASS
platform-core.v18-boot-refusals P0 cli 1 1 Tier 1 pin + live legs FAIL
platform-core.protocol-18-handshake-and-stored-replay P1 mixed 1 1 Tier 1 pin + live legs PARTIAL
platform-core.settings-organization-isolation-and-platform-rung P1 api 1 1 Tier 1 pin + live legs PARTIAL
platform-core.serve-composition-v18 P2 cli 1 1 Tier 1 pin + live legs PARTIAL

Tier 1 pin evidence: every file named in the area's automated.ref fields was run once, batched per package at the subject sha (RUNNER rule 6). Framework pins: 122 files, all green (cli 61 + nightly-tier e2e 2, core 72, metadata/-core/-protocol 393, objectql 274, platform-objects 44, plugin-audit 172, plugin-hono-server 38, plugin-security 192, plugin-sharing 69, dogfood 448 passed / 1 skipped [the attachments cross-tenant (g) dependency marker — scores no clause here], rest 86, runtime 291, service-automation 49, service-settings 117, service-storage 279, spec 42). A pin was cited only for the clauses it actually asserts; every clause it does not assert was driven live or is marked below.

Per-clause verdicts

by = runner; evidence is server truth (API / log / test output) in one line; UI clauses describe what the checked screenshot showed.

platform-core.boot-health (rev 7) — PASS

clause verdict by evidence
acceptance[0] pass D curl /api/v1/health → 200 {"status":"ok","version":"18.0.0-next.5"}. Time to healthy was 23 s from spawn.
acceptance[1] pass D GET /api/v1/ready → 200 {"status":"ready","state":"running"}.
acceptance[2] pass D Banner: Flows: 32 flow(s) 19 bound … · 8 draft. Its only two non-ok lines are `ℹ 1 flow declares a 'time_relative' / 'schedule'…
acceptance[3] pass D GET /_console/ → 200 text/html; charset=utf-8. GET /api/v1/meta/app?id=showcase_app → 200 with 1 item, keys `name,label,ico…
acceptance[4] pass D Served grp_data has 12 entries (nav_projects … nav_cascade, from showcase_project to showcase_cascade). Diffed against `src/ui/ap…
negative[0] pass (not triggered) D No SeedLoader rejection or dropped-record line in the log.
negative[1] pass (not triggered) D No ERROR lines in the boot window.

platform-core.seed-integrity (rev 3) — PASS

clause verdict by evidence
acceptance[0] pass A Expected counts come from running tsx on the real ShowcaseSeedData export: 19 seed sets, 132 rows. I then called GET /api/v1/da…
acceptance[1] pass A I read Specimen — Full with GET /api/v1/data/showcase_field_zoo?$filter={"name":"Specimen — Full"} and diffed it field by field a…
acceptance[2] pass A Both boots (first and restart) print Seeds: com.example.showcase 132 rows in the plain form, with no ⚠ and no error or lost-lin…
acceptance[3] pass A I restarted against the same DB and swept again. The per-object counts are identical to the first sweep (empty diff). All 132 (ob…
acceptance[4] pass A These are expected to be empty, and they are. Specimen Full and Minimal: f_user null, f_users null, f_secret null. All 10 s…
negative[0] pass (not triggered) A No nav-visible object has a count of 0.
negative[1] pass (not triggered) A Counts did not grow on restart.

platform-core.console-login (rev 4) — PASS

clause verdict by evidence
acceptance[0] pass D Both runs landed on /_console/home. The screenshot shows the header, "Good afternoon, Dev Admin.", the "Your apps" launcher (Sh…
acceptance[1] pass D Reloaded on /apps/com.example.showcase/page/showcase_capability_map. The first authed request after reload was `GET /api/v1/aut…
acceptance[2] pass D POST /api/v1/auth/sign-out → 200 {"success":true}. The same bearer, still in localStorage, then got `GET /api/v1/meta/app?id=…
acceptance[3] pass D On a full navigation after expiry, the console redirected to /_console/login?redirect=%2Fapps%2Fcom.example.showcase, and the s…
acceptance[4] pass D After re-login from the redirect, the console returned to the same route (`/apps/com.example.showcase/page/showcase_capability_ma…
negative[0] pass D Fresh context, wrong password: POST /auth/sign-in/email → 401 INVALID_EMAIL_OR_PASSWORD. The UI showed a red alert "Invalid e…
negative[1] pass (not triggered) D The 401 and the redirect were both observed.

platform-core.nav-surfaces-render (rev 6) — PASS

clause verdict by evidence
acceptance[0] pass J Final full run smoke-full2.log: 49 passed (2.7m), exit 0. All 7 chart surfaces were green: Delivery Operations, Chart Galle…
acceptance[1] pass J GET /api/v1/meta/app?id=showcase_app returned 50 leaves: 49 destinations plus 1 separator. The diff against SURFACES (`nav-diff…
acceptance[2] pass J /_console/apps/com.example.showcase/object_that_does_not_exist, run twice on fresh loads: the screenshot shows the shell (sideb…
acceptance[3] pass (none encountered) J No surface rendered the ErrorBoundary fallback ("Something went wrong") in any run: boundary count 0 on the bad-route probes. The…
negative[0] pass J No surface had a blank ‹main›; the suite's mainText.length › 0 assertion held on all 49.
negative[1] pass J Both splash assertions (marker plus both English lines) held on 49/49 in the final run. In the starved run the marker check corre…
negative[2] pass J Bad route keeps the shell.
negative[3] pass J The spec polls boundingBox up to SURFACE_BUDGET_MS (spec lines ~221). There is no fixed sleep followed by a single read.

platform-core.metadata-registry-serving (rev 2) — PASS

clause verdict by evidence
acceptance[0] pass G GET /api/v1/meta (admin bearer) → 200, entries=34. All 19 kinds named in the steps are present (object, view, page, dashboard, ap…
acceptance[1] pass (pin) G packages_qa_dogfood.log, file meta-types-create-seed.dogfood.test.ts: "carries the dashboard create seed (widgets: [])", "carri…
acceptance[2] pass G GET /api/v1/meta/types → 200 {types, entries(34)}. The body is byte-identical to GET /meta, which the pin "answers the same bod…
acceptance[3] pass G GET /meta/view/showcase_task → 200 item keys list, form, listViews, formViews. listViews includes in_progress, board, gantt (14…
acceptance[4] pass G GET /meta/view → 36 items covering the task, project, inquiry, business_unit, contact and field_zoo families (one family per file…
acceptance[5] pass G GET /meta/object/showcase_account → loyalty_tier select with options bronze/silver/gold/platinum, linkedin_url url, csat_score nu…
acceptance[6] pass G PATCH /data/showcase_account/9zPt7L8kd-U61KLc {loyalty_tier:'gold',csat_score:88} → 200. GET → loyalty_tier=gold, csat_score=88…
negative[0] pass G No registered type is missing from /meta, and seeds match the pin.
negative[1] pass G All 3 overlay fields are in /meta and writable through /data.
negative[2] pass G Unauthenticated GET /api/v1/meta → 401 UNAUTHENTICATED, so the registry is not leaked.

platform-core.metadata-authoring-roundtrip (rev 3) — PASS

clause verdict by evidence
acceptance[0] pass G POST /packages {manifest:{id:'com.qa.g-author',…type:'app'}} → 201 source=authored, writable=true. PUT /meta/view/showcase_task…
acceptance[1] pass G Before publishing, GET …/published → 404. POST /packages/com.qa.g-author/publish-drafts → 200 outcome=published, publishedCount=1…
acceptance[3] pass G PUT /meta/view/showcase_task.os_qa_view_g2?mode=draft&package=com.example.showcase → 422 code:"WRITABLE_PACKAGE_REQUIRED" ("tha…
acceptance[4] pass G PUT /meta/object/showcase_task (served body, label changed) → 403 NOT_OVERRIDABLE. The label still reads "Task" afterwards. Sid…
acceptance[5] pass G PUT /meta/view/showcase_task.os_qa_bad_g1 {…columns:42} in both draft and active mode → 422 INVALID_METADATA "failed spec valid…
negative[0] pass G Both deny-side attempts were refused (422 and 403).
negative[1] pass G The malformed body was not stored.
negative[2] pass G The published view appears in the console switcher after reload.
acceptance[2] (Studio record page issue… pass (hand-driven, vendored console at 42102) J At /_console/apps/showcase_app/metadata/page/new I set the Label, set Page type list→record (combobox #mdf-type), picked …

platform-core.builtin-apps-nav-render (rev 6) — PASS

clause verdict by evidence
acceptance[0] pass D Setup 42/42 and Account 8/8, walked by following every sidebar link's real href. That was 28 links plus 14 more after expandi…
acceptance[1] pass D ?id=setup has 9 group anchors (group_overview … group_advanced), all filled. Every SETUP_NAV_CONTRIBUTIONS id is served except …
acceptance[2] pass D Mei on /_console/apps/setup, /apps/com.objectstack.setup and /apps/com.objectstack.setup/sys_user/view/all_users: each scre…
acceptance[3] pass D Forged requests with Mei's bearer: GET /api/v1/meta/app?id=setup → 200 {"items":[]}. GET /api/v1/meta/app/setup → 403 `…
acceptance[4] pass D As Mei, ?id=setup → {"items":[]}, so nav_api_keys and the manage_platform_settings settings URLs are unreachable. Control onl…
acceptance[5] pass D Gated-entry table: nav_organizations (requiresService org-scoping) is ABSENT, and /discovery services have no org-scoping. nav_…
acceptance[6] pass D nav_sso_providers is absent from the served payload (SSO not wired, per the knownGap). No nav entry renders a dead "failed to loa…
negative[0] pass (not triggered) D No blank or placeholder destinations.
negative[1] pass (not triggered) D The member was refused on the wire (403 or empty).
negative[2] pass (not triggered) D The member's account nav has no permission-gated entries. Setup was not obtainable.

platform-core.settings-hub-roundtrip (rev 4) — PASS

clause verdict by evidence
acceptance[0] pass E Before: GET /api/settings/localization timezone {value:"UTC",source:"tenant"} (dev seed). PUT {"timezone":"Asia/Tokyo"} → 200…
acceptance[1] pass E GET /api/v1/auth/me/localization returned timezone:"UTC" before the PUT and "Asia/Tokyo" after it. After the env-lock restart…
acceptance[2] pass E GET /api/v1/data/sys_setting_audit?filter=namespace=localization → row `key:timezone, scope:tenant, action:set, source:api, actor…
acceptance[3] pass E Screenshot before: Default country "US" had no badge (source default). The UI edit went out as `PUT /api/settings/localization {"…
acceptance[4] pass E Restart with OS_LOCALIZATION_TIMEZONE=Europe/Paris → GET `{value:"Europe/Paris",source:"env",locked:true,lockedReason:"Set via en…
acceptance[5] pass E Screenshot: Default timezone shows the "Locked by env" badge with a greyed Europe/Paris input. Playwright reports isEditable=fals…
acceptance[6] pass E POST /api/settings/mail/test {"provider":"log","to":"x@example.com"} → 400 SETTINGS_ACTION_FAILED, details.ok:false, message …
acceptance[7] pass E PUT mail.smtp_password and ai.openai_api_key. sys_secret has rows sec_282ab7… and sec_f21b28… (aes-256-gcm, v2: ciphertext)…
acceptance[8] pass E GET /api/settings/mail and /ai: the set secrets (smtp_password [password], openai_api_key [encrypted:true]) have value = 8×U+2022…
acceptance[9] pass E Env-pinned OS_MAIL_SMTP_PASSWORD (password type) and OS_AI_ANTHROPIC_API_KEY (encrypted:true): each GET returns value=mask, sourc…
acceptance[10] pass E Echoed mask sent in both shapes ({smtp_password:mask} and {values:{openai_api_key:{value:mask}}}, then the reverse) → 200 `{v…
acceptance[11] pass E Anonymous GET /api/settings/localization → 401 {code:"UNAUTHENTICATED"}. Anonymous GET /api/settings → 401 UNAUTHENTICATED. N…
acceptance[12] pass E All 11 namespaces (localization, company, branding, auth, mail, sms, storage, ai, knowledge, feature_flags, lifecycle) return 200…
negative[0] pass E The effect clause was scored on auth/me/localization (consumer output), not on the form.
negative[1] pass E All env-locked PUTs (3 keys) → 409. None returned 200.
negative[2] pass E No plaintext was found in GET bodies, sys_setting, sys_platform_setting.value or the data.db bytes.
negative[3] pass E The set secret is served as the mask; the key is present, not omitted.
negative[4] pass E After the echoed-mask PUT, the decrypt still returns the original plaintext, not the mask.
negative[5] pass, by proxy E The in-process path is not masked. I proved this by decrypting via LocalCryptoProvider with the boot's key file and the same co…
negative[6] pass E The test action returns ok:false.
negative[7] pass E Anonymous list → 401.

platform-core.package-lifecycle-enable-disable (rev 1) — FAIL

clause verdict by evidence
acceptance[0] pass E Before disable: GET /api/v1/data/qaprobe_widget 200 rows=3, /meta/object 200, /meta/view 200, /meta/app names include qaprobe_app…
acceptance[1] pass E PATCH /enable → 200 status:installed. /data 200 rows=3, /meta/object and /meta/view 200, qaprobe_app is back in /meta/app with …
acceptance[2] pass E DELETE /packages/com.qa.probe → 200 registryRemoved:true, deletedCount:3. Afterwards: /data 404 OBJECT_NOT_FOUND, qaprobe a…
acceptance[3] pass E GET /packages/:id/commits: count=1 before the second publish. I added a color field and ran publish-drafts. Count is then 2; th…
acceptance[4] pass E /meta/object/qaprobe_widget/published fields were name before the change and name,color after it. POST /packages/:id/commits/…
acceptance[5] FAIL E Nav absent: pass (home screenshot has no QA Probe tile). Stale deep-link: fail. /_console/apps/showcase_app/qaprobe_widget stay…
acceptance[6] pass E PATCH /packages/com.example.showcase/disable → 422 WRITABLE_PACKAGE_REQUIRED. DELETE com.example.showcase → 422. com.objectstac…
acceptance[7] pass E Row count was 3 before disable and 3 after re-enable (w-a, w-b, w-c).
negative[0] pass E /data returns 404 after disable.
negative[1] pass E No orphaned metadata after the uninstall.
negative[2] pass E Revert restored the prior shape.
negative[3] pass E 422 on both read-only verbs.

platform-core.notification-center (rev 2) — PASS

clause verdict by evidence
acceptance[0] pass E Payload (sys_inbox_message + sys_notification_receipt as fetched by the console): groups digest n=5 u=5 and approval.requested n=…
acceptance[1] pass E Popover screenshot shows three tabs: "Notifications 2", "Approvals 3", "Activity feed".
acceptance[2] pass E Screenshot first. "Scheduled project digest ×5" became aria-expanded=true after the row-button click and showed 5 member rows. "A…
acceptance[3] pass E Clicking "Mark read" on the Approval-requested group sent one `POST /api/v1/notifications/read {"ids":["3Z3l4g4deu3Uu_E6","57PPkX…
acceptance[4] pass E "Mark all read" sent POST /api/v1/notifications/read/all {}, which returned 200 readCount:6. The badge went 4 → 3 and the hea…
acceptance[5] pass (see note) E The Approvals tab shows "3 pending approvals" with a "View approvals" button. sys_approval_request with status=pending returns 3 …
acceptance[6] pass E Fresh context and reload. GET /api/v1/notifications?view=mine shows all 9 marked rows read:true. Only the newly delivered diges…
negative[0] pass E The badge counted topics (5), not rows (8).
negative[1] pass E Mark-read on a 3-member group sent one POST.
negative[2] pass E Read state persisted across reload.
negative[3] n/a E Cross-reference note only.

platform-core.docs-audience-gate (rev 1) — PARTIAL

clause verdict by evidence
acceptance[0] pass A Anonymous against qadocs_org_book, qadocs_gated_book, implicit com.qa.docsgate, com.objectstack.setup and com.example.showcase: e…
acceptance[1] pass A Results by audience: public: showcase_manual and qadocs_public_book gave 200 for anonymous, phone, auditor and admin. org…
acceptance[2] pass (half), unknown-shape half not-run A I ran npx vitest run src/system/book.test.ts -t audienceAllows in packages/spec: 4 passed, including "permission-set gate FAILS…
acceptance[3] pass A Phone's tree of qadocs_public_book is [public, i18n, org, orphan]. Auditor's is the same plus gated_doc. Anonymous gets only [pub…
acceptance[4] pass A qadocs_orphan_doc is in no book, but it does show in the Uncategorized group of qadocs_public_book for authenticated callers. The…
acceptance[5] pass A GET /meta/book/com.qa.docsgate/tree: anonymous 401 UNAUTHENTICATED. Phone 200 with group all = [i18n, org, orphan, public] (gat…
acceptance[6] pass A With Accept-Language: zh-CN, qadocs_org_book's entry is {"doc":"qadocs_i18n_doc","label":"QA 国际化文档"}; without the header it i…
negative[0] pass (not triggered) A No non-public book served a tree to anonymous.
negative[1] pass (not triggered) A The public book's anonymous tree contains only the docs it claims.
negative[2] pass (not triggered) A Refusal bodies are generic strings plus a code, with no group or doc names.
negative[3] pass (not triggered) A No 404 where a 401 or 403 was due.
negative[4] pass (not triggered) A ?package=com.qa.docsgate&package=com.example.showcase returned 400 VALIDATION_ERROR "The "package" query parameter was suppli…

platform-core.interrupted-migration-boot-report (rev 2) — PASS

clause verdict by evidence
acceptance[0] pass G boot2.log: `WARN Interrupted migration run 'qa-interrupted-1' (plan 'qa_plan', started …): 0 chunk(s) committed 1 chunk(s) with U…
acceptance[1] pass G After the warning, health=200 and ready=200. The journal rows (id, run_id, seq, kind, plan_hash, chunk_index, detail, created_at)…
acceptance[2] pass G Recovery-line counts: boot1 (empty journal) 0, boot2 2, boot3 (after the seq 2 run_done insert) 0. All three ran on the same co…
acceptance[3] pass (pin) G packages_runtime.log: migration-recovery-plugin.test.ts "MigrationRecoveryPlugin — quiet degradation › skips silently when sys_mi…
acceptance[4] pass (pin) G Same file: "boot scan › reports a scan FAILURE rather than reading it as "nothing found"" ✓
negative[0] pass G Booting wrote nothing to the journal.
negative[1] pass G Pinned by both degradation tests.
negative[2] pass G Silence was scored only after boot2 proved the scan active.

platform-core.manifest-install-contract (rev 3) — PASS

clause verdict by evidence
acceptance[0] pass B POST /api/v1/packages probe-old engines.protocol:'^17' → 422 OS_PROTOCOL_INCOMPATIBLE. Then GET /packages/com.example.qa-manife…
acceptance[1] pass B `details:{requiredRange:"^17", rangeSource:"engines.protocol", protocolVersion:"18.0.0", targetMajor:17, migrateCommand:"objectst…
acceptance[2] pass B prec-ok {protocol:^18, platform:^17} → 201. prec-no {protocol:^17, platform:^18} → 422 rangeSource engines.protocol. legacy…
acceptance[3] pass B norange → 201 and reads back. wsrange workspace:* → 201 and reads back. Log line: `[protocol] package 'com.example.qa-manifest-…
acceptance[4] pass B (a) probe-b ns qa_mfp → 422 NAMESPACE_CONFLICT: "Namespace conflict: namespace "qa_mfp" is already owned by package "com.e…
acceptance[5] pass B GET /packages/com.example.leave → manifest.namespace:"leave". GET /packages/com.example.holiday → "timeoff". sqlite `sys_pack…
negative[0] pass (not triggered) B no incompatible package returned 2xx, and none has a row.
negative[1] pass (not triggered) B no-range and workspace:* were both admitted.
negative[2] pass (not triggered) B the namespace conflict maps to 422, not 5xx.
negative[3] pass (not triggered) B the conflict message names the namespace, the owner and the incoming id.
negative[4] pass (not triggered) B the derived namespace is present in the echo, the GET and sys_packages alike.

platform-core.activation-ledger-registration-home (rev 5) — PASS

clause verdict by evidence
acceptance[0] pass (pin) G dogfood packaged-activation-ledger-reach, describe "#12359 — actions and NO automation service": all 5 tests ✓ ("the automation s…
acceptance[1] pass G Live stock boot :41703. POST /actions/_activation/showcase_task/showcase_mark_done {enabled:false} → 200. POST /automation/showca…
acceptance[2] pass (pin) G Three tests: dogfood "the ledger object has exactly ONE owner, and it is the package that declares it" ✓. service-automation acti…
acceptance[3] pass (pin) G platform-objects plugin.test (manifest triple) ✓ and dogfood "the table keeps the datasource binding it had before the registrar …
acceptance[4] pass G platform-object-names.ts: sys_metadata_activation occurs once (line 62), inside the 'platform-objects': [ array that opens at…
negative[0..3] pass G No 503. The anti-vacuity control is green. There was no boot-time ownership throw. The binding is unchanged per the pins.

platform-core.activation-ledger-row-contract (rev 4) — PASS

clause verdict by evidence
acceptance[0] pass G GET /data/sys_metadata_activation → 200 with 4 rows. POST, PATCH and DELETE each → 405 OBJECT_API_METHOD_NOT_ALLOWED "API opera…
acceptance[1] pass G Row dump: one row per (metadata_type, name). With the server stopped, a duplicate INSERT ('action', 'showcase_mark_done') → `Inte…
acceptance[2] pass G PRAGMA cols: id, created_at, updated_at, created_by, updated_by, metadata_type, name, package_id, active, __search. No organizati…
acceptance[3] pass G After re-enabling all 4 switches: the same 4 ids (sCkgvTk7…, t41TqmJ9…, lgnPV3Up…, 5Xiyz1PF…), count 4 → 4, all active=True.
acceptance[4] pass G The distinct metadata_type set is {action, flow, permission, position}. POST /security/_activation/capability/showcase.export_dat…
acceptance[5] pass G The object source has "no lifecycle block on purpose" (line 48). The restart against the same DB gave a sqlite pre==post row tu…
negative[0..5] pass G No 2xx on generic writes. No tenant column. Re-enable updated rows and deleted none. The duplicate was refused. The capability an…

platform-core.marketplace-install-local-lifecycle (rev 4) — PASS

clause verdict by evidence
acceptance[0] pass B Boot A (no OS_CLOUD_URL, :41201): GET /marketplace/install-local → 200 {items:[],total:0,storageDir}. GET /marketplace/pack…
acceptance[1] pass B Boot A runtime/config features:{installLocal:true, marketplace:true}; Boot B {installLocal:true, marketplace:false}. All four…
acceptance[2] pass B os package install /home/user/objectstack/examples/app-crm/dist/objectstack.json -r http://localhost:41202 --email/--password p…
acceptance[3] pass B Admin: the entry carries installedBy:"KSD4…" and the envelope carries storageDir. Member (identity proven by get-session as q…
acceptance[4] pass B Before purge: account 4 (3 seed plus the user row "QA User-Authored Account B", id 6h-gOWCxjoPOD6YB), contact 3, opp 12, lead 5, …
acceptance[5] pass B Member, own session: POST install, DELETE, reseed and purge each → 403 FORBIDDEN naming the manage_metadata capability (e.g. "P…
acceptance[6] pass B DELETE as admin → 200 `{manifestId, cleanups:[{name:"security.package-permissions",success:true,removed:0}], note:"Cached manifes…
negative[0] pass (not triggered) B install-local answered 200 under off.
negative[1] pass (not triggered) B the flags matched the routes on both boots.
negative[2] pass (not triggered) B the user-authored row survived the purge.
negative[3] pass (not triggered) B no 2xx for the member or anonymous on any of the 8 cells.
negative[4] pass (not triggered) B purged rows did not return after the restart.
negative[5] n/a B the browse upstream "fetch failed" (502) was not filed. It is an egress limit, blocked(environment) for upstream reachability onl…

platform-core.runtime-config-boot-read (rev 1) — PASS

clause verdict by evidence
acceptance[0] pass A Default boot (plugins include com.objectstack.cloud.connection, marketplace-proxy and `com.objectstack.runtime.runtime-config…
acceptance[1] pass A I fetched GET /api/v1/studio/runtime-config anonymously at the same moment (parallel curl). It returned 200, and cmp shows the …
acceptance[2] pass A Cloud-arm boot: anonymous 200, as above. Offline boot (OS_CLOUD_URL=off, same port and DB; the plugin list has no cloud.connect…
acceptance[3] pass A On both boots, a case-insensitive grep of the body for token, secret, password, authorization, bearer, cookie, session, key, dsn …
negative[0] pass (not triggered) A No 401 or 403 on any read.
negative[1] pass (not triggered) A The alias has not drifted.
negative[2] pass (not triggered) A No credential material in the body.
negative[3] n/a A Flag agreement belongs to the marketplace item. I only saw that marketplace goes from true to false offline.

platform-core.docs-portal-render (rev 2) — PASS

clause verdict by evidence
acceptance[0] pass E Admin API: /meta/book has 1 book (showcase_manual) and /meta/doc has 9 docs (8 showcase plus setup_overview from com.objectstack.…
acceptance[1] pass E /docs/manual/showcase_index body rendered (screenshot). Its cross-link "documentation guide" (href /_console/docs/showcase_docs_g…
acceptance[2] pass E goto /_console/docs/showcase_tour_data (200) ended at /_console/docs/manual/showcase_tour_data, which renders "Guided tour — Data…
acceptance[3] pass E /_console/apps/com.example.showcase/docs lists only the 8 showcase docs under app-scoped hrefs, inside the Showcase shell. /_cons…
acceptance[4] pass E The member was minted by invite-member then sign-up/email; get-session confirms qa-e-member@… with positions org_member/everyone.…
acceptance[5] pass E Screenshots of the index, book landing (auto-opens the first doc), reader, app-scoped index (showcase and setup) and member pages…
negative[0] pass E The member's tree is not wider than the member's API set.
negative[1] pass E No entry returned 401/403 (the only 403 in the session was GET /meta/_drafts during the member's initial home load, not a docs …
negative[2] pass E The flat URL redirected and did not 404.
negative[3] pass E Screenshot-first reads were done after a 3.5 s settle.

platform-core.url-overlay-contract (rev 1) — PASS

clause verdict by evidence
acceptance[0] pass J Drawer: on the showcase_team list (hist 4), clicking "Platform" gave ?recordId=SyE2oWQkUm2t_w-v, hist 5, dialog=1 (screen…
acceptance[1] pass J Tabs: list, then record (push), then 5 tab clicks (Invoices, Projects, History, Related, Invoices). The URL went to `?tab=rel…
acceptance[2] pass J Fresh context, deep link …/showcase_account/record/p9fIbnZ0kZcphz__?tab=related:showcase_project opened with aria-selected tab …
acceptance[3] pass J Projects tab, then the related list's "New", gave `?tab=related:showcase_project&form=new&formObject=showcase_project&formLink=ac…
acceptance[4] pass J Account Fabrikam, Projects tab, then the "Compliance Audit" row gave `showcase_project/record/4JTlSri7ZjPQ6vnd?from=[{"o":"showca…
acceptance[5] pass J /_console/forms/showcase_task.form?recordId=‹project id›&recordObject=showcase_project, run twice (R1, R5), rendered the error …
negative[0] pass J Back never stepped through tabs or palette/shortcuts (acceptance[1] above).
negative[1] pass J No /data read or write for the mismatched pair (acceptance[5]).
negative[2] pass J Nothing violated on the driven surfaces, and a static scan of examples/app-showcase/src found no page or view repurposing `reco…
negative[3] pass J Cold reload and fresh-context opens kept the overlay and the pre-link.

platform-core.home-admin-cluster-links (rev 3) — PASS

clause verdict by evidence
acceptance[0] pass D All 9 URLs land on real pages (screenshots reviewed): Settings hub, Applications (Showcase/Setup/Account), App Marketplace (named…
acceptance[1] pass D /apps/setup/system trace: [/apps/setup/system, replaceState:/apps/setup/system, replaceState:/apps/setup/system/settings]. Th…
acceptance[2] pass D Legacy URLs, each with one replaceState hop: users → /apps/setup/sys_user, organizations → /apps/setup/sys_organization, role…
acceptance[3] pass D Plain member minted by invite then sign-up (qa-d-member@example.com). get-session showed positions [org_member, everyone]. `/…
negative[0] pass (not triggered) D No RouteNotFound or system record view.
negative[1] pass (not triggered) D All 5 legacy URLs redirect.
negative[2] pass (not triggered) D No Administration entry for the member. Server half: the member gets ?id=setup → [] (see the builtin item).

platform-core.lifecycle-retention-sweep (rev 4) — PASS

clause verdict by evidence
acceptance[0] pass G Seeded rows: 5 sys_automation_run rows status=completed, created_at −40d, in data.telemetry.db. The control boot (OS_LOG_LEVEL=in…
acceptance[1] pass G The survivors are exactly qa_run_paused and qa_run_running, which is the seeded non-terminal set.
acceptance[2] pass (live retention + pin for the report half) G Live: qa_audit_old (−100d) survived the sweep. The "reported skipped archive-pending" half is not visible in the aggregate log li…
acceptance[3] pass G Pin: "unguarded reap batching (#5194) › bounds the FIRST sweep over a large backlog, and drains the rest on later sweeps" ✓ plus …
acceptance[4] pass G Re-seeded qa_run_killswitch (completed, −40d). The boot ran with OS_LIFECYCLE_DISABLED=1 and OS_LOG_LEVEL=info, and other INFO li…
acceptance[5] pass G Spec object.zod.ts LifecycleClassSchema is record, audit, telemetry, transient, event (5). The engine has SYSTEM_LEDGER_LIFECYCLE…
idle heartbeat (steps[4]) pass G Fresh info-level boot on the cleaned DB: `[lifecycle] sweep: 18 policy(ies) applied, ~0 rows reaped, 0 datasource(s) reclaimed, 0…
negative[0..4] pass G The paused/running rows were not reaped. The audit row was not hot-deleted. Every absence was read after ≥60 s on an armed compos…

platform-core.seed-mode-matrix (rev 2) — PASS

clause verdict by evidence
acceptance[0] pass A Publish 1 {A:a1, B:b1} gave seedApplied inserted 2, updated 0. I then PATCHed A.note to "runtime-edit" (A.updated_at 12:40:25.3…
acceptance[1] pass A The update-mode publish {A:a2, D:d1} gave inserted 0, updated 1. Total stayed 3, before and after. A became a2. Filtering `{"na…
acceptance[2] pass A The ignore-mode publish {A:a3, E:e1} gave inserted 1, updated 0. A still reads a2 with updated_at 12:40:33.255Z, both unchang…
acceptance[3] pass A The insert-mode publish {A:a-ins} gave inserted 1. A second A-named row appeared (id 19_N…), so there are two "A" rows and tota…
acceptance[4] pass (expected posture recorded) A I hand-inserted F with POST /api/v1/data, then published replace {G}, which gave inserted 1. F (30W7…) survives and G is insert…
acceptance[5] pass A In spec/src/data/seed.zod.ts, SeedMode = z.enum(['insert','update','upsert','replace','ignore']) has 5 members (the enumSourc…
negative[0] pass (not triggered) A I re-published the upsert draft unchanged twice. Replay 1 gave inserted 0, updated 1: it re-converged the newest A row (19_N…, …
negative[1] pass (not triggered) A Update did not create D. Ignore did not rewrite A.
negative[2] pass (honoured) A The replace clause is recorded as posture, not as a pass of scoped deletion.
negative[3] pass (honoured) A I used only the scratch object, in its own isolated DB.

platform-core.settings-audit-secret-fingerprint (rev 2) — PASS

clause verdict by evidence
acceptance[0] pass G PUT /api/settings/mail {provider:'resend', api_key:V1, from_email} → 200. sys_setting_audit api_key action=set, encrypted=True, `…
acceptance[1] pass G Offline search over both full ledger dumps: V1 plaintext no-hit, fnv32(JSON V1)=fnv32:95ea83c2 no-hit, sha256(V1) no-hit, 'sha256…
acceptance[2] pass G Writes V1, V1, V2, V1 on both ledgers: b9fb35cf…, b9fb35cf…, f6c98912…, b9fb35cf…. Equal values give equal fingerprints and V2 di…
acceptance[3] pass G PUT {provider:'log', api_key:null}: sys_setting_audit api_key action=reset, new_hash=None. sys_audit_log config_change metadata e…
acceptance[4] pass G from_email rows carry fnv32:6d1d9810 and fnv32:c8753918 on both ledgers, which equals the offline FNV-1a of the quoted JSON.
acceptance[5] pass (pin) G service-settings settings-audit-secret-digest.test: "legacy inline-adapter path with no provider records no fingerprint and repor…
negative[0..4] pass G No unkeyed digest and no plaintext. Fallback and veto are pinned. The positive control is present.

platform-core.v18-boot-refusals (rev 1) — FAIL

clause verdict by evidence
acceptance[0] pass (pin) G runtime organization-ownership-boot-guard.test.ts (17 tests ✓, incl. "⭐ a v17-shape database is refused, naming the command and e…
acceptance[1] pass G os serve (production; OS_DATABASE_URL=file:‹copy›) against two planted v17-shape copies exits rc=1 after 7 s / 11 s. There …
acceptance[2] FAIL G Checksums before and after the refused boot differ. Reproduced 3 times on fresh copies: pinshape adf7d2b6… → dafa44ed…, real 00ec…
acceptance[3] blocked(fixture) G The step's "scratch config with services:{auth:false}" names no real stack key. I tried tiers:['core'] + `plugins:[new Security…
negative[0] pass with caveat G The v18 boot did not serve the v17 DB: it exited before listening. Whether the additive DDL counts as "half-migrates" is exactly …

platform-core.protocol-18-handshake-and-stored-replay (rev 1) — PARTIAL

clause verdict by evidence
acceptance[0] pass (pin) G runtime packages-install-protocol-incompatible.test (6 ✓). cli migrate-meta-protocol-range.test (19 ✓). spec conversions/stored.t…
acceptance[1] pass G POST /api/v1/packages with engines.protocol "^17" → 422 OS_PROTOCOL_INCOMPATIBLE, details.migrateCommand "objectstack migrate m…
acceptance[2] pass G Planted: PUT a canonical page qa_planted_page, stop, then sqlite UPDATE sys_metadata.metadata to template:'full-width' (retired…
acceptance[3] blocked(fixture) G No ^18 artifact built before a retirement exists in this checkout, and making one needs an older prerelease build. Pinned only: "…

platform-core.settings-organization-isolation-and-platform-rung (rev 1) — PARTIAL

clause verdict by evidence
acceptance[0] pass (pin) G settings-organization-isolation.pin (18 ✓), settings-read-door.pin (27 ✓), settings-admission-tenancy-posture (18 ✓), config-chan…
acceptance[1] pass G As platform admin, PUT /api/settings/mail {from_email} (mail is scope 'global') → 200. GET /data/sys_platform_setting → 200 with …
acceptance[2] blocked(environment) G A boot with OS_TENANCY_POSTURE=isolated is refused by 18.0 by design: `✖ FATAL: tenancy posture 'isolated' is not supported in 18…
acceptance[3] blocked(environment) G Same cause: only the walled posture refuses, and the pin says "is not refused under the 'single' posture". Pinned: "is refused wh…

platform-core.serve-composition-v18 (rev 1) — PARTIAL

clause verdict by evidence
acceptance[0] pass (pin) G cli serve-config-boot-residual (14 ✓), serve-datasource-mapping-before-sync (2 ✓), serve-no-storage-boot-guard (5 ✓), console.not…
acceptance[1] pass G Scratch packages[] config (2 package bodies + a top-level qag_note object/view), production serve → exactly 1 warn line: `[AppPlu…
acceptance[2] pass G Scratch app with page qagorg_organization_detail (record, sys_organization, isDefault) → boot ready, 0 DEFAULT_RECORD_PAGE_CONFLI…
acceptance[3] pass G Scratch host config: datasources primary (sqlite ./primary.db) + datasourceMapping [{default:true, datasource:'primary'}] + OS_DA…
acceptance[4] pass G Host config (inline plugin, no OS_DATABASE_URL, no --dev, NODE_ENV unset, bin/run.js) → rc=1: `✖ This production serve has no sto…
acceptance[5] blocked(environment) G Staging an unbuilt console means removing packages/console/dist from the shared tree, which this runner may not touch. A dist-les…

Handoff — items not reached (NOT-RUN)

Tier 3 deferred by the 18.0 release-sweep plan (plan B: P2 items without an automated.ref are not driven this wave):

  • platform-core.shell-nav-personalization (P2, browser, rev 4) — not-run
  • platform-core.app-management-toggle (P2, mixed, rev 3) — not-run
  • platform-core.packaged-object-extend-only (P2, api, rev 2) — not-run
  • platform-core.marketplace-console-honesty (P2, browser, rev 5) — not-run
  • platform-core.keyboard-shortcut-surface (P2, browser, rev 4) — not-run
  • platform-core.theme-mode-persistence (P2, browser, rev 2) — not-run
  • platform-core.console-installability-indicators (P2, browser, rev 1) — not-run

Reproduction rules for each FAIL

platform-core.package-lifecycle-enable-disable · acceptance[5] — product defect (objectui console)

Clause: after disable, the package's nav is gone and a stale deep link lands on a named not-found inside the shell, never a dead page. Nav-absent half passes; the deep-link half fails. Reproduced 2/2 by the first runner and 2/2 by an independent RUNNER rule 7 verifier on a fresh boot (traps ruled out: 60 s settle with silent network after 1.1 s; console stamp = pin; direct navigation, no clicks on the failing surface).

  1. Boot showcase (objectstack dev --ui --seed-admin); POST /api/v1/auth/sign-in/email {"email":"admin@objectos.ai","password":"admin123"} → bearer.
  2. POST /api/v1/packages {"manifest":{"id":"com.qa.probe","name":"QA Probe","version":"0.1.0","type":"app","namespace":"qaprobe"}} → 201.
  3. PUT /api/v1/meta/object/qaprobe_widget?mode=draft&package=com.qa.probe {"name":"qaprobe_widget","label":"QA Widget","sharingModel":"public_read_write","fields":{"name":{"type":"text"}}} → 200; POST /api/v1/packages/com.qa.probe/publish-drafts {} → 200; GET /api/v1/meta/object/qaprobe_widget → 200.
  4. PATCH /api/v1/packages/com.qa.probe/disable {} → 200 status:disabled. GET /api/v1/meta/object/qaprobe_widget → 404 {"error":"Object 'qaprobe_widget' belongs to a disabled package…","code":"OBJECT_PACKAGE_DISABLED"}.
  5. Sign in through /_console/login, open /_console/apps/showcase_app/qaprobe_widget.
    • expected: Showcase shell with a named not-found / package-disabled state.
    • actual: full-page "ObjectOS · Opening your console…" splash, still present at 60 s; network shows two 404 OBJECT_PACKAGE_DISABLED, then nothing.
    • control: /_console/apps/showcase_app/no_such_object_xyz → 404 RESOURCE_NOT_FOUND → named "Object Not Found" inside the shell.

Discriminator (verifier, Playwright response rewrite, status kept 404): wrapped body with the SAME code still hangs; flat or wrapped body with code RESOURCE_NOT_FOUND renders the named not-found. The code value decides, not the envelope. Mechanism (objectui at the pin and on objectui main 61ed5ad alike): isMetaItemAbsentError (data-objectstack) recognises only RESOURCE_NOT_FOUND, so the by-name scope read is classed failed; fetchScopeName drops it without re-render; the first-paint gate in AppContent.tsx never settles. Secondary framework observation (not the cause): the RestServer /meta/object/:name refusal is the flat {error, code} shape without the object key /data carries, while the runtime dispatcher answers the wrapped envelope — both are live ADR-0112 shapes; the #7557 changelog example shows only the wrapped one.

platform-core.v18-boot-refusals · acceptance[2] — assertion defect (not a product break)

Clause: "the refused boot did not alter the database", oracle build, checksum before == after.

  1. Build a real v17 database: npm @objectstack/cli@17.7.0, os init, os dev --seed-admin -d file:v17.db, create 3 records, stop (sha256 de915b8f…, 69 tables, 66 rows).
  2. Copy it; from examples/app-showcase run OS_DATABASE_URL=file:COPY OS_SECRET_KEY=64-hex objectstack serve -p PORT.
  3. Result 3/3: rc=1 before listening, refusal names the 7 tables still carrying organization_id and os migrate organization-ownership (acceptance[1] pass). sha256 after ba74b704… ≠ before — expected by the clause: equal.
  4. Row-level diff (pristine vs after, each table on its original columns): 0 tables differ, 66/66 rows identical, no new table holds a row, no column dropped. The change is the engine's additive schema sync (41 empty tables, __search columns, indexes). A 17.7.0 boot of the refused copy still serves the 3 original rows.

§5 disposition: assertion defect. The declared contract is row-level: runtime CHANGELOG ("judges … after the engine's schema sync (the column the rewrite step waits for is still added) … A refused boot leaves every row as it found it"), the guard's header, and the kernel pin that asserts the additive tables exist and hold no rows. negative[0] (served or half-migrated v17 DB) holds. Owed: re-point acceptance[2] to a row-level oracle (routed to the wave anchor, see below). acceptance[3] is blocked(fixture): the step's services:{auth:false} is not a real stack key.

RUNNER rule 7 (P0 fails / release-blocking findings)

  • platform-core.v18-boot-refusals acceptance[2] (P0): independent agent re-derived from the captured evidence alone — FAIL against the clause as written, PASS against the declared contract — then re-ran on a realistic 17.7.0 database (3/3). Agreement: assertion defect, not release-blocking.
  • platform-core.package-lifecycle-enable-disable acceptance[5] (P1, user-visible): independent agent re-derived FAIL from the evidence alone and reproduced 2/2; it corrected the first runner's causal story (code value, not envelope shape). Product defect in objectui; not a data or security issue.

Partial items — what was not proven

  • docs-audience-gate acceptance[2]: the unknown-future-audience-shape fail-closed branch is unreachable live (a save with an unknown shape is refused 422) and has no test; only the source line evidences it.
  • protocol-18-handshake-and-stored-replay acceptance[3]: blocked(fixture) — no ^18 artifact built before a retirement exists in this checkout.
  • settings-organization-isolation-and-platform-rung acceptance[2], [3]: blocked(environment) — 18.0 refuses OS_TENANCY_POSTURE=isolated at boot (NOT_IMPLEMENTED, single only); pins pass.
  • serve-composition-v18 acceptance[5]: blocked(environment) — needs an unbuilt console, i.e. removing the shared tree's console dist.

Checklist-accuracy findings / fixture gaps (for the wave anchor card — not extracted)

  • v18-boot-refusals: re-point acceptance[2] to a row-level oracle (above); step 2 services:{auth:false} is not a stack key; the literal ORGANIZATION_OWNERSHIP_MIGRATION_REQUIRED is only on error.code, never printed.
  • package-lifecycle-enable-disable: the step should say an object needs sharingModel and a view viewKind before publish accepts them.
  • builtin-apps-nav-render steps[5]: 45 Setup destinations → this boot serves 42 (matches source minus gates); Configuration / Advanced (Setup) and Developer (Account) groups render collapsed — a sidebar walk must expand them.
  • home-admin-cluster-links acceptance[3]: the Help menu also lists Keyboard shortcuts and About, not "documentation only".
  • settings-hub-roundtrip: invalid-timezone code is value_domain, not invalid_option; no stock namespace is user-scoped, so the multi-scope secret walk cannot run as written.
  • notification-center: console polls sys_inbox_message / sys_notification_receipt through the data API, not GET /notifications?view=mine; the Approvals tab is a count + "View approvals" link, not a list (scored pass on the count match — reword).
  • docs-audience-gate: knownGaps[0] half stale (showcase ships a public book); acceptance[3] "lesser persona's tree ⊂ admin's" is wrong for permission-set books (a non-holder admin sees less than a holder) — reword to holder vs non-holder. Missing test: unknown audience shape denies.
  • runtime-config-boot-read steps[1]: logoUrl / faviconUrl / brandColor appear only when configured.
  • manifest-install-contract: knownGaps[3] and negative[2] say NamespaceConflictError has no code — stale; it carries NAMESPACE_CONFLICT / 422.
  • marketplace-install-local-lifecycle: step 3 typo install./examples; "fresh sign-up" must be admin create-user (invite-only posture); on showcase the cloud arm comes from host config, not the CLI.
  • activation-ledger-row-contract: the catalog door now also accepts sharing_rule — a fifth ledger writer; the four-value variants are stale.
  • serve-composition-v18: examples/app-crm no longer declares a datasourceMapping.
  • settings-organization-isolation-and-platform-rung / walled legs generally: the isolated-posture fixture cannot boot on 18.0 — knownGap should say live legs wait for the walled release.
  • url-overlay-contract: useUrlOverlay.test.tsx asserts no history behaviour (replace semantics evidenced only by hand); step 5 "breadcrumb" is now an inline back link.
  • metadata-authoring-roundtrip: objectui studio-record-page.spec.ts red (stale, as noted); studio-object-designer.spec.ts F1 (targets the not-loaded studio app) and F4 (new select-options rule) are red too, contrary to the item's note; acceptance[2] hand-driven instead.
  • RUNNER env fact: showcase resolves @playwright/test 1.63.0, not 1.62.1.
  • fixture: marketplace browse needs egress to the cloud catalog (502 MARKETPLACE_PROXY_FAILED here) — knownGap, not scored.

Observations (not clause verdicts)

  • Seed replay rewrites 5 unchanged showcase rows on every restart (updated_at bumped; counts and ids unchanged) — extracted as a product defect at close-out.
  • A list view bound to an object outside the writing package's dependency closure is accepted with unknown columns fields on active PUT and draft→publish (observed while driving metadata authoring; no clause asserts it) — extracted at close-out.
  • console-login: after a server-side sign-out, in-app navigation without reload does not auto-redirect (data pages show "Sign in required"); not scored by the item.
  • builtin-apps: a member's user record shows both "Unban User" and "Ban User".
  • seed-mode-matrix: with two rows sharing the match key, upsert matched the most recently created one; replace mode inserts without clearing (posture recorded, not scored as scoped deletion).
  • docs-portal: in-body cross-links inside the app-scoped docs viewer leave the app for global /docs.

Timing

Wave-level (one shared build for all three area runs): environment preparation 20 min wall (12:26 → 12:46 UTC: pnpm install 25 s, pnpm build 7m45s, console build 19 min incl. one re-run after a concurrent-build race in @objectstack/lint DTS), of which the API/unit lane was ready after 9 min; testing ~70 min wall (12:35 → 13:45) across parallel runners. Environment : testing ≈ 1 : 3.5 wall. Inside the runners, per-item boot/wait time summed ~55 min of agent time vs ~300 min of driving. This area: Tier 1 batch ~14 min (shared), Tier 2 drivers 4 parallel groups.

Derived item verdicts

  • PASS (21): platform-core.boot-health, platform-core.seed-integrity, platform-core.console-login, platform-core.nav-surfaces-render, platform-core.builtin-apps-nav-render, platform-core.metadata-registry-serving, platform-core.metadata-authoring-roundtrip, platform-core.interrupted-migration-boot-report, platform-core.activation-ledger-registration-home, platform-core.activation-ledger-row-contract, platform-core.url-overlay-contract, platform-core.lifecycle-retention-sweep, platform-core.settings-audit-secret-fingerprint, platform-core.settings-hub-roundtrip, platform-core.notification-center, platform-core.manifest-install-contract, platform-core.marketplace-install-local-lifecycle, platform-core.runtime-config-boot-read, platform-core.docs-portal-render, platform-core.home-admin-cluster-links, platform-core.seed-mode-matrix
  • PARTIAL (4): platform-core.docs-audience-gate, platform-core.protocol-18-handshake-and-stored-replay, platform-core.settings-organization-isolation-and-platform-rung, platform-core.serve-composition-v18
  • FAIL (2): platform-core.v18-boot-refusals, platform-core.package-lifecycle-enable-disable
  • NOT-RUN (7): Tier 3 deferred, listed above

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Close-out (checklist-test SKILL §5).

    Extracted: objectstack-ai/objectui#13052 · platform-core.package-lifecycle-enable-disable · acceptance[5]
    Extracted: #24562 · platform-core.seed-integrity · acceptance[3]
    Extracted: #24563 · platform-core.metadata-authoring-roundtrip · observation outside the clauses

    FAIL dispositions:

    • platform-core.package-lifecycle-enable-disable · acceptance[5] → product defect (objectui console), extracted above. RUNNER rule 7: independent re-derivation agreed (FAIL, 2/2 re-run).
    • platform-core.v18-boot-refusals · acceptance[2] → assertion defect (clause demands byte-identity; declared contract is row-level, measured 0/66 rows changed on a real 17.7.0 database). RUNNER rule 7: independent re-derivation agreed — not release-blocking. The test-fix (re-point to a row-level oracle) is routed to the wave anchor card by the dispatch session; this wave files no checklist cards.

    Partial gaps and checklist-accuracy findings / fixture gaps: listed in the record body, routed to the wave anchor card by the dispatch session.
    NOT-RUN: 7 Tier 3 items deferred by the 18.0 release-sweep plan (handoff list in the body).


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Parked-on: #24579 · this record's checklist-accuracy findings, fixture gaps, partial coverage gaps and not-run handover (wave anchor §2–§4)


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Superseded-by: #24603

    Round 2 at ba4afcc re-judged this record's A-class unjudged clauses (platform-core.serve-composition-v18 acceptance[5] — pass) and carried every other verdict forward to #24603 (Carried-forward: lines there, valid for 5b14b7f). B-class gaps stay parked on #24579.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions