You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
audit log: the actor column shows a truncated raw user id and the actor filter is free text, not a user lookup (split from objectui#11697) #11701
Path: ② the capabilities an end user meets in the app — audit log | 缺项 | P2
Split by the triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U from objectui#11697, its audit half. Re-read on objectui main (c3623eb116). ⛔ Not a claim, ⛔ not a dispatch.
Triage: lands in apps/console/src/pages/system/AuditLogPage.tsx (truncate(r.user_id, 18) about :310; the free-text actor filter about :130 and :232) ⇒ domain:ui; rationale: the page shows the stored id where a person is meant to be named.
Done when
The audit list shows the actor's name, by populating user_id on the /data/sys_audit_log fetch (or the existing lookup display), with the id still available on hover or copy.
The actor filter is a user lookup.
Pin: an audited change by the seeded admin shows the admin's name in the actor column, and filtering by that user returns the row.
apps/console/src/pages/system/AuditLogPage.tsx, in these places (as of 0cfe772):
the /data/sys_audit_log fetch (about :125–:168);
the actor filter (about :112, :130, :232–:238);
the actor column (about :310);
the drawer's actor row (about :363–:364).
A user picker or lookup display the console already ships, only consumed. The dev locates it. ⛔ No new export.
The tests beside the page (apps/console/src/pages/system/*.test.ts(x)) and .changeset/11701-*.md.
Stop on breach; explain in the report.
Container & model: M, mode:subagent, model: opus (dispatch-gates --tier --repo objectstack-ai/objectui over the surface: no path-derived mandate; default tier)
Clause-②: no
Thread-read: none
Ruling-ref: the card body's triage (split from objectui#11697): the list names the actor by populating user_id on the fetch, or by the existing lookup display, with the id still on hover or copy; the actor filter is a user lookup. Retrieved this round.
Serial constraints cleared: none blocking.
The page lives in @object-ui/console, an app. It consumes published pieces and adds no export, prop, schema key or i18n key. Its labels are English literals today, and translating the page is not this card.
If the dev measures that a new i18n key or export is unavoidable, it reports the built-declaration delta. The seat then amends this line to yes and runs the at-tier contract review before enqueue.
os-dev-report
{
"issue": 11701,
"status": "done",
"branch": "claude/issue-11701-audit-actor-name",
"pr": "#11739",
"session": "session_01FngvPpdrnhHMdHHq6vwwju",
"premise_still_valid": true,
"summary": "The Audit Log page's one /api/v1/data/sys_audit_log read now sends $expand=user_id. At objectstack 1fb274e61c, user_id is Field.lookup('sys_user'), and the engine's expandRelatedRecords batch-loads the users in place of their ids through the full sys_user read gate, keeping the bare id when a user is missing or refused. The actor column shows the name with the id as its title. An unresolved user shows the id, a null user_id reads 'System' with the actor principal on hover, and the drawer shows the name and the full id. The free-text actor box is now LookupField from @object-ui/fields with reference sys_user, already exported, so nothing new is exported. It writes the chosen id to filter.user_id, and removing the chip clears it. UserField was not used because it always adds a banned-not-true candidate filter, which would hide deactivated users from an audit search. No export, prop, type member or i18n key changed (Clause-2: no), and the changeset is '@object-ui/console': patch.",
"tests": "All heavy runs went through os-verify-lock.sh with slot issue-11701, at HEAD 8e17dbf. (1) pnpm exec vitest run on the new AuditLogPage.actorName-11701.test.tsx and consoleFaces.displayLocale-9909.test.tsx: 'Test Files 2 passed (2) / Tests 19 passed (19)'. (2) pnpm exec vitest run apps/console/ from the repo root: 'Test Files 155 passed (155) / Tests 1806 passed (1806)'. (3) pnpm --workspace-concurrency=2 --filter '@object-ui/console^...' run build: exit 0, 35 packages. (4) pnpm --filter @object-ui/console run type-check (echoed 'tsc --noEmit && tsc -b tsconfig.node.json --force'): exit 0, and tsc --listFilesOnly lists both changed .tsx files. (5) pnpm --filter @object-ui/console run lint: exit 0, '0 errors, 219 warnings'. The 2 warnings on AuditLogPage.tsx (err: any, and the useEffect calling load) are on code already present at base. ABLATION, one leg, prediction written before the run (exactly 2 pins red): HEAD held the fix. node ablation-replace.mjs replaced the anchor in ActorCell's face.name return so it renders truncate(face.id, 18). Evidence: 'anchor x1 to x0', 'replace x0 to x1', 'blob 970a60a9c060 to f13067506aca', 'ok mutation landed'. Result: 'Tests 2 failed | 5 passed (7)'. The two failures were "shows the seeded admin's name in the actor column, with the id on hover" and "choosing the admin sends user_id equal to the admin's id, and lists the admin's row", each reading 'Expected Admin User, Received usr_admin_0001'. Restore: 'blob after restore 970a60a9c060 == blob at HEAD 970a60a9c060, git diff HEAD empty', DIFF_HEAD_BYTES=0, git status empty. The suite imports ./AuditLogPage by relative path, so the subject is src and needs no dist leg. Two earlier lock calls ended in queue-timeout (exit 99), recorded as NOT MEASURED and then re-run to the results above.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "3 — (1) pr_create through the fleet relay: POST /repos/objectstack-ai/objectstack/dispatches executed POST /repos/objectstack-ai/objectui/pulls, giving draft #11739, read back byte-identical at 8729 bytes; (2) label-write.mjs --assign os-justin through the relay: POST /repos//issues/11739/assignees, read back as MATCHES, with zero label calls; (3) this os-dev-report comment through post-stamped.mjs: POST /repos//issues/11701/comments. Separately, 4 git pushes (the empty-branch probe and 3 commits), which are not REST.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (Acceptance notes of #11739). When a sys_user lookup dropdown opens, LookupField previews the email column through EmailCellRenderer, whose copy control is a button nested inside the option button. React logs 'button cannot contain a nested button' in this suite's stderr on a failing run. The code is @object-ui/fields LookupField; no test fails, and no public-door measurement was taken, so it is outside classes a, b and c. Dedupe words: LookupField nested button, EmailCellRenderer copy button, lookup option preview email",
"carrier: objectui#11739 (touches the file) · noted, not filed. AuditLogPage still reads through a raw fetch with credentials 'include' rather than the console adapter that AGENTS.md section 7 asks for. This predates the change, which kept the one fetch and added $expand. Read-only observation. Dedupe words: AuditLogPage raw fetch, audit log adapter, credentials include bearer"
],
"gates": [
{
"cmd": "pnpm exec vitest run apps/console/src/pages/system/AuditLogPage.actorName-11701.test.tsx apps/console/src/pages/consoleFaces.displayLocale-9909.test.tsx",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm exec vitest run apps/console/",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm --workspace-concurrency=2 --filter '@object-ui/console^...' run build",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm --filter @object-ui/console run type-check",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm --filter @object-ui/console run lint",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "node ablation-replace.mjs (ActorCell name to raw id) -- vitest run the new suite",
"exit": 1,
"head": "8e17dbf",
"note": "expected red: 2 failed / 5 passed as predicted; restore proven blob == HEAD, git diff HEAD empty"
},
{
"cmd": "node scripts/check-changeset-presence.mjs",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "node scripts/check-changeset-no-major.mjs",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "node scripts/check-changeset-fixed.mjs",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:new-line-citations",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:control-bytes",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:changeset-claims",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:pending-changeset-literals",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "node scripts/check-governed-queue-guard.mjs --test (3 changed paths)",
"exit": 0,
"head": "8e17dbf",
"note": "NOT GOVERNED"
},
{
"cmd": "pnpm check:vi-mock-specifiers",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:vi-mock-inherit",
"exit": 0,
"head": "8e17dbf",
"note": "red at 7569d75/f910b17 on the hand-listed app-shell factory; fixed in 8e17dbf"
},
{
"cmd": "pnpm check:vi-mock-override-shape",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:test-path-roots",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:i18n-keys",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:phantom-deps",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:unused-deps",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:element-data-source-declaration",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:handler-key-reads",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:metadata-write-doors",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:unreferenced-sources",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:eager-closure",
"exit": 2,
"head": "8e17dbf",
"note": "NOT MEASURED: prerequisite missing (apps/console/dist/eager-closure.json needs a console vite build, not run locally). Both mounts of the page are React lazy dynamic imports. CI owns it."
}
],
"line_budget": "n/a — no skills/** or line-ratcheted ledger touched. Diff: +333 / -13 across 3 files.",
"deviations": [
"Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and an emoji PR footer. I followed AGENTS.md's model-free trailer pair (Claude-Session + Co-authored-by: Claude) and os-dev.md's session-URL PR footer, which take precedence.",
"Zone 2 assumption 3 named UserField or LookupField. Measured: UserField always appends a banned-not-true filter, so I mounted LookupField with reference sys_user, which matches sys_audit_log.user_id's declared lookup type. Both are already exported, and no new export or prop was added.",
"Zone 2 assumption 2: I took the $expand path, not a batched sys_user read. The reason is in the summary and the PR body.",
"Gate list: I ran the whole console package (155 files) instead of only pages/system. Root-level suites are not on the package graph and were not run, and the diff adds no root test or script.",
"NOT MEASURED: check:eager-closure (prerequisite), a live backend and browser run (the objectstack checkout here is not installed or built), and repo-wide lint and pnpm test (CI's).",
"No i18n key and no built en.d.ts delta. Clause-2 stays no."
],
"files_changed": [
{
"path": ".changeset/11701-audit-actor-name.md",
"added": 11,
"removed": 0
},
{
"path": "apps/console/src/pages/system/AuditLogPage.actorName-11701.test.tsx",
"added": 215,
"removed": 0
},
{
"path": "apps/console/src/pages/system/AuditLogPage.tsx",
"added": 107,
"removed": 13
}
]
}
ACCEPT: PR objectui#11739 at 8e17dbf (Fixes #11701). No contract review is owed; it lands when CI is green
domain:ui execution seat 2 · session_01FngvPpdrnhHMdHHq6vwwju (os-justin) · 2026-10-06T18:01Z. Dev report: os-dev-report on this card. Claim 6021171727.
Shape:
The PR is a draft on base main (merge-base 22b503c). Its first line is Fixes #11701, and Clause-②: no starts a line.
It has 3 files, +333/−13, all inside the claim's surface. git merge-tree against main at 5a2a6ab is clean. NOT GOVERNED. The assignee is os-justin.
The commits: 7569d75 (the fix), f910b17 (the changeset), and 8e17dbf. 8e17dbf makes the new suite inherit the real @object-ui/app-shell surface, after check:vi-mock-inherit went red on a hand-listed factory at the first two heads.
Measured by the dev at objectstack 1fb274e6:
sys_audit_log.user_id is Field.lookup('sys_user').
The engine's expandRelatedRecords batch-loads the referenced users through the full sys_user read gate.
It keeps the bare id when a user is gone or not readable.
So $expand=user_id on the page's one read names the actors with no second request. This is the triage's first-named path.
Seat's own reading of the diff (AuditLogPage.tsx):
actorOf(row) maps the row to one face:
an expanded record gives its name and id;
a bare string gives the id;
a nulluser_id reads "System", with the actor principal (svc:NAME) on hover.
ActorCell shows the name with title set to the id, otherwise the truncated id in monospace, so it never shows a blank.
The drawer's ActorDetail shows the name with the full id below it, for copying.
The free-text actor box is LookupField from @object-ui/fields, already exported, with reference: 'sys_user' and the console's useAdapter(). The other apps/console pages under the same connected routes read that adapter too. It commits the chosen id to filter.user_id, and removing the chip, or "Clear filters", clears it.
UserField was not used, by measurement: it always adds a banned-not-true candidate filter, which would hide deactivated users from an audit search.
Clause-②: no, confirmed.@object-ui/console is an app. No export, prop, type member or i18n key is added. The page's labels stay English literals, and the lookup brings its existing translated strings.
Changeset (@object-ui/console: patch): the seat checked it sentence by sentence against the diff. It covers the expanded read, the name with the id on hover, the bare id for an unresolved user, "System" with the principal, the drawer row, and the lookup filter with its clear path. patch fits.
Tests and gates (dev, measured at 8e17dbf):
apps/console/: 155 files, 1806 tests, green, including the new AuditLogPage.actorName-11701.test.tsx.
The console closure build (35 packages), type-check and lint: 0 errors.
The check:* set, including the three vi-mock gates: all exit 0.
One ablation leg (the name face reverted to the raw id) went 2 red / 5 green as predicted, both reading Expected Admin User, Received usr_admin_0001. It was restored by blob.
Declared NOT MEASURED: check:eager-closure (a prerequisite was missing; both mounts of the page are lazy imports) and a live backend run. CI owns them.
Out-of-scope findings (2), Acceptance notes, not filed:
LookupField's option preview nests EmailCellRenderer's copy button inside the option button. It is a React DOM-nesting warning, and no test fails.
The page still reads through a raw fetch with credentials: 'include', not the console adapter. This predates the change, which kept the one read.
CI on 8e17dbf: in progress at this read (29 success, 3 skipped, 10 running, 0 failed).
Activity
objectstack-fleet commentedon Oct 6, 2026
Claim: PM loop round 1
Session:
session_01FngvPpdrnhHMdHHq6vwwjuAccount:
os-justinBranch:
claude/issue-11701-audit-actor-nameWorktree:
objectui-issue-11701Domain:
domain:uiSeat:
domain:ui#2File surface:
apps/console/src/pages/system/AuditLogPage.tsx, in these places (as of0cfe772):/data/sys_audit_logfetch (about:125–:168);:112,:130,:232–:238);:310);:363–:364).apps/console/src/pages/system/*.test.ts(x)) and.changeset/11701-*.md.Stop on breach; explain in the report.
Container & model:
M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover the surface: no path-derived mandate; default tier)Clause-②: no
Thread-read: none
Ruling-ref: the card body's triage (split from objectui#11697): the list names the actor by populating
user_idon the fetch, or by the existing lookup display, with the id still on hover or copy; the actor filter is a user lookup. Retrieved this round.Serial constraints cleared:
noneblocking.apps/console/src/pages/system/**. Read: objectui#11728, feat(i18n): render instants in the served display zone (objectui#11693) #11729, fix(plugin-view,console,layout,components,fields): name and nest the controls axe flagged on the list and settings pages (objectui#11690) #11732 (other seats), fix(fields,plugin-detail,plugin-grid,app-shell,i18n): read-only booleans, the boolean list face and the Home greeting follow the locale (objectui#11689) #11731, fix(app-shell): DefaultRegisterPage moves a signed-in visitor on instead of an empty layout (objectui#11714) #11734, fix(app-shell,i18n): the organization slug field is read-only while environments reference the slug (objectui#11720) #11735 (this seat), feat(cli):objectui validateandobjectui checkjudge through the strict authoring face (objectui#5250, slice A) #11069, and the release PR objectui#11600.area:accesshas no card in flight in any seat.Read 2026-10-06T16:53Z.
Why
Clause-②: no:@object-ui/console, an app. It consumes published pieces and adds no export, prop, schema key or i18n key. Its labels are English literals today, and translating the page is not this card.yesand runs the at-tier contract review before enqueue.Generated by Claude Code
objectstack-fleet commentedon Oct 6, 2026
os-dev-report
{
"issue": 11701,
"status": "done",
"branch": "claude/issue-11701-audit-actor-name",
"pr": "#11739",
"session": "session_01FngvPpdrnhHMdHHq6vwwju",
"premise_still_valid": true,
"summary": "The Audit Log page's one /api/v1/data/sys_audit_log read now sends $expand=user_id. At objectstack 1fb274e61c, user_id is Field.lookup('sys_user'), and the engine's expandRelatedRecords batch-loads the users in place of their ids through the full sys_user read gate, keeping the bare id when a user is missing or refused. The actor column shows the name with the id as its title. An unresolved user shows the id, a null user_id reads 'System' with the actor principal on hover, and the drawer shows the name and the full id. The free-text actor box is now LookupField from @object-ui/fields with reference sys_user, already exported, so nothing new is exported. It writes the chosen id to filter.user_id, and removing the chip clears it. UserField was not used because it always adds a banned-not-true candidate filter, which would hide deactivated users from an audit search. No export, prop, type member or i18n key changed (Clause-2: no), and the changeset is '@object-ui/console': patch.",
"tests": "All heavy runs went through os-verify-lock.sh with slot issue-11701, at HEAD 8e17dbf. (1) pnpm exec vitest run on the new AuditLogPage.actorName-11701.test.tsx and consoleFaces.displayLocale-9909.test.tsx: 'Test Files 2 passed (2) / Tests 19 passed (19)'. (2) pnpm exec vitest run apps/console/ from the repo root: 'Test Files 155 passed (155) / Tests 1806 passed (1806)'. (3) pnpm --workspace-concurrency=2 --filter '@object-ui/console^...' run build: exit 0, 35 packages. (4) pnpm --filter @object-ui/console run type-check (echoed 'tsc --noEmit && tsc -b tsconfig.node.json --force'): exit 0, and tsc --listFilesOnly lists both changed .tsx files. (5) pnpm --filter @object-ui/console run lint: exit 0, '0 errors, 219 warnings'. The 2 warnings on AuditLogPage.tsx (err: any, and the useEffect calling load) are on code already present at base. ABLATION, one leg, prediction written before the run (exactly 2 pins red): HEAD held the fix. node ablation-replace.mjs replaced the anchor in ActorCell's face.name return so it renders truncate(face.id, 18). Evidence: 'anchor x1 to x0', 'replace x0 to x1', 'blob 970a60a9c060 to f13067506aca', 'ok mutation landed'. Result: 'Tests 2 failed | 5 passed (7)'. The two failures were "shows the seeded admin's name in the actor column, with the id on hover" and "choosing the admin sends user_id equal to the admin's id, and lists the admin's row", each reading 'Expected Admin User, Received usr_admin_0001'. Restore: 'blob after restore 970a60a9c060 == blob at HEAD 970a60a9c060, git diff HEAD empty', DIFF_HEAD_BYTES=0, git status empty. The suite imports ./AuditLogPage by relative path, so the subject is src and needs no dist leg. Two earlier lock calls ended in queue-timeout (exit 99), recorded as NOT MEASURED and then re-run to the results above.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "3 — (1) pr_create through the fleet relay: POST /repos/objectstack-ai/objectstack/dispatches executed POST /repos/objectstack-ai/objectui/pulls, giving draft #11739, read back byte-identical at 8729 bytes; (2) label-write.mjs --assign os-justin through the relay: POST /repos//issues/11739/assignees, read back as MATCHES, with zero label calls; (3) this os-dev-report comment through post-stamped.mjs: POST /repos//issues/11701/comments. Separately, 4 git pushes (the empty-branch probe and 3 commits), which are not REST.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (Acceptance notes of #11739). When a sys_user lookup dropdown opens, LookupField previews the email column through EmailCellRenderer, whose copy control is a button nested inside the option button. React logs 'button cannot contain a nested button' in this suite's stderr on a failing run. The code is @object-ui/fields LookupField; no test fails, and no public-door measurement was taken, so it is outside classes a, b and c. Dedupe words: LookupField nested button, EmailCellRenderer copy button, lookup option preview email",
"carrier: objectui#11739 (touches the file) · noted, not filed. AuditLogPage still reads through a raw fetch with credentials 'include' rather than the console adapter that AGENTS.md section 7 asks for. This predates the change, which kept the one fetch and added $expand. Read-only observation. Dedupe words: AuditLogPage raw fetch, audit log adapter, credentials include bearer"
],
"gates": [
{
"cmd": "pnpm exec vitest run apps/console/src/pages/system/AuditLogPage.actorName-11701.test.tsx apps/console/src/pages/consoleFaces.displayLocale-9909.test.tsx",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm exec vitest run apps/console/",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm --workspace-concurrency=2 --filter '@object-ui/console^...' run build",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm --filter @object-ui/console run type-check",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm --filter @object-ui/console run lint",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "node ablation-replace.mjs (ActorCell name to raw id) -- vitest run the new suite",
"exit": 1,
"head": "8e17dbf",
"note": "expected red: 2 failed / 5 passed as predicted; restore proven blob == HEAD, git diff HEAD empty"
},
{
"cmd": "node scripts/check-changeset-presence.mjs",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "node scripts/check-changeset-no-major.mjs",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "node scripts/check-changeset-fixed.mjs",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:new-line-citations",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:control-bytes",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:changeset-claims",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:pending-changeset-literals",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "node scripts/check-governed-queue-guard.mjs --test (3 changed paths)",
"exit": 0,
"head": "8e17dbf",
"note": "NOT GOVERNED"
},
{
"cmd": "pnpm check:vi-mock-specifiers",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:vi-mock-inherit",
"exit": 0,
"head": "8e17dbf",
"note": "red at 7569d75/f910b17 on the hand-listed app-shell factory; fixed in 8e17dbf"
},
{
"cmd": "pnpm check:vi-mock-override-shape",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:test-path-roots",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:i18n-keys",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:phantom-deps",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:unused-deps",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:element-data-source-declaration",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:handler-key-reads",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:metadata-write-doors",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:unreferenced-sources",
"exit": 0,
"head": "8e17dbf"
},
{
"cmd": "pnpm check:eager-closure",
"exit": 2,
"head": "8e17dbf",
"note": "NOT MEASURED: prerequisite missing (apps/console/dist/eager-closure.json needs a console vite build, not run locally). Both mounts of the page are React lazy dynamic imports. CI owns it."
}
],
"line_budget": "n/a — no skills/** or line-ratcheted ledger touched. Diff: +333 / -13 across 3 files.",
"deviations": [
"Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and an emoji PR footer. I followed AGENTS.md's model-free trailer pair (Claude-Session + Co-authored-by: Claude) and os-dev.md's session-URL PR footer, which take precedence.",
"Zone 2 assumption 3 named UserField or LookupField. Measured: UserField always appends a banned-not-true filter, so I mounted LookupField with reference sys_user, which matches sys_audit_log.user_id's declared lookup type. Both are already exported, and no new export or prop was added.",
"Zone 2 assumption 2: I took the $expand path, not a batched sys_user read. The reason is in the summary and the PR body.",
"Gate list: I ran the whole console package (155 files) instead of only pages/system. Root-level suites are not on the package graph and were not run, and the diff adds no root test or script.",
"NOT MEASURED: check:eager-closure (prerequisite), a live backend and browser run (the objectstack checkout here is not installed or built), and repo-wide lint and pnpm test (CI's).",
"No i18n key and no built en.d.ts delta. Clause-2 stays no."
],
"files_changed": [
{
"path": ".changeset/11701-audit-actor-name.md",
"added": 11,
"removed": 0
},
{
"path": "apps/console/src/pages/system/AuditLogPage.actorName-11701.test.tsx",
"added": 215,
"removed": 0
},
{
"path": "apps/console/src/pages/system/AuditLogPage.tsx",
"added": 107,
"removed": 13
}
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 6, 2026
ACCEPT: PR objectui#11739 at
8e17dbf(Fixes #11701). No contract review is owed; it lands when CI is greendomain:uiexecution seat 2 ·session_01FngvPpdrnhHMdHHq6vwwju(os-justin) · 2026-10-06T18:01Z. Dev report:os-dev-reporton this card. Claim6021171727.Shape:
main(merge-base22b503c). Its first line isFixes #11701, andClause-②: nostarts a line.git merge-treeagainstmainat5a2a6abis clean. NOT GOVERNED. The assignee isos-justin.7569d75(the fix),f910b17(the changeset), and8e17dbf.8e17dbfmakes the new suite inherit the real@object-ui/app-shellsurface, aftercheck:vi-mock-inheritwent red on a hand-listed factory at the first two heads.Measured by the dev at objectstack
1fb274e6:sys_audit_log.user_idisField.lookup('sys_user').expandRelatedRecordsbatch-loads the referenced users through the fullsys_userread gate.So
$expand=user_idon the page's one read names the actors with no second request. This is the triage's first-named path.Seat's own reading of the diff (
AuditLogPage.tsx):actorOf(row)maps the row to one face:nameandid;nulluser_idreads "System", with theactorprincipal (svc:NAME) on hover.ActorCellshows the name withtitleset to the id, otherwise the truncated id in monospace, so it never shows a blank.ActorDetailshows the name with the full id below it, for copying.LookupFieldfrom@object-ui/fields, already exported, withreference: 'sys_user'and the console'suseAdapter(). The otherapps/consolepages under the same connected routes read that adapter too. It commits the chosen id tofilter.user_id, and removing the chip, or "Clear filters", clears it.UserFieldwas not used, by measurement: it always adds abanned-not-true candidate filter, which would hide deactivated users from an audit search.Clause-②: no, confirmed.
@object-ui/consoleis an app. No export, prop, type member or i18n key is added. The page's labels stay English literals, and the lookup brings its existing translated strings.Changeset (
@object-ui/console:patch): the seat checked it sentence by sentence against the diff. It covers the expanded read, the name with the id on hover, the bare id for an unresolved user, "System" with the principal, the drawer row, and the lookup filter with its clear path.patchfits.Tests and gates (dev, measured at
8e17dbf):apps/console/: 155 files, 1806 tests, green, including the newAuditLogPage.actorName-11701.test.tsx.type-checkandlint: 0 errors.check:*set, including the threevi-mockgates: all exit 0.Expected Admin User, Received usr_admin_0001. It was restored by blob.check:eager-closure(a prerequisite was missing; both mounts of the page are lazy imports) and a live backend run. CI owns them.Out-of-scope findings (2), Acceptance notes, not filed:
LookupField's option preview nestsEmailCellRenderer's copy button inside the option button. It is a React DOM-nesting warning, and no test fails.fetchwithcredentials: 'include', not the console adapter. This predates the change, which kept the one read.CI on
8e17dbf: in progress at this read (29 success, 3 skipped, 10 running, 0 failed).Generated by Claude Code
objectstack-fleet commentedon Oct 6, 2026
Landed: PR objectui#11739 →
maina526249, verified by content.Fixesclosed this carddomain:uiexecution seat 2 ·session_01FngvPpdrnhHMdHHq6vwwju(os-justin) · 2026-10-06T18:27Z.The merge.
a526249went through the merge queue. It has one parent,5a2a6ab, and is an ancestor oforigin/main.git merge-treeof the parent and the reviewed head8e17dbf(tree88a3b795…on both).3cdb6ecf…on both).No contract review was owed:
Clause-②: no(ACCEPT6022351222).Content check against the first parent:
5a2a6aba526249$expanduser_idon theAuditLogPagelist readLookupFieldAuditLogPage.actorName-11701.test.tsxpresentClosures.
Fixes #11701closed this card as completed at the merge. No other issue closed in the landing window.pm:dispatchedcomes off in this stroke.Recorded, not filed:
LookupField's option preview nests a copy button inside the option button (a DOM-nesting warning).fetch, not the console adapter. This was already true before the change.Generated by Claude Code
fix(console): the audit log names the actor and filters by a user loo…