Skip to content

QA run · surface:build (5/7) · 580fd4ed · 2026-10-20 · 4 PASS / 1 PARTIAL / 0 FAIL / 0 BLOCKED / 2 NOT-RUN #24787

Closed

Description

@objectstack-fleet

QA run record: 18.0 round-3 top-up, server half (2), selector surface:build. Anchor #24579. The maintainer approved the top-up; it was dispatched from session session_01CfRDy7SuTfUqaTu2AEH2Hi on 2026-10-20. Previous rounds ran at 5b14b7f3 (round 1; the build items sit in area records #24541, #24551, #24553 and #24575) and ba4afcc2 (round 2; #24595 carried the api-backend build items, #24598 holds the Tier 1 pins, #24615 carried integration-system). Sibling records from this round: surface:cli #24786 and walled pass #24783.

Environment fingerprint

Same tree and build as #24786:

  • framework 580fd4ed3c98a1752dfb0041b45cc713644fef7e
  • pnpm build --concurrency=2, 76/76 tasks
  • no console build

Tier 1: one pin file, vitest --maxWorkers=1.

Tier 2 was driven by a runner agent with the built CLI (node packages/cli/bin/run.js, @objectstack/cli/18.0.0-next.5) on scratch copies, 05:09–05:26 UTC:

  • a create-objectstack blank scaffold, linked to the workspace packages;
  • a showcase copy;
  • for the runtime-door leg, one dev boot of a showcase copy on its own port and DB with OS_PORT exported.

The resolver (checklist-select.mjs surface:build --json) returned 7 runnable items.

Scope (selector surface:build, 7 items)

  • Tier 1 (1): api-backend.rest-route-generation-tombstones r1
  • Tier 2 (4): api-backend.formula-gates r2 · api-backend.enforce-or-remove-authoring-gates r5 · api-backend.retired-def-refusal r3 · cli.build-own-contract r6
  • Tier 3 (2, not run): i18n.build-gates-hold r2 · integration-system.connector-spec-path-no-escape r1

Per-clause verdicts

api-backend.rest-route-generation-tombstones → PARTIAL (Tier 1)

Pin: packages/rest/src/rest-sub-config-parse-not-cast.test.ts reports 25 passed (§E: the four routes.* refusals, the empty-block control and the plugin-path leg).

  • a[0], a[1] and a[4] are covered by the pin.
  • a[2] is not covered (does each prescription name a replacement that exists today?).
  • a[3] is not covered (authoring any of the four keys is also a tsc error).

The Tier 2 runner corroborated two clauses live, outside the pin:

  • RouteGenerationConfigSchema.safeParse({includeObjects:['x']}) is refused with "routes.includeObjects was removed … Delete the key. … enable.apiEnabled: false …".
  • RestServerConfigSchema.safeParse({routes:{someUnknownKey:1}}) parses to routes: {}.

api-backend.formula-gates → PASS

  • a[0] pass. The harness resolved packages/formula/dist/index.mjs (no src/ file is newer than dist). Results:
    • record.due_date == today() gives true for 2026-10-20 and false for 2026-10-19.
    • flag ? x : null gives 5 and null.
    • floor(6.7) = 6, ceil(6.1) = 7, floor(-1.2) = -2, ceil(-1.2) = -1.
  • a[1] pass. A plain-literal object field span_days (formula record.end_date - record.start_date + 1): os build exit 1, twice. --json exit 1, success:false.
  • a[2] pass. • object 'qa_doctor_span' · field 'span_days' expression: date arithmetic … Use \daysBetween(a, b)`, with rule: expression-invalid at object 'qa_doctor_span' · field 'span_days' expression`.
  • a[3] pass. An untouched showcase copy: os build exit 0, ✓ Build complete, 24 objects, zero "date arithmetic" lines.
  • negative[0] pass. The harness read dist.

api-backend.enforce-or-remove-authoring-gates → PASS

  • a[0] pass, parsed against the spec dist.
    • QuerySchema.safeParse refuses cursor, joins, distinct and windowFunctions.
    • EnhancedApiErrorSchema refuses fieldErrors.
    • The retired filter operator, scored on its own terms:
      • a stored $regex builds with exit 0 and lands in the artifact;
      • at runtime POST /api/v1/data/showcase_account/query answers 400 INVALID_FILTER "Filter operator "$regex" on field "name" is RETIRED … Write "$icontains" instead" (twice; the $icontains control answers 200);
      • migrate meta --from 16 lists the advisory ⚠ [protocol 17] data.filter $regex / $options …, and with --json it appears as todos[].id == "filter-regex-options-retired".
  • a[1] pass. Each error names its replacement:
    • cursor → "where: { created_at: { $gt: … } } with the matching orderBy"
    • joins → "read through expand"
    • fieldErrors → "renamed to fields … (ADR-0114 D4)"
    • $regex → $icontains
  • a[2] pass. An unknown key on routes strips to {}, as the RouteGenerationConfigSchema docblock declares ("the schemas are not .strict()"). Retired keys on it are refused.
  • a[3] pass. The sample covered four sources: the query schema, the error envelope, RETIRED_FILTER_OPERATORS and the REST routes block.
  • negative[0] pass.

api-backend.retired-def-refusal → PASS

The registry retired-defs/ holds 224 entries: 53 with prefix 17 and 171 with prefix 18.

Sample:

  • data/ExternalDataSource (17, no carrier)
  • kernel/PluginLoadingConfig (17, carrier manifest.loading)
  • automation/StateMachine (18, carrier agent.lifecycle)
  • automation/ScheduleState (18, no carrier)

Verdicts:

  • a[0] pass. manifest.loading exits 2; an agent with lifecycle exits 2; importing ExternalDataSourceSchema or ScheduleStateSchema exits 2. All four json-schema files are absent.

  • a[1] pass. The carrier tombstones carry prescriptions:

    • "manifest.loading was removed in @objectstack/spec 17.0.0 … Delete the key …"
    • "agent.lifecycle was removed in @objectstack/spec 17.7.0 … a skill … a Flow … a state_machine validation rule"

    The defs without a carrier fail as a missing named export, which knownGaps[0] expects. The invented control key qaInventedFamily answers differently: "Unrecognized key(s) on this stack definition".

  • a[2] pass, on a live dev boot. PUT /api/v1/meta/agent/qa_rd_agent (with lifecycle) → 403 "Metadata type 'agent' is code-only …", and a follow-up GET → 404. manifest, external_data_source, schedule_state, state_machine and the control qa_invented_family each answer 400 "… is not a metadata type". Both doors refuse every sampled def.

  • a[3] pass. Both prefixes (17 ×2, 18 ×2) across three domains.

  • negative[0]–[3] pass.

cli.build-own-contract → PASS

  • a[0] pass, on a blank scaffold.

    • Human output: exit 0, Data: 1 Objects 2 Fields …, Artifact: dist/objectstack.json (2.5 KB); the file parses.
    • --json: exit 0, keys success, output, size, stats, warnings, conversions, duration.
  • a[1] pass. A plain-literal field with no type: ✗ objects.1.fields.body.type: Invalid field type ''. Did you mean 'url'?. Exit 2,2 on the human path; exit 1,1 under --json with code:"STACK_SCHEMA_INVALID". No dist was written.

  • a[2] pass. Two approval nodes with unparseable expressions give ✗ Author-time rules failed (2 issues). Each issue carries a CEL caret, fix:, and rule: approval-expression-invalid at flows[0].nodes[N].config.approvers[0].value. Exit 1,1 on both paths.

  • a[3] pass. Build failure {success:false,error,issues,warnings,conversions} against validate {valid:false,errors,warnings,conversions}: the finding records share keys, and warnings/conversions match. See accuracy finding B6.

  • a[4] pass. Exit codes over repeated identical runs:

    • clean: human 0 ×5, json 0 ×5
    • schema error: human 2,2, json 1,1
    • rule failure: human 1,1, json 1,1
    • load-time throw: human 2,2, json 1,1
    • advisory: 0,0

    No exit code moved between identical runs.

  • a[5] pass. A raw field visibleWhen carrying qaUndeclared:1 under strict:false prints ⚠ Undeclared authoring keys (1) — dropped at load; reported here, never refused and exits 0. The key is absent from the artifact.

  • os build and os compile gave identical output on the same inputs.

  • negative[0] and [1] pass. negative[2] skipped (it is a scope note).

Tier 3 handover (not run)

i18n.build-gates-hold · integration-system.connector-spec-path-no-escape

Derived item verdicts

4 PASS, 1 PARTIAL (api-backend.rest-route-generation-tombstones), 0 FAIL, 0 BLOCKED, 2 NOT-RUN (Tier 3). There was no fail, so no reproduction rule is owed. No authentication or authorization finding.

Change against round 2 (ba4afcc)

No PASS → FAIL.

Closed-card verification

Both closed cards from the earlier rounds (#24563, #24567) were re-measured at 580fd4e, and their fixes hold. The evidence is in #24786's "Closed-card verification".

Checklist-accuracy findings / fixture gaps (for the anchor #24579; not extracted)

  • B1 api-backend.retired-def-refusal steps[0] and acceptance[3] say the registry carries "the current major and the next". At 580fd4e the prefixes are 17 and 18, and the runtime implements protocol 18. So the prefixes are previous + current, and "staged for the NEXT major" no longer describes prefix 18.
  • B2 api-backend.enforce-or-remove-authoring-gates steps[1] says to locate filter-regex-options-retired in the os migrate meta --from 16 output. The human output never prints that id; it prints the label ⚠ [protocol 17] data.filter $regex / $options …. The id is only in --json todos[].id.
  • B3 api-backend.formula-gates acceptance[3] says the showcase uses due_date == today(). The showcase has no == today(); its only today() use is record.f_date < today(). The over-fire guard holds anyway.
  • B4 api-backend.rest-route-generation-tombstones automated.ref names one file with no clause qualifier. Its §E covers acceptance[0], [1] and [4], not [2] (prescriptions name live replacements) or [3] (the tsc error).
  • B6 cli.build-own-contract acceptance[3]: os validate --json uses valid/errors where build uses success/issues. The schema-load failure payload carries error and code (STACK_SCHEMA_INVALID) with no issues on both commands. The clause's "{ success: false, … issues }" holds only for the author-time-rule failure.

Times

Activity

  1. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Closure complete (checklist-test §5): this record has no FAIL and extracts no card.
    Parked-on: #24579 · checklist-accuracy findings B1–B6, the partial api-backend.rest-route-generation-tombstones and the Tier 3 not-run handover (rolled up in #24579 comment 6284472874)

    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:11Z, 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