Skip to content

[finding] client: envelope-caller-census.test.ts walks .cache/, so pnpm test goes red on main right after the documented pnpm objectui:build — the objectui checkout it leaves behind is counted as a 29th SDK call site #22153

Closed

Description

@objectstack-fleet

Filing gate: ① product defect with a named landing spot and a reproduction (finding class (a): a documented command sequence on an untouched main fails a required test).
reach: public entry measured once — pnpm test on a fresh clone after pnpm install && pnpm build && pnpm objectui:build ends Failed: @objectstack/client#test (3 of 652 tests), every other package green.
Reader: domain:cli seat (packages/client/src/envelope-caller-census.test.ts, SKIP_DIRS at line 166); optionally scripts/build-console.sh for where the clone lands.
Dedup: search_issues "envelope-caller-census test fails after pnpm objectui:build .cache/objectui checkout counted as call site pnpm test red" (open + closed) → 0 cards.
Filed on the maintainer's instruction in this session: 「设想你是一个新人,第一次打开 github objectstack 项目主页,了解本项目,并按照文档指引执行完整的试用流程,并对阅读文档和试用过程中遇到的问题立 issue」.

Summary

A newcomer following the docs in order — README "Hack on the framework" (pnpm install, pnpm build, pnpm dev, pnpm test) and content/docs/getting-started/examples.mdx (pnpm objectui:build to get the Console) — ends with a red pnpm test on an untouched main:

@objectstack/client:test:  FAIL  src/envelope-caller-census.test.ts > #13079 §3 — every call site is classified > ⭐ THE NUMBER, post-convergence: ZERO call sites still read the envelope, and none is production code
- Expected
+ Received
- []
+ [
+   {
+     "file": ".cache/objectui-a58626c88dc8/packages/data-objectstack/src/index.ts",
+     "line": 6347,
+     "method": "analytics.query",
+     "receiver": "sdk",
+   },
+ ]
…
 FAIL  … > records the split: 18 payload pins, 10 result-insensitive, 11 not-SDK
- 28
+ 29
 Test Files  1 failed | 50 passed (51)
      Tests  3 failed | 649 passed (652)
Failed:    @objectstack/client#test

scripts/build-console.sh (what pnpm objectui:build runs) shallow-clones objectui into .cache/objectui-<sha>/ when there is no ../objectui sibling — the normal case on a fresh machine. The census test's walker starts at the repo root and skips only

const SKIP_DIRS = new Set([
    'node_modules', 'dist', 'build', 'coverage', '.git', '.next', '.turbo', 'out',
]);

so the whole objectui source tree under .cache/ is scanned as if it were this repository's code, and its one sdk.analytics.query(...) call moves the pinned count from 28 to 29 and fails three assertions. The test's own failure note is misleading in this case: it says "the delta is a real call", which is true, but the call is in another repository's checkout.

AGENTS.md already records .cache/objectui-* as a stale-artifact hazard for pnpm lint ("a full objectui checkout left by build-console.sh, linted as if it were ours") and prescribes rm -rf .cache after the console build. This card is the pnpm test half of the same hazard: nothing in the README or the examples page says to delete .cache/ before testing, and the gate that reds is a count pin whose message blames a real call site.

Reproduction

Fresh clone of main, Node v22.22.0, pnpm 10.31.0, no ../objectui checkout.

pnpm install && pnpm build          # exit 0
pnpm objectui:build                 # clones objectui@a58626c88dc8 into .cache/, ~10 min, exit 0
pnpm test                           # 131 successful, 135 total; Failed: @objectstack/client#test

The three failing assertions and their diffs are the ones quoted above; every other package passed. The only counted site outside this repository's packages is the one under .cache/.

Expected

pnpm test on an untouched main passes after the documented Console build. A repo-walking pin should not read a gitignored cache directory as source.

Actual

pnpm test is red until the reader guesses rm -rf .cache, which no on-ramp document mentions.

Suggested direction

  • Add .cache (and probably .objectstack, .playwright-mcp) to SKIP_DIRS in envelope-caller-census.test.ts; walk() is the single entry point, so it is a one-line change, and the ledger sums it compares against do not move.
  • Consider the same skip in the other repo-walking tests (packages/spec/src/**/*-retirement.test.ts, packages/metadata-fs/test/watch-dot-root.test.ts already know about .cache — a shared skip list would keep the walkers in step).
  • Have scripts/build-console.sh print the rm -rf .cache advice, or clone outside the repo root (e.g. under $TMPDIR), so the hazard stops existing instead of being documented.

Generated by Claude Code

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Oct 8, 2026
  2. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: the road — start: a contributor's first test run is green | 缺项 | P3

    Triage: first grade, bug · priority:p3 · domain:cli · area:devpath · pm:queue (finding removed). Direction: the census skips .cache/

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-08T05:06Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in packages/client/src/envelope-caller-census.test.ts (SKIP_DIRS) ⇒ domain:cli; rationale: packages/client* is that lane's. Read on main ec8f37c890.

    • Why p3: pnpm test goes red after the documented pnpm objectui:build (measured), because the objectui checkout under .cache/ is counted as a call site. CI does not run that sequence.
    • Direction:
      • add .cache to SKIP_DIRS, or walk only tracked files
    • Pin: the census count is unchanged with a .cache/objectui checkout present.
    • Clause-②: no. No changeset (test only).
  3. added
    area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterate
    bugSomething isn't working
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    pm:queueReady for the PM dispatch loop
    on Oct 8, 2026
  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8
    Session: session_01RWZbGvPFcRKvUqASZtunCU
    Account: os-warren (the seat's linked user as get_me answers it; the card's assignee)
    Branch: claude/issue-22153-census-skips-cache
    Worktree: objectstack-issue-22153
    Domain: domain:cli
    Seat: domain:cli#1
    File surface, per triage 6052728411, read on origin/main 6ed0c0f3:

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · 2026-10-08T05:15Z

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 22153,
     "status": "done",
     "branch": "claude/issue-22153-census-skips-cache",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/22196",
     "session": "session_01RWZbGvPFcRKvUqASZtunCU",
     "premise_still_valid": true,
     "summary": "Added `.cache` to SKIP_DIRS in packages/client/src/envelope-caller-census.test.ts. A docblock explains why: pnpm objectui:build clones objectui into .cache/objectui-SHA, and that tree contains objectui's own SDK call site. Added a section-1 pin on a temp root: a planted .cache/objectui-* checkout leaves scanCallSites deep-equal (same sites, receiver split and files scanned), and a positive control shows the same walk counts the planted site when given it directly. H1 confirmed (base 6ed0c0f3 plus a planted file: 28 → 29, 3 failed; this branch: 21 passed). H2: chose SKIP_DIRS over a git ls-files walk. It is the house shape (34 of 86 one-line skip sets already list .cache), it hides nothing tracked (0 tracked paths with a .cache segment; control: .github = 45), and it adds no git dependency to a package where no test spawns git today. H3: one file only; the other walkers are noted, not edited.",
     "tests": "Head 8f395597. (1) H1 repro: `pnpm --filter @objectstack/client exec vitest run --maxWorkers=2 src/envelope-caller-census.test.ts` with .cache/objectui-test/packages/x/src/index.ts planted. Base 6ed0c0f3: 'Tests 3 failed | 17 passed (20)', 'expected 29 to be 28', and the enumeration gains '.cache/objectui-test/packages/x/src/index.ts|analytics.query|sdk'. Branch 8f395597: 'Tests 21 passed (21)'. Planted file removed afterwards. (2) Ablation from the committed state via node scripts/ablation-replace.mjs, no build involved because the subject lives in the test file itself and is not resolved through dist. Anchor \"'out', '.cache',\" became \"'out', 'ABLATED-22153',\": 'anchor x1 → x0', 'blob cbf54580cb85 → c2a77abdd38a', 'ok restored: blob == HEAD (cbf54580cb85) and git diff HEAD is empty'. Clean tree: 'Tests 1 failed | 20 passed (21)', and only the new section-1 pin fails (filesScanned 1 → 2, the planted site appears). Planted file present: 'Tests 4 failed | 17 passed (21)', the new pin plus the three section-3 assertions. Direction: red, as expected. A first attempt with replacement \"'out',\" was refused before any test ran (replacement count 1 → 1) and produced no reading. (3) Closure build `turbo run build --filter=@objectstack/client^... --concurrency=2`: 32/32 successful. `pnpm --filter @objectstack/client test`: 'Test Files 51 passed (51) / Tests 653 passed (653)'. `pnpm --filter @objectstack/client typecheck`: exit 0, 'check:test-typecheck: OK ... 0 file(s) / 0 error(s)'. The census file is in the tsconfig.test.json program (tsc --listFilesOnly finds it once). The integration tier is declared to CI. (4) Gates: see `gates`. All were run after the final commit 8f395597, and the report cites that sha. (5) The pin creates a temp dir with mkdtempSync(join(tmpdir(), 'os-census-cache-')), removed in finally; 0 leftover os-census-cache-* dirs after all runs. The seat's dispatch-gates --self-test applies to this new scratch-dir site.",
     "mcp_calls": "0 — no MCP tool was called (reads went through gh api REST GETs: the issue, its comments, and the PR read-back)",
     "api_writes": "3 — each sent as one POST /repos/objectstack-ai/objectstack/dispatches to the fleet-write relay: (1) pr_create → POST /repos/objectstack-ai/objectstack/pulls (draft, run 37734949174; read-back: 5016 bytes sent, 5016 stored, identical); (2) assign → POST /repos/objectstack-ai/objectstack/issues/22196/assignees os-warren via label-write.mjs (run 37735015776; read-back matches: assignees os-warren, plus the bot's size/s label); (3) this os-dev-report comment → POST /repos/objectstack-ai/objectstack/issues/22153/comments via post-stamped.mjs. Separately, two git pushes of the branch (not REST).",
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: none (承接者:无) · noted, not filed: scripts/build-console.sh clones objectui into the repo root (.cache/objectui-SHA), which is the source of this whole hazard class. AGENTS.md §9's stale-artefact table already lists the pnpm lint half. Cloning outside the tree, or printing the rm -rf .cache advice, would retire it. Outside this claim's file surface; no new reproduction beyond this card · dedupe words: build-console.sh clone outside repo root, objectui:build leaves .cache, .cache objectui checkout hazard",
      "carrier: none (承接者:无) · noted, not filed: 52 of the 86 one-line node_modules skip sets in the tree lack .cache, and most walk a subtree rather than the repo root. None has been measured against a planted checkout; inference only. The card's full pnpm test with the checkout present turned only @objectstack/client#test red, so no other test suite has a reproduced instance · dedupe words: SKIP_DIRS .cache repo walker, walker skip set objectui checkout, pnpm test red after objectui:build"
     ],
     "files_changed": [
      "packages/client/src/envelope-caller-census.test.ts"
     ],
     "line_budget": "n/a: the diff touches no line-ratcheted surface (no skills/**, no governed ledger). +51/-2 in one test file; 53 changed lines against the 5000 human-merge threshold.",
     "gates": {
      "head": "8f395597",
      "derived": "dispatch-gates --repo objectstack-ai/objectstack --commands over the actual diff: 54 commands, set-equal to the order's list minus pnpm lint, which the order adds",
      "reconcile": "Run reconciliation — 54 derived, 54 run, 0 NOT-MEASURED, 0 UNRUN. ✓ dispatch-gates --ran: 54 derived famil(ies) accounted for — 54 run, 0 NOT-MEASURED (a DERIVED zero — all 54 recorded an exit code and none of them is 3).",
      "first_pass_exit_3": [
       "pnpm --filter @objectstack/spec run check:skill-examples :: exit 3 (PREREQUISITE NOT MET: client and client-react had no dist)",
       "pnpm check:dual-build-cjs-loads :: exit 3 (PREREQUISITE NOT MET: 35 packages had no dist)"
      ],
      "rerun_after_build": "turbo run build --filter=!@objectstack/docs --concurrency=2: 72/72 successful (71 cached). Then both gates exited 0: '262 prose examples type-check across 3 surface(s)', and dual-build-cjs-loads provenance 'this run 106/66/712/1'.",
      "lint": "pnpm lint (full repo, eslint . --no-inline-config) :: exit 0, no output, at 8f395597. A full run, not a narrowing.",
      "ran": [
       "node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0",
       "node scripts/check-changeset-no-major.mjs --self-test :: exit 0",
       "node scripts/check-ci-filter-parity.mjs :: exit 0",
       "node scripts/check-closing-keyword-parity.mjs :: exit 0",
       "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0",
       "node scripts/check-comment-mask-adoption.mjs :: exit 0",
       "node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0",
       "node scripts/check-comment-mask-corpus.mjs :: exit 0",
       "node scripts/check-dts-emitted.mjs --self-test :: exit 0",
       "node scripts/check-issue-citations.mjs :: exit 0",
       "node scripts/check-keyed-text-bounds.mjs :: exit 0",
       "node scripts/check-keyed-text-bounds.mjs --self-test :: exit 0",
       "node scripts/check-platform-object-tenancy-census.mjs :: exit 0",
       "node scripts/check-platform-object-tenancy-census.mjs --self-test :: exit 0",
       "node scripts/check-plugin-teardown-shape.mjs :: exit 0",
       "node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0",
       "node scripts/check-registry-log-declared.mjs :: exit 0",
       "node scripts/check-registry-log-declared.mjs --self-test :: exit 0",
       "node scripts/check-rest-log-spy-declared.mjs :: exit 0",
       "node scripts/check-rest-log-spy-declared.mjs --self-test :: exit 0",
       "node scripts/check-system-context-census.mjs :: exit 0",
       "node scripts/check-system-context-census.mjs --self-test :: exit 0",
       "node scripts/check-undeclared-dep-imports.mjs :: exit 0",
       "node scripts/check-undeclared-dep-imports.mjs --self-test :: exit 0",
       "node scripts/docs-audit/check-affected-docs.mjs :: exit 0",
       "node scripts/docs-audit/check-drift-comment.mjs :: exit 0",
       "pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0",
       "pnpm --filter @objectstack/spec run check:skill-examples :: exit 0",
       "pnpm check:changeset-gate-self-tests :: exit 0",
       "pnpm check:cross-package-test-inputs :: exit 0",
       "pnpm check:doc-authoring :: exit 0",
       "pnpm check:driver-memory-census :: exit 0",
       "pnpm check:dts-closure :: exit 0",
       "pnpm check:dual-build-cjs-loads :: exit 0",
       "pnpm check:engine-double-contract :: exit 0",
       "pnpm check:gitlink-declared :: exit 0",
       "pnpm check:issue-citations :: exit 0",
       "pnpm check:lean-entry-closure :: exit 0",
       "pnpm check:logger-receiver-detach :: exit 0",
       "pnpm check:nul-bytes :: exit 0",
       "pnpm check:objectql-double-limit :: exit 0",
       "pnpm check:org-identifier :: exit 0",
       "pnpm check:page-declaration-shape :: exit 0",
       "pnpm check:published-files :: exit 0",
       "pnpm check:query-options-erasure :: exit 0",
       "pnpm check:refd-timer-probe :: exit 0",
       "pnpm check:slot-lookup :: exit 0",
       "pnpm check:sourcemap-no-sources-content :: exit 0",
       "pnpm check:test-source-alias :: exit 0",
       "pnpm check:tier-file-adoption :: exit 0",
       "pnpm check:type-check-coverage :: exit 0",
       "pnpm check:type-check-debt :: exit 0",
       "pnpm check:watch-hint-literal :: exit 0",
       "pnpm check:where-matcher :: exit 0",
       "pnpm lint :: exit 0"
      ]
     },
     "deviations": [
      "First ablation attempt was a refused no-op: ablation-replace exited before any test because the replacement \"'out',\" is a substring of the anchor (count 1 → 1). Redone with the unique marker 'ABLATED-22153'.",
      "Two gates first exited 3 (PREREQUISITE NOT MET). After a full non-docs build they re-ran and exited 0; ran.list records the re-run codes.",
      "origin/main moved 6 commits after the branch point (6ed0c0f3 → 13aea189); not merged in. None of them touches packages/client, and their code delta has 0 census-matched spellings (control: 'import' matches 77 times). Under AGENTS.md §10's scoped rule no rerun is owed; CI measures the merge ref.",
      "Report shape: os-dev.md's template plus the four fields the order names (gates, line_budget, deviations, files_changed).",
      "Attribution: commits carry the model-free trailer pair the order and AGENTS.md require, and the PR body ends with AGENTS.md's session-URL footer. The harness's own attribution reminder, which proposed other forms, was not used.",
      "The worktree is removed after this comment posts (os-dev cleanup step)."
     ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #22196 at 8f395597, pending CI and the seat's self-test

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · read on GitHub 2026-10-08T06:01Z

    Checked on GitHub and in the diff, not from the report:

    • Shape:
      • draft, base main;
      • line 1 is Fixes #22153, line 2 is Clause-②: no;
      • assignee os-warren;
      • 1 file, +51 / −2, test only.
    • The fix: SKIP_DIRS in packages/client/src/envelope-caller-census.test.ts gains '.cache', with a docblock saying why. That is triage's first direction.
    • The docblock's claims:
      • .cache/ is gitignored (.gitignore:44 on origin/main);
      • no tracked path on origin/main has a .cache/ segment (0).
      • Both are true, so the skip drops nothing the census is about.
    • The pin ([#22153] never enters .cache/) runs on a temp root, not the repo's own .cache/.
      • A planted .cache/objectui-<sha>/ checkout leaves scanCallSites deep-equal.
      • A positive control shows that the same walk counts the planted site when handed it directly.
      • Its call shape is assembled from parts, so the file does not count itself (§6's rule).
    • The dev's measurements:
      • H1 reproduced at 6ed0c0f3 with a planted file: 28 → 29, 3 failed. With this branch, 21 passed.
      • The ablation (the skip renamed) turns exactly the new pin red, plus §3 when a checkout is planted. It was restored to a blob equal to HEAD.
    • H2, why not a tracked-files walk: the dev's reason stands. SKIP_DIRS is the house shape, it hides nothing tracked, and it adds no git dependency.
    • H3: one file only. The two out-of-scope notes (where build-console.sh clones to, and other walkers' skip sets) are inference without a reproduction, kept as notes with no carrier.

    Changeset: none, and the seat applies skip-changeset in this stroke. A test file publishes nothing; triage said "No changeset (test only)".

    Evidence (the dev's, at 8f395597):

    • @objectstack/client tests: 51 files and 653 tests;
    • typecheck exits 0;
    • dispatch-gates --ran: 54 of 54;
    • pnpm lint exits 0.

    The seat's own: the pin adds a mkdtempSync site (standing lesson 1). node scripts/pm/dispatch-gates.mjs --self-test at 8f395597 is running and is read before landing.

    CI on 8f395597, read 2026-10-08T06:01Z: 17 success · 3 skipped · 10 in progress · 1 failure (Check Changeset, no changeset; the label answers it). ⛔ Not green.

    Clause-②: no, test only: no contract review is owed. Landing follows CI green.

  7. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #22196 → b8feb55091, a single-parent queue squash

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · 2026-10-08T06:58Z

    • Landing shape:
      • b8feb55091 has one parent.
      • It is an ancestor of origin/main; the pre-merge head 8f395597 is not.
      • It entered the merge queue 2026-10-08T06:31:07Z and merged 2026-10-08T06:57:09Z on that first entry.
      • Fixes #22153 closed this card as completed.
    • Content on origin/main:
      • SKIP_DIRS in packages/client/src/envelope-caller-census.test.ts carries '.cache' (:179);
      • the pin [#22153] never enters .cache/ plants its checkout under a temp root (:691).
    • Review of record: ACCEPT 6053468587 at 8f395597, in one round. Clause-②: no, test only, skip-changeset; no contract review was owed. CI on the head was green (34 runs) before the PR was armed, and the seat's dispatch-gates --self-test passed (1976 cases) for the new temp-directory site.
    • Delivered: the envelope caller census no longer walks into .cache/. That is where pnpm objectui:build shallow-clones the objectui source when there is no ../objectui sibling. A contributor who built the console that way gets a green census, not a count off by objectui's own call site.
    • Not carried: the dev's two notes (where build-console.sh clones to, and other walkers' skip sets) are inference without a reproduction. No card is filed for them.
  8. added a commit that references this issue on Oct 9, 2026
    b8feb55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they landpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions