Uh oh!
There was an error while loading. Please reload this page.
docs(qa): correct the checklist and close the fixture gaps the 17.1.0 sweep found - #10594
Merged
Merged
Conversation
… sweep found (#10236) Checklist-accuracy + fixture work from the 17.1.0 post-release QA sweep. No product defect is involved: every edit is to the QA ledger and its runner protocol. Three of the card's own premises were re-derived from source rather than trusted, and two of them changed the fix: - the 422 FLOW_NO_START_NODE arm was expected to be a knownGap; FlowSchema requires no start node and nothing refuses a start-less flow at publish, so it is authorable and became a provisioned clause instead of a waiver; - the declarative-connector `fetch failed` was recorded as a network-restricted runner; it is a self-URL address problem an isolated boot creates for itself (`-p` never exports OS_PORT), so the clause is runnable rather than blocked; - the contributor-bound member was recorded as a missing fixture; it is provisionable on stock fixtures today and was proven in run #7629 — what was missing was a replayable recipe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HFdDHyLhGfbBnWpgdxu6Rq
…-anchor-checklist-edits
os-elon
marked this pull request as ready for review
August 21, 2026 04:27
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#10236
Checklist-accuracy and fixture work from the 17.1.0 post-release QA sweep. No product defect is involved — every change is to the QA ledger (
docs/qa/platform-checklist/areas/*.json) and its runner protocol (RUNNER.md). Nopackages/spec/src/**change; no contract's accept/reject behaviour moves; no public surface widens.Every item edit is revise +
revisionbump + ahistoryentry, per the README lifecycle. No row was deleted.Premises verified before building — three changed the fix
The card is a set of findings, so each was re-derived rather than trusted. Three did not survive contact with the source, and in each case the corrected reading produced a better fix than the one requested.
1. The
422 FLOW_NO_START_NODEarm is not aknownGap— it is authorable. The card expected to waive it for want of a no-start-node flow on showcase.FlowSchemadeclaresnodes: z.array(FlowNodeSchema)with no.min(1)and no refinement requiring astartmember (packages/spec/src/automation/flow.zod.ts:658), and nothing refuses a start-less flow at publish — the refusal happens at dispatch, in the engine (service-automation/src/engine.ts:3212-3220). So the row is reachable through a scratch package exactly asqa-scratch-authzauthors objects, and it became a provisioned clause instead of a waiver.2. The connector
fetch failedis a boot misconfiguration, not a network-restricted runner. The card recordedconnector_action(showcase_status_api.request) failed: fetch failedon every record-change firing and proposed a declared stub orblocked(environment). The showcase's declarative connectors dial the server itself viaresolveShowcaseSelfUrl()(examples/app-showcase/src/system/self-url.ts), which readsSHOWCASE_SELF_URL→OS_PORT→PORT→ the literalhttp://127.0.0.1:3000from the environment. The CLI's-pflag only takes its default fromOS_PORT(cli/src/commands/serve.ts:220) and nothing writes it back — confirmed by grep: no code path assignsprocess.env.OS_PORT. So the dogfood §0 isolated boot (-p PORT, env untouched) listens on that port while every connector dials 3000. That module's own header records this failure class and warns it is indistinguishable from a sandbox egress block — #7516 burned a run proving it was an address problem with a TCP forwarder. Recording it as blocked, or building a stub, would have waived a clause that runs fine withOS_PORTexported.3. The contributor-bound member was never missing. The card called it "the one persona gap that is real". It is provisionable on stock fixtures today — a sign-up plus one
sys_user_positionrow — and run #7629 already drovesearch.rls-both-personasto 4/4 PASS on exactly that persona. What was missing was a replayable recipe: the sequence existed only as prose on one item, so the 17.1.0 runner reached for the seeded demo personas instead and recordedblocked(fixture). Both measurements the card reports are mechanically explained by the permission sets: Mei holds no position, soshowcase_contributornever merges and the object gate answersPERMISSION_DENIED(no rows at all); Ada holdsauditor→showcase_auditor, which carriesshowcase_invoice: { allowRead: true, viewAllRecords: true }— VAMA bypasses record scope, so she sees all 12. Neither is a subset; acontributor-bound member is, viainvoice_own_rows(owner == current_user.email).B2's premise held, and is stronger than stated. The card asked whether Studio's absence is a product choice by the showcase or an oversight, and to report a fork if the latter. It is neither: no stock boot registers Studio at all, by design at the platform layer. Both boot paths carry the identical note —
@objectstack/studiois intentionally NOT default-loaded because "the console ships a dedicated Studio surface at/_console/studio/{pkg}/{pillar}, so Studio no longer needs to exist as a navigable app tile" (plugin-dev/src/dev-plugin.ts:620,cli/src/commands/serve.ts:2302; both register only@objectstack/setupand@objectstack/account, andcli/src/adr-0048-app-split.test.ts:14states the same). So the ruling was applied — reword to the apps a stock boot registers, carve-out intofixtures.knownGaps— and Studio was not installed.A3's measurement re-derived, and it is stronger than the card's. The card said a REST
200proves nothing because JSON parsing rounds2**53 + 1. True, and there are two independent reasons, the second decisive: the literal9007199254740993parses to9007199254740992, which isFILTER_COMPARAND_BIGINT_EXACT_LIMITand so is inside the inclusive<=bound; and the refusal arm is guarded bytypeof value === 'bigint', whichJSON.parsenever produces at any magnitude. The door is in-process by construction, so the fix is both halves — name the engine door inverifyand mark the clause door-specific.A2's stale count explained rather than swapped.
client-brief.object.tswas added to the showcase between the two sweep subjects, which is the15 verified→16 verifiedmove. The--rlsfigure is not stale but not comparable:formatRlsReportemits a per-persona line and anall personastotal whose unit the source stamps into the line —[unit: one object × persona probe]. RUNNER.md was quoting the per-persona line against a total.What changed
A1 — new item
automation.trigger-status-contract(P1, api). The area asserted flow behaviour but never the status a caller observes, so reverting any of 17.1.0's three BREAKING status changes left it fully green. The 14-variant matrix is derived from the three changesets' own tables, then reconciled against the single runtime definition inpackages/runtime/src/flow-dispatch-status.ts— which is wider than the changesets: the same table is read by/actions, the MCPrun_actionbridge and declared endpoints, and it carries a sixth non-terminal row (PAUSED, #9510) the changesets do not tabulate. Clauses cover both trigger routes, all seven resume arms, the cross-door single-mapper property, and the SDK's reject-on-non-2xx half. Ships with the area recipeqa-flow-status-doorsfor the two rows stock fixtures cannot reach.A2 —
RUNNER.md. Corrected both environment facts, plus the?id=bullet, which namedstudioas a real stock name.A3 —
api-backend.filter-comparand-conformanceclause 2 →oracle: test, pointed atengine-comparand-type-door.test.tsand the five driver conformance suites, marked door-specific, with the REST verdict recorded as not-applicable rather than blocked.A4 —
platform-core.builtin-apps-nav-renderclause 4 reworded for whole-app refusal. The member cannot obtain thesetupapp at all (200 {"items":[]}), so there is no member-side Setup nav to diff. The clause now also names theaccountapp as an explicit non-substitute: every one of its entries is gated byrequiresObject/requiresService(presence gates), so admin and member navs are identical (7 vs 7) by construction — scoring the gate off that comparison is a false pass.A5 — five per-item notes. Chart synonyms (identical tiles are the expected observation, with an explicit exemption from the wrong-family negative); connector self-URL (above);
boot-healthclause 2 scoped to the boot window, because a caller-error refusal logs at ERROR with a full stack before answering 4xx; the demo personas named onerror-envelope-ledger; and the objectui-pinned items — measured at 23, not the 15 the card estimated (items whoseautomated.refnames objectui exclusively; five more mix objectui with a framework pin and are partly runnable here). The protocol lives once in RUNNER.md, with a one-line pointer on each of the 23.B1 — area recipe
qa-contributor-bound-memberinareas/search.json, referenced bysearch.rls-both-personasviaprovisioning.use. Its step 4 is a premise guard that distinguishes all three outcomes —403= the binding did not take, 12 rows = a VAMA set, 0 of 12 = correct — so mis-provisioning is caught before any verdict rests on it.records-forms.crud-roundtripclause 7 now namesshowcase_invoice+ INV-1003 (it cannot be scored onshowcase_account, which ispublic_read_write) and states the404-vs-403discriminator the sweep tripped on.B2/B3 — as described above.
Deviations from the dispatch
knownGap(premise 1). PM asked for exactly this check.blocked(environment)(premise 2).whyrecords that nothing was missing from the fixtures.records-forms.crud-roundtripneedssearch.json's recipe, butprovisioning.useis area-scoped, so it cross-references by name inknownGapswith an explicit "do not fork a second copy". Filed as finding: the checklist's area-scopedfixturesrecipe convention has hit its stated revisit trigger — 3 areas, and a consumer that cannot reference the recipe it needs #10593 — this trips the revisit condition the README states for docs(qa-checklist): attachments-storage maintenance — totalSize step fix, ADR-0104 D3 receipt clause, and the scratch authz fixture landed permanently #7716's deferred option C.Gates
Run at
b6471387e(the final commit; tree clean), after mergingorigin/main:node scripts/checklist-select.mjs --self-test✓ checklist-select self-test: 17 cases pass.node scripts/check-platform-checklist.mjscheck-platform-checklist: OK — 15 areas, 205 items (205 active); coverage: 30 kinds mapped, 0 waived.node scripts/check-nul-bytes.mjscheck-nul-bytes: OK (scanned 6187 text file(s) ... no raw ASCII control bytes).node scripts/pm/dispatch-gates.mjs(no paths — derives its own changeset)No check family names the given paths in its own source, and no workflow's path filter schedules one for them.· residue0 matched · 40 undetermined · 81 silentTogether the first two are⚠️ That gate is deliberately not in CI (maintainer decision, recorded in
pnpm check:platform-checklist.lint.yml:805-811and the checklist README: it is a QA ledger, not a per-PR code gate), so the local run above is the only authority for it — CI will not re-derive it.check-nul-byteswas run because the diff discusses control characters.dispatch-gatesalso lists five changeset-triggered families that "apply once a changeset exists, unless this card is docs-only". It is docs-only —docs/qa/platform-checklist/**publishes no package — so this PR carriesskip-changesetinstead.One thing no path derivation can check:
provisioning.useis not resolved by the validator (deferred, #7716 option C). All six references in the tree were verified by hand to resolve against their own area's block, and both new recipes are referenced by at least one item — no dangling pointers, no dead text.Out of scope, filed not fixed
@objectstack/studio's package header describes a pending boot-path switch that already concluded the other way #10592 —packages/apps/studio/src/index.ts's header still says the package is "NOT yet wired into the dev/serve plugin set" and that removing the app from plugin-auth's manifest "lands separately". Both halves are stale in opposite directions, and the first reads as an unfinished chore whose obvious next step would put a Studio tile back into every stock boot.fixturesrecipe convention has hit its stated revisit trigger — 3 areas, and a consumer that cannot reference the recipe it needs #10593 (finding) — the area-scoped recipe convention has hit its stated revisit trigger: three areas now, plus the first consumer that cannot reference the recipe it needs.Generated by Claude Code