Repository navigation
Access, audit and approval pages predate ObjectStack 17.0–17.6: masking, record-view audit, deactivation, query-door FLS, the guest baseline and approval visibility are missing or wrong #329
Description
Filing gate: ③ — a task the maintainer dispatched directly in session chat.
Reader: the repo:objectos PM seat (objectstack-ai/objectstack#9831), session session_01CXCwzqwMhkphKoBC11oPSz, which dispatches it to an os-dev subagent in this round.
Dedupe: all 118 objectos issues, open and closed (REST page walk; 301 issues + PRs), grepped for masking, maskingRule, record_views, audit-logs, guest, deactivat, approval → closed hits only: #154 (17.1 allowExport, landed), #146 (audit-log page, earlier), #80 (guest, 16.x). None covers this scope.
Priority: P1. Several rows are wrong statements about who can see what.
Maintainer, this session's chat, 2026-10-15: 「参考官网的文档站点和最近的版本更新。」「创建issue并派发。」
Why
The docs samples parse with @objectstack/spec 17.7.0 (PR #321), but the prose on the access, audit and approval pages was last aligned with 17.0/17.1. The source is the official release notes, objectstack origin/main 1ced0f82, content/docs/releases/v17/17-0.mdx … 17-7.mdx.
Work items
Each line is the seat's reading on main 76988da. Falsify it against the tree first. Some rows may apply only to the open-source runtime; for those, measure whether an ObjectOS operator can reach the setting, and report rather than document if they cannot.
| Release | Item | Status | Where |
|---|---|---|---|
| 17.0 | Approval requests are readable by participants only | missing | build/automation/approvals.mdx ("What the approver experiences"), use/approvals.mdx:31 |
| 17.0 | Anonymous data access is denied unconditionally; public access is a form or a share link | stale | reference/security.mdx:84 "denied by default" |
| 17.1 | A deactivated permission set or position stops granting, and its sharing-rule shares are revoked | missing | configure/permissions/permission-sets.mdx, positions.mdx |
| 17.1 | Partial field masking (maskingRule), a third FLS state |
missing | configure/permissions/field-level-security.mdx, reference/security.mdx:87-88 |
| 17.1 | Record-view auditing (read action, record_views view) |
missing; applicability unverified (plugin option) | operate/audit-logs.mdx:30-39 |
| 17.1 | Read-only approval visibility tier (recordReaderVisibleObjects) |
missing; applicability unverified | build/automation/approvals.mdx |
| 17.1 | API keys bound to the minter's active organization (walled postures) | missing | configure/api-access.mdx:69+ |
| 17.3 | Self sign-up closed by default (auth.audience.posture = invite_only) |
missing; check against OS_AUTH_MEMBERSHIP_POLICY |
configure/authentication.mdx, configure/users.mdx ("Add people") |
| 17.5 | RLS refuses predicates it cannot enforce; a using-only policy gates writes |
missing | configure/permissions/record-access.mdx:74-93 |
| 17.6 | A caller with no permission set gets the deny baseline; guest grants nothing |
stale | configure/permissions/positions.mdx:58-59 "bind to guest to open something to anonymous visitors"; configure/permissions/index.mdx:64-66 |
| 17.6 | FLS applies at every query door: filtering, sorting or grouping on a hidden or masked field answers 403 | missing | configure/permissions/field-level-security.mdx:121-126 |
| 17.6 | Audit and activity rows are served only for readable records, admins included; delete and sign-out rows are no longer served | stale | operate/audit-logs.mdx:25-28, :37, :38; operate/observability.mdx:82-83 |
File surface
content/docs/configure/permissions/{index,permission-sets,positions,field-level-security,record-access}.mdxcontent/docs/reference/security.mdxcontent/docs/operate/{audit-logs,observability}.mdxcontent/docs/build/automation/approvals.mdxcontent/docs/use/approvals.mdxcontent/docs/configure/{api-access,authentication,users}.mdx- Locale siblings: deletion only, and only where a correction reverses a capability claim (
AGENTS.mdtranslation workflow, step 3)
Not in this card
- Flows, REST, CEL, localization, upgrade, changelog, environment variables and CLI (the sibling build/API/ops card).
- Glossary, data sources and agents (the sibling ontology card).
- There is no getting-started path for ObjectOS itself: Quickstart boots the open runtime, Deploy/Operate are not marked self-managed, and License & Pricing is buried #300's "Cloud vs self-managed" labels on Configure pages.
Done looks like
- Every row is fixed or falsified, with the release-note line it rests on.
- New samples parse under
check-doc-samples.mjs. - The
ci.ymlgates pass locally. - No locale sibling is hand-edited.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 15, 2026
Claim: PM loop,
repo:objectosseat, R1Session:
session_01CXCwzqwMhkphKoBC11oPSzAccount:
os-tesla(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-329-access-audit-17xWorktree:
objectos-issue-329Domain: n/a (single-lane repo)
Seat:
repo:objectos(objectstack-ai/objectstack#9831)File surface: as listed in this card's "File surface" section, read on
main76988da. Stop on breach and explain in the report.Container & model:
M/L,mode:subagent,model: opus(default tier;dispatch-gates.mjs --tier --repo objectstack-ai/objectosover this surface at objectstack1ced0f82answers "no path-derived mandate")Clause-②: no
Responsibility: these docs pages produce the risk (objectos
content/docs) · the platform path already covers it: the 17.0–17.6 release notes on objectstack.ai · every admin reading the permission and audit pages reaches it todayThread-read: none
Serial constraints cleared: nothing is in flight on objectos. #300 (blocked) will later label Configure pages as Cloud or self-managed; it is not in flight. Sibling cards #328 and #330 are dispatched in this round with disjoint file surfaces. The five open PRs are Dependabot bumps, none on
content/docs/**.Generated by Claude Code
objectstack-fleet commentedon Oct 15, 2026
os-dev-report
{ "issue": 329, "status": "done", "branch": "claude/issue-329-access-audit-17x", "pr": "https://github.com/objectstack-ai/objectos/pull/331", "session": "session_01CXCwzqwMhkphKoBC11oPSz — this run's harness-stamped id (subagent = parent's)", "premise_still_valid": true, "final_commit": "6067fb5854b48c5dea766acba541ba1243fc71d2", "summary": "All 12 card rows are settled; each verdict cites its release-note line in the PR's row table. Ten are fixed across 13 English pages, two of them with a correction to the card. (1) An organization-less API key is refused only under `isolated`; `group` still admits it (core 17.7.0 `organization_required`; the 17-4 note's wording is wrong). (2) 17.7's `view_all_audit_log` returns the deletion and sign-out trail to platform admins, so the card's 'admins included' no longer holds. Two rows are falsified for ObjectOS and left undocumented: record-view auditing (`AuditPlugin({ readAudit })`) and `recordReaderVisibleObjects`. Both are plugin constructor options; the `requires` capability providers carry no configKey for audit or approvals; and no metadata key, environment variable or Setup field reaches them on 17.x (`enable.approvalsVisibleToReaders` exists only on objectstack main, 18.0.0-next). This rests on documented surfaces only, because ObjectOS's own composition is private. The 17.3 sign-up audience IS reachable: Setup → Authentication → Audience, in the same service-settings `auth` namespace that already holds ObjectOS's documented Membership group (published 17.3.0 and 17.7.0 carry it). It is a separate decision from OS_AUTH_MEMBERSHIP_POLICY, and the page says so. The 17.6 guest row was confirmed three ways: the 17-6 deny-baseline section, the 2026-10-06 correction (#21158 closed as not planned), and the current ObjectStack positions page. Under the #256 criterion, the 14 locale siblings of positions.mdx and permissions/index.mdx are deleted, because their guest claim is reversed. Every other sibling is kept. The masking sample was written to the PM's suggested route, and the query-door 403 is a table row plus an 'On query' paragraph.", "tests": "Docs-only diff; no tested behaviour changed, so there was nothing to ablate. `node .github/scripts/check-doc-samples.mjs` exit 0: '79 English page(s) parses with @objectstack/spec 17.7.0 · 99 pass · 10 not a spec sample · 2 opted out'. The new sample reads 'PASS content/docs/configure/permissions/field-level-security.mdx:57 — fields of an object'. Negative control: the same fragment with `maskingRule: 'iban'` in a scratch --docs tree exits 1 with 'fields.mobile.maskingRule: Invalid input'. Rendered check on the local build (6067fb5): the built HTML carries every new anchor (#masked-fields, #who-may-sign-up-objectstack-173, #what-each-reader-is-served, #deactivating-a-position, #deactivating-a-permission-set, #keys-belong-to-an-organization-objectstack-171, #row-level-security-refuses-what-it-cannot-enforce) and every cross-page target (views#public-forms, environment-variables#multi-organization-deployments, users#add-people). The zh-Hans and de routes for positions and permissions render the corrected English. CI's 'The docs site renders — smoke-check a local preview' passed on 6067fb5.", "gates": "Local, all on final head 6067fb5, each exit captured before any pipe: gen-zh-hant --check 0 ('52 generated file(s) match'); check-doc-samples 0; check-translation-ownership --actor os-tesla 0 (TRANSLATION_BOT_LOGIN unset → reports, 14 deletions + 13 English); check-translations 0 ('translations gate passed'); shared lock `pnpm turbo run type-check --continue` VERDICT command-exit 0 (cache miss); `pnpm turbo run build` VERDICT command-exit 0 (cache miss; dynamic OG fonts fail to fetch through the container proxy — environmental); then check-locale-surface 0, check-positioning 0, check-search-locales 0; `pnpm turbo run test` VERDICT command-exit 0 (cache hit 557f349216d5379a, valid: none of its declared inputs .github/scripts/** or apps/docs/lib/i18n.ts changed); check-half-states --self-test 0; check-node-floor 0; control-byte scan of the changed files: no match. The gate list was hand-derived from objectos ci.yml + translations.yml (objectos has no dispatch-gates.mjs). CI check-runs on 6067fb5: build success (including Docs code samples parse, zh-Hant current, type-check, build, Locale surface, Positioning, Search answers every locale, test, Worker bundle fits the size budget, and The docs site renders — smoke-check a local preview); Node floor success; Ownership & freshness success; Deploy docs skipped (PR event).", "mcp_calls": "0", "api_writes": "3 REST writes, sent as 2 fleet-write relay strokes (each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]): stroke 1 pr_create → POST /repos/objectstack-ai/objectos/pulls (draft) + POST /repos/objectstack-ai/objectos/issues/331/assignees [os-tesla]; read-back: 11010 bytes sent = stored, assignee os-tesla. Stroke 2 comment → POST /repos/objectstack-ai/objectos/issues/329/comments (this report). Plus 2 git pushes of the branch (not REST). 0 label writes, 0 card-assignee writes, 0 PR body edits, PR left draft.", "open_questions": [], "out_of_scope_findings": [ "class: a · reach: public door — docs.objectos.ai/docs/resources/changelog, the 17.1 bullets 'sys_audit_log can answer \"who viewed this record\" … See Audit Logs' and 'Read-only approval visibility … See Approvals' send ObjectOS readers to pages that (after #331) correctly do not document either capability, because neither is reachable from ObjectOS (evidence in the PR's Reachability section) · evidence: content/docs/resources/changelog.mdx 17.1 section at main 76988da · carrier: #330 (owns changelog.mdx; in flight this round) · dedupe words: changelog 17.1, record-view auditing, readAudit, recordReaderVisibleObjects", "carrier: none · noted, not filed — operate/audit-logs.mdx 'Preset views' lists 4 tabs; plugin-audit ships `All` since 17.0.0 and `Record Views` since 17.1 (published 17.0.0 / 17.7.0 dist listViews), and the latter would be empty on ObjectOS; pre-existing, outside the card's rows", "carrier: none · noted, not filed — plugin-auth 17.x also reads OS_AUTH_AUDIENCE_POSTURE (named in its own refusal log lines); reference/environment-variables.mdx (#330's surface) does not list it, so #331 documents only the Setup path", "carrier: none · noted, not filed — objectstack main (18.0.0-next.1) retires sys_position_permission_set and makes everyone/guest bindings unauthorable; positions.mdx describes 17.x and goes stale at v18 GA" ], "deviations": [ "Commit trailers use the model-free pair from objectstack AGENTS.md (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By; the PR footer uses the os-dev session-URL form. Both follow the os-dev definition's precedence rule.", "Evidence for 17.x runtime behaviour came from `npm pack` of the published 17.x packages into the scratchpad (read only, never executed), because objectstack main is 18.0.0-next and its hand-written permission pages already describe unreleased v18." ], "files_changed": [ "M content/docs/build/automation/approvals.mdx", "M content/docs/configure/api-access.mdx", "M content/docs/configure/authentication.mdx", "M content/docs/configure/permissions/field-level-security.mdx", "M content/docs/configure/permissions/index.mdx", "M content/docs/configure/permissions/permission-sets.mdx", "M content/docs/configure/permissions/positions.mdx", "M content/docs/configure/permissions/record-access.mdx", "M content/docs/configure/users.mdx", "M content/docs/operate/audit-logs.mdx", "M content/docs/operate/observability.mdx", "M content/docs/reference/security.mdx", "M content/docs/use/approvals.mdx", "D content/docs/configure/permissions/index.{de,es,fr,ja,ko,zh-Hans,zh-Hant}.mdx", "D content/docs/configure/permissions/positions.{de,es,fr,ja,ko,zh-Hans,zh-Hant}.mdx" ], "line_budget": "n/a — no skills/** or ratcheted ledger touched; diff +330/−1628 across 27 files (14 locale deletions, under the 5000-line human-merge threshold)", "cleanup": "worktree /home/user/objectos-issue-329 removed after node_modules deletion (no --force); remote branch tip = local HEAD 6067fb5 before removal" }objectstack-fleet commentedon Oct 15, 2026
ACCEPT → PR #331 comment 6192993343 · 2026-10-15T13:17Z · awaiting a human merge (merging to
mainpublishes production).Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report-addendum
{ "issue": 329, "status": "done", "addendum_to": "os-dev-report 6192934020 (head 6067fb5)", "pr": "https://github.com/objectstack-ai/objectos/pull/331", "final_commit": "dc12fdb3e5e6d9bb4580c973b74279026d1242a1", "summary": "Follow-up from the seat: in reference/security.mdx ('How AI can mutate state'), 'plus one `action_NAME` tool per declared action' now reads 'per action its author exposed to AI'. That means `ai: { exposed: true }` with an `ai.description` of at least 40 characters, on a type that runs without a UI (`script`, `flow` or `api`); an unexposed action is invisible to agents and refused if called. It links /docs/build/interface/actions#from-an-ai-agent; the anchor exists on main 76988da and on #332's head d4f1305, which also corrects that section. Sources: objectstack content/docs/ai/actions-as-tools.mdx and packages/spec/src/ui/action.zod.ts at 4e4e8814 (`api` dispatches on the ObjectOS runtime only), and objectos configure/mcp.mdx. It is one commit, +6/−2, on a page with no locale siblings. Gates on dc12fdb, each exit captured before any pipe: check-doc-samples 0 (99 pass), gen-zh-hant --check 0, check-translation-ownership 0, check-translations 0; under the shared lock, turbo build VERDICT command-exit 0 (cache miss); then check-positioning 0 and check-locale-surface 0. The built page carries the new link. CI on dc12fdb: build success (samples, zh-Hant, Locale surface, Positioning, Search, size budget and render smoke-check all success), Node floor success, Ownership & freshness success, Deploy docs skipped. The PR stays ready, untouched by me. The PR body is NOT edited: os-dev says dev writes the body once and never PATCHes, and that wins over this follow-up's '≤1 body edit'. The seat should add this row to the row table: | — | reference/security.mdx AI tools sentence (follow-up, found by #328's dev) | **Fixed** | `reference/security.mdx`, 'How AI can mutate state' | an `action_NAME` tool exists only for an action its author exposed (`ai.exposed`, `ai.description` ≥ 40 chars, a `script` / `flow` / `api` type); objectstack `content/docs/ai/actions-as-tools.mdx` and `packages/spec/src/ui/action.zod.ts` at `4e4e8814`; objectos `configure/mcp.mdx` |", "api_writes": "1 this round: comment → POST /repos/objectstack-ai/objectos/issues/329/comments via one fleet-write relay stroke; plus 1 git push (not REST). 0 PR body edits, 0 label or assignee writes.", "mcp_calls": "0" }