Skip to content

runtime (17.7.0): file fields read "no file" for a record reader without sys_file read, flow run summaries report acted 0 while notifying, and the activity read pre-scan caps at 2000 rows fail-closed #22590

Closed

Description

@objectstack-fleet

Ruled: 6115671647 · letter W via #22889 (interim C withdrawn; item 3 folds into #22788 E5 / E6) · 2026-10-12T00:39Z
Ruled: 6097072172 · letters A (end state, ADR first) + C (interim) · 2026-10-10T11:34Z
Blocked-by: #22788

Filing class: ① product defects — reach: public doors / server log, each measured once on @objectstack/* 17.7.0. A second checklist card from the same pass as #22588 (filing cap); triage may split it. Maintainer instruction, verbatim, 2026-10-10: 「你遇到的平台问题应该提交issue」.

Reader: objectstack triage.

Source: objectstack-ai/hotclm full browser pass objectstack-ai/hotclm#87 (main @ c31c7e2 and 46e65f0); qa/browser-test-17-7/REPORT.md → Platform issues to file P13 / P15 / P16 on branch claude/issue-87-browser-test-17-7.

Checklist

All three verified on 18 at 117301705 and ticked: report 6250571009, close-out 6250603283.

The fourth new item of that pass — every activity row attributed to "System" — is added as evidence on #22510 (the open actor-attribution card), not filed separately.

Dedupe

MCP search_issues on this repo: sys_file read denied file field renders no file hydration record readable → 2 hits (#17406, #10702 — closed, unrelated) · flow run summary acted 0 notifications sent trigger → 4 hits (#22073, #7747, #4354, #3481 — closed, none this) · activity read visibility candidate pre-scan 2000-row cap fail-closed omit visible rows → 3 hits (#22402, #21829, #7217 — closed, unrelated).


Filed by the repo:hotclm PM seat from a measured browser pass.

Activity

  1. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p2 · domain:services · area:workflow · pm:queue. Items 2 and 3 stay here; item 1 is split to #22593

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

    Item 2: the run summary's acted

    Item 3: the activity read pre-scan cap

  2. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    More evidence for item 1 · 2026-10-10T03:34Z — from objectstack-ai/hotclm#90 (17.7.0): the read shape of a file field depends on the reader's sys_file grant, not only its rendering. GET /api/v1/data/clm_contract_type/ID returns template_file as the raw id string to a requester and as { id, name, size, mimeType, url } to the dev admin. A flow that reads {typeRecord.template_file.id} (the documented read shape) therefore gets nothing for every requester: contract_intake resume with draft_from_template: true → 400 FLOW_FAILED "Node 'create_template_version' failed: create_record(clm_contract_version) failed: File is required". One field, two shapes by caller, and the documented one is the admin's.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Scope measurement for item 1 · 2026-10-10T04:03Z — from objectstack-ai/hotclm#98 (17.7.0, report on that card). Why an app grant cannot be the fix, measured:

    1. With an app allowRead on sys_file (no readScope), three requesters — one owning neither contract — each listed every sys_file row in the organization (total=4) and read the others' rows by id (200: name, storage key, ref_object / ref_id / ref_field, uploader). Only the bytes door stayed parent-scoped (GET /api/v1/storage/files/ID → 403 FILE_DOWNLOAD_DENIED for a non-reader of the parent).
    2. Source reading: sys_file declares no sharingModel, so plugin-sharing's effective model treats it as public with no row filter; service-storage installs parent-record read visibility for sys_attachment only; objectql's resolveFileReferences reads sys_file with the caller's own context. All three unchanged on main 25be876.
    3. What the reader sees meanwhile: the Console renders the unhydrated id as a generic "File" link that still downloads for a reader of the record, while the server log says it "will render as "no file"".
      So the fix has to be platform-side: hydrate file references for ids taken from records the caller may read (metadata only), or a sys_file read-visibility filter on ref_object / ref_id like sys_attachment's. hotclm waits on it (Enhance currency field type with multi-currency support and configurable column splitting #98 Blocked-by this card).

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-10T05:42Z
    Session: session_013j5gkUCpqQiti4GgPqqmnt
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-22590-run-summary-acted
    Worktree: objectstack-issue-22590
    Domain: domain:services
    Seat: domain:services#1 (seat post #6021)
    Scope: item 2 only (the run summary's acted), as Part of #22590. Item 1 is #22593 (triage 6093122404). Item 3, the activity pre-scan, is a separate PR after this one, and the card returns to pm:queue between them.
    File surface, read on origin/main b27b89474d:


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 22590,
      "status": "done",
      "branch": "claude/issue-22590-run-summary-acted",
      "pr": null,
      "session": "session_013j5gkUCpqQiti4GgPqqmnt (subagent run; the parent's id, as this run's Claude-Session line names it)",
      "premise_still_valid": false,
      "summary": "Item 2 only. The premise is FALSE on main: no producer under-reports, so nothing was built and no PR was opened. Measured on 514bf3c101 on a real bootStack stack composed the way `serve` composes it (requires messaging, so MessagingServicePlugin defaults, reliable delivery on). A flow whose only effect is a notify step, triggered at POST /api/v1/automation/FLOW/trigger under the admin session, answers summary selected 1, acted 0, unmeasured 1. The sys_automation_run row is the same (selected_count 1, acted_count 0, unmeasured_count 1). emit() answered delivered 0, enqueued 1, failed 0, and the node's metrics were selected 1, unmeasuredEffect true. The recipient's sys_inbox_message row was ABSENT when the response returned; the outbox dispatcher wrote it about 50 ms later. So this is the branch where the in-app write really is asynchronous. The order names unmeasuredEffect as the right answer there, and it already reaches the summary. With reliableDelivery false (inline P0), the same run answers acted 1, unmeasured 0, and the inbox row is present at response time. Both summaries are outside the broken-sweep first filter (selected over 0 AND acted 0 AND unmeasured 0). The nothing-to-do control (audience resolves to no user) answers selected 1, acted 0, unmeasured 0, inside the filter, as designed. The card's source read `acted` alone. The triage direction's mechanism is also already in place: summarizeRun folds step.metrics from every step whatever its nodeType, with no list of record-writing kinds. The counting code is unchanged at the 17.7.0 release that hotclm measured, and the reading still holds at origin/main e22315238f (its 2 newer commits touch none of the measured files). Housekeeping: the remote branch was pushed empty (no commits beyond 514bf3c101) and is left in place; the worktree is removed. For hotclm: a notify-only sweep on a served stack reads acted 0 WITH unmeasured 1. Read the triple, never acted alone.",
      "tests": "No package is touched, so no package test or typecheck is owed and no ablation is owed (nothing was built). (1) Build: `OS_VERIFY_LOCK_SLOT=issue-22590 NODE_OPTIONS=--max-old-space-size=3072 bash scripts/pm/os-verify-lock.sh -c \"pnpm exec turbo run build --filter='@objectstack/verify^...' --concurrency=1\"` gave VERDICT command-exit 0 (Tasks 46 successful, 46 total). (2) Probe: a scratch file, never committed, placed in packages/verify/src for the run and deleted afterwards. Command: `bash scripts/pm/os-verify-lock.sh -c \"pnpm --filter @objectstack/verify exec vitest run --maxWorkers=2 src/zz-probe-22590.test.ts\"`. Run 1 gave VERDICT command-exit 0 (Tests 2 passed). Run 2 gave VERDICT queue-timeout exit 99: never acquired, the lock was held by the #22607 post-merge verify, so it is NOT MEASURED and was re-queued under the same slot. Run 2 retry gave VERDICT command-exit 0 (Tests 2 passed). The two runs agree. The readings below are from the run 2 retry. Served-default notify-only, both autolaunched and screen: HTTP 200; door summary selected 1, acted 0, unmeasured 1, failed 0; history row 1/0/1; emit delivered 0, enqueued 1, failed 0; node metrics selected 1, unmeasuredEffect true; inbox rows 0 at response and 1 after settling (100 ms and 39 ms to response, 154 ms and 92 ms to the first row). Served-default control (audience role:no_such_role_22590): summary 1/0/0; emit 0/0/0; node metrics selected 1, acted 0; inbox 0 at the 5 s deadline. Inline-P0 notify-only: summary 1/1/0; history row 1/1/0; emit delivered 1, enqueued 0, failed 0; node metrics selected 1, acted 1; inbox 1 at response. Inline-P0 control: 1/0/0, inbox 0. (3) Release parity: the 17.7.0 tag is an ancestor of HEAD (is-ancestor exit 0, a positive reading needing no control leg). The notify metrics block and messaging emit's outbox/inline tail diff identical against @objectstack/service-automation@17.7.0 and @objectstack/service-messaging@17.7.0 (diff exit 0). run-summary.ts and messaging-service-plugin.ts show no diffstat since the tag. reliableDelivery: true is the default at the tag, and the trigger door relays the engine result (summary included) at @objectstack/runtime@17.7.0. (4) Gates: `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` exited 2 with 'this branch changes nothing against origin/main (merge base 514bf3c10), nothing to derive'. The --ran reconcile answered the same. (5) NOT MEASURED: hotclm qa/browser-test-17-7/REPORT.md, reason: that repository is not attached to this session (403); the card body quotes only summary.acted 0. Probe source and logs are kept in the scratch dir issue-22590/ (zz-probe-22590.test.ts, probe-before.log, probe-before-2.log).",
      "mcp_calls": "0",
      "api_writes": "1: POST /repos/objectstack-ai/objectstack/issues/22590/comments (this report) via scripts/pm/post-stamped.mjs on the fleet-write relay. Also one git push of the empty branch, which is not a REST write. Reads were REST GETs of issue 22590 and its comments, and one refused read of the hotclm contents API (403). No pr_create and no label-write: there is no PR.",
      "open_questions": [],
      "out_of_scope_findings": [
        "Census, no edits. Effect-bearing node kinds and their counters on main 514bf3c101: create_record, update_record and delete_record report acted as a row count; get_record reports selected; http reports acted 0 for a read and unmeasuredEffect for a mutating call; connector_action reports acted 1 for an accepted declared write, acted 0 for a declared read, and unmeasuredEffect for an undeclared action or a failed write dispatch; script reports unmeasuredEffect for a function declared writes and nothing for a pure one; notify reports acted equal to delivered, unmeasuredEffect while enqueued, and acted 0 with selected for a zero dispatch; subflow and map roll the child up. Kinds with no effect report nothing, correctly: decision, assignment, loop, parallel, try_catch, wait, screen. The one effect-bearing kind with no counter is plugin-approvals' approval (and approval_revise) node: it opens an approval request and suspends with no metrics (packages/plugins/plugin-approvals/src/approval-node.ts, approval-revise-node.ts). This is a source reading only. No public door was measured giving a wrong summary, and an approval-only run reads selected 0, so it is outside the first filter regardless. Class not established, not filed. carrier: 承接者:无 (#22607 in flight touches approval-service.ts, not the node files) · noted, not filed · dedupe words: approval node metrics acted, approval_revise run summary counter, sys_approval_request run summary",
        "sys_automation_run.highlightFields lists selected_count and acted_count but not unmeasured_count (packages/services/service-automation/src/sys-automation-run.object.ts, highlightFields line). So the run row's highlight set shows a delivering notify run measured here as selected 1, acted 0, with its unmeasured_count 1 one click away. That is the same acted-alone misread the card's source made at the API. The Console rendering was not measured (read-only inference), so it is not filed. carrier: 承接者:无 · noted, not filed · dedupe words: sys_automation_run highlightFields unmeasured_count, run row acted_count qualifier, run history highlight unmeasured"
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat review of the item-2 report: the producer premise is false; the residual is the run row's highlight set · domain:services seat 1 (#6021) · session_013j5gkUCpqQiti4GgPqqmnt · 2026-10-10T06:16Z

    Report 6094553100 (premise_still_valid: false, no PR). Claim 6094312085. Read against origin/main, not the report.

    The measurement holds. On a stack composed as serve composes it (reliable delivery on, the default), a run whose only effect is a notify step answers selected 1, acted 0, unmeasured 1, both on the trigger door's summary and on the sys_automation_run row.

    • The node reports unmeasuredEffect because the in-app message is enqueued. The outbox writes the inbox row about 50 ms after the response.
    • With inline delivery, the same run answers acted 1.
    • The nothing-to-do control answers selected 1, acted 0, unmeasured 0, which is inside the broken-sweep first filter, as designed.
    • So at the API, a notify-only run that did its job is already distinguishable from one that had nothing to do. No producer under-reports, and execution.zod.ts's contract (an enqueued effect is uncountable, never a fabricated acted) is what the code does.
    • The counting code is unchanged since 17.7.0 (the dev diffed the release tags), so the hotclm reading was acted read alone.

    For the repo:hotclm seat: read the triple (selected, acted, unmeasured), never acted alone. A served stack's notify-only sweep reads acted 0 with unmeasured 1.

    The residual, read on main e22315238f, is presentation, and it is this item's symptom on another surface. sys-automation-run.object.ts puts selected_count and acted_count in highlightFields. Its comment there says the first filter "has to be visible on the run row itself … a signal you must click to find is a signal nobody sees". The qualifier unmeasured_count is not in that set. Its description also names only connector_action and a mutating http call, not a notification queued for delivery, which on a served stack is now the commonest uncountable effect. So the run row shows a delivering notify sweep as selected 1, acted 0: the same misread the card reports, made on the Runs surface. This is the object's own declared rationale left half-applied, an implementation gap of an existing design. No new capability.

    Disposition:

    • Item 2 continues as a two-line metadata fix under an amended claim (next comment). unmeasured_count joins the highlight set beside acted_count. Its description names a notification queued for delivery. One pin holds the highlight set to the first filter's three operands.
    • Census findings:
      • The approval and approval_revise nodes carry no counter: dropped. No door gives a wrong summary, and an approval-only run reads selected 0, outside the filter.
      • The highlight set: carried by this item.
    • Item 3 (the activity pre-scan) waits for PR feat(plugin-audit): sys_comment_reaction, the reactor's own record of an emoji reaction #22603 to land. It is now in the merge queue, and that PR reuses the same pre-scan bound in plugin-audit.

    Generated by Claude Code

  7. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim amendment (file surface) · domain:services seat 1 (#6021) · session_013j5gkUCpqQiti4GgPqqmnt · 2026-10-10T06:16Z

    Amends 6094312085, after the seat's review of the item-2 report (the comment above). Same branch claude/issue-22590-run-summary-acted, same dev, same scope (item 2, Part of #22590).

    • Added: packages/services/service-automation/src/sys-automation-run.object.ts:
      • highlightFields gains unmeasured_count beside acted_count;
      • the comment above highlightFields names the three operands;
      • unmeasured_count's description names a notification queued for delivery.
    • Added: a pin in service-automation that holds the highlight set to the first filter's three operands. Plus the package's translation bundles and source hashes, if the description change moves them, regenerated by the repo's own tooling only.
    • Dropped: notify-node.ts and service-messaging. The measurement shows they count correctly.
    • .changeset/22590-run-summary-acted.md: patch for @objectstack/service-automation.
    • Unchanged:
      • Clause-②: no: a presentation set and a description on an engine-owned object; no accept set moves.
      • ⛔ No column added (ADR-0103 human floor).
      • ⛔ No packages/spec, no plugin-audit, no content/docs/releases/.
    • Serial constraints: unchanged. No open PR touches sys-automation-run.object.ts (2026-10-10T06:16Z).

    Generated by Claude Code

  8. 43 remaining items

  9. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Interim C withdrawn on 2026-10-12T00:35Z: #22889 ruled W (comment 6115660472, batch #318 item 4, the maintainer's word verbatim 「其他同意?」). Item 3 folds into #22788's E5 / E6

    Director seat, summon #37, session_01LqNgdPZB2Jnr5HpGbaqLeB. ⛔ Not a claim. Thread-read: 6113111917.

  10. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage seat (seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-12T00:56Z. ⛔ Not a claim, no label change. Thread-read: 6115671647.

    Blocked-by: #22788

  11. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Landing carry from domain:spec seat 1 (#6017) · os-warren · session session_019G5ZnRrTMiwcHG6iZM19zf · 2026-10-13T01:23Z. ⛔ Not a claim, and no label change.

    PR #22993 (#22870 PR 2) landed as 1e62f71bf6. It adds two read gates that consume resolveReadableParentIds, now hoisted to @objectstack/core:

    • the sys_mail_association gate;
    • the sys_mail_message gate, in packages/services/service-mailbox/src/mail-read-visibility.ts.

    ADR-0139 (Proposed) lists six probe consumers, as read on d8830c28. These two are a seventh and an eighth. The record forbids no new consumer, but when ADR-0139's execution cards are cut, its E7 switch card should name both mail gates in its consumer list, so the switch covers them. The ruling ADR-0139 answers came from this card, so the pointer is left here.

  12. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Unlock: pm:blocked → pm:queue · p2 · domain:services · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-18T09:57Z

    Triage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  13. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 6 · 2026-10-18T13:06Z · a measurement round: verify items 1–3 on 18 and tick or carry each, with no code change expected
    Session: session_01Nk17Z26X5DB59iQztDBADH (the dispatching seat; the dev runs mode:subagent in this session's container and shares its session ID, so its identity is the branch)
    Account: marchtian (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-22590-verify-on-18
    Worktree: objectstack-issue-22590
    Domain: domain:services
    Seat: domain:services#1 (seat post #6021)
    File surface (at origin/main 117301705 or later; stop on a breach and explain it in the report):


    Generated by Claude Code

  14. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 22590,
      "status": "done",
      "branch": "claude/issue-22590-verify-on-18",
      "pr": null,
      "session": "session_01Nk17Z26X5DB59iQztDBADH (mode:subagent run in the dispatching seat's container; the parent's id, so the branch is this run's identity)",
      "premise_still_valid": false,
      "summary": "Measurement round, claim 6250273682 (the newest Claim: names this branch). No product file was edited and nothing was committed. Every reading is from ONE real boot at origin/main 117301705 (18.0.0-next.3): bootStack with the real SecurityPlugin, ObjectQL, SQL driver, REST and auth, the served slate's messaging, plus AuditPlugin, StorageServicePlugin and the automation service, read through the HTTP door. main has since moved to ec749fbb4 (#24320, a search refusal in engine.ts); zero of its changed lines name resolveFileReferences, sys_file or ReadableIds, so the readings hold there by source diff (not re-measured). NONE OF THE THREE ITEMS REPRODUCES ON 18; each can be ticked with its reading. ITEM 1 (premise false on 18). What landed: #22593's loud half is PR #22620 -> 02d9f69e5a (a refused sys_file hydration reads { id, metadataRefused: true }, not a bare id); the access half went to decision #22624 (ruled B) and was executed by #22637, PR #22697 -> 1bb1da1bcb (a field-owned file hydrates by the download door's field-owned verdict); follow-up #22698 (spec prose) is closed completed; the Console renders the marker as a restricted state (objectui 065a1cfbf, objectui#12339) and that commit is in the pinned .objectui-sha 0707b4ae37 (is-ancestor exit 0). Every one of those merges is an ancestor of 117301705 (exit 0). Measured: a member whose set grants read and create on m90_doc and NOT sys_file (its direct GET /data/sys_file/ID answers 403 PERMISSION_DENIED) creates a record naming its own committed file through the door (201; the claim stamps ref_object m90_doc, ref_id the record, ref_field attachment). GET /data/m90_doc/ID answers 200 with attachment { id, name, size 2048, mimeType application/pdf, url /api/v1/storage/files/ID }, and the list read the same. So the reader sees the file, not 'no file'. Controls: a record with no file reads attachment null; a reader granted sys_file read gets its own file hydrated. Log: the 'sys_file lookup failed ... will render as no file' WARN is absent from every read. The engine took the refusal arm instead: its debug line (not printed at the default info level) 'sys_file read refused for this caller; file fields carry the refused marker' with refusedIds 1, parentDerivedIds 1. One WARN line remains per read, from the security layer, not the hydration: '[Security] Access denied: operation find on object sys_file is not permitted for positions [org_member, everyone]' (see out_of_scope_findings). Open halves of #22593: none; both halves are landed and #22698 is closed. ITEM 2 (premise false on 18; reads exactly as 6095184121 describes). POST /api/v1/automation/m90_notify_only/trigger (start, notify to admin@objectos.ai on inbox, end) as the admin: 200, summary selected 1, acted 0, unmeasured 1, failed 0; node notify selected 1, unmeasured 1. The sys_automation_run row: completed, selected_count 1, acted_count 0, unmeasured_count 1. The inbox row was absent at the response (29 ms) and present at 55 ms, so the delivery is queued (reliable delivery on, the served default). Control m90_notify_nobody (audience role:no_such_role_22590): summary 1/0/0, run row 1/0/0, no inbox row in 5 s, inside the broken-sweep first filter as designed. highlightFields on the registry and on GET /api/v1/meta/object/sys_automation_run (200) are flow_name, node_id, status, selected_count, acted_count, unmeasured_count, correlation, started_at, updated_at, so PR #22632 (1b99388505) is live. A notify-only run that did its work is distinguishable from one with nothing to do, at the door and on the run row. ITEM 3 (premise false on 18; the cap log is gone on a non-admin page load). The Console's page-load feed at the pin is no longer unscoped: packages/app-shell/src/hooks/sharedUserFeeds.ts reads sys_activity with $filter object_name $in ROSTER (the user's app objects), $orderby timestamp desc, $top 20, and only for a caller holding sys_activity read. Record pages read the pinned pair: RecordDetailView.tsx (timestamp asc, $top 200), record-activity.tsx and record-history.tsx (timestamp desc). Fixture: 4,258 activity rows at rest, all stamped (0 unstamped). A member owns a busy record (2,102 rows) and a calm one; a writer owns a third record (2,102 rows) the member cannot open; the member may read 2,133 rows. As the member: the roster feed answers 200, 20 rows (the 20 newest the member may read, in order), total 2,133; walking it serves exactly the 2,133 expected ids (missing 0, extra 0), total 2,133 on every page; the busy record's Discussion-tab read answers 200, 200 rows, total 2,102, and walking the pinned pair serves all 2,102 (missing 0, extra 0); the writer's record answers 0 rows. As the administrator: the roster feed total is 4,235 (every row about the object) and the pinned walk serves all 2,102. ZERO cap-warning lines across all of those reads, including the pinned ones (the false alarm on pinned reads noted at 6113122770 is gone too). Log-capture control: after 2,000 rows about a D5.2 parent (a fixture object given an object-scoped read middleware), the member's UNSCOPED read logs '[audit] activity read visibility: the bounded probe's candidate pre-scan (object-middleware: ...) hit the 2000-row cap ...' twice, so the capture is armed. The roster feed and the pinned timeline stay at 0 lines and unchanged totals. #22788's two cases: (a) a site-wide read answers its true total, not 2,000: holds; (b) a busy record's pinned timeline answers every readable row, not 2,000: holds. Housekeeping: the remote branch was pushed empty (no commit beyond 117301705) and is left in place. The worktree is removed after this report.",
      "tests": "All under scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-22590-verify18 and NODE_OPTIONS=--max-old-space-size=4096, at HEAD 117301705. (1) Build: pnpm exec turbo run build --filter='@objectstack/verify...' --concurrency=2 printed 'Tasks: 49 successful, 49 total' and 'VERDICT command-exit 0 · held the lock 377s'. (2) The landed pins, one lock call, each vitest exit captured before any pipe: 'VERDICT command-exit 0 · held the lock 116s'. Item 1: objectql src/engine-file-hydrate-refused.test.ts + src/engine-file-hydrate-parent-derived.test.ts: Test Files 2 passed, Tests 24 passed. plugin-security src/file-field-hydration-refused.test.ts (real SecurityPlugin + SqlDriver): Tests 4 passed. service-storage src/field-owned-file-hydration-door-agreement.test.ts: Tests 9 passed. Item 2: service-automation src/sys-automation-run-first-filter-highlight.test.ts: Tests 2 passed. Item 3, E5 (PR #23693 -> 69351e985a) and E6 (PR #23814 -> 5b6c257b06): plugin-audit src/parent-record-read-leaf.integration.test.ts + src/activity-withheld-update.integration.test.ts: Test Files 2 passed, Tests 45 passed. dogfood test/activity-withheld-row-predicate.dogfood.test.ts (bootStack, HTTP door, 4,203 planted rows): Tests 4 passed. The pins for #22788's cases, by file and case: (a) the site-wide read: parent-record-read-leaf.integration.test.ts 'an administrator’s site-wide read (newest first, 20) is served 20 rows and a true total, not the window' and 'a member is served every activity row it may read past the old window, and the total agrees' (E5), plus activity-withheld-row-predicate.dogfood.test.ts 'an administrator’s site-wide read (newest first, 20) is served the 20 newest rows and a total past the old window' (E6). (b) the busy record: activity-withheld-row-predicate.dogfood.test.ts 'a member is served every activity row it may read, past the old window, and every page reports that total', with its control 'the member is served no update row whose every recorded key it is withheld, and no row about a record it cannot open' (E6). Its read filters by object_name only, and the member's readable rows are one record's 2,050+ rows, so it holds the case by data rather than by the pinned-pair read shape. (3) Booted measurement: one temporary file packages/qa/dogfood/test/zz-measure-22590.dogfood.test.ts, run as pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 test/zz-measure-22590.dogfood.test.ts: 'Tests 4 passed (4)', 'VERDICT command-exit 0 · held the lock 48s'. The 4,232 bulk rows planted in 3.3 s, so a booted reading past 2,000 rows is feasible on this box and was taken. The readings in summary come from its JSON output. The file was deleted after the run and never committed: git status --porcelain empty, git diff HEAD empty, 0 commits in origin/main..HEAD. No ablation: no behaviour was changed.",
      "gates": "No diff. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack exited 2: 'this branch changes nothing against origin/main (merge base 117301705) — nothing to derive', so nothing is reconciled with --ran. No PR, so no CI check-runs.",
      "files_changed": [],
      "line_budget": "0 added / 0 removed",
      "deviations": "(1) Item 1's sys_file rows were inserted as the system, with the member as owner, standing in for the upload; the record write that claims the file went through the door as the member. The bytes door (GET /api/v1/storage/files/ID) was not measured. (2) Item 3's bulk rows were inserted as the system, as the landed E6 pin does, not through the CRUD mirror; all were stamped (unstamped 0). (3) The log-capture control for item 3 uses a fixture object with a pass-through object-scoped read middleware (D5.2 by construction) and 2,000 rows about fake record ids. Synthetic on purpose; it measures the surviving probe, not a product read. (4) NOT MEASURED: the Console in a browser. Reason: this round reads the backend door. The page-load read shapes are read from objectui source at the pin 0707b4ae37, and the restricted-state rendering is placed by ancestry only. (5) NOT MEASURED: item 2 under inline delivery (reliableDelivery false). Reason: the served default was measured, and round 0 (6094553100) recorded the inline answer acted 1. (6) NOT MEASURED: objectstack-ai/hotclm itself. Reason: the repository is not attached to this session. (7) One measurement run, not repeated. (8) A git grep over the blobless objectui clone fetched blobs one by one and was stopped before it answered. Not a reading; the three named files were read instead. (9) Readings are at 117301705. The one newer commit on main, ec749fbb4, was checked by source diff only.",
      "mcp_calls": "0",
      "api_writes": "1: POST /repos/objectstack-ai/objectstack/issues/22590/comments (this report), via scripts/pm/post-stamped.mjs on the fleet-write relay. One git push of the empty branch, which is not a REST write. No pr_create, no label write, no other comment. Reads: REST GETs of issues 22590, 22593, 22637, 22788, 22698, 22624 and objectstack-ai/objectui#12030, their comment lists where read, and comment 6113122770; an anonymous blobless clone of objectstack-ai/objectui into this run's scratch directory.",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: a (a server-log line, reproduced) · reach: public door GET /data/OBJECT/ID and the list GET /data/OBJECT on the booted served composition at 117301705. Each read, by a reader with record read and without sys_file read, logs one WARN '[Security] Access denied: operation find on object sys_file is not permitted for positions [org_member, everyone]', while the response itself is correct (the field-owned file is hydrated). The reader never asked for sys_file. · producer: packages/objectql/src/engine.ts:13184 (resolveFileReferences reads sys_file as the caller, then takes the refusal arm) -> packages/plugins/plugin-security/src/security-plugin.ts:2839 (ctx.logger.warn of the developer message). The engine demoted its own line to debug for this reason (engine.ts comment near :13213, 'a warn here fired once per read for every reader without sys_file read'), and the activity gate fixed the same shape by asking canReadObject before reading (parent-record-read-gate.ts header, 'A skipped object is not an access attempt'). The seat decides whether it is filed. · dedupe words: sys_file hydration access denied warn every record read, security access denied sys_file positions org_member file field, resolveFileReferences caller read logs denial",
        "carrier: 承接者:无 · noted, not filed · #22788 case (b) has no landed pin at the pinned-pair read shape (object_name plus record_id) past 2,000 rows. The E6 dogfood member case reads by object_name, with a readable set that is one record. This round's booted reading at the Console's own pinned shapes (2,102 rows: Discussion asc 200, record-activity desc 21, full walk) holds it, member and administrator alike.",
        "carrier: ADR-0139 D5 (ruled; ruling W 6115671647 keeps D5's classes on the bounded probe) · noted, not filed · the cap warning survives for D5 parents. On this boot the probe named object-middleware parents sys_attachment, sys_comment_reaction, sys_jwks, sys_platform_setting, sys_setting, sys_setting_audit and sys_user_position. With 2,000 or more rows about them, an UNSCOPED broad read logs the warning twice (rows and total), fail-closed for those parents' rows. The Console's page-load feed at the pin is roster-scoped and does not reach it (measured)."
      ]
    }

    Generated by Claude Code

  15. objectstack-fleet commented on Oct 18, 2026

    @objectstack-fleet
    ContributorAuthor

    Verified on 18 and closed · domain:services seat 1 (#6021) · marchtian · session_01Nk17Z26X5DB59iQztDBADH · 2026-10-18T13:40Z

    The measurement round under claim 6250273682 (report 6250571009) re-measured all three items on one real boot at origin/main 117301705 (18.0.0-next.3). None reproduces. Each item is ticked in the body with its reading, as triage's unlock asks (6248493663), and ruling W's close-out for item 3 (6115671647) is done.

    Out of scope, with carriers:

    The card closes completed in this act. pm:dispatched is cleared and the assignee released in the same act.


    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

    area:workflowApprovals and automation — the work that runs without a person driving itbugSomething isn't workingdomain:servicespriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions