Skip to content

QA run · t2:24681-touched (28/28) · 307ce4c4 · 2026-10-20 · 12 PASS / 16 PARTIAL / 0 FAIL / 0 BLOCKED / 0 NOT-RUN #24841

Closed

Description

@objectstack-fleet

QA run record — 18.0 round-4 supplementary sweep, the #24681 targeted pass (18.x steps 5 and 6, the upgrade ceremony opened), record 3 of 3: the 28 unpinned P0/P1 server items (surface api / cli / build) among the items #24681's source files map to, driven by hand on a fresh stock showcase. Framework 307ce4c4. Maintainer-approved (dispatch session session_01CfRDy7SuTfUqaTu2AEH2Hi, 2026-10-20). Wave anchor: #24579. Previous round: round 3 at 580fd4ed (#24779 surface:api, #24786 surface:cli, #24787 surface:build). Sister records: #24838 (upgrade:ceremony) and the tier1:24681-touched record (close-out comment).

Environment fingerprint

  • Framework 307ce4c4b42503347d7f85825f572e4ca058b05f (pinned, detached; no pull). No console build: every browser leg is not-run (browser).
  • Cold tree: pnpm install --frozen-lockfile (21 s), pnpm build --concurrency=2 (76/76, 7m29s), check-dev-prereqs green.
  • Runner A (27 items, a runner subagent with its own port and DBs, clause verdicts re-read by the parent): port 41841 (41842 only for a local delay server in the RESUME_IN_PROGRESS probe); scratch root /tmp/qa4/t2/. Boot: OS_PORT=41841 setsid pnpm -C DIR exec objectstack dev --ui --seed-admin -p 41841 -d file:/tmp/qa4/t2/NAME.db, stopped by the listener's process group. Install, OS_CLOUD_URL=off, scratch-app and connector items ran from a full scratch copy of examples/app-showcase (made with tar — rsync is not installed here). DBs: p0.db (4 boots), dup.db, qasuite.db, bootb.db (3 boots), conn.db, conntwin.db, aiboot.db.
  • Runner B (the parent): cli.dev-boot-contract on a scratch copy at ports 41858/41859, DBs under /tmp/qa4/dbc/.
  • Boot banner: Tenancy: single · Flows: 32 flow(s) 19 bound to triggers (record_change, schedule, time_relative, api) · 8 draft · Seeds: com.example.showcase 132 rows. On an info-level fresh boot: [organization-ownership] a datastore created from empty: birth marker written (shape generation 1, platform 18.0.0-next.5). No second or third boot over an existing DB was refused by the ownership guard (3 restarts over p0.db, 2 over bootb.db, plus the seed-integrity, flow-disable, clone and marketplace restart legs).
  • Afterwards examples/app-showcase/.objectstack/ holds only the pre-existing data; no installed-packages/ (RUNNER install-escape check); git status clean.
  • Timestamps (UTC, 2026-10-20): runner A 08:13–08:57; negatives completed 09:36–09:38 (from captured evidence, no new boots); runner B 09:17–09:26; expired-token leg 09:38.

Scope

Selector t2:24681-touched — a maintainer-named set: the 28 items among the #24681-touched set whose surface is api / cli / build, that carry no automated.ref, at P0/P1. Revisions per row below. No item is planned.

Result

12 PASS / 16 PARTIAL / 0 FAIL / 0 BLOCKED / 0 NOT-RUN of 28. No clause failed; no authentication or authorization finding.

How negatives are scored: every negative[] entry gets a verdict. A negative that states only a runner or recording rule (no product expectation) is not-run (procedural), so its item derives PARTIAL even when every product clause passed — 12 of the 16 PARTIALs are that and nothing else (named per row). Round 3 scored such negatives pass in its Tier 2 tables; the difference is the rule, not the product (see "Against round 3").

Per-item verdicts (aN = acceptance[N], nN = negative[N])

item rev verdict clauses
platform-core.seed-integrity 3 PASS a0–a4 pass · n0 pass · n1 pass
automation.packaged-flow-disable-durable 3 PARTIAL a0–a4 pass · n0–n2 pass · n3 not-run (procedural)
access-security.packaged-flow-write-door-parity 2 PARTIAL a0–a3 pass · n0 pass · n1, n2 not-run (procedural)
automation.packaged-flow-clone-contract 5 PARTIAL a0–a5 pass · a6 pass (API durability) + not-run (browser: Studio rail) · n0–n2 pass · n3 pass (anonymous half; the non-manage_metadata member half not driven)
automation.packaged-flow-subflow-disable-refusal 5 PARTIAL a0–a4 pass · n0, n1 pass · n2 not-run (procedural)
automation.trigger-status-contract 3 PARTIAL a0–a3 pass · a4 pass on every reachable arm + blocked(fixture: 503 STORE_UNAVAILABLE has no stock trigger) · a5, a6 pass · n0–n5 pass
access-security.owd-save-gate 5 PARTIAL a0–a4 pass · n0 not-run (browser) · n1 pass · n2 not-run (procedural)
ai.mcp-run-action-exposure-gate 4 PASS a0–a4 pass · n0, n1 pass
api-backend.aggregate-contract-matrix 3 PASS a0–a5 pass · n0–n2 pass
api-backend.filter-comparand-conformance 3 PARTIAL a0–a4 pass · n0 pass · n1 not-run (no cross-type coercion probe; whether the contract refuses a string comparand against a number field was not established) · n2, n3 pass
approvals.approver-resolution-matrix 5 PASS a0–a5 pass · n0–n4 pass
search.rls-both-personas 7 PARTIAL a0–a3 pass · n0 pass · n1 not-run (procedural)
identity-auth.self-service-password-reset 3 PASS a0–a4 pass · n0 pass · n1 pass (reuse: 400 INVALID_TOKEN; expiry: simulated, see evidence) · n2, n3 pass
integration-system.external-datasource-federated-read 4 PASS a0–a2 pass · n0 pass
platform-core.runtime-config-boot-read 2 PARTIAL a0–a3 pass · n0–n2 pass · n3 not-run (procedural)
cli.build-own-contract 6 PARTIAL a0–a5 pass · n0, n1 pass · n2 not-run (procedural)
cli.doctor-health-report 4 PASS a0–a7 pass · n0–n5 pass
cli.hook-body-extraction-gates 4 PARTIAL a0–a6 pass · n0–n3 pass · n4 not-run (procedural)
cli.migrate-duplicates-inventory 8 PARTIAL a0–a7 pass · n0, n1, n3 pass · n2 not-run (procedural)
cli.migrate-meta-codemod 5 PASS a0–a7 pass · n0–n6 pass (n3: see note)
cli.qa-suite-execution 7 PARTIAL a0–a7 pass · n0–n3 pass · n4 not-run (procedural)
platform-core.seed-mode-matrix 2 PARTIAL a0–a5 pass (a4 records the replace-mode gap) · n0, n1 pass · n2, n3 not-run (procedural)
platform-core.marketplace-install-local-lifecycle 5 PARTIAL a0–a6 pass · n0–n4 pass · n5 not-run (procedural)
platform-core.manifest-install-contract 4 PASS a0–a5 pass · n0–n4 pass
integration-system.connector-degraded-recovery 3 PASS a0–a4 pass · n0, n1 pass
ai.agent-tool-skill-metadata-roundtrip 6 PASS a0–a5 pass · n0, n1 pass
api-backend.retired-def-refusal 3 PASS a0–a3 pass · n0–n3 pass
cli.dev-boot-contract 5 PARTIAL a0 pass (health 200, ready 200) + not-run (console not built) · a1–a6 pass · n0–n3 pass

Evidence (text oracle, one line per clause group)

  • seed-integrity — counts from the artifact's data[] (132 rows) equal the API totals for all 19 seeded objects (account 14, contact 32, project 5, task 10, invoice 12, …; 0 mismatches); Specimen — Full: f_multiselect {red, green}, f_lookup = Northwind's id, f_master_detail → "Website Relaunch", f_json {nested:{k:v},list:[1,2,3]}; banner plain; info level [Seeder] Seed loading complete {"inserted":132,…,"errored":0}; restart {"inserted":0,"updated":0,"skipped":132,"errored":0}, count diff empty, restart not refused; f_user / f_users / f_secret / task.cover null as documented.
  • packaged-flow-disable-durable — toggle 200; ledger row {metadata_type:flow, name:showcase_urgent_task_alert, package_id:com.example.showcase, active:false}, key set without organization_id, the only matching row; trigger → 409 FLOW_DISABLED naming the ledger (ADR-0126 §7.2) and the remedies; cold restart logs "Activation ledger: 1 packaged flow(s) are switched off …", _status enabled:false bound:false; runs stayed at 1 after a post-restart urgent create; re-enable kept the row id (active:true) and the next create made run 2.
  • packaged-flow-write-door-parity — PUT /meta/flow 403 NOT_OVERRIDABLE (with ?package= 403 ITEM_LOCKED); PUT /automation/NAME 403 NOT_OVERRIDABLE; DELETE 403 "sealed against removal"; GET before/after byte-identical; flow still runs.
  • packaged-flow-clone-contract — {} / missing name / missing label → 400 VALIDATION_FAILED with fields[].code required; clone key diff exactly name, label, status→draft and the dropped provenance keys; one urgent create fired base (3→4) and clone (0→1), notice equals FLOW_CLONE_NOTICE; same name 409 RESOURCE_CONFLICT with suggestion showcase_urgent_task_alert_copy; unknown 404; Bad-Name! 400 invalid_format; anonymous 401; subflow config kept; clone PUT 200; after restart the clone exists (package null) and runs.
  • subflow-disable-refusal — 409 DELETE_RESTRICTED naming the calling flow and the remedy; no ledger row for refused flows; child enable 200; caller off then child off 200; engine pin flow-activation-ledger.test.ts 47 passed ("names EVERY packaged caller").
  • trigger-status-contract — both doors identical: 404 RESOURCE_NOT_FOUND, 409 FLOW_DISABLED, 422 FLOW_NO_START_NODE, 400 FLOW_FAILED (details.errorMessage + summary), 200 success; wizard 200 paused with runId/screen; action and endpoint doors 409 with the same ledger message; resume arms 403 / 400 INVALID_SCREEN_INPUT / 400 INVALID_SIGNAL / 409 RESUME_IN_PROGRESS / 404 RUN_NOT_FOUND / 400 inputs+variables, run stays paused and a later resume completes; edited-away node and deleted flow → 404; @objectstack/client rejects with httpStatus/code on every refusal.
  • owd-save-gate — 422 INVALID_METADATA at the active and draft doors on externalSharingModel ("removed in @objectstack/spec 18 … Delete the key."), follow-up GET 404; without the key 200; widen → 403 NOT_OVERRIDABLE (with ?package= 403 ITEM_LOCKED); GET byte-identical; pins meta-object-owd-gate.test.ts 11 passed, object-posture-gate.test.ts 10 passed.
  • mcp-run-action-exposure-gate — run_action on an unexposed action refused with the opt-in sentence, task updated_at unchanged; list_actions only showcase_portfolio_snapshot; its result {accounts:14, projects:5, invoices:12} equals REST totals; [action-audit] … executes TRUSTED (system-elevated …) log line; sys_user object refused.
  • aggregate-contract-matrix — 6 functions × grouped/ungrouped equal local computation (count-all 14, count(signed_on) 11); 5 date granularities match local ISO buckets with one real null bucket (Sunday 2024-08-11 → W32); empty-set identities; retired/unknown functions 400 with prescriptions; contributor-bound member's aggregate equals its own baseline; analytics day labels identical at UTC and America/Los_Angeles.
  • filter-comparand-conformance — string/number/boolean/null comparands 200 with answer sets equal to local counts (1/7/1/3); date and bigint via engine pin (12 passed); plain object / array-for-scalar / operator-less object → 400 located; dotted heads on relation/formula/scalar → 400; POST 400 VALIDATION_FAILED and GET $filter 400 INVALID_FILTER with the same sentence; driver past-limit bigint case passed on memory, sqlite-wasm, turso, mongodb, sql.
  • approver-resolution-matrix — user/manager/team/role/org_membership_level/department/field slates as declared, descendant units included, deactivated unit dropped; role deprecation WARN with equal slate; every no-holder policy as specified (admin_rescue pending with __resolvedFrom.abandoned, fail → run failed NO_APPROVERS, auto_approve with marker, fallback and its degradation); queue WARN 审批节点「处理人 Value」应改为记录 lookup(现查 metadata 端点→只能手填);附 approver value 语义核实 + queue 未实现 #3508.
  • search.rls-both-personas — member: INV-1003 by id 404, search 0; admin search finds it; pagination totals 3/3/3 (admin 14); member finds its own INV-QA-RLS.
  • self-service-password-reset — reset mail row in sys_identity_email (not sys_email) with reset-password/TOKEN; reset 200, new password signs in, old refused INVALID_EMAIL_OR_PASSWORD; reuse 400 INVALID_TOKEN; garbage 400 INVALID_TOKEN with the password unchanged; known/unknown request bodies identical 200. Expired leg (parent, 09:38, same sha, the next.5 database after the ceremony): a fresh token's sys_verification.expires_at set one hour into the past (simulated clock) → POST /auth/reset-password 400 {"message":"Invalid token","code":"INVALID_TOKEN"}, current password still 200, attempted password 401.
  • external-datasource-federated-read — external objects in /meta; orders 4 rows, filter={"status":"paid"} total 3, top 2; OData $filter 400 INVALID_FILTER; POST/PATCH 403 EXTERNAL_WRITE_FORBIDDEN; datasource listed schemaMode external, status ok.
  • runtime-config-boot-read — anonymous 200 with features/branding/telemetry; alias byte-identical on both boots; OS_CLOUD_URL=off boot anonymous 200 (installLocal:true, marketplace:false); no credential strings; admin read identical.
  • build-own-contract — clean build exit 0 (723.1 KB) and --json shape; plain-literal field without type → human exit 2 / --json exit 1 STACK_SCHEMA_INVALID; two broken CEL approvers reported at once with rule, path, hint, caret; load-time throw 2/1 repeated identically; undeclared nested key dropped with a notice, exit 0; build and compile byte-identical.
  • doctor-health-report — always-rows print; .env provenance finding; isolatd ✗ row with accepted values and exit 1; broken ledger entry ⚠; unique-scope line rules; dependency/object/view findings and their ✓ forms; warnings-only exit 0, errors exit 1; skip rows ℹ with -v "Looked for …" lines.
  • hook-body-extraction-gates — --strict-body: all 14 forbidden patterns refused with their own reasons, exit 1, --json issues 14; capability inference find/update/alias/uuid/log/hash-only as specified; body-as-data shipped verbatim; module helper default exit 0 / strict exit 1 naming the out-of-scope identifier; body-only config skips the legacy bundle; default build warns with 14 per-hook reasons.
  • migrate-duplicates-inventory — reportVersion 2, counters, holders with createdAt; cross-partition T-0001 reported, within-partition repeat absent; row/sequence/sqlite_master checksums identical before and after; preflight blocks idx_sys_metadata_overlay_active with its group; liveConditions follow counter edits; filters; --database-url parity; memory://qa → {error:"boot_failed"} exit 1; pins 18 passed.
  • migrate-meta-codemod — planted retired keys listed with their entries; refusal for the no-rewrite key; sha256 unchanged without --write; snapshot drops both keys with the schema warning; replay --from 17 clean; --from 3 floor refusal exit 1; 385 manual changes; --write wrote 2 of 2 and a second --write wrote nothing; --from 18 empty-range warning.
  • qa-suite-execution — suite found, scenarios ✅ with ids/durations, exit 0, repeatable; teardown deletes the captured id; failing assertion message and exit 1; contains on undefined explained; malformed suite refused at load naming the file, siblings still run; zero-match exit 0, --fail-on-empty exit 1; unauthenticated roundtrip 401 exit 1.
  • seed-mode-matrix — upsert / update / ignore / insert / replace behave as declared (replace inserts beside hand rows — the recorded gap); replays converge {0,0} with updated_at untouched.
  • marketplace-install-local-lifecycle — boot A (cloud on) and B (OS_CLOUD_URL=off) routes and /runtime-config agree; air-gapped inline install of the CRM artifact; admin/member/anonymous visibility of the entry; purge 28 / second purge skipped 28, user row survives, restart keeps the purge; reseed 28; member 403 and anonymous 401 on every door; uninstall withdraws objects and app immediately and across a restart.
  • manifest-install-contract — ^17 → 422 OS_PROTOCOL_INCOMPATIBLE (details requiredRange, rangeSource, protocolVersion 18.0.0, targetMajor 17, migrateCommand "objectstack migrate meta --from 17"), no row; precedence and legacy spellings as specified; no range / workspace:* 201 with warns; namespace conflict 422 naming owner and incoming; derived namespaces stored.
  • connector-degraded-recovery — boot completes with a degraded MCP connector husk (reason, actions []); bad transport kind aborts the boot; dispatch refused with the degraded sentence; retries 5/10/20/40 s and an immediate retry on publish; after the upstream returns, recovery without restart and the next run completes.
  • agent-tool-skill-metadata-roundtrip — valid trio builds; the three tombstoned keys exit 2 with guidance; singular types in /meta; package probes list with provenance; runtime skill/tool drafts 200, package ones 403; anonymous 401; tool execute 501 NOT_IMPLEMENTED.
  • retired-def-refusal — four sampled retired defs (prefixes 17 and 18; kernel, data, automation) exit 2 with no artifact; carrier prescriptions differ from the invented control; runtime door refusals match the control.
  • dev-boot-contract (runner B) — health 200 after 11 s, ready 200, /_console/ 503 (not built); seed idempotent (original password 200 after a --admin-password changed99 restart, changed99 401); Database matrix: nothing chosen → .objectstack/data/objectstack.db, -d :memory:, env URL, legacy dev.db with the "Reading legacy database file … migrate with: mv …" notice; --fresh tempdir line, SIGINT exit 130, tempdir deleted; busy port "↪ server bound to port 41859 (requested 41858)"; stale artifact warning with newest source and fix; no config → exit 1 with the remedy; memory driver refused as flag (exit 2), env (exit 1, before any Database line) and URL (exit 1, after it).

Against round 3 (580fd4ed)

Closed and open cards re-checked at 307ce4c4 (beside the clauses, on a fresh stock boot)

Observations (no declared contract violated; not filed)

Checklist-accuracy findings / fixture gaps (for #24579)

  • Procedural negatives: 14 negatives across 12 of these items state a runner or recording rule with no product expectation; scored as not-run they hold their items at PARTIAL forever. Move them to traps / notes so the items can reach PASS (round 3 scored them pass in Tier 2 and not-run in Tier 1 — one rule is needed).
  • identity-auth.self-service-password-reset: requires/steps still say sys_email; the reset mail is in sys_identity_email. The expired-token leg has no step that can run without a clock wait — name the sys_verification.expires_at simulation (or a short configured expiry).
  • cli.migrate-meta-codemod n3: --write also moves engines.protocol (^17 → ^18) in objectstack.config.ts, announced by the closing line, not in the "Wrote N … into K file(s)" block; the clause's "changed files are exactly the files the block names" should allow for it.
  • automation.trigger-status-contract steps[5]: INVALID_SIGNAL needs {"inputs":{"new_assignee":"x"},"output":{"$x":1}} on the wizard (its screen requires new_assignee).
  • cli.migrate-duplicates-inventory: plan prints "[Registry] Overwriting view: qa_dup_view", not "Registered view"; planting the within-partition repeat needs the partitioned unique index dropped first.
  • platform-core.seed-mode-matrix: the scratch object needs the package namespace prefix or its publish is refused.
  • cli.build-own-contract: the [cli/lint] 作者时规则的命令覆盖漂移是系统性的:23/26 条手工接线规则只跑部分命令,9 条 error 级有门禁盲区(os build 会发布 os lint 拒绝的流) #4409 approver fixture needs requires: ['automation','triggers'].
  • cli.doctor-health-report: a hand-built user-app tree was used instead of npx create-objectstack@latest (no registry install).
  • Fixture gaps: 503 STORE_UNAVAILABLE (trigger-status a4); a sys_* action for mcp-run-action a4's runtime spelling; a console build for the dev-boot-contract a0 leg.
  • Environment: rsync is not installed in this container.

Item verdicts (derived)

12 PASS / 16 PARTIAL / 0 FAIL / 0 BLOCKED / 0 NOT-RUN of 28.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Close-out.

    Parked-on: #24579 · procedural negatives holding 12 items at PARTIAL, the password-reset steps (sys_identity_email, expiry leg), and the fixture gaps listed in this record

    Still reproduces at 307ce4c, commented on each card: #24781, #24782, #24750. Sister records: #24838 (upgrade:ceremony), #24840 (tier1:24681-touched).


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Closure complete (checklist-test §5): this record has no FAIL and extracts no card. Its procedural-negative partials and other findings are parked on #24579 (the Parked-on: line in comment 6288158563, rolled up in #24579 comment 6288485402).

    Closed by: the 18.0 QA wave dispatch session session_01CfRDy7SuTfUqaTu2AEH2Hi, on the maintainer's standing instruction there (2026-10-19, verbatim 「qa-run的卡片处理完的是不是可以关闭」), at 2026-10-20T13:13Z, after 18.0.0 was published.


    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