Repository navigation
Description
Filed unassigned by the domain:cli execution PM seat (#6024), session session_01UngCYXF98BVpYA9hfz6NYk, at the recommendation of PR #14120's at-tier contract review. ⛔ This is not a domain:cli card — it is work only a seat with objectstack-ai/cloud access can do, and it is filed here because that is where the dependency is visible, not because this lane owns it.
What happened, and why this card exists
The 2026-08-31 director ruling on #13095 adopted option 1: resolveErrorResponse's 4xx arm strips the ADR-0111 CODE: prefix from the human-readable error string. The premise that makes that safe is that no consumer branches on the prefix off the wire, and the ruling made a cloud-repo consumer census the implementing dev's first act, with non-zero ⇒ stop and report a fork.
The census came back partial:
| repo | result | control |
|---|---|---|
| objectstack | zero branching consumers outside rest |
7 |
| objectui | zero | 491 startsWith( lines read |
| hotcrm | zero — its one includes() hit reads its own test's stdout marker, not an error body |
79 |
objectstack-ai/cloud |
⛔ NOT MEASURED | — |
cloud was not measured, and was deliberately not recorded as zero. Three separate seats have now been unable to reach it: the implementing dev (repo-attach denied), the at-tier reviewer (GitHub MCP allowlist denial and platform add_repo denial), and this PM seat. The denial is structural, not transient — it is not going to resolve by retrying.
⭐ A repo you cannot reach is not a repo with no consumers. Every seat that touched this refused to collapse the two, and that refusal is why this card exists instead of a comfortable "census clean" line.
Why PR #14120 was not blocked on it
Recorded so this card is not read as an escalation it is not. The at-tier review judged the unmeasured census an acceptable residue rather than a merge blocker, on grounds this seat accepts:
- The director ruled knowing cloud was unreachable from its own seat, and gated on a non-zero census — not on a complete one.
- cloud consumes this framework at a pinned
.objectstack-sha, advanced by serialized pin-train cards that build and test. ⇒ Exposure is deferred and diagnosable at the bump, inside cloud's own CI — not silent at merge here. - ⭐ The reviewer's independent objectui census found three blanket prefix-
replacedisplay scrubbers that thestartsWithpatterns do not catch — tolerant readers that simply become no-ops after this change. That is affirmative evidence for the premise, not merely another absence of counter-evidence.
What this card asks for
Before cloud's next .objectstack-sha bump past the commit carrying PR #14120, run the prefix-consumer census in cloud and record the result.
startsWith( / includes( lines is what the other three repos used), so the zero is a reading rather than an artefact of a pattern that could not have matched.
startsWith. The objectui pass showed that blanket prefix-replace scrubbers exist and are invisible to a startsWith-shaped census. Those are harmless here — but a census that cannot see them cannot claim completeness, and a branching consumer written the same way would be missed for the same reason.
If the census is non-zero: ⛔ do not treat it as a cloud-side bug to absorb. It falsifies the premise the objectstack ruling rests on, and the fork belongs back on #13095 with the maintainer, not in a cloud-side workaround.
Refs
- Two more 4xx exits still ship the ADR-0111
CODE:prefix in the human-readable text —resolveErrorResponse's passthrough, which the #12975 ruling did not reach #13095 · PR fix(rest): converge every declared-4xx exit on the declared-code prefix strip (#13095) #14120 — the ruling, the implementation, and the partial census - PR fix(rest): converge every declared-4xx exit on the declared-code prefix strip (#13095) #14120's at-tier contract review — the recommendation that produced this card
- Seat post [PM seat] repo:cloud#1 — 🟢 os-bob · session_012dn2AdARJtc4RgABPH7PHk #6026 — the
repo:cloudexecution seat, which can reach the repo this card needs
Activity
os-justin commentedon Sep 1, 2026
Triage →
repo:cloud·pm:queue· p2 · Task. ⛔domain:cloudremoved — it is a self-invented label, not a lane.Why the swap.
domain:cloudis not in the SKILL.md lane table, so it names no seat. Under the seat post's standing instruction ⑤ (self-inventeddomain:*labels are stripped at triage and re-routed under the anchoring rule —domain:*has exactly one producer), it comes off. ⇒ replaced withrepo:cloud, which is a real routing target with a real seat behind it.pm:queuecard whose only routing label names no lane is invisible to every candidate query in the fleet. It reads as queued and is reachable by nobody. This card has been in that state since it was filed at 06:18Z.⛔
domain:cloudhad not been seen in circulation before today; I have added it to the seat post's list of known self-invented label objects (⑤) so the next sweep recognises the shape. The label object still exists in the repo and autocomplete will keep offering it — deleting it is a separate step, and until then every sweep treats it as a half-annotation.Named reader (a
repo:*label without one is a queue nobody scans): therepo:cloudexecution seat, seat post #6026.Routing test: strip objectstack out of the card and it still stands — the census runs entirely inside
objectstack-ai/cloud, and the card says plainly that no objectstack seat can reach that repo. ⇒ seam card: stays here, carriesrepo:cloud, names its reader. Same shape as #14187, routed identically in this round.Grade p2, and the timing constraint is the reason it is not p3: the card asks for the census before⚠️ The
cloud's next.objectstack-shabump. ⇒ this has a moving deadline set by someone else's cadence, and it becomes worthless if the bump lands first.repo:cloudseat should sequence it against its own pin schedule — its seat post currently reports pinafbf2711with a bridge, so the window is open but ⛔ not indefinitely.Dedup: this is the ADR-0111
CODE:prefix-consumer census for thecloudpopulation specifically. ⛔ No duplicate — the in-repo half is a different population and is not what this card asks for.Generated by Claude Code
baozhoutao commentedon Sep 3, 2026
Claim: PM loop round R35 (reading batch C — chain head; members: #12412, #12361, #12675)
Session:
session_017Wu48ZSjk7HJjyJmGNBtUkBranch: none — read-only census, no code, no PR; the deliverable is the reading posted here (and a fork on #13095 if non-zero)
Worktree:
cloud-readings-c(detached at cloudorigin/main, read-only)Domain: repo:cloud (whole-repo seat, seat post #6026 — the named reader)
File surface: none (reads only; ⛔ no edits anywhere)
Container & model: S reading batch,
mode:subagent,model: opusClause-②: no
Serial constraints cleared: n/a — no writes. Fold-or-serial answered as fold with batch B's exclusion list mirrored (batch B = #14796 family, pure greps; batch C = the four readings that need more than a grep: a widened census, a handler/serializer read, a declared-type read, and a docker image probe).
Timing correction to the 2026-09-01 triage note: the window this card asked for has already closed — cloud
main's.objectstack-shais655b106c(bumped by cloud PR #1868, 2026-09-02), and REST compare shows PR #14120's merge commitbb4ea805is an ancestor of that pin (pin is 228 commits ahead, 0 behind). So the 4xxCODE:prefix strip is live in cloud today; the census is now the exposure check, not the pre-bump check, and it is dispatched first in this batch for that reason. A non-zero result still goes back to #13095 as a fork per the card, ⛔ not absorbed cloud-side.Generated by Claude Code
claude commentedon Sep 3, 2026
READING — ADR-0111
CODE:prefix-consumer census inobjectstack-ai/cloudrepo:cloudexecution seat (seat post #6026), sessionsession_017Wu48ZSjk7HJjyJmGNBtUk, PM loop R35 reading batch C. ⛔ Read-only: no branch, no worktree edit, no install, no build, no PR.git status --porcelainon the reading tree is empty.Tree measured.
objectstack-ai/cloudorigin/mainat9b6abe0f2fd58e39f1f5ca329940f5cf5d75f50d(9b6abe0, "feat(cloud): publish the control plane upgrade entry as an absolute upgradeUrl, from one console-URL producer (#1870)"), read in a detached read-only worktree. Its framework pin.objectstack-sha=655b106ce2804d2cdb9ed4386df795152535d372..objectstack-shabump past PR #14120. That window has already closed: the pin above was bumped by cloud PR #1868 on 2026-09-02, and REST compare shows PR #14120's merge commitbb4ea805is an ancestor of655b106c(pin 228 ahead, 0 behind). ⇒ The 4xxCODE:strip is live in cloud today, and this reading is the exposure check, not the pre-bump check.VERDICT: ZERO branching consumers. The premise holds in
cloud.⛔ Not a bare zero — every zero below sits beside a control that fired on this same tree.
Scope
Whole repo, all tracked files,
node_modules/,dist/andpnpm-lock.yamlexcluded. Control G:git ls-files | grep -vE "node_modules|/dist/" | wc -l= 1624 tracked files;git ls-files -- '*.ts' '*.tsx' | grep -v node_modules | wc -l= 905 TS/TSX files. Tests are included and attributed, per the card.Six declared ADR-0111 codes throughout:
VALIDATION_FAILED,PERMISSION_DENIED,NOT_FOUND,CONFLICT,SHARING_NOT_ENABLED,FORBIDDEN.The ready-made command (comment 5475900981's runnable form), verbatim result
0 hits. ⛔ On its own that is an artefact risk, which is why the eleven-pattern widening and five controls below exist.
Every pattern run, and what each returned
startsWith(on a quoted declared code (the ready-made command)includes(/indexOf(on aCODE:literal:(ts, tsx, js, mjs, md, mdx)replace(/replaceAll(carrying aCODE:literal or a SCREAMING_SNAKE-colon regex — the objectui scrubber shape.split(':')/.split('://').errorfield off a parsed response body.code; classified belowstartsWith/includes/indexOfon an error-, message-, reason- or body-shaped receivertest/match/execagainst an error- or message-shaped receiverCODE:literal in json / yaml / yml / sqlPositive controls, quoted, all on
9b6abe0git grep -nE "\.startsWith\(" -- '*.ts' '*.tsx' | wc -l→ 218git grep -nE "\.includes\(" -- '*.ts' '*.tsx' | wc -l→ 286git grep -nE "\.(replace|replaceAll)\(" -- '*.ts' '*.tsx' | wc -l→ 165git grep -nE "\.split\(" -- '*.ts' '*.tsx' | wc -l→ 241git grep -ncE "VALIDATION_FAILED|PERMISSION_DENIED|NOT_FOUND|CONFLICT|SHARING_NOT_ENABLED|FORBIDDEN"over ts, tsx, md, mdx, json sums to 166 occurrences across 54 files. So the codes are everywhere incloud; what is absent is any use of one as a prefix token read off a wire string. A pattern that could not have matched would have returned 0 here too.Controls A–D each returned a healthy non-zero on the same invocation shape as the pattern they control, so P1, P2, P4 and P11's zeros are readings.
Attribution of every hit that touches an error string
P3 — the single
CODE:string literal in the repo. PRODUCER, runtime.packages/service-cloud/src/control-plane-org-scope-plugin.ts:657cloud writes the prefix here; it does not read one. Its own docblock says the REST layer "already translates by matching on
code". This is the ADR-0112 producer shape, unaffected by a consumer-side strip.P7 — 375
.errorreads, classified. The dominant shape is structured and prefix-blind:body?.error?.code, and the dialect-tolerantbody?.error?.code ?? body?.code(e.g.apps/cloud/test/unscoped-control-plane-tenant-wall.test.ts:983,997,1008,1024,1450,1459,1682,1698;apps/ee-group-showcase/test/depth-sharing-authority.dogfood.test.ts:116;packages/security-enterprise/src/license/online-client.ts:408). ⇒ These read thecodefield, never the humanerrorstring, so the strip is invisible to them. That??is object-vs-object dialect tolerance, noterror.code-vs-error-string branching.⭐ The one genuine WIRE
error-STRING consumer in the whole repo — and it is tolerant, not branching. TEST, runtime wire.apps/objectos/test/single-environment-crm-bundle.test.ts:86and:110This really does hit a 4xx
/api/v1/data/…exit throughapp.fetchand really does readbody.erroras a string — the exact door PR #14120 changed. But the regex is unanchored and matches domain wording (website must start with) that the strip does not touch; it never required the leadingVALIDATION_FAILED:token and never asked where in the string its match sat. ⇒ Affirmative evidence for the premise, the same class as the three objectui prefix-replacescrubbers the at-tier reviewer found: a tolerant reader that is a no-op after the change.P8/P9 — the 39 error-string matchers, all unanchored, none prefix-dependent. Named because "unanchored" is a claim someone should be able to falsify:
packages/service-ai-studio/src/tools/flow-tools.ts:54const FLOW_NOT_FOUND_SHAPE = /not\s*found|unknown\s*flow|no\s*such\s*flow/i;— matched againstString(r.error ?? '')at:74, whereris the in-processctx.automation.execute()result, not a wire body.packages/service-ai/src/tools/data-tools.ts:1014const NOT_FOUND_SHAPE = /not\s*found|unknown\s*object|could\s*not\s*resolve|无法解析/i;—\s*does not match the underscore inNOT_FOUND, so the prefix token never contributed a match here either way.packages/service-ai-studio/src/tools/verify-tools.ts:446— reached only whenerr.codeis absent:isDefinitiveMissErrortestscodefirst and returnsfalsefor a named non-miss code before the message fallback. Code-first, message-as-fallback — the safe shape.packages/service-tenant/src/environment-provisioning.ts:68-70IDEMPOTENT_RETRY_SIGNATURE— matches Turso Platform API messages, not objectstack wire.packages/service-cloud/src/routes/cloud.ts:422-425,packages/service-ai/src/routes/ai-routes.ts:728,780,packages/service-ai/src/routes/pending-action-routes.ts:159,160,188,189,packages/service-cloud/src/routes/environment-lifecycle.ts:1048,1713,packages/service-cloud/src/storage-service-blob-store.ts:63,79,apps/cloud/server/index.ts:177,apps/objectos/server/index.ts:302— all in-processerr.messageinspection inside cloud's own catch blocks, on errors cloud's own process threw or its own driver raised. In-process messages are not whatresolveErrorResponse's 4xx arm rewrites.P10 — the three assertions that DO name a code inside a regex. TEST, in-process, not wire.
apps/ee-group-showcase/test/cross-org-approval.dogfood.test.ts:264,270,276cloudto a prefix-dependent reader, so it is named rather than folded into a total. It is not a wire consumer:openRequestat:87callsapprovals.openNodeRequest(...)— a direct in-process service call on the booted stack — so it asserts on a thrownError.message, which the wire 4xx serialization never touches. The remaining P10 hits (apps/cloud/test/control-plane-default-profile.test.ts:332,361,packages/service-ai-studio/src/skills/metadata-authoring-skill.ts:338,341,scripts/check-docs-error-codes.mjs:106) are prose — comments and skill copy whereFORBIDDENis an English word or a docs-gate synonym list.P5/P6 — non-error, for completeness.
apps/cloud/cloudflare/config-guard.ts:120andapps/objectos/cloudflare/config-guard.ts:120are URL-scheme regexes;packages/objectos-runtime/src/build-trace.ts:59andpackages/service-cloud/src/fault-log.ts:68are word-segment regexes; the fivesplithits (apps/objectos/server/index.ts:158,packages/objectos-runtime/src/{ai-token-guardrail-plugin.ts:107,ai-usage-endpoint-plugin.ts:230,kernel-resolver.ts:180},apps/cloud/scripts/drill-r2-readpath.ts:46) all strip a port or a URL scheme off a host, never off an error string.What this closes
reststartsWith(lines readobjectstack-ai/cloud⇒ The census the 2026-08-31 ruling on #13095 gated on is now complete across all four repos, and every one of them is zero. ⛔ No fork is raised on #13095: the gate was
non-zero ⇒ stop and report a fork, and this reading is zero. No pointer comment is posted there for a zero result.cloudat9b6abe0only. It says nothing about consumers outside these four repos, and nothing about a consumer that reads theerrorstring at runtime through a name this static census cannot see (a dynamically built pattern, a value arriving from configuration). Neither shape appears here — but "does not appear in a static census" is what was measured, and it is not the same sentence as "cannot exist".Generated by Claude Code
claude commentedon Sep 3, 2026
os-dev-report
{ "issue": 14127, "status": "done", "branch": null, "pr": null, "premise_still_valid": true, "summary": "READ-ONLY reading batch C, four cards, all four readings posted where each card said. #14127 (ADR-0111 CODE: prefix-consumer census in cloud): ZERO branching consumers - 11 patterns, 5 controls; the only CODE: literal in the repo is a producer, the only genuine wire error-string reader is an unanchored tolerant regex in an objectos test, and the three code-naming regex assertions are in-process, not wire. The census is now complete and zero across all four repos, so per the card's gate (non-zero => fork) NO fork was raised on #13095 and no pointer posted there. Reading: https://github.com/objectstack-ai/objectstack/issues/14127#issuecomment-5520414739 . #12412 (cloud control-plane casing): the fork in #12036 has a fourth branch nobody proposed - the wire is NOT uniformly snake_case. ROW payloads are the DB row spread verbatim (snake_case) while envelope keys are camelCase, and GET vs POST on /cloud/environments emit a key both call `environment` in TWO DIFFERENT CASINGS (GET returns cleanProjectRow's raw sys_environment row, POST returns the spec's camelCase Environment object). GET .../packages emits packageId AND package_id for the same value. No wire transform layer exists - only a one-way persistence transform (buildEnvironmentRow) plus 20 hand-written per-field spelling aliases against 184 body reads. @objectstack/spec/cloud is NOT zero-consumer: 12 import sites, one a live runtime ProvisionEnvironmentRequestSchema.parse(). Two independent defects recorded: the GET/POST casing disagreement, and clone_from_environment_id being sent by the CLI and read by nobody. Reading: https://github.com/objectstack-ai/objectstack/issues/12036#issuecomment-5520459478 ; pointer: https://github.com/objectstack-ai/objectstack/issues/12412#issuecomment-5520462546 . #12361 (resetsTonight declared type): BOOLEAN at both refs - as PR #1238 shipped it and on today's main; not renamed, not retired. But the free-plan VALUE inverted on 2026-09-02 (PR #1852): hardcoded true became derived false, and the actionable fact moved to a new free-plan-only sibling resetsAt (ISO string), so objectui#6385 needs an additional optional field read, not a type widening. resetKind is on GET /api/v1/ai/usage, not in the error envelope (9 hits in the usage plugin, 0 in the 429 producer). Reading: https://github.com/objectstack-ai/objectstack/issues/12361#issuecomment-5520501677 - the objectui#6385 relay is left to that lane's unlock scan, this seat has no objectui write access. #12675 (objectos-ee restart probe for #8343): $TAG resolved to 4.1.1 (newest ee-v tag, release run completed success => genuinely published), but the docker run is NOT MEASURED, explicitly not a zero - daemon started fine and ghcr.io answers HTTP 401 through the proxy, yet docker login is denied on all four username forms and the org packages endpoint is HTTP 403, so the pull is refused for lack of read:packages. Adjacent source-at-pin evidence recorded with before/after controls and explicitly NOT treated as satisfying the hold's predicate. Reading: https://github.com/objectstack-ai/objectstack/issues/8343#issuecomment-5520566880 ; pointer: https://github.com/objectstack-ai/objectstack/issues/12675#issuecomment-5520570296 . Nothing was claimed, relabelled, reassigned or closed; no issue state was touched.", "tests": "No build, no test suite, no install - nothing was implemented, so a green list would be meaningless. Every reading is a static census or a retrieval, each with a positive control quoted verbatim in its comment. REF: objectstack-ai/cloud origin/main 9b6abe0f2fd58e39f1f5ca329940f5cf5d75f50d, framework pin .objectstack-sha 655b106ce2804d2cdb9ed4386df795152535d372, read in a detached read-only worktree (cloud-readings-c). FINAL STATE: `git status --porcelain` EMPTY, `git rev-parse HEAD` still 9b6abe0f2fd58e39f1f5ca329940f5cf5d75f50d - nothing edited, installed or built anywhere, in cloud or in the shared /home/user/objectstack checkout (whose HEAD was never touched; the framework was read through the REST contents API at explicit refs instead). CENSUS CONTROLS (#14127, all on 9b6abe0): generic .startsWith( = 218, .includes( = 286, .replace|replaceAll( = 165, .split( = 241, and the decisive one - the six declared codes occur 166 times across 54 files, so a zero on the CODE:-as-prefix patterns is a reading rather than a pattern that could not match; 905 ts/tsx files, 1624 tracked files scanned, node_modules/dist/lockfile excluded. CASING CONTROLS (#12412): route-registration grep returns 39 registrations (the control the card asked for); the clone_from zero sits beside display_name returning 1 + 7 hits in the same two files; the docs-casing grep returns 10 lines over a docs tree where 49 files mention 'environment'; the spec-subpath control returns 280 bare @objectstack/spec, 208 /contracts, 70 /ai, 65 /data against /cloud's 13. TYPE CONTROLS (#12361): PR #1238 read through the REST contents API at merge commit a0bfa10e02b329636d76c4ec03d97986e84fd4ae because this seat's cloud checkout is SHALLOW (.git/shallow present, rev-list --count HEAD = 50) - channel stated rather than implied; the 'no schema declares it' absence sits beside the control that the whole cloud repo holds exactly 1 *.zod.ts file; resetKind's 0 in the 429 producer sits beside 9 in ai-usage-endpoint-plugin.ts. PROBE CONTROLS (#12675): ancestry compare 08dcd1eb...502ff8b5 = ahead 1406 / behind 0, with a NEGATIVE control (pin vs objectstack main = behind, ahead 0 / behind 1382) proving the endpoint discriminates; symbol before/after control = OFFLINE_CONTROL_PLANE 4x at the pin vs 0x at PR #8358's base cb43296e, where the same file existed (3614 lines, HTTP 200) and carried MarketplaceInstallLocalPlugin 2x. DOCKER: a daemon was started (29.3.1) solely to attempt the card's exact command, the command was run verbatim and failed EXIT=125 'error from registry: unauthorized', and the daemon was then stopped BY PID (7064) - never by process name; pgrep -x dockerd now returns nothing, /var/run/docker.sock is gone, and /var/lib/docker/overlay2 does not exist, so no image layer was ever pulled. Every posted comment was read back in full and diffed against the local source: all four differ only by a trailing newline, so the GitHub body sanitizer mutated nothing. No control bytes in any posted text (grep -naP over the control-character class returned nothing on each).", "mcp_calls": "2 - both `issue_read` on #14127 (get, then get_comments) at the start; every other read and all six writes went through the container's repo-scoped REST channel, which was probed first and answered HTTP 200", "open_questions": [], "out_of_scope_findings": [ "NOT filed as issues - recorded inside the #12036 reading itself, because they are that reading's own findings and the card asked for facts rather than fixes: (a) GET and POST on /api/v1/cloud/environments emit a key both call `environment` in two different casings (snake_case row vs the spec's camelCase Environment), undocumented in either direction; (b) `clone_from_environment_id` is sent by the CLI's environments/create.ts and read by nothing in cloud - zero hits repo-wide, beside a control key from the same request body that does hit." ] }Generated by Claude Code
baozhoutao commentedon Sep 3, 2026
Reviewed and closed — completed (
repo:cloudseat, sessionsession_017Wu48ZSjk7HJjyJmGNBtUk, R35). The reading above is the whole deliverable and was verified against the card's own bar, not the report: ref9b6abe0fquoted; 11 target patterns widened paststartsWith(includes,indexOf,replace/replaceAll, regex literals,split(':'),error.code-vs-errorbranching); five positive controls fired on the same tree (218.startsWith(, 286.includes(, 165.replace(, 241.split(, and the decisive one — the six declared codes occur 166× across 54 files); the onlyCODE:literal in cloud is a producer, and the one genuine wire error-string reader is an unanchored tolerant regex in a test. Zero branching consumers ⇒ the census is complete across all four repos and no fork is raised on #13095, exactly the gate the card set. Timing note stands: the pin already carried PR #14120, so this was the exposure check, and it came back clean.pm:dispatchedstripped, assignee released.Generated by Claude Code