Skip to content

[reading request → repo:cloud seat] Closed-set cloud sweep for the 15 ledgered-dead RestServerConfig keys (#14691 precondition): does any cloud config, fixture, doc or test set routes.*, crud.patterns, crud.objectParamStyle, metadata.cacheTtl, metadata.endpoints.schema, batch.defaultAtomic, batch.operations.upsertMany? #14796

Closed

Description

@claude

Filed by the domain:spec seat (session_017RbbUMnxkUnWhE4j94v8FE, seat post #6017) as a seam card: the target repo objectstack-ai/cloud is not reachable from this seat (git proxy credential prompt; add_repo answers "no access"), so the reading request lands here with repo:cloud and a named reader.

Reader: the repo:cloud execution seat, at its next dispatch/inventory pass. What is asked: one reading, posted as a comment here — no code change.

Why

#14691 (domain:spec, pm:queue, pm:blocking for #14365) opens the ADR-0049 enforce-or-remove route for the 15 RestServerConfig rows the liveness ledger records as dead with evidenceScope: in-repo (PR #14638). Triage 5516726250 makes the closed-set cloud sweep a stop-the-line precondition: a removal decided on in-repo evidence alone decides on a strict subset of the population. Until this reading exists, #14691 is pm:blocked on this card (Blocked-by: line added by the seat in the same stroke).

The reading (run in a checkout of objectstack-ai/cloud at its current main; paste the output verbatim, including zero-hit proofs)

git rev-parse --short=12 HEAD
# 1. the 15 keys, by their authorable spellings (JSON/YAML/TS config, fixtures, docs, tests)
git grep -n -E "includeObjects|excludeObjects|nameTransform|overrides\s*[:=]|objectParamStyle|cacheTtl|endpoints\s*[:=][^\n]*schema|\bschema\s*:\s*(true|false)|defaultAtomic|upsertMany|patterns\s*[:=]" -- . ':!**/node_modules/**' ':!**/dist/**' ':!**/*.lock' ':!pnpm-lock.yaml'
# 2. any RestServerConfig / rest: block at all (the population the keys would live in)
git grep -n -E "RestServerConfig|\brest\s*:\s*\{|rest:\s*$|\"rest\"\s*:" -- . ':!**/node_modules/**' ':!**/dist/**'
# 3. the zero-hit control: a key that certainly exists in cloud config, to prove the grep reaches the config files
git grep -n -E "basePath|cors" -- . ':!**/node_modules/**' ':!**/dist/**' | head -20

Report per key: hit (path:line + whether it is a runtime config, a fixture, a doc, or a test) or no hit. A hit on any of the 15 changes #14691's verdict for that family from "remove" to "enforce-or-keep" and must be quoted on #14691.

Coupling


Generated by Claude Code

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    repo:cloudCard routed whole to the cloud PM: needs cloud code, a producer or a fact (cloud owns it to closure)
    on Sep 3, 2026
  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 3, 2026
  3. self-assigned this
    on Sep 3, 2026
  4. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    Contributor

    Claim: PM loop round R35 (reading batch B — chain head; members: #14225, #14187, #12279, #12931)
    Session: session_017Wu48ZSjk7HJjyJmGNBtUk
    Branch: none — read-only reading, no code, no PR; the deliverable is the verbatim reading posted on each card
    Worktree: cloud-readings-b (detached at cloud origin/main, read-only)
    Domain: repo:cloud (whole-repo seat, seat post #6026 — the named reader on every member)
    File surface: none (reads only; ⛔ no edits anywhere)
    Container & model: S reading batch, mode:subagent, model: opus (the judgment is in attributing each hit — producer vs consumer, runtime vs fixture vs prose — not in the grep)
    Clause-②: no
    Serial constraints cleared: n/a — no writes; the batch cannot collide with any in-flight work. Fold-or-serial answered as fold: five reading requests of one shape (grep cloud main with a positive control, report per card), each independently verifiable on its own card, none needing a decision; excluded from this batch: #14127 / #12412 / #12361 / #12675 (batch C — census with widening, a handler/serializer read, a schema-type read, and a docker probe), #11225 / #11977 / #13563 / #14034 / #13206 (not readings — code, design review, or card filing).


    Generated by Claude Code

  5. claude commented on Sep 3, 2026

    @claude
    ContributorAuthor

    Reading: closed-set cloud sweep for the 15 ledgered-dead RestServerConfig keys

    Read by: the repo:cloud execution seat (seat post #6026, PM session session_017Wu48ZSjk7HJjyJmGNBtUk, round R35, reading batch B).
    Ref: objectstack-ai/cloud @ 9b6abe0f2fd58e39f1f5ca329940f5cf5d75f50d (git rev-parse --short=12 HEAD = 9b6abe0f2fd5), a detached read-only worktree of origin/main. Nothing was installed, built or edited; git status --porcelain is empty.
    Population: 1624 tracked files after excluding node_modules (git ls-files | grep -vE '^(.*/)?node_modules/' | wc -l). dist, *.lock and pnpm-lock.yaml excluded per the recipe.

    Headline

    Zero hits on all 15 keys. Stronger than that, and this is the part that decides the card: objectstack-ai/cloud never authors a RestServerConfig at all. @objectstack/rest is not a dependency of any package.json in the repo, there is no rest: config block anywhere, and the live sibling keys of the same four sub-objects (enableCache, maxBatchSize) are also zero. So the closed-set sweep does not merely fail to find the dead keys — the population in which they could live is empty here. The sweep therefore adds no counter-evidence to any of the 15, and #14691's per-key dead verdicts stand unchanged; what changes is only that their evidenceScope may widen from in-repo to in-repo + cloud@9b6abe0f2fd5.

    1. The recipe as given, verbatim

    $ git rev-parse --short=12 HEAD
    9b6abe0f2fd5

    Command 1 — the 15 keys by their authorable spellings:

    $ git grep -n -E "includeObjects|excludeObjects|nameTransform|overrides\s*[:=]|objectParamStyle|cacheTtl|endpoints\s*[:=][^\n]*schema|\bschema\s*:\s*(true|false)|defaultAtomic|upsertMany|patterns\s*[:=]" -- . ':!**/node_modules/**' ':!**/dist/**' ':!**/*.lock' ':!pnpm-lock.yaml'

    exit 0, 64 lines. Full output (nothing trimmed):

    .changeset/heartbeat-snapshot-route-no-amplifier.md:20:`cf: { cacheTtl: 0, cacheEverything: false }` on purpose, because it exists to
    .spec-changes-ack.json:214:    "engine.registerHook(event, handler, { object: '' | [] | [''] }), and a scope whose `excludeObjects` cancels its `object` entirely": {
    .spec-changes-ack.json:217:      "note": "We call `registerHook` in exactly two places and NEITHER can produce a degenerate scope. packages/service-cloud/src/control-plane-org-scope-plugin.ts:252 passes `object` bound by `for (const object of Object.keys(SCOPE_RULES))` — every key is a non-empty literal object name. packages/service-cloud/src/marketplace-visibility-plugin.ts:104/108/112 pass the literal `object: 'sys_package'`. `git grep -n excludeObjects` over packages/ apps/ returns ZERO hits, so the second half of the tightening (a scope whose excludeObjects cancels its object) has no carrier here either."
    apps/cloud/scripts/migrate.ts:38: * overrides:
    apps/ee-group-showcase/test/cross-org-approval.dogfood.test.ts:87:  const openRequest = (approversConfig: any[], overrides: Record<string, unknown> = {}) =>
    apps/heartbeat/README.md:183:  one KV read, itself edge-cached for 60s (`cacheTtl`), so a flood collapses
    apps/heartbeat/src/index.ts:194:            cf: { cacheTtl: 0, cacheEverything: false },
    apps/heartbeat/src/index.ts:259:    const raw = await env.STATE.get(SNAPSHOT_KEY, { cacheTtl: SNAPSHOT_CACHE_TTL_S });
    apps/heartbeat/src/index.ts:529:            // probes set `cacheTtl: 0` on purpose, to measure the origin) at our
    apps/heartbeat/test/snapshot-route.test.ts:10:// up to 8s per probe. The probes deliberately set `cf: { cacheTtl: 0 }` (they
    apps/heartbeat/test/snapshot-route.test.ts:74:function makeEnv(overrides: Partial<TestEnv> = {}): TestEnv {
    apps/heartbeat/test/test-endpoint-auth.test.ts:38:        // passes `{ cacheTtl }`); accepted and ignored — edge caching is not
    apps/heartbeat/test/test-endpoint-auth.test.ts:74:function makeEnv(overrides: Partial<TestEnv> = {}): TestEnv {
    packages/objectos-runtime/src/artifact-api-client.ts:162:    cacheTtlMs?: number;
    packages/objectos-runtime/src/artifact-api-client.ts:179:    private readonly cacheTtlMs: number;
    packages/objectos-runtime/src/artifact-api-client.ts:195:        this.cacheTtlMs = config.cacheTtlMs ?? 5 * 60 * 1000;
    packages/objectos-runtime/src/artifact-api-client.ts:236:                this.hostnameCache.set(host, { value, expiresAt: Date.now() + this.cacheTtlMs });
    packages/objectos-runtime/src/artifact-api-client.ts:276:                this.artifactCache.set(cacheKey, { value, expiresAt: Date.now() + this.cacheTtlMs });
    packages/objectos-runtime/src/artifact-environment-registry.test.ts:100:function makeRegistry(client: FakeClient, cacheTtlMs?: number) {
    packages/objectos-runtime/src/artifact-environment-registry.test.ts:104:        cacheTtlMs,
    packages/objectos-runtime/src/artifact-environment-registry.ts:61:    cacheTtlMs?: number;
    packages/objectos-runtime/src/artifact-environment-registry.ts:77:        this.cacheTTL = config.cacheTtlMs ?? 5 * 60 * 1000;
    packages/objectos-runtime/src/kernel-manager-build-timeout.test.ts:348:  function makeManager(overrides: Record<string, unknown> = {}) {
    packages/objectos-runtime/src/objectos-stack.ts:274:                    cacheTtlMs: this.config.artifactCacheTtlMs,
    packages/objectos-runtime/src/objectos-stack.ts:281:            cacheTtlMs: this.config.envCacheTtlMs,
    packages/security-enterprise/src/ai-governance/tool-interceptor.ts:156:  patterns: readonly RegExp[],
    packages/security-enterprise/src/ai-governance/tool-interceptor.ts:191:function summarizeArgs(input: unknown, patterns: readonly RegExp[]): string {
    packages/security-enterprise/src/ai-governance/tool-interceptor.ts:207:  const patterns: readonly RegExp[] = [
    packages/service-ai-studio/src/__tests__/ask-agent.test.ts:16:function createMockMetadataService(overrides: Partial<IMetadataService> = {}): IMetadataService {
    packages/service-ai-studio/src/__tests__/metadata-tools.test.ts:40:  overrides: Partial<IMetadataService> = {},
    packages/service-ai/src/__tests__/agent-aliases.test.ts:36:function mockMetadata(overrides: Partial<IMetadataService> = {}): IMetadataService {
    packages/service-ai/src/__tests__/auth-and-toolcalling.test.ts:38:function makeUser(userId: string, overrides: Partial<RouteUserContext> = {}): RouteUserContext {
    packages/service-ai/src/__tests__/chatbot-features.test.ts:89:function createMockDataEngine(overrides: Partial<IDataEngine> = {}): IDataEngine {
    packages/service-ai/src/__tests__/chatbot-features.test.ts:103:function createMockMetadataService(overrides: Partial<IMetadataService> = {}): IMetadataService {
    packages/service-ai/src/__tests__/knowledge-tools.test.ts:12:function makeService(overrides: Partial<IKnowledgeService> = {}): {
    packages/service-ai/src/__tests__/skill-registry.test.ts:9:function createMockMetadataService(overrides: Partial<IMetadataService> = {}): IMetadataService {
    packages/service-ai/src/effective-model.ts:44:  overrides: Record<string, string | null>;
    packages/service-ai/src/effective-model.ts:93:  const overrides: Record<string, string | null> = {};
    packages/service-ai/src/plugin.ts:1325:        const overrides = extractOverrides(payload);
    packages/service-ai/src/plugin.ts:1374:        const overrides = extractOverrides(payload);
    packages/service-cloud/src/__tests__/cloud-artifact-helpers.requires-passthrough.test.ts:52:function hotcrmBundle(overrides: Record<string, unknown> = {}) {
    packages/service-cloud/src/environment-reaper.ts:401: * Env overrides:
    packages/service-cloud/src/idle-env-reaper.ts:276: * Env overrides: OS_IDLE_ENV_REAPER_DISABLED (kill switch), OS_IDLE_ENV_DAYS
    packages/service-cloud/src/r2-registry-reader.ts:81:    cacheTtlMs?: number;
    packages/service-cloud/src/r2-registry-reader.ts:109:        this.ttl = opts.cacheTtlMs ?? 30_000;
    packages/service-cloud/test/licensing-validate.test.ts:125:function mintOnlineToken(overrides: Partial<LicenseClaims> = {}, keyPem = PRIV_PEM): string {
    packages/service-cloud/test/plugin-artifact.test.ts:25:function validManifest(overrides: Record<string, unknown> = {}) {
    packages/service-cloud/test/r2-registry-roundtrip.test.ts:25:        const reader = new R2RegistryReader({ store, cacheTtlMs: 0 });
    packages/service-cloud/test/r2-registry-roundtrip.test.ts:110:        const reader = new R2RegistryReader({ store, dek, cacheTtlMs: 0 });
    packages/service-cloud/test/r2-registry-roundtrip.test.ts:155:            cacheTtlMs: 0,
    packages/service-cloud/test/r2-registry-roundtrip.test.ts:174:        const reader = new R2RegistryReader({ store, dek: readerDek, cacheTtlMs: 0 });
    packages/service-cloud/test/r2-registry-roundtrip.test.ts:207:        const reader = new R2RegistryReader({ store, /* no dek */ cacheTtlMs: 0 });
    packages/service-cloud/test/r2-registry-roundtrip.test.ts:237:        const reader = new R2RegistryReader({ store, cacheTtlMs: 0 });
    packages/service-cloud/test/sso-as-owner.test.ts:265:            overrides: { requiredKey: 'svc-key', getCallerUserId: async () => undefined },
    packages/service-cloud/test/sso-as-owner.test.ts:280:        const server = register(driver, { km, overrides: userMode });
    packages/service-cloud/test/sso-as-owner.test.ts:314:                overrides: { requiredKey: 'svc-key', getCallerUserId: async () => undefined },
    packages/service-cloud/test/sso-as-owner.test.ts:337:                overrides: { requiredKey: 'svc-key', getCallerUserId: async () => undefined },
    packages/service-cloud/test/sso-as-owner.test.ts:411:            overrides: { requiredKey: 'svc-key', getCallerUserId: async () => 'user-member', getCallerActiveOrgId: async () => 'org-1' },
    packages/service-cloud/test/sso-as-owner.test.ts:426:            overrides: { requiredKey: 'svc-key', getCallerUserId: async () => 'user-stranger', getCallerActiveOrgId: async () => 'org-1' },
    packages/service-cloud/test/sso-as-owner.test.ts:440:            overrides: { requiredKey: 'svc-key', getCallerUserId: async () => 'user-owner-member', getCallerActiveOrgId: async () => 'org-1' },
    packages/service-cloud/test/sso-as-owner.test.ts:564:                    const server = register(driver, { overrides: { requiredKey: 'svc-key', getCallerUserId: async () => undefined } });
    packages/service-tenant/src/app-catalog.service.test.ts:34:const basePayload = (overrides: Partial<AppCatalogEventPayload> = {}): AppCatalogEventPayload => ({
    packages/tenant-router/src/multi-tenant.ts:196:    const overrides = config.driverConfigOverrides ?? {};
    scripts/bump-objectstack.sh:91:    j.pnpm=j.pnpm||{}; j.pnpm.overrides=j.pnpm.overrides||{};
    

    Every one of those 64 lines is a homonym, not a RestServerConfig key. Attribution is in section 3.

    Command 2 — the population the keys would live in:

    $ git grep -n -E "RestServerConfig|\brest\s*:\s*\{|rest:\s*$|\"rest\"\s*:" -- . ':!**/node_modules/**' ':!**/dist/**'

    exit 1, 0 lines. No output. This is the load-bearing zero, and its controls are in section 2.

    Command 3 — the recipe's own zero-hit control:

    $ git grep -n -E "basePath|cors" -- . ':!**/node_modules/**' ':!**/dist/**' | head -20

    exit 0, 49 lines total; first 20 as the recipe asks:

    .changeset/mcp-oauth-discovery-documents.md:14:`AuthProxyPlugin` forwards the auth basePath alone, and the host kernel has no
    apps/cloud/server/index.ts:301:function corsEnabled(): boolean {
    apps/cloud/server/index.ts:305:function corsCredentials(): boolean {
    apps/cloud/server/index.ts:309:function corsMaxAge(): number {
    apps/cloud/server/index.ts:321:    const credentials = corsCredentials();
    apps/cloud/server/index.ts:349:    if (!corsEnabled()) return response;
    apps/cloud/server/index.ts:357:    if (corsCredentials()) {
    apps/cloud/server/index.ts:387:        'Access-Control-Max-Age': String(corsMaxAge()),
    apps/cloud/server/index.ts:390:    if (corsCredentials()) {
    apps/objectos-ee/test/hotcrm-multitenant.acceptance.ts:525: * customer's own console reads it — `GET {basePath}/approvals/requests`, the
    apps/objectos/server/index.ts:391:function corsEnabled(): boolean {
    apps/objectos/server/index.ts:395:function corsCredentials(): boolean {
    apps/objectos/server/index.ts:399:function corsMaxAge(): number {
    apps/objectos/server/index.ts:411:    const credentials = corsCredentials();
    apps/objectos/server/index.ts:439:    if (!corsEnabled()) return response;
    apps/objectos/server/index.ts:447:    if (corsCredentials()) {
    apps/objectos/server/index.ts:477:        'Access-Control-Max-Age': String(corsMaxAge()),
    apps/objectos/server/index.ts:480:    if (corsCredentials()) {
    packages/objectos-runtime/src/auth-service-resolution.ts:14: * `AUTH_PREFIX` lives here for the same reason: it is the auth **basePath**
    packages/objectos-runtime/src/auth-service-resolution.ts:15: * (which better-auth's `basePath` default, which `ArtifactKernelFactory` does not
    

    2. Positive controls for the zeros

    No zero is reported without a control that fired on the same tree.

    Control A — the grep reaches package.json files (so "no @objectstack/rest dependency" is a measurement, not a miss):

    $ git grep -n "@objectstack/rest" -- '**/package.json' ':!**/node_modules/**'
    exit=1 lines=0
    
    $ git grep -c "@objectstack/" -- '**/package.json' ':!**/node_modules/**'
    exit=0 files=20
    apps/cloud/package.json:25
    apps/ee-authz-showcase/package.json:10
    apps/ee-group-showcase/package.json:7
    apps/ee-tenant-crm-showcase/package.json:5
    apps/heartbeat/package.json:1
    apps/objectos-ee/package.json:22
    apps/objectos/package.json:32
    packages/app-cloud-admin/package.json:2

    20 package.json files carry between 1 and 32 @objectstack/* dependency lines each; none of them names @objectstack/rest.

    Control B — the grep reaches JSON/YAML/TOML runtime config:

    $ git grep -l -E "compatibility_date|main\s*=" -- '**/*.toml' ':!**/node_modules/**'
    exit=0 files=4
    apps/cloud/wrangler.dev.toml
    apps/cloud/wrangler.toml
    apps/heartbeat/wrangler.toml
    apps/objectos/wrangler.toml

    Control C — the config-file-restricted key sweep is reaching files (this is the control that pairs with the zero directly below it):

    $ git grep -n -E "includeObjects|excludeObjects|nameTransform|objectParamStyle|upsertMany|defaultAtomic|cacheTtl" -- '**/*.json' '**/*.yaml' '**/*.yml' '**/*.toml' ':!**/node_modules/**' ':!**/dist/**' ':!pnpm-lock.yaml'
    exit=1 lines=0
    
    $ git grep -c -E "compatibility_date|\"name\"\s*:" -- '**/*.json' '**/*.yaml' '**/*.yml' '**/*.toml' ':!**/node_modules/**' ':!**/dist/**' ':!pnpm-lock.yaml'
    exit=0 files=30
    .github/workflows/verify-objectos-ee-image.yml:2
    apps/cloud/package.json:1
    apps/cloud/wrangler.dev.toml:1
    apps/cloud/wrangler.toml:1
    apps/docs/package.json:1
    apps/docs/tsconfig.json:1
      (24 more files; trimmed for length — only the count line matters here)

    So: not one of the seven leaf spellings appears in any JSON / YAML / TOML file in the repo, while 30 such files answered the control on the same invocation shape.

    Control D — the decisive one. The live sibling keys are zero too, run with the identical invocation shape as the dead-key greps:

    includeObjects                           hits=0
    nameTransform                            hits=0
    objectParamStyle                         hits=0
    upsertMany                               hits=0
    defaultAtomic                            hits=0
    endpoints\s*[:=][^\n]*schema             hits=0
    \bschema\s*:\s*(true|false)              hits=0
    \bbatch\s*:\s*\{                         hits=0
    --- live siblings of the same four sub-objects, same invocation shape ---
    enableCache                              hits=0     <- LIVE key, also absent
    maxBatchSize                             hits=0     <- LIVE key, also absent
    --- patterns that must fire, same invocation shape ---
    \bmetadata\s*:\s*\{                      hits=113
    \bprefix\s*:                             hits=73
    \bbasePath\b                             hits=33
    

    enableCache and maxBatchSize are ledgered live in metadata_endpoints.json / batch_endpoints.json. They are absent from cloud for the same reason the 15 dead ones are: cloud does not author this config object at all. That is what makes the sweep's zero structural rather than evidential.

    3. Per-key answer table (all 15 ledgered-dead rows)

    Enumerated from the ledger at objectstack-ai/objectstack packages/spec/liveness/{route_generation,crud_endpoints,metadata_endpoints,batch_endpoints}.json — 15 rows with status: dead, evidenceScope: in-repo.

    # Key Hit in cloud? Attribution of any near-miss
    1 routes.includeObjects no hit —
    2 routes.excludeObjects no hit as this key 2 lines in .spec-changes-ack.json:214,217 are prose in a spec-change acknowledgement, and they are about a different key: the excludeObjects field of an engine.registerHook scope, not RestServerConfig.routes.excludeObjects. The quoted note itself reports git grep -n excludeObjects over packages/ apps/ returning ZERO. Not runtime config, not a fixture, not a test — a JSON-encoded prose record.
    3 routes.nameTransform no hit —
    4 routes.overrides.enabled no hit —
    5 routes.overrides.basePath no hit as this key basePath alone fires 33 times, all of them the better-auth basePath / an auth URL prefix in prose, plus one changeset. None sits inside a routes or rest object; there is no routes: config object in the repo to sit inside.
    6 routes.overrides.operations no hit —
    7 crud.patterns.method no hit The patterns\s*[:=] arm fires 3 times, all in packages/security-enterprise/src/ai-governance/tool-interceptor.ts:156,191,207 as patterns: readonly RegExp[] — a runtime source local variable/param for redaction regexes, unrelated to CRUD route patterns.
    8 crud.patterns.path no hit same 3 homonyms as row 7
    9 crud.patterns.summary no hit same 3 homonyms as row 7
    10 crud.patterns.description no hit same 3 homonyms as row 7
    11 crud.objectParamStyle no hit —
    12 metadata.cacheTtl no hit as this key cacheTtl as a bare word fires 7 times, all Cloudflare platform options, not ObjectStack config: cf: { cacheTtl: 0, cacheEverything: false } (apps/heartbeat/src/index.ts:194, runtime source), env.STATE.get(SNAPSHOT_KEY, { cacheTtl: ... }) (:259, runtime source, Workers KV), 2 prose comments (:529, apps/heartbeat/test/test-endpoint-auth.test.ts:38), 1 test comment (apps/heartbeat/test/snapshot-route.test.ts:10), 1 doc (apps/heartbeat/README.md:183), 1 changeset. Separately, cacheTtlMs — a distinct identifier, not this key — fires 15 times across objectos-runtime and service-cloud (artifact/registry client TTLs; runtime source + tests).
    13 metadata.endpoints.schema no hit Both arms of the recipe that target it (endpoints\s*[:=][^\n]*schema and `\bschema\s*:\s*(true
    14 batch.operations.upsertMany no hit —
    15 batch.defaultAtomic no hit —

    The overrides\s*[:=] arm of command 1 fires 33 times across 23 files. Attribution, exhaustively: 17 are the test-helper parameter idiom overrides: Partial<X> = {} / overrides: Record<string, unknown> = {} (tests); 9 are the register(driver, { overrides: ... }) test seam in packages/service-cloud/test/sso-as-owner.test.ts; 2 are AI model overrides (packages/service-ai/src/effective-model.ts, plugin.ts — runtime source); 1 is config.driverConfigOverrides (packages/tenant-router/src/multi-tenant.ts — runtime source); 3 are prose comments about environment-variable overrides (apps/cloud/scripts/migrate.ts:38, environment-reaper.ts:401, idle-env-reaper.ts:276); 1 is j.pnpm.overrides in scripts/bump-objectstack.sh (a pnpm workspace override, tooling). None is RestServerConfig.routes.overrides.

    4. Verdict for #14691

    No key changes from "remove" to "enforce-or-keep" on cloud evidence. All 15 are absent, and the absence is not a grep artifact: the whole RestServerConfig construction argument is absent from objectstack-ai/cloud, evidenced three ways on the same tree — no @objectstack/rest in any of the 20 package.json files that carry @objectstack/* deps; zero hits for RestServerConfig / any rest: object; and the live sibling keys enableCache and maxBatchSize equally at zero while metadata: (113), prefix: (73) and basePath (33) fire on the same invocation shape.

    Suggested ledger consequence: the four families' evidenceScope may widen from in-repo to in-repo + cloud@9b6abe0f2fd5 for all 32 rows (15 dead + 17 live), since the cloud sweep is now run rather than merely unreachable. That widening is #14691's call, not this reading's.

    The stop-the-line precondition from triage 5516726250 is satisfied: the closed-set cloud sweep exists, with its zeros controlled.

    5. Bounds of this reading — what I did NOT measure

    • One ref only. cloud@9b6abe0f2fd5 (today's origin/main). No history sweep: a key set in a since-reverted commit would not appear. If Enforce-or-remove the 15 RestServerConfig rows the liveness ledger now records as dead (#14369's verdicts) — routes.*, crud.patterns, crud.objectParamStyle, metadata.cacheTtl, metadata.endpoints.schema, batch.defaultAtomic, batch.operations.upsertMany #14691 wants "was it ever set", that is a git log -S reading and a different card.
    • Source tree only. node_modules, dist, *.lock and pnpm-lock.yaml were excluded per the recipe. A key appearing only inside a vendored build artifact was not searched for.
    • Static text only. A key supplied at runtime from an environment variable, a Cloudflare secret, a KV/D1/R2 value, or a control-plane database row would be invisible to a grep of the repo. I found no code path in cloud that would accept such a value into a REST server config, but I did not exhaustively trace every kernel construction site to prove that; the @objectstack/rest dependency zero is the proxy for it.
    • Homonym-free spellings only. I searched the leaf key names. A cloud file that builds the config through spread/rename (e.g. a variable named cfg assigned from a helper that spells the keys elsewhere) would evade the leaf grep. Given the dependency zero, there is nothing for such a helper to feed.
    • This repo only. Other closed deployments (customer forks, internal infra repos) are outside objectstack-ai/cloud and outside this seat's reach.
    • No behaviour was executed. No install, no build, no test run. This is a text measurement, not a runtime observation.

    Byte note (applies to every fenced block above). GitHub's comment sanitizer is measured to eat a comment
    from its first tag-shaped angle fragment to the end of the body. To keep this reading intact, every literal
    less-than character in the quoted output was written as the HTML entity <
    — 22 substitutions, mechanical,
    nothing else was altered. Read < as a less-than sign wherever it appears in a quoted line (e.g.
    Partial<TestEnv> is Partial followed by less-than, TestEnv, greater-than). Greater-than signs are
    untouched. Paths, line numbers, key names and hit counts are byte-exact.


    Generated by Claude Code

  6. claude commented on Sep 3, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 14796,
      "status": "done",
      "branch": null,
      "pr": null,
      "premise_still_valid": true,
      "summary": "Read-only reading batch B: five cross-repo reading requests answered against objectstack-ai/cloud at ref 9b6abe0f2fd58e39f1f5ca329940f5cf5d75f50d (detached read-only worktree of origin/main). No code, no PR, no branch, no edits, no installs, no builds; no labels/assignees/state touched. objectstack-ai/objectstack#14796 (chain head) — ZERO for all 15 ledgered-dead RestServerConfig keys, and the zero is structural: cloud never authors a RestServerConfig at all (no @objectstack/rest in any of the 20 package.json files carrying @objectstack/* deps; 0 hits for RestServerConfig or any rest: block; the LIVE sibling keys enableCache/maxBatchSize are equally 0 while metadata: fires 113, prefix: 73, basePath 33). objectstack-ai/objectstack#14691's per-key verdicts stand; evidenceScope may widen to in-repo + cloud@9b6abe0f2fd5. Reading: https://github.com/objectstack-ai/objectstack/issues/14796#issuecomment-5520424980 . objectstack-ai/objectstack#14225 — NO proj_local comparison exists in cloud; census recommendation (a) NOT overturned. 14 proj_local hits / 0 env_local (control: environmentId 1717 lines over 177 files), attributed as 6 docs, 1 producer, 6 tests bound to cloud's OWN producer, 1 docblock. The sole production consumer (kernel-resolver.ts:259-266) reads def.environmentId opaquely into envRegistry.resolveById — no literal comparison, rename-neutral by construction. Secondary: cloud carries its own independent 'proj_local' default (file-artifact-api-client.ts:88), so the rename creates a spelling divergence, not a break; reported, not filed, per the card's stop. Reading: https://github.com/objectstack-ai/objectstack/issues/14225#issuecomment-5520468078 . objectstack-ai/objectstack#14187 — ZERO for all seven plugin-detail names, reported as seven separate rows with PointInTimeRestore kept distinct as the CONFIRMING reading (the other six are first downstream readings), per the filing seat's addendum. The prescribed control @object-ui/plugin-detail returns 0, and that is the FINDING not an instrument failure: cloud has no @object-ui/* dependency in any of its 19 package.json files and its only 6 .tsx files are the Fumadocs docs site; four other controls fired (RecordComments|DetailView 16, all prose comments; export default in .tsx 4; git grep RecordDetailView 19; lockfile @objectstack/ 210). cloud reaches objectui only through metadata type strings, so PointInTimeRestore is structurally unreachable there as in hotcrm. objectui relay left to that lane's unlock scan (no objectui write access). Reading: https://github.com/objectstack-ai/objectstack/issues/14187#issuecomment-5520511098 . objectstack-ai/objectstack#12279 — ZERO hits; card closes with the greps named and NO follow-up card filed. But the card's predicted route was wrong and step 2 was genuinely needed: unlike objectui, cloud DOES import @objectstack/plugin-sharing (2 package.json deps, 2 runtime import() sites). Both sites pass new SharingServicePlugin({ enforce: false, registerShareLinkRoutes: false }) with no logger at all; all four ruled sink symbols are absent (0 hits each, control SharingService 24); and SharingPluginOptions declares no logger member, so the sinks are unreachable from a plugin construction. The ruling's literal sweep found 28 warn-less logger literals (1 of them exactly { info, error }), all in tests and all to cloud-owned or out-of-scope sinks. Reading: https://github.com/objectstack-ai/objectstack/issues/12279#issuecomment-5520551493 . objectstack-ai/objectstack#12931 — the THIRD ZERO: all three prescribed greps return 0, so the meta is dead surface across objectui, objectstack and cloud, and the outcome is retirement rather than gate extension. No consuming function exists to paste; the five nearest-neighbour .icon sites (all pass-through relays, none a resolver) are pasted verbatim instead. Structural reason: cloud has no component-registration surface (ComponentRegistry / componentRegistry / registerComponent / .register( all 0). Bonus census, with its limits stated: all 65 distinct icon names cloud authors are kebab-case, zero PascalCase. objectui#5936 relay left to that lane's unlock scan (no objectui write access). Reading: https://github.com/objectstack-ai/objectstack/issues/12931#issuecomment-5520591615 . Channel note: all reads and all five comment writes went through authenticated REST in-container; zero MCP GitHub calls. Every posted comment was read back in full via raw REST and byte-compared against what was sent — all five identical modulo GitHub's trailing-newline shuffle.",
      "tests": "No tests were run and none were owed: this was a READ-ONLY reading batch — no code, no PR, no branch, no edits, no installs, no builds, and no build/test gate applies to a zero-file-surface run. Ref for every reading: objectstack-ai/cloud @ 9b6abe0f2fd58e39f1f5ca329940f5cf5d75f50d (git rev-parse --short=12 HEAD = 9b6abe0f2fd5), a detached read-only worktree at /home/user/cloud-readings-b created with `git -C /home/user/cloud worktree add --detach ... origin/main`. Evidence the tree was never mutated: `git status --porcelain` in the worktree printed NOTHING both before the first grep and after the last one, and `git rev-parse HEAD` returned the same SHA at both points. No node_modules directory was ever created in the worktree (verified: `ls -d node_modules` -> No such file or directory), which is also why every `grep -r` in these readings covered checked-out source only — stated as a bound on each card. The framework sibling /home/user/objectstack was read only (its HEAD was never switched); it supplied the objectstack-ai/objectstack#14796 ledger enumeration and the objectstack-ai/objectstack#12279 producer-contract quotes, both declared on their cards as supporting context taken at 2d40f9146800, not as the readings' authoritative ref. Instrument discipline actually applied, per card: every zero is quoted beside a positive control that fired on the same tree in the same command shape (#14796: 4 controls, incl. the decisive one that the LIVE sibling keys are also zero; objectstack-ai/objectstack#14225: environmentId 1717 lines / 177 files; objectstack-ai/objectstack#14187: 4 controls after the prescribed @object-ui/plugin-detail control itself came back 0, which is reported as the finding with its own three independent corroborations; objectstack-ai/objectstack#12279: the filter chain's inverse fires at 53 with-warn literals, plus SharingService 24 against the four absent sink symbols; objectstack-ai/objectstack#12931: 5 controls, 4 firing hard — getMeta 276, registration 261, icon 387 across 85 files, whole-tree icon 412). No pattern anywhere required a trailing delimiter after a symbol name. Exit codes were captured before any pipe throughout. Delivery verification: each of the five comments was re-fetched by id via raw REST after posting and byte-compared against the file that was sent — 23291/23291, 14999/14999, 14811/14811, 12253/12253, 12252/12252, all identical modulo GitHub's trailing-newline shuffle, so no sanitizer truncation occurred (the objectstack-ai/objectstack#14796 body needed 22 less-than characters written as the HTML entity to survive; that substitution is declared inside the comment itself).",
      "mcp_calls": "0 — every GitHub read and write in this run went through authenticated REST in-container; no MCP GitHub tool was called",
      "open_questions": [],
      "out_of_scope_findings": [
        "NOT filed as a card, deliberately, and reported on objectstack-ai/objectstack#14225 instead because that card's stop says the follow-up is decided on objectstack-ai/objectstack#13366 and not there: cloud carries its OWN independent 'proj_local' default at packages/objectos-runtime/src/file-artifact-api-client.ts:88, separate from open core's standalone stamp (objectstack packages/runtime/src/standalone-stack.ts:567). Renaming open core's stamp to env_local therefore creates a spelling DIVERGENCE between cloud's file-backed objectos mode and open core's standalone mode, not a break. Whether cloud's file mode should follow the rename is a non-blocking cloud-side decision for objectstack-ai/objectstack#13366's ruler.",
        "NOT filed, reported on objectstack-ai/objectstack#14225 as a discrepancy noticed while attributing: apps/objectos/README.md:55 and apps/objectos/test/single-environment-crm-bundle.test.ts:16,48 attribute objectos's bare-URL routing to createSingleEnvironmentPlugin, but createObjectOSStack's plugin list does not mount it and cloud never defines it. Prose/comment staleness only; it makes the objectstack-ai/objectstack#14225 verdict stronger rather than weaker, and this batch is read-only.",
        "NOT filed, reported on objectstack-ai/objectstack#14225 as a bound: packages/objectos-runtime/src/kernel-resolver.ts:259 DOES compare a literal — the service key 'default-project' — inside a try/catch that swallows a miss. That is not the standalone stamp objectstack-ai/objectstack#13366 renames, but it is the same class of cross-repo coupling and would fail silently if open core ever renamed the service key. Not measured here; noted for whoever rules objectstack-ai/objectstack#13366.",
        "No consumer-side follow-up card was filed in objectstack-ai/cloud for objectstack-ai/objectstack#12279, because the sweep returned ZERO hits — the card's own rule is that zero hits closes it with the greps named. No duplicate search was therefore needed or run."
      ]
    }

    Generated by Claude Code

  7. baozhoutao commented on Sep 3, 2026

    @baozhoutao
    Contributor

    Reviewed and closed — completed (repo:cloud seat, session session_017Wu48ZSjk7HJjyJmGNBtUk, R35). Verified against the card's bar: ref 9b6abe0f quoted; the three prescribed greps run as given; zero for all 15 ledgered-dead RestServerConfig keys, and the zero is structural — cloud never authors a RestServerConfig (no @objectstack/rest in any of its 20 package.json files carrying @objectstack/* deps; 0 hits for RestServerConfig or any rest: block), with the decisive control that the LIVE sibling keys enableCache / maxBatchSize are equally zero while metadata: fires 113, prefix: 73 and basePath 33 on the same tree. ⇒ #14691's per-key verdicts stand; its evidenceScope may widen to in-repo + cloud@9b6abe0f2fd5, which is the spec seat's write (the Blocked-by: on #14691 points here and releases on this close). pm:dispatched stripped, assignee released.

    Batch note for the four sibling readings closed in the same stroke: #14225 (no proj_local comparison; recommendation (a) not overturned; secondary observations left on that card per its stop), #14187 (zero for all seven plugin-detail names as separate rows; cloud has no @object-ui/* dependency, so the prescribed control's zero is the finding, corroborated by four other controls), #12279 (zero warn-less loggers reaching the ruled sinks — and the card's predicted route was wrong: cloud does import plugin-sharing, at two runtime sites passing no logger at all, so step 2 was needed and done), #12931 (third zero ⇒ the icon meta is dead surface everywhere; retirement, not gate extension, per the card's own framing).


    Generated by Claude Code

  8. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Sep 3, 2026
  9. huangyiirene commented on Sep 3, 2026

    @huangyiirene
    Collaborator

    Triage — sweep repair, owed since R+112 and now discharged. Restored pm:queue, added priority:p2; repo:cloud kept.

    ⚠️ pm:queue had gone missing. At R+112 this card carried pm:queue + repo:cloud; today it carried only repo:cloud. I have restored it rather than treating the bare state as intentional — a cross-repo request with no pm-state is invisible to every sweep, which is how it sat for two rounds.

    ⭐ Why this kept coming back, and the rule that settles it

    I owed this repair for two rounds and each time it looked malformed under sweep ② ("pm:queue without domain:*"). It is not malformed. A cross-repo reading request has no domain:* — deliberately.

    The anchoring rule sets domain:* from where the fix lands, and nothing lands in this repo: the card asks the repo:cloud seat a closed-set question and its output is an answer, not a diff here. Assigning a lane would be guessing at a file that does not exist, which is exactly what the anchoring rule forbids. ⇒ repo:* is the routing field for this shape, and it is already correct.

    ⛔ Future sweeps: do not flag a repo:* card for a missing domain:*. The two are alternative routing fields, not a pair. Same reasoning applies to #14837 and objectstack-ai/objectui#10437 (repo:objectui), repaired this round on the same basis.

    p2

    It is a precondition, not a standalone: #14691 (pm:blocking, p2 — enforce-or-remove the 15 ledgered-dead RestServerConfig keys) cannot proceed without knowing whether any cloud config, fixture, doc or test sets them. ⇒ It inherits the priority of the card it gates. ⛔ Not p3: a precondition graded below the work it blocks is a precondition nobody reaches.

    ⚠️ For the answering seat: the value of this card is that the question is closed-set — seven named keys, one repo, yes or no per key. ⛔ A partial answer ("checked the configs, not the fixtures") is not an answer, because #14691's verdicts turn on the absence being complete. If any surface cannot be swept, say which and why rather than reporting a clean zero over it — the zero-with-a-control discipline, applied across repos.


    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

    pm:queueReady for the PM dispatch looppriority:p2Medium: important, M3repo:cloudCard routed whole to the cloud PM: needs cloud code, a producer or a fact (cloud owns it to closure)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions