Skip to content

QA run · automation (18/22) · 5b14b7f3 · 2026-10-19 · 15 PASS / 2 PARTIAL / 1 FAIL / 0 BLOCKED / 4 NOT-RUN #24545

Closed as not planned

Description

@objectstack-fleet

Run record for the 18.0 release QA wave (dispatch session session_01CfRDy7SuTfUqaTu2AEH2Hi; maintainer-approved plan B: Tier 1 + Tier 2, Tier 3 deferred). Runner session session_016CErRJhdMYZdRg4pe8iQfD. Protocol: .claude/skills/checklist-test/SKILL.md + docs/qa/platform-checklist/RUNNER.md.

Environment fingerprint

  • framework: 5b14b7f3ad8e2e0786d228772f473d07b36b2477 (pinned; pnpm install --frozen-lockfile + pnpm build, 76/76 tasks green)
  • .objectui-sha: 4016370af3c9c9dafec2bc5299afd8e8079701b8; console built with pnpm objectui:build (shallow clone into .cache/objectui-4016370af3c9), packages/console/dist/.objectui-sha matches, pnpm check:console-sha green
  • resolver: node scripts/checklist-select.mjs area:automation --json → 22 runnable · 0 blocked hidden · 0 planned
  • app: showcase · boot OS_PORT=P objectstack dev --ui --seed-admin -p P -d file:…/ITEM.db · per-runner port range and per-item file DB · seeded admin + demo personas; staged configs only in scratch copies of the app
  • browser: Playwright on /opt/pw-browsers/chromium, headless, one context per persona
  • timestamp: 2026-10-19 (UTC) · execution: parallel fan-out, one sub-agent runner per item group:
    • U1: ports [41380,41381,41382,41383] · env 4 min / test 15 min
    • U2: ports [41390,41391] · env 3 min / test 10 min
    • U3: ports [41400,41401] · env 10 min / test 22 min
    • U4: ports [41410] · env 2 min / test 13 min

Scope

Selector area:automation · 22 runnable item(s) (revision = the one each verdict is valid for):

  • automation.flow-run-step-nesting r5 · P1 · mixed · Tier 2 → pass (runner U2)
  • automation.time-relative-trigger r3 · P2 · mixed · Tier 3 → not-run
  • automation.rollup-summary-filter r4 · P1 · mixed · Tier 2 → pass (runner U2)
  • automation.flow-node-type-matrix r6 · P1 · mixed · Tier 1 → pass (runner U4)
  • automation.trigger-type-matrix r4 · P1 · mixed · Tier 1 → pass (runner U4)
  • automation.flow-error-handling r4 · P1 · mixed · Tier 2 → pass (runner U2)
  • automation.screen-flow-roundtrip r4 · P1 · browser · Tier 1 → pass (runner U4)
  • automation.durable-suspend-restart r1 · P1 · api · Tier 1 → pass (runner U3)
  • automation.paused-run-trigger-record-masked r1 · P2 · api · Tier 1 → pass (runner U3)
  • automation.connector-dispatch-matrix r3 · P2 · mixed · Tier 3 → not-run
  • automation.flow-runs-page-test-trigger r2 · P2 · mixed · Tier 3 → not-run
  • automation.flow-toggle-kill-switch r3 · P2 · api · Tier 3 → not-run
  • automation.trigger-status-contract r2 · P1 · api · Tier 2 → partial (runner U1)
  • automation.packaged-flow-disable-durable r3 · P0 · api · Tier 2 → pass (runner U1)
  • automation.packaged-flow-subflow-disable-refusal r3 · P1 · api · Tier 2 → pass (runner U1)
  • automation.packaged-flow-clone-contract r3 · P1 · api · Tier 2 → pass (runner U1)
  • automation.setup-packaged-automation-board r3 · P1 · browser · Tier 1 → partial (runner U4)
  • automation.flow-registration-verdict-on-read r1 · P1 · api · Tier 1 → pass (runner U3)
  • automation.flow-authoring-refusals-v18 r1 · P1 · cli · Tier 1 → fail (runner U3)
  • automation.flow-run-semantics-v18 r1 · P1 · api · Tier 1 → pass (runner U3)
  • automation.inbound-hook-timestamped-signature r1 · P1 · api · Tier 1 → pass (runner U3)
  • automation.scheduled-work-opt-in r1 · P1 · api · Tier 1 → pass (runner U3)

Per-clause verdicts

item clause short verdict evidence
automation.flow-run-step-nesting acc[0] 3-item run completed, send_reminder ×3 pass run_a377b3ad-… status=completed; steps with nodeId=send_reminder = 3
automation.flow-run-step-nesting acc[1] guard/send_reminder tags; top-level untagged pass guard_reminder ×3 {parentNodeId:loop_tasks, regionKind:loop-body, iteration 0,1,2}; send_reminder ×3 {parentNodeId:guard_reminder, regionKind:try, it…
automation.flow-run-step-nesting acc[2] loop{parallel}: iteration=row, branch=position pass run_75054689-… (2 rows): parallel-branch steps notify_owner(it0,br0) notify_watcher(it0,br1) notify_owner(it1,br0) notify_watcher(it1,br1) — each pai…
automation.flow-run-step-nesting acc[3] designer Runs panel renders nested tree pass Studio flow designer Runs tab (not developer Flow Runs page): loop_tasks → '↳ ITERATION 1/2/3' → guard_reminder TRY_CATCH → '↳ TRY' → send_reminder, …
automation.flow-run-step-nesting acc[4] rendered tree agrees with API tags pass panel rows: 8 step rows = 8 API steps for each run; grouping (iteration N ↔ iteration N-1, branch N ↔ branch N-1) matches parentNodeId/iteration/bran…
automation.flow-run-step-nesting acc[5] empty collection completes with zero children pass run_4e799b9a-… tasks=[] → status=completed, steps [start, loop_tasks(success)], 0 steps with parentNodeId=loop_tasks
automation.flow-run-step-nesting neg[0] not a flat rendering pass tree rendered with region headers and indentation; developer Flow Runs page not used as oracle
automation.rollup-summary-filter acc[0] baseline roll-ups equal recomputation pass EXP-2001 (I8Ts9qIzJn6HIAXC), 4 lines [620 approved F, 340 approved F, 512 submitted T, 28.5 submitted F]: total 1500.5/1500.5, approved 960/960, reim…
automation.rollup-summary-filter acc[1] status flip moves only status-filtered roll-ups pass PATCH line oB6l… approved→rejected (200): approved 960→620, rejected 0→1 (= recompute); total 1500.5, reimbursable 512, line_count 4, over_limit 2 un…
automation.rollup-summary-filter acc[2] billable flip moves only reimbursable_amount pass PATCH line vGS3… billable true→false (200): reimbursable 512→0 (= recompute); other five identical (1500.5, 620, 4, 1, 2)
automation.rollup-summary-filter acc[3] delete recomputes every matching roll-up pass DELETE line glWq… (620, approved, ›=500, not billable) 200: total 1500.5→880.5, line_count 4→3, approved 620→0, over_limit 2→1; reimbursable 0 and re…
automation.rollup-summary-filter acc[4] Studio filter editor edits & persists on scratch base pass duplicate of com.example.showcase → 422 DUPLICATE_SOURCE_NOT_A_BASE (expected); POST /packages com.u2.rollup 201; authored rollup_u2_report.approved_…
automation.rollup-summary-filter neg[0] untouched-filter roll-ups never move pass rejected_count stayed 1 across billable flip and delete of a non-rejected row; over_limit/total/line_count unchanged on both flips
automation.flow-node-type-matrix acc[0] palette feed offers 19 non-structural variants pass GET /api/v1/automation/actions: 19 descriptors decision,assignment,loop,parallel,try_catch,get_record,create_record,update_record,delete_record,scree…
automation.flow-node-type-matrix acc[1] each variant located as executed step pass start: every run · decision/get_record/delete_record: run_f8a7bc80 showcase_inquiry_purge success · assignment: run_26834ef8 mark_ok success · loop: …
automation.flow-node-type-matrix acc[2] suspending types park paused then complete pass screen run_140ba2a2 paused-›completed; wait run_af1ad4ce paused (12:58:41) -› completed after PT1M timer; approval run_40c84475 paused -› completed a…
automation.flow-node-type-matrix acc[3] every step names its nodeType pass sweep of all runs of all registered flows: 49 runs, 132 steps, 0 with empty/missing nodeType
automation.flow-node-type-matrix acc[4] container body steps carry region tags pass loop: guard_reminder parent=loop_tasks region=loop-body (run_68ca3db9); parallel: notify_owner/slack_post parent=fan_out region=parallel-branch (run_…
automation.flow-node-type-matrix acc[5] unknown node type late-bound, four parts pass (1) POST /api/v1/automation u4_bogus_probe with node type 'bogus_node' -› 200, GET read-back carries type bogus_node; (2) boot log WARN "Flow 'u4_bog…
automation.flow-node-type-matrix neg[0] unknown-type probe not silent pass WARN present with phrase + both meta lists; trigger success:false; run failed with NO_EXECUTOR
automation.trigger-type-matrix acc[0] every trigger kind produces a run of its flow pass record_change: run_de7e29e3 showcase_urgent_task_alert (Flow.type record_change) trigger {type:'record-after-write',object:'showcase_task',recordId:'…
automation.trigger-type-matrix acc[1] record-after-write discriminates create/escalate/no-transition pass urgent create GIlFo1nTjCP6mbwr -› run_de7e29e3; medium create ntjsSdN8oVRKkoV- then PATCH priority urgent -› run_4bd25157; further PATCH notes on BOT…
automation.trigger-type-matrix acc[2] webhook intake 202 + payload becomes record pass POST /api/v1/automation/hooks/showcase_inbound_task_webhook/intake with signHttpBodyAt t=…,v1=… -› 202 {accepted:true}; created showcase_task pyMxwsn…
automation.trigger-type-matrix acc[3] schedule fires repeatedly on interval pass showcase_scheduled_digest runs at 12:58:50.510Z and 12:59:50.507Z (60.0 s apart), trigger.type 'schedule', 7 runs by end; admin inbox rows 'Scheduled…
automation.trigger-type-matrix acc[4] screen run pauses then resume completes pass browser network: POST /api/v1/actions/showcase_task/showcase_bulk_reassign -› {status:'paused',runId:run_140ba2a2…}; POST …/runs/run_140ba2a2…/resume…
automation.trigger-type-matrix acc[5] conformance ledger classifies every Flow.type pass pin packages/qa/dogfood/test/flow-trigger-conformance.test.ts: 2/2 passed in t1-automation.log ('is a sound conformance ledger + ratchet, every flow …
automation.trigger-type-matrix neg[0] anonymous trigger denied, no run pass unauthenticated POST /api/v1/automation/showcase_batch_reminders/trigger -› 401 UNAUTHENTICATED; showcase_batch_reminders runs count stayed 1
automation.trigger-type-matrix neg[1] bad/missing HMAC refused, no task pass wrong-secret signature -› 401 INVALID_SIGNATURE; no signature -› 401 INVALID_SIGNATURE; task query on webhook assignee returns only the one good-sign…
automation.flow-error-handling acc[0] handled run completed; try_catch step success pass GET /automation/showcase_resilient_sync/runs/run_a7a3ccf4-… → status=completed, error=null; step guarded_push nodeType=try_catch status=success (7205…
automation.flow-error-handling acc[1] failed try attempts recorded, before catch pass steps[2..5] push/http status=failure parentNodeId=guarded_push regionKind=try error={code:NODE_FAILURE,message:'http: fetch failed'}; steps[6] record…
automation.flow-error-handling acc[2] retryAttempt 0..3 countable; duration corroborates pass retryAttempt values on try steps = 0,1,2,3 (4 = maxRetries+1), all failure; run durationMs=7215 (›= 1s+2s+4s backoff ladder)
automation.flow-error-handling acc[3] $error bound into sync_status/sync_error pass GET /data/showcase_task/ZfWN9sl6gEFYsQv- → status=done, sync_status=failed, sync_error="Node 'push' failed: http: fetch failed"
automation.flow-error-handling acc[4] unhandled probe run failed with run-level error pass probe u2_unhandled_probe (start→http POST api.example.com→end, no try_catch) fired by record-after-create on showcase_task: run_bd00b03a-… status=fai…
automation.flow-error-handling acc[5] Runs panel shows step errors and nesting pass designer Runs tab (studio …/automations?surface=flow:…): handled run shows guarded_push TRY_CATCH → '↳ TRY' 4× FAILURE push 'http: fetch failed' (ind…
automation.flow-error-handling acc[6] ERROR log line for trigger-fired failure pass boot log: "ERROR Trigger-fired run of flow 'u2_unhandled_probe' failed (trigger 'record_change') — no caller holds this result and nothing retries th…
automation.flow-error-handling neg[0] unhandled failure not reported completed/empty error pass probe run status=failed with non-empty error (see acceptance[4])
automation.flow-error-handling neg[1] catch absent when try succeeds pass scratch flow u2_trycatch_success_probe (try: GET http://127.0.0.1:41390/api/v1/health; catch: assignment) api-triggered → completed, steps [start, gu…
automation.flow-error-handling neg[2] caught failure leaves forensic trace (#7546) pass 4 regionKind=try status=failure steps present in handled run (not the [start, container, catch] silence shape)
automation.flow-error-handling neg[3] container success not a finding pass container status=success recorded as by-design; not filed
automation.screen-flow-roundtrip acc[0] action door launches run that pauses at screen pass row action click -› POST /api/v1/actions/showcase_task/showcase_bulk_reassign {recordId:2Emr5lptpPhdvG2M,params:{}} 200 {status:'paused',runId:run_14…
automation.screen-flow-roundtrip acc[1] GET /screen serves contract with required pass GET /automation/showcase_reassign_wizard/runs/run_4795da78…/screen 200 {screen:{nodeId:'collect',title:'New Assignee',fields:[{name:'new_assignee',la…
automation.screen-flow-roundtrip acc[2] console renders screen as dialog pass screenshot: modal over Tasks grid, caption 'Reassign Task', heading 'New Assignee', required text input, Cancel/Submit; then heading role visible + #…
automation.screen-flow-roundtrip acc[3] Submit POSTs resume with inputs; run completes pass POST /automation/showcase_reassign_wizard/runs/run_140ba2a2…/resume body {inputs:{new_assignee:'u4-submit-1792415044810@example.com'}} 200; run re-re…
automation.screen-flow-roundtrip acc[4] update_record persisted on authoritative read pass GET /api/v1/data/showcase_task/2Emr5lptpPhdvG2M -› assignee 'u4-submit-1792415044810@example.com'
automation.screen-flow-roundtrip acc[5] empty-inputs resume 400, run stays paused pass action-door run run_080fe561… then POST …/resume {inputs:{}} -› 400 INVALID_SCREEN_INPUT 'Screen field "new_assignee" is required'; re-read status=pa…
automation.screen-flow-roundtrip acc[6] cancel parks run, still resumable pass dialog opened on row GIlFo1nTjCP6mbwr, Cancel clicked: only the action-door POST was sent (no resume), dialog count 0; GET run run_4795da78… status=p…
automation.screen-flow-roundtrip neg[0] required input enforced server-side pass empty-inputs resume answered 400, run not completed
automation.screen-flow-roundtrip neg[1] cancel neither consumes nor orphans run pass post-cancel status paused (not cancelled/completed), task unchanged until the explicit resume, which completed it
automation.durable-suspend-restart acc[0] suspend persists paused row with rehydration payload pass pin flow-durable-suspend.dogfood.test.ts ✓ 'suspends at the screen node and PERSISTS the pause as a paused row' + ✓ 'the durable row is what a rehydr…
automation.durable-suspend-restart acc[1] paused rows survive literal cold boot, same file pass pin ✓ 'the paused row survives the restart with its continuation intact' + ✓ 'ordinary business rows survive the restart'. Live: killed the listener …
automation.durable-suspend-restart acc[2] timer resumes on new process; notify lands pass not pinned (the pin uses a screen node). Live: task created 12:56:51, process 1 killed 12:57:12, process 2 healthy 12:57:37. Run run_ead19bae… status…
automation.durable-suspend-restart acc[3] nested pause: one approve completes both, bubbles decision pass not pinned. Live on process 2: before, parent paused@signoff (correlation subflow:run_e9b7f691…) and child paused@ask_signoff. POST /approvals/reques…
automation.durable-suspend-restart acc[4] resume consumes paused row; history row remains pass pin ✓ 'the suspension is CONSUMED from the durable store on resume — no zombie row'. Live: GET /data/sys_automation_run/‹each of the 3 paused ids› → …
automation.durable-suspend-restart neg[0] no vanished pause; no success with row still paused pass no paused row was lost across the restart, and each resume left no paused row behind (see acceptance 1 and 4)
automation.paused-run-trigger-record-masked acc[0] member reads paused row: masked, internal absent pass pin ✓ 'persisted variables_json and context_json carry the mask' + ✓ 'data door … serves the same masked columns' (admin). Live, as non-admin member …
automation.paused-run-trigger-record-masked acc[1] run read door serves same masked roots pass pin ✓ 'GET /automation/:name/runs/:runId shows the same'. Live as member: GET /automation/showcase_qa_vault_paused/runs/run_cee7ff88… → 200; variable…
automation.paused-run-trigger-record-masked acc[2] post-pause node reads mask; ordinary field value pass pin ✓ 'a node after the pause reads the mask off record and previous'. Live: resume {inputs:{note:'echo-hot'}} → echo row seen_name='v1-renamed', see…
automation.paused-run-trigger-record-masked acc[3] cold boot: rehydrated run resumes masked pass pin ✓ 'the rehydrated run resumes with the masked record'. Live: paused run_c79dc424… (row v2) before the restart, cold-booted a second process over …
automation.paused-run-trigger-record-masked acc[4] privileged path unchanged (pin) pass pin flow-trigger-record-credential-mask.dogfood.test.ts ✓ 'the scene is armed: the stored row holds the plaintext password, a secret ref and the inte…
automation.paused-run-trigger-record-masked neg[0] no credential spelling for any reader pass the leak scan over both columns and the door body was empty for the member, hot and after the cold boot
automation.paused-run-trigger-record-masked neg[1] no mask on ordinary field/non-trigger var pass name/seen_name keep their written values on every surface; only qa_password/qa_token are masked and qa_hidden is omitted
automation.trigger-status-contract acc[0] trigger rows status+code on both routes pass both /:name/trigger and /trigger/:name: unknown → 404 RESOURCE_NOT_FOUND; qa_always_fails → 400 FLOW_FAILED; disabled showcase_urgent_task_alert → 40…
automation.trigger-status-contract acc[1] paused run is 200 with runId+screen pass showcase_reassign_wizard trigger → 200 {status:'paused', runId, screen{nodeId:'collect',fields:[new_assignee required]}} on both routes; that runId l…
automation.trigger-status-contract acc[2] other doors answer same status+code pass disabled showcase_reassign_wizard via POST /actions/showcase_task/showcase_bulk_reassign/:id → 409 FLOW_DISABLED (same ledger message); disabled show…
automation.trigger-status-contract acc[3] 400 FLOW_FAILED carries errorMessage + summary pass both trigger routes: 400 FLOW_FAILED details.errorMessage='QA always-fails probe: the unroutable http node failed', details.summary{failed:1,nodes:[s…
automation.trigger-status-contract acc[4] resume refusals: reachable arms + suspension intact pass 403 PERMISSION_DENIED (non-starter member) → run still paused → later admin resume 200; 400 INVALID_SCREEN_INPUT (inputs {} / unknown $evil field) → …
automation.trigger-status-contract acc[4] 409 RESUME_IN_PROGRESS arm not-run 3 concurrent resumes of one paused run answered 200 + 404 RUN_NOT_FOUND + 404 RUN_NOT_FOUND; no deterministic stock trigger for the 409 window
automation.trigger-status-contract acc[4] 503 STORE_UNAVAILABLE arm blocked blocked(fixture): no stock trigger, as the clause anticipates
automation.trigger-status-contract acc[5] stale suspension → 404 RUN_NOT_FOUND, class named pass scratch screen flow qa_stale_screen paused then DELETE /meta/flow → resume 404 RUN_NOT_FOUND "Flow 'qa_stale_screen' not found for run '…'"; qa_stale…
automation.trigger-status-contract acc[6] SDK rejects with httpStatus+code pass @objectstack/client dist: automation.trigger()/execute() REJECTED httpStatus/code 404 RESOURCE_NOT_FOUND, 400 FLOW_FAILED, 409 FLOW_DISABLED, 422 FLO…
automation.trigger-status-contract neg[0] refusal row as 200 + inner success:false pass no refusal row answered 200 at any door
automation.trigger-status-contract neg[1] never-dispatched exit as 400 FLOW_FAILED pass disabled → 409, no-start → 422, unknown → 404 at every door driven
automation.trigger-status-contract neg[2] 409 and 422 collapsed pass 409 FLOW_DISABLED vs 422 FLOW_NO_START_NODE distinct
automation.trigger-status-contract neg[3] paused run answered as refusal/complete pass 200 status:'paused' with runId
automation.trigger-status-contract neg[4] retryable refusal consumed suspension pass run read 'paused' after each 403/400 refusal and a later valid resume succeeded
automation.trigger-status-contract neg[5] door with its own copy of the table pass source: the three doors import classifyFlowRefusal from flow-dispatch-status.ts (lines cited above)
automation.packaged-flow-disable-durable acc[0] toggle writes durable ledger row, no org column pass POST …/showcase_urgent_task_alert/toggle {enabled:false} → 200 {name,enabled:false}; GET /data/sys_metadata_activation → total 1, row id P_ajZ_9Xcs6E…
automation.packaged-flow-disable-durable acc[1] FLOW_DISABLED message names the ledger pass POST …/trigger → 409 {code:FLOW_DISABLED, message:"Flow 'showcase_urgent_task_alert' is disabled — it is switched off for this installation in the pa…
automation.packaged-flow-disable-durable acc[2] cold restart: enabled=false bound=false + ledger log pass process tree killed, second boot over same file:durable.db with --log-level info: /_status → {name:showcase_urgent_task_alert, enabled:false, bound:f…
automation.packaged-flow-disable-durable acc[3] kill switch holds on new process pass runs count 1 before post-restart urgent create (task LUgAEAE19HI4JBHZ created) and 1 after (only baseline run_bebd189f)
automation.packaged-flow-disable-durable acc[4] re-enable updates same row; firing resumes pass toggle {enabled:true} → 200; GET /data/sys_metadata_activation/P_ajZ_9Xcs6ErIdG → active=true, updated_at advanced, total still 1; /_status enabled:t…
automation.packaged-flow-disable-durable neg[0] 2xx toggle with no row pass row present after toggle; no 'IN PROCESS ONLY' warn in boot log
automation.packaged-flow-disable-durable neg[1] restart re-arms flow pass post-restart enabled:false bound:false, no run from post-restart create
automation.packaged-flow-disable-durable neg[2] re-enable deletes row pass same id P_ajZ_9Xcs6ErIdG present with active=true after re-enable
automation.packaged-flow-disable-durable neg[3] ledger scored from code alone pass clause 1 scored on the message text, quoted above
automation.packaged-flow-subflow-disable-refusal acc[0] subflow-caller disable → 409 DELETE_RESTRICTED naming caller pass POST showcase_notify_owner/toggle {enabled:false} → 409 {code:DELETE_RESTRICTED, message:"Flow 'showcase_notify_owner' cannot be disabled while 1 pac…
automation.packaged-flow-subflow-disable-refusal acc[1] map caller counts pass POST showcase_one_task_signoff/toggle {enabled:false} → 409 DELETE_RESTRICTED naming 'showcase_release_signoff'
automation.packaged-flow-subflow-disable-refusal acc[2] refused attempt writes no row; flow still armed pass ledger records [] after each of the three refusals; task created status in_review then PATCH done → showcase_task_done_notify_owner run completed wit…
automation.packaged-flow-subflow-disable-refusal acc[3] child enable never guarded pass showcase_notify_owner toggle {enabled:true} with caller off → 200 (ledger row active=true); with caller re-armed (no-op) → 200
automation.packaged-flow-subflow-disable-refusal acc[4] remedy followable pass caller showcase_task_done_notify_owner disable → 200; retry child disable → 200; ledger showcase_notify_owner active=false (row GSq-5OGkl50VNQbq)
automation.packaged-flow-subflow-disable-refusal neg[0] 2xx on step 2 or 3 pass both answered 409
automation.packaged-flow-subflow-disable-refusal neg[1] refusal names only first caller pass engine pin flow-activation-ledger.test.ts:348 'names EVERY packaged caller' — vitest run of the file (-t caller): 25 passed, 22 skipped; stock fixtur…
automation.packaged-flow-subflow-disable-refusal neg[2] UI half not scored here skipped by design — owned by automation.setup-packaged-automation-board
automation.packaged-flow-clone-contract acc[0] name and label mandatory, per-field 400 pass {} → 400 VALIDATION_FAILED fields[{field:name,code:required}]; {name:x} → 400 fields[{field:label,code:required}]; {label:x} → 400 fields[{field:name…
automation.packaged-flow-clone-contract acc[1] whole copy, only name/label/status differ, no ancestry pass key diff source vs clone: name, label, status active→draft, plus _provenance/_packageId/_packageVersion dropped; nodes and edges deep-equal; descript…
automation.packaged-flow-clone-contract acc[2] draft double-fires; notice verbatim pass one urgent create → base runs 0→1 and clone runs 0→1 (both completed); response.notice === FLOW_CLONE_NOTICE (flow-clone.ts:177) byte-for-byte
automation.packaged-flow-clone-contract acc[3] refusal arms 409/404/400 pass same name → 409 RESOURCE_CONFLICT with shadowing rationale and suggestion 'showcase_urgent_task_alert_copy'; does_not_exist → 404 RESOURCE_NOT_FOUND;…
automation.packaged-flow-clone-contract acc[4] references not re-pointed pass qa_task_done_clone node call_notify type subflow config.flowName='showcase_notify_owner' (response and stored read)
automation.packaged-flow-clone-contract acc[5] clone editable via PUT pass PUT /automation/qa_urgent_alert_clone (label '(edited)') → 200; re-read label 'QA urgent alert clone (edited)'
automation.packaged-flow-clone-contract acc[6] clone survives restart and reaches Studio pass after cold restart over same clone.db: GET → 200 with edited label; /meta/flow lists qa_urgent_alert_clone and qa_task_done_clone with _packageId nul…
automation.packaged-flow-clone-contract neg[0] missing source facet pass nodes/edges/variables-free source; every non-mutated key equal
automation.packaged-flow-clone-contract neg[1] ancestry field anywhere pass no clonedFrom/origin-like key in response, stored def or /meta/flow listing
automation.packaged-flow-clone-contract neg[2] same-name clone 2xx pass 409 RESOURCE_CONFLICT
automation.packaged-flow-clone-contract neg[3] anonymous reaches clone door pass no-credential POST …/clone → 401 UNAUTHENTICATED (non-manage_metadata member persona not driven on this item)
automation.setup-packaged-automation-board acc[0] reachable from Setup nav (served body + sidebar click) pass GET /api/v1/meta/app?id=setup 200: group_apps holds {id:nav_packaged_automation,type:component,label:'Packaged Automation',componentRef:'automation:p…
automation.setup-packaged-automation-board acc[1] inventory = packaged flows; actions section; tenant flows absent pass 32 packaged-flow-* rows == the 32 /api/v1/meta/flow items passing isPackagedFlowItem (all _packageId com.example.showcase, _provenance package): miss…
automation.setup-packaged-automation-board acc[2] toggle OFF persists across reload + ledger row pass POST /automation/showcase_urgent_task_alert/toggle {enabled:false} 200 {enabled:false}; after page.reload switch aria-checked=false; GET /api/v1/data…
automation.setup-packaged-automation-board acc[3] clone on flow rows only pass 32 'Clone' buttons inside packaged-flow-* rows; 0 clone buttons and 0 /clone/i text inside packaged-actions-section (section screenshot taken)
automation.setup-packaged-automation-board acc[4] no lineage surface even with clone present pass with u4_urgent_clone present: page text contains none of customized/clonedFrom/cloned from/diff/drift/lineage/base version/overridden/Modified; no da…
automation.setup-packaged-automation-board acc[5] server refusals verbatim in role=alert blocked(dependency) ADMIN cell PASS: 409 DELETE_RESTRICTED text verbatim in row role=alert, no fallback string. MEMBER cell not consulted via its dom oracle (page unreac…
automation.setup-packaged-automation-board acc[6] clone dialog needs both fields; 400 legible; notice pass 'Create clone' disabled with both empty / name-only / label-only, enabled with both; 'Bad-Name!' -› POST /clone 400 VALIDATION_FAILED, dialog role=al…
automation.setup-packaged-automation-board acc[7] member posture recorded (not a gate) pass RECORDED: identity proven server-side (get-session 200 u4.member@example.com, minted via invite-member + sign-up, own browser context, form sign-in).…
automation.setup-packaged-automation-board neg[0] nav not ticked off typed URL/unit pin pass nav clause scored on served body + real sidebar click; typed URL never used for it
automation.setup-packaged-automation-board neg[1] member cell not scored with admin token pass member ran in a fresh browser + own form sign-in; get-session proved u4.member@example.com; member API probes used the member's own token (403 capabi…
automation.setup-packaged-automation-board neg[2] switch vs row mismatch after reload pass post-reload switch Off and ledger row active=false agree; after re-enable both read On/true
automation.flow-registration-verdict-on-read acc[0] pins pass at subject sha pass packages/rest meta-flow-cached-registration.test.ts 3 passed; packages/services/service-automation flow-refused-registration-read.integration.test.ts…
automation.flow-registration-verdict-on-read acc[1] showcase flow registered; refused flow refused, status kept pass GET /meta/flow/showcase_task_follow_up → registration {state:'registered'}; /showcase_project_closure → registered, status active. qa_refused_flow2 (…
automation.flow-registration-verdict-on-read acc[2] list registrations keyed by name incl. refused pass GET /meta/flow top keys [type, items, registrations]; 44 entries keyed by flow name: 43 registered, 1 refused (qa_refused_flow2 with reason), showcas…
automation.flow-authoring-refusals-v18 acc[0] nine spec/lint pins pass pass spec: flow-value-slot-template 172✓, flow-text-slot-template 32✓, flow-builtin-node-config-keys 38✓, -values 55✓, flow-bound-variable-name 115✓, auto…
automation.flow-authoring-refusals-v18 acc[1] each arm fails os validate at right path pass all 10 arms exit 1: single-brace value → expression-invalid at config.fields.owner 'Write {record.owner} as { dialect:'cel', source:'record.owner' …
automation.flow-authoring-refusals-v18 acc[2] same bodies at PUT → 422, nothing stored fail 422 INVALID_METADATA + read-back 404 for single-brace value, single-brace text, $x screen field, outputVariable 42, notify bogusKey, dangling edge, e…
automation.flow-authoring-refusals-v18 acc[3] three controls validate and save pass CEL envelope {dialect:'cel',source:'record.owner'}, notify title 'Case {{ record.name }}', get_record filter {owner_id:'{current_user_id}'}: os valid…
automation.flow-authoring-refusals-v18 neg[0] no arm validates clean at build pass every arm, including record.x and user.id, is refused by os validate (the build door); the two runtime-accepted bodies are the runtime PUT gate stand…
automation.flow-run-semantics-v18 acc[0] five pins pass at subject sha pass service-automation: flow-cel-current-user 14✓, flow-cel-record-binding 17✓, decision-overlapping-edge-conditions.pin 22✓; runtime: action-flow-elevat…
automation.flow-run-semantics-v18 acc[1] record-triggered run stamps member's id pass member qa.u3.member (positions org_member/everyone, isPlatformAdmin false, made with admin create-user and a password change) PATCHed showcase_qa_sta…
automation.flow-run-semantics-v18 acc[2] member start of elevated flow → 403, no run pass member POST /api/v1/automation/showcase_qa_elevated/trigger → 403 {code:PERMISSION_DENIED,'This caller may not start this flow…'}; run list 0 before …
automation.flow-run-semantics-v18 acc[3] decision takes the first true edge only pass showcase_qa_decision n=5 (edges e2 'n › 1' then e3 'n › 0', both true) → output {branch:'first'}, steps gate:success first:success second:skipped; co…
automation.flow-run-semantics-v18 neg[0] no non-system success on runAs system pass no run of showcase_qa_elevated exists after the member's attempt (run count 0). The admin is also refused 403, as a non-system caller
automation.inbound-hook-timestamped-signature acc[0] three pins pass at subject sha pass trigger-api inbound-hook-member.test.ts 12 passed; core http-signature.test.ts 16 passed; runtime domains/automation-hooks.test.ts 19✓ (runtime summa…
automation.inbound-hook-timestamped-signature acc[1] valid t=,v1= signature → 202 accepted pass anonymous POST /api/v1/automation/hooks/showcase_inbound_task_webhook/intake, x-objectstack-signature t=‹now›,v1=‹hmac(t.body)› → 202 {"accepted":tru…
automation.inbound-hook-timestamped-signature acc[2] four refusals byte-identical 401, nothing enqueued pass body-only sha256=, t=now-301, unknown flow qa_no_such_flow, wrong hook id → each 401 {"success":false,"error":{"code":"INVALID_SIGNATURE","message":"…
automation.scheduled-work-opt-in acc[0] per-kernel policy pins pass pass trigger-schedule per-kernel-scheduled-work-policy.test.ts 10 passed (1 file / 10 tests); service-automation per-kernel-scheduled-work-policy.test.ts …
automation.scheduled-work-opt-in acc[1] flag unset: boot says off, no scheduled runs pass boot A (variable unset via env -u): 'Flows: 32 flow(s) 19 bound' + 'ℹ 1 flow declares a 'schedule' trigger but is NOT bound — disabled by deployment …
automation.scheduled-work-opt-in acc[2] flag set: scheduled flow runs on interval pass boot B (OS_AUTOMATION_SCHEDULED_WORK_ENABLED=1): banner has no NOT-bound line, _status bound:true for both; showcase_scheduled_digest runs completed …

Reproduction rules (fails)

Derived item verdicts

15 pass · 2 partial · 1 fail · 0 blocked · 4 not-run (of 22).

Tier 1 pin runs (RUNNER rule 6, one vitest batch per package, all at the subject sha):

  • packages/spec: 8 files, 582 passed (flow-value-slot-template, flow-text-slot-template, flow-builtin-node-config-keys, flow-builtin-node-config-values, flow-bound-variable-name, flow, retry-policy, anonymous-elevated-flow-gate)
  • packages/runtime: 3 files, 71 passed (action-flow-elevated-door, endpoint-flow-elevated-door, domains/automation-hooks)
  • packages/services/service-automation: 5 files, 70 passed (flow-cel-current-user, flow-cel-record-binding, decision-overlapping-edge-conditions.pin, flow-refused-registration-read.integration, per-kernel-scheduled-work-policy)
  • packages/lint: 1 file, 80 passed (validate-expressions.flow-cel-root)
  • packages/core: 1 file, 16 passed (security/http-signature)
  • packages/platform-objects: 1 file, 4 passed (apps/setup-packaged-automation-nav)
  • packages/triggers/trigger-api: 1 file, 12 passed (inbound-hook-member); packages/triggers/trigger-schedule: 1 file, 10 passed (per-kernel-scheduled-work-policy)
  • packages/rest: 1 file, 3 passed (meta-flow-cached-registration)
  • packages/qa/dogfood: 4 files, 22 passed (flow-durable-suspend, flow-node, flow-trigger-conformance, flow-trigger-record-credential-mask)
  • objectui-only refs (setup-packaged-automation-board component tests, screen-flow-roundtrip e2e/live/screen-flow.spec.ts) were NOT run from this checkout — both items were driven BY HAND in the browser against the live boot with the 4016370af3c9 console (RUNNER option (a))

Partial / gap notes:

  • automation.trigger-status-contract: acceptance[4] 409 RESUME_IN_PROGRESS arm not-run (3-way concurrent resume answered 200 + 404 + 404; no deterministic stock trigger) and 503 STORE_UNAVAILABLE arm blocked(fixture); every other arm passed
  • automation.setup-packaged-automation-board: acceptance[5] scored blocked(dependency) by the parent — the admin cell passed (409 text verbatim in role=alert), but the member cell's dom oracle is unreachable because a plain member cannot open Setup (knownGaps[2]); server-side the member toggle answers 403 with the exact manage_metadata sentence

Handover — items with no verdict this run

  • automation.time-relative-trigger r3 · P2 · mixed — Tier 3 deferred by the 18.0 release-sweep plan
  • automation.connector-dispatch-matrix r3 · P2 · mixed — Tier 3 deferred by the 18.0 release-sweep plan
  • automation.flow-runs-page-test-trigger r2 · P2 · mixed — Tier 3 deferred by the 18.0 release-sweep plan
  • automation.flow-toggle-kill-switch r3 · P2 · api — Tier 3 deferred by the 18.0 release-sweep plan

Checklist-accuracy findings / fixture gaps

Recorded for the wave anchor (collected by the dispatch session); not extracted, no checklist edit in this run.

Checklist accuracy:

  • automation.packaged-flow-clone-contract · acceptance[1] · FLOW_CLONE_DROPPED_KEYS is 10 today, not 9: flow-clone.ts:149 appends 'protection' to the 2 read decorations + 7 protection fields; the clause's enumerated list omits 'protection'
  • automation.packaged-flow-subflow-disable-refusal · acceptance[0] · remedy text is caller-specific ('Disable the calling flow '‹name›' first — or leave this one armed.'), not the quoted generic 'Disable the calling flow(s) first, or leave this one armed' — substring match on the quote fails although meaning is identical
  • automation.trigger-status-contract · steps[2] · 'a flow that succeeds' is unnamed; stock showcase_resilient_sync triggered bare answers 400 FLOW_FAILED (its CEL condition reads record status), so name showcase_notify_owner with {params:{ownerId,message}} (200) as the success specimen
  • automation.trigger-status-contract · steps[5] · INVALID_SIGNAL arm: the route maps inputs ?? variables, so a body carrying valid inputs plus variables:{$x} silently drops variables and resumes; a $ key inside inputs answers INVALID_SCREEN_INPUT first. The reachable spelling is output:{'$x':1} (→ 'collect.$x'); also the pause must be triggered with recordId+objectName or the valid resume fails 400 FLOW_FAILED (update_record needs recordId)
  • automation.trigger-status-contract · steps[5] · the 403 persona must be admin-created and must change password first (otherwise 403 PASSWORD_RESET_REQUIRED, which looks like the arm but is not)
  • automation.flow-error-handling · step 5 / fixtures.requires · says to author the probe flow 'in the scratch package' via POST /api/v1/automation, but that door reads no package selector (automation-flow-door-package-address.test.ts) — the flow lands package-unbound ('Organization flows', /_console/studio/~org/automations). Either drop 'in the scratch package' or name PUT /api/v1/meta/flow/:name?package=
  • automation.flow-run-step-nesting · acceptance[1] · names an 'end' step that 'carries no parentNodeId', but the engine logs no step for the end node (both showcase_batch_reminders and showcase_resilient_sync runs end at the last real node) — the clause holds vacuously for end
  • automation.rollup-summary-filter · step 7 / acceptance[4] · should say that objects authored into the scratch base must carry the package namespace prefix (POST /packages derives namespace from the id's last segment, e.g. com.u2.rollup → 'rollup_'), otherwise the Studio edit cannot be published (publish-drafts outcome=refused NAMESPACE_PREFIX) and the persisted-metadata half cannot be reached
  • automation.flow-authoring-refusals-v18 · acceptance[2] · the runtime PUT gate stands down on the CEL root-scope judgment by design (flow-cel-root-scope.ts:138-157, perWriteSnapshotEntrance; rulings 5791822697/6104584601 on lint(runtime gate): a flow write's per-write snapshot carries no actions and no other flows, so a flow CEL root rule cannot see the entrances that hand a flow its record (W, from #22565) #22636), so the record.x and user.id arms answer 200 at PUT /meta/flow. The clause should exclude those two arms (they are build-door-only).
  • automation.flow-authoring-refusals-v18 · steps · 'job retryPolicy:{maxRetry:3}' cannot be PUT to /meta/flow. The flow-shaped equivalents are try_catch config.retry.maxRetry (422) or errorHandling.maxRetry (422, but no did-you-mean). The steps should name which one.
  • automation.flow-authoring-refusals-v18 · steps · the anonymous-endpoint arm at PUT is judged only in the flow direction: it needs a code-declared authRequired:false endpoint, and then PUT of a runAs:'system' target flow answers 422 at path runAs. PUT /meta/api is NOT_CREATABLE by default. With OS_METADATA_WRITABLE=api, an anonymous elevated endpoint row is saved 200 without the D2b judgment, but it is never served (POST to its path → 404 ENDPOINT_NOT_FOUND), as documented at metadata-protocol/src/protocol.ts:22265-22297.
  • automation.flow-authoring-refusals-v18 · acceptance[1] · schema-layer arms surface from os validate as code STACK_SCHEMA_INVALID with a contract sentence ('refused at bogusKey by the notify contract'), not as a rule id 'node-config-refused-by-contract'. Match on path + sentence, not on the rule id.
  • automation.flow-registration-verdict-on-read · fixtures · storing the refused flow also needs OS_METADATA_WRITABLE=flow (the flow type is not overlay-writable on stock showcase), and it needs a NAME NEVER REGISTERED: a refused re-registration keeps the previous registration and reads 'registered'. Working recipe: an api-type flow with no config.secret, PUT under the OS_ALLOW_UNLINTED_METADATA_WRITES=1 hatch.
  • automation.paused-run-trigger-record-masked · fixtures · the member's read grant is applied by POST /data/sys_user_permission_set {user_id, permission_set, organization_id} as admin. Admin create-user answered membershipCreated:false, and the member still resolved positions org_member/everyone.
  • automation.trigger-type-matrix · acceptance[4] / steps[5] · says 'capture the trigger POST'; since objectui#12037 the declared flow action launches through POST /api/v1/actions/showcase_task/showcase_bulk_reassign (screen-flow-roundtrip rev4 already re-pointed this) — re-word to 'the action-door launch POST'
  • automation.setup-packaged-automation-board · acceptance[1] / steps[3] · 'default all On' / 'confirm every switch reads On' — showcase_approver_bindings is authored status:'obsolete', so its switch correctly reads Off (31 On / 1 Off); the clause should exempt obsolete-status flows
  • automation.flow-node-type-matrix · acceptance[1] · 'end logs no step' — an end node on an UNTAKEN branch is logged as a step with status 'skipped' (showcase_inquiry_purge run_f8a7bc80: node end nodeType end status skipped; also exec_review approval skipped in budget_approval); a taken end logs nothing. Harmless, but the wording 'end logs no step' is not literally true
  • automation.flow-node-type-matrix · steps[1] · 'open the Studio flow-designer palette' — on stock showcase the package is read-only, so the canvas has no Add node; the palette is reachable only on a writable scope (here: an org-scoped clone made via Setup › Packaged Automation, Studio ~org scope). Name that route in the step
  • automation.setup-packaged-automation-board · steps[1] · the sidebar entry lands on /_console/apps/com.objectstack.setup/component/automation/packaged (package-id path segment), not /apps/setup/component/automation/packaged as the fallback URL is spelled

Fixture gaps:

  • automation.trigger-status-contract · 409 RESUME_IN_PROGRESS has no deterministic stock trigger (3-way concurrent resume race lost) — record as knownGap or provision a slow resume path
  • automation.trigger-status-contract · qa-flow-status-doors recipe lacks a success-row specimen; recipe itself now proven live (all steps 2xx)
  • automation.paused-run-trigger-record-masked · stock showcase has no active pausing record-change flow on a credential object and no run-reader permission set; authored in the scratch copy (known gap, still open)
  • automation.flow-run-semantics-v18 · stock showcase has no current_user-stamping record flow, no autolaunched runAs:'system' flow and no overlapping-edge decision; authored in the scratch copy
  • automation.flow-registration-verdict-on-read · stock showcase ships no refused flow; one was planted at runtime through the lint hatch
  • automation.flow-node-type-matrix · showcase_fan_out_notify / showcase_resilient_sync http steps need outbound egress (fetch failed here); covered by the self-ping scratch flow per knownGaps[1]
  • automation.trigger-type-matrix · stock showcase_task_due_reminder only sweeps daily 08:00 UTC; in-session proof needs a runtime cadence-override copy (method recorded in notes)

Incidental product findings (outside any clause)

Both seen while driving items in this area, independently re-verified on a fresh boot, and extracted as their own defect cards at close-out (see the close-out comment):

  • while driving automation.trigger-status-contract steps[5]: POST /api/v1/automation/:name/runs/:runId/resume silently drops variables when inputs is also present (the route reads inputs ?? variables), so a body carrying both resumes 200 and the second bag is never checked.
  • while driving automation.rollup-summary-filter step 7: an active PUT /api/v1/meta/object/:name?package= saves an object name WITHOUT the package namespace prefix (200, the object is live), while publish-drafts for the same object in the same package refuses it with NAMESPACE_PREFIX.

Activity

  1. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Close-out (extraction) for this run record.

    Extracted: #24546 · automation.trigger-status-contract · steps[5] (incidental, outside clauses)
    Extracted: #24547 · automation.rollup-summary-filter · step 7 (incidental, outside clauses)
    

    Still open on this record, handed to the dispatch session for the wave anchor (runners file no anchor card this wave):

    • automation.flow-authoring-refusals-v18 acceptance[2] fail — disposition stale-spec (the runtime PUT gate stands down on the CEL root-scope judgment by ruling; os validate still refuses both arms). Re-point belongs on the anchor.
    • automation.trigger-status-contract partial — 409 RESUME_IN_PROGRESS not-run, 503 STORE_UNAVAILABLE blocked(fixture).
    • automation.setup-packaged-automation-board partial — acceptance[5] member cell blocked(dependency): a plain member cannot open Setup (knownGaps[2]).
    • 4 Tier 3 items not-run by plan (handover list in the body).

    P0 automation.packaged-flow-disable-durable passed; no authentication/authorization finding.


    Generated by Claude Code

  2. changed the title [-]QA run · area:automation (18/22) · 5b14b7f3 · 2026-10-19 · 15 PASS / 2 PARTIAL / 1 FAIL / 0 BLOCKED / 4 NOT-RUN[/-] [+]QA run · automation (18/22) · 5b14b7f3 · 2026-10-19 · 15 PASS / 2 PARTIAL / 1 FAIL / 0 BLOCKED / 4 NOT-RUN[/+] on Oct 19, 2026
  3. 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)
    Parked-on: #24579 · automation.flow-authoring-refusals-v18 · acceptance[2] (re-point, wave anchor §1)


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Superseded-by: #24596

    Round 2 at ba4afcc re-judged this record's A-class unjudged clauses (automation.trigger-status-contract acceptance[4] 409 arm — pass (503 arm still blocked)) and carried every other verdict forward to #24596 (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