Repository navigation
Description
Filing gate: ① product defect, user-visible, reproduced in a browser and at the REST door.
What happened
On main at c20d397 (@objectstack/* 18.2.0), a fresh pnpm demo (and pnpm demo:zh), signed in as the account the banner names (admin@objectos.ai, "Dev Admin" / 演示管理员):
- My week row: the row actions show only Edit and Delete. There is no Complete and no Skip.
- Task record header: Edit and ⋯ only. The ⋯ menu holds Add to favorites, Share and Delete.
- REST:
POST /api/v1/actions/duly_task/duly_task_complete/<id>answers403 PERMISSION_DENIED, "requires capability [duly.task.update_status] — caller is missing [duly.task.update_status]". - Session: the account holds
admin_full_accessandorganization_admin_no_bypass, withpositions: platform_admin, org_owner, everyone. It holds noduly_*set, so it has none of theduly.*capabilities the actions require (requiredPermissionsinsrc/actions/*.actions.ts).
The boot banner says so itself: "platform admin — … but NO app-declared capability, so an app that gates … may show it an empty menu; grant it a permission set under Setup → Users".
The same account owns 4 tasks in My week, so the evaluator is looking at their own work with no way to tick it. The one-click completion the product is designed around (docs/product/design-principles.md §9) is invisible in the demo.
17.3.0 (74342a1) behaves the same: the task record shows no Complete either. This is not an 18.2 regression.
Verified that the binding is the whole cause
In the same demo, Setup → Users → Dev Admin → Permission Sets → New, I granted duly_member and then duly_admin, then signed in again:
- My week rows show a Complete button, and the ⋯ menu holds Skip.
- The task record header shows Complete, then Undo once the task is done.
- Toasts: "Done." / "Reopened." / "Skipped." in English, and 已完成。/ 已重新打开。/ 已跳过。 in zh-CN. This is the 18.2 template-slot
successMessage, working. - Role catalog: the list toolbar shows Apply to people, and it opens its dialog.
Fix direction (for the dev and seat to choose)
- A. Bind the demo admin in the demo fixture. Seed
sys_user_permission_setrows forADMIN→duly_adminandduly_member, beside the natural-key-onlysys_userrow insrc/data/demo-org.ts. Demo only;pnpm devstays empty. - B. Grant both in
scripts/demo.mjs's priming step, which already writes to the account (the zh-CN rename), and verify the grant the way it verifies sign-in.
Either way, add a check that the demo's sign-in account holds duly.task.update_status. Today every action test passes while the person trying the demo cannot see the action.
docs/getting-started.md §8 covers granting the people the duty names, but not the admin. On a plain pnpm dev the admin also needs a Duly set to use the app as a person. Worth a sentence there too.
Business reason
Who benefits: anyone evaluating Duly through pnpm demo, which is the template's front door (M4, #127). The scenario: the evaluator opens My week, sees their own late task, and looks for the tick. Without the fix the core interaction never appears, and the demo reads as a read-only report.
Reader
The duly pm-dispatch seat dispatches this to a dev. It is small and demo-only.
Duplicate check
demo admin no permission set actions hidden requiredPermissions platform admin capability in objectstack-ai/duly: 0 hits. Related: #60 (on hold, "the three task actions do not render anywhere"). I am commenting there separately with the 18.2 measurement.
Evidence
Screenshots in the project's shared folder duly-18.2-browser-check/:
en-US/21-task-record.pnganden-US/22-task-more.png: without the set.en-US/43-permset-granted.png: the grant.en-US/50-myweek-member.png,en-US/53-done-toast.png,en-US/55-undo-toast.pnganden-US/57-skip-toast.png: with the set.zh-CN/53-done-toast.png.
Activity
objectstack-fleet commentedon Oct 27, 2026
Seat triage
First touch by the duly lane seat at 2026-10-27T11:31Z (session
session_011HyoSXGRy6L13mYq1Hp4n1).priority:p1, size S,M4,pm:ready. This is not a regression; 17.3 behaves the same. Still,pnpm demois the template's front door (Epic: Duly as the standard ObjectStack template app (M4 — install it, load your catalog, run it without us) #127), and today it hides the product's core interaction.sys_user_permission_setrows (duly_adminandduly_member) in the demo fixture beside the admin'ssys_userrow insrc/data/demo-org.ts, so they ship with the demo seed only. AGENTS.md's metadata-first rule asks for data over script, andpnpm devstays empty, as Make the repository template-shaped: empty first boot, template-readiness checklist, README and getting-started for a reader with their own spreadsheet #132 requires. Use option B (scripts/demo.mjspriming step) only if a measurement shows the seed cannot bind to the minted admin, and report that as a fork first.duly.task.update_statusand every otherduly.*capability the declared actions'requiredPermissionsname. Derive the list from the action metadata, not a hand list, so a new action cannot ship unreachable to the person trying the demo. The three task actions from #4 do not render anywhere in the UI — one-click completion has no button #60 is closed on the 18.2 re-measure (comment 6440766640).docs/getting-started.md§8. On a plainpnpm dev, the admin needs a Duly permission set to use the app as a person.pnpm demoandpnpm demo:zh. Complete and Skip show on a My week row, and Complete then Undo on the record header. ThePOST .../duly_task_complete/<id>call answers 200. Include one screenshot per locale.src/data/demo-org.ts(andsrc/data/demo-zh.tsonly if a string is needed), one test file,docs/getting-started.md.Clause-②: no.Metadata-protocol: none. It does not intersect Demo fixture drifts with the wall clock: "Not moving" leaves 2–3 from 2026-11-08 and "Stalled-not-late" hits 0 from 2027-01-01 #150's diff (demo-catalog.ts,demo-history.ts). Neutral default progress phrases and readable position names everywhere — remove the last customer-specific defaults (folds #120) #128 and Catalog pack format + first pack: food-safety recurring duties (seed-only, no code) #134 queue behind it on demo data.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 2
Session:
session_011HyoSXGRy6L13mYq1Hp4n1Account:
os-warren(the seat's linked user; the card's assignee)Branch:
claude/project-thread-xj2bug(platform-assigned card-thread branch, atorigin/mainc20d397)Worktree:
duly-issue-152Domain: n/a. objectstack-ai/duly is a single-lane app repo with no
domain:*.Seat:
repo:duly#1File surface:
src/data/demo-org.ts(andsrc/data/demo-zh.tsonly if a string is needed), one new test file,docs/getting-started.md. Stop on any breach, includingscripts/demo.mjs, which needs a fork report first, and explain it in the report.Container & model:
S,mode:thread,model: TIER_DEFAULT(hand-derived),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: the app's demo fixture; see the seat triage.
Thread-read: 6440833881
Premise: holds. The card measured this on
c20d397: the demo admin holds noduly_*set, andduly_task_completeanswers 403.Serial constraints cleared: #150 is in flight on
src/data/demo-catalog.ts,src/data/demo-history.tsandtest/demo-calendar.test.ts, and #151 onsrc/objects/task.object.ts,src/objects/assignment.object.ts,src/views/task.view.tsand a test. Neither intersects this surface. #128 and #134 queue behind it.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim amendment (2026-10-27T11:41Z). The surface widens as measured by the card thread. This is not a fork: option A holds, and
scripts/demo.mjsstays untouched.src/data/org.seed.ts: anadminPermissionSetSeedbesideuserSeed. The admin'ssys_userrow lives here, not indemo-org.ts.src/data/index.ts: one barrel line adding it todemoSeeds, so it ships with the demo dataset only.test/seed.test.ts,test/seed-locale.test.ts,test/business-unit-membership.test.ts: onekernel.use(new SecurityPlugin())line each.sys_user_permission_setis registered by SecurityPlugin, and on 18.2 one unregistered object makes the seed loader fail as a whole. This is the same pattern these suites already use forSharingServicePlugin.test/demo-admin-capabilities.test.ts(new) is the named test file.Serial note: #150 claims
test/seed*.test.ts, and its diff, as reported, touchesdemo-catalog.ts,demo-history.tsandtest/demo-calendar.test.ts. Whichever of #150 and #152 lands second mergesmainand re-runs the full suite, including the demo-calendar sweep, before the seat lands it.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{ "issue": 152, "status": "done", "branch": "claude/project-thread-xj2bug", "pr": "https://github.com/objectstack-ai/duly/pull/154", "session": "session_01JQwxbYxhsVHjKfVacPmJcj", "premise_still_valid": true, "summary": "Option A, declarative. The demo seed now carries adminPermissionSetSeed (sys_user_permission_set, upsert keyed on user_id + permission_set) granting ADMIN duly_member and duly_admin; ADMIN_PERMISSION_SETS lives beside ADMIN in demo-org.ts. On a fresh pnpm demo and demo:zh the grants bind to the account plugin-auth mints (sys_user stays at 13 rows, no ghost), so no fork and scripts/demo.mjs is untouched. New test/demo-admin-capabilities.test.ts derives the required capabilities from every declared action's requiredPermissions and resolves the seeded admin through plugin-security buildContextForUser. Surface was amended by the seat to org.seed.ts, index.ts and one SecurityPlugin mount in each of the three suites that boot the demo seed.", "tests": "All at 12fae85. pnpm test exit 0: Test Files 37 passed (37), Tests 894 passed (894), demo-calendar 3/3 (366-day sweep, fixture-only, no kernel). New suite 3/3. Before the SecurityPlugin mounts, seed.test/seed-locale/business-unit-membership went 13 red: SeedLoaderService failed as a whole on Object 'sys_user_permission_set' not found. Ablation one leg: ADMIN_PERMISSION_SETS cut to duly_member, the capability test went red naming duly_catalog_apply, duly_catalog_sync, duly_catalog_apply_to_people (1 failed 2 passed); restored with git checkout HEAD, git diff HEAD empty. Browser on fresh pnpm demo (3000) and demo:zh (3300): My week row shows Complete, row menu holds Skip (dialog, toast Skipped. / 已跳过。), row Complete toast Done. / 已完成。, record header Complete then Undo (Reopened. / 已重新打开。). REST: POST /api/v1/actions/duly_task/duly_task_complete/ID 200 in both locales, undo 200. Screenshots: project folder duly-152-demo-admin/ (en-US, zh-CN, five each).", "gates": "Local: pnpm validate exit 0 (9 warnings, identical count to base c20d397 measured on a detached base checkout); pnpm typecheck exit 0; pnpm test exit 0; pnpm build exit 0. dispatch-gates.mjs not run: it derives objectstack's families and duly has no equivalent; the repo's own gates are the four package scripts. CI: PR #154 check-run verify in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm", "mcp_calls": "6 — read only: mcp__github__issue_read x5 (152 get, 152 comments x3, 60 comments), mcp__github__pull_request_read x1 (154 check runs); no MCP write", "api_writes": "2 — fleet-write relay: pr_create on objectstack-ai/duly (POST /repos/objectstack-ai/duly/pulls + POST /issues/154/assignees), this os-dev-report comment (POST /repos/objectstack-ai/duly/issues/152/comments); plus git push (not REST)", "open_questions": [], "out_of_scope_findings": [ "class: observation, not filed · reach: test kernels only (a real boot always mounts SecurityPlugin) · SeedLoaderService on 18.2 fails the whole batch when one dataset names an object the registry does not hold (WARN SeedLoaderService failed, falling back to basic insert), so natural keys stop resolving for every other dataset · dedupe words: SeedLoaderService unregistered object fallback basic insert natural key · carrier: none, noted in PR Acceptance notes", "deviation: PR review request to os-warren (session-context instruction) not sent — os-dev write budget is push + pr_create + report; the seat can add it with pr_request_reviewers", "deviation: os-dev rule 'stop on breach until the amendment is posted' — I continued after messaging the seat and before the amendment landed; seat noted it" ] }Generated by Claude Code