Skip to content

QA run · automation (5 of 10 items) · e4e5c6e3 · 2026-08-17 · 1 PASS / 3 PARTIAL / 1 BLOCKED #9336

Description

@os-zhuang

R3-C round of the #9296 wave. Scope is 5 of the area's 10 runnable items — this is NOT a full-area run. The 5 unreached items are listed as not-run at the bottom. No product defects found.

Environment fingerprint

readingvalue
framework sha (subject, unmoved)e4e5c6e3c608b1b807c83a0d5b734f213eb1a1dd
.objectui-sha pin665661ab093263f39f2e660a295ea615dbcee35a (console dist stamp matches — check:console-sha ✓)
checklist specorigin/main post-#9309 — 190 items, 30 kinds, 0 waived
app / port / dbshowcase · 3401 · file:/tmp/qa-r3c/api-backend-filter.db
seed--seed-adminadmin@objectos.ai; com.example.showcase 130 rows
clock / TZ2026-08-17T14:1xZ · UTC

Scope — selector and per-item revision

node scripts/checklist-select.mjs area:automation --json10 runnable, 1 hidden blocked (automation.rollup-summary-filter, excluded by the resolver by design).

#itemrevprisurfaceverdict
1flow-toggle-kill-switch1P2apipass
2durable-suspend-restart1P1apipartial
3flow-node-type-matrix3P1mixedpartial
4trigger-type-matrix1P1mixedpartial
5screen-flow-roundtrip2P1browserblocked(dependency)

Per-clause verdicts

1. flow-toggle-kill-switch (rev 1, P2) — pass · 4/4

Driven live against the running hono server (the item's dispatcher-vs-hono-route trap: oracle is a live server trace, never a simulated dispatch). Run counts are deltas computed per step, never absolute.

clauseverdictoracle evidence (text)
0 baseline: an urgent task fires the flow exactly oncepassPOST /api/v1/data/showcase_task {priority:'urgent'} → 201; GET /api/v1/automation/showcase_urgent_task_alert/runs 2 → 3, delta = 1
1 toggle OFF is a real kill switchpassafter POST /api/v1/automation/showcase_urgent_task_alert/toggle {enabled:false} → 200, a second urgent task produced runs 3 → 3, delta = 0
2 runtime state mirrors the togglepassGET /api/v1/automation/_status while off: {enabled:false, bound:false, status:"active", triggerType:"record_change", object:"showcase_task"}; while on: {enabled:true, bound:true, …}. The record_change trigger is genuinely unbound, not merely flagged
3 toggle ON restores firingpassafter {enabled:true} → 200, a third urgent task produced runs 3 → 4, delta = 1

Negative probe (unknown flow): POST /api/v1/automation/does_not_exist/toggle {enabled:false}404{"success":false,"error":{"code":"RESOURCE_NOT_FOUND","message":"Flow 'does_not_exist' not found","httpStatus":404}}, no state change.

Automation self-check (RUNNER rule 2) — caught one instrumentation bug before it became a false fail. My first pass parsed the runs list with a generic record extractor and read 0 at every step, including the baseline, which would have been recorded as "the flow never fires". The runs envelope is {success, data:{runs:[], hasMore}}data is an object, not a row array. Re-driven with the correct path; all four clauses then behaved. Nothing was recorded from the broken pass.

2. durable-suspend-restart (rev 1, P1) — partial · 3 pass, 2 not covered

automated.ref = packages/qa/dogfood/test/flow-durable-suspend.dogfood.test.ts. Per RUNNER rule 6 the pin is the evidence: 11/11 tests passed.

clauseverdictoracle evidence (text)
0 each suspend persists a paused row carrying rehydration statepasspin: "precondition: sys_automation_run really exists — the table #4420 was missing" · "suspends at the screen node and PERSISTS the pause as a paused row" · "the durable row is what a rehydration would read — the whole SuspendedRun round-trips"
1 paused rows + ordinary records survive a literal cold bootpasspin: "ordinary business rows survive the restart — stop() returning means DURABLE" · "the paused row survives the restart with its continuation intact" · "the resumed result is itself durable — a THIRD boot still reads it"
2 the timer wait resumes without intervention after restartnot coveredthe pin exercises a screen-node resume across a cold boot ("the cold kernel RE-FETCHES the screen … RESUMES the run and takes the right branch"), not the timer/PT1M wait path this clause names. Not re-driven by hand this round
3 nested pause: child at approval, parent at subflow, one decision completes bothnot coveredno assertion in the pin addresses the linked parent/child run correlation or the approval bubbling
4 resume consumes the paused row, leaving run historypasspin: "the suspension is CONSUMED from the durable store on resume — no zombie row is left behind"

3. flow-node-type-matrix (rev 3, P1) — partial · pin covers a slice of the matrix

automated.ref = packages/qa/dogfood/test/flow-node.dogfood.test.ts2/2 passed: "precondition: the automation service is wired and the flow is registered"; "runs the update_record node and wires the input variable into the filter".

The item is a node-type matrix with 6 clauses; the pin proves one node type (update_record) plus variable wiring end-to-end. The remaining node types in the matrix were not driven this round, so the item cannot be scored pass — recorded partial rather than promoting a one-node pin to matrix-wide coverage.

4. trigger-type-matrix (rev 1, P1) — partial · conformance ledger proven, per-trigger firing not driven

automated.ref = packages/qa/dogfood/test/flow-trigger-conformance.test.ts2/2 passed: "ADR-0060 D5 — flow trigger-type conformance ledger is a sound conformance ledger + ratchet, every flow type has a runtime + proof"; "sanity: discovery finds the known flow types".

That is strong evidence for the ledger/ratchet clauses — every declared flow type has a runtime and a proof, enforced by the ratchet. It is not evidence that each trigger type fires live on this build; the item's clauses that name live firing per trigger type were not driven. Recorded partial.

Corroborating live reading from the boot log (not a clause verdict): Flows: 29 flow(s) 22 bound to triggers (record_change, schedule, time_relative, api) · 7 draft.

5. screen-flow-roundtrip (rev 2, P1) — blocked(dependency)

automated.ref = objectui e2e/live/screen-flow.spec.ts — the pin lives in objectstack-ai/objectui, which is not checked out in this session, so the declared oracle cannot be consulted from here. The console dist is built and stamped at the pin, so this is not an environment failure; it is a cross-repo dependency. Recorded blocked(dependency, objectui e2e suite not available in this checkout) rather than substituting a hand-driven browser pass for the pin the item names.

Not run — 5 of 10 items

itemrevprisurface
flow-run-step-nesting2P1mixed
time-relative-trigger2P2mixed
flow-error-handling2P1mixed
connector-dispatch-matrix1P2mixed
flow-runs-page-test-trigger1P2mixed

Also excluded by the resolver, by design: automation.rollup-summary-filter (blocked, fixture).

Findings

No product defects. No fail verdicts, so no defect reproduction rule is owed.

Environment note carried from #9333 (same round, same tree): the dispatched setup recipe omits @objectstack/cli, so objectstack dev is unavailable until a full pnpm exec turbo run build runs. Also relevant to this area's fixtures — stock showcase seeds carry only admin@objectos.ai, auditor.demo@example.com, phone.demo@example.com, with no credentialed non-admin persona for gate-both-sides clauses.

Boot diagnostics observed (recorded, not scored — none is a clause oracle here): the showcase boot logs 3 warnings, two of which touch this area's neighbourhood — SharingServicePlugin: boot rule backfill failed for share_open_tasks_with_manager and share_red_projects_with_execs, both SHARING_NOT_ENABLED because the target object is under a public sharing model or lacks owner_id. Flagged for whoever owns access-security.

Parent: #9296.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions