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
Measure which template knobs a customer can change in Setup / Studio without code — configurability matrix #129
The M4 gate is "a customer can install it, load their own catalog, and run it without us". Today every knob a deployment is likely to turn lives in TypeScript metadata: the duty catalog, frequencies and anchors, the stagnation thresholds (14 / 30 days) in src/datasets/stagnation.dataset.ts, default grace and lead days, the progress phrases, the reminder email templates, the dashboard tile texts. Nobody has measured which of these the platform's Setup / Studio surface can change at runtime on @objectstack/* 17.3.0, and which are compile-time only.
What "done" is
A measured matrix, committed as docs/product/configurability.md, one row per knob:
| knob | where it is authored | editable in Setup / Studio? (measured) | survives objectstack build redeploy? | if not: platform issue # |
Rows to cover at minimum: catalog items (create / edit / retire), duty frequency & anchor & offset & lead & grace, progress phrase options, stagnation thresholds, dashboard widget titles and descriptions, email template subject/body, positions and permission sets, business units and membership, locale bundles.
Method: boot pnpm dev (empty) on a free port, sign in as the dev admin, use the console's Setup / Studio / metadata-admin surfaces to attempt each change, and read the result back through /api/v1/meta/* and a browser screenshot. Record "editable", "editable but lost on redeploy", or "not reachable". For every "not reachable" that a template customer would need, file an objectstack-ai/objectstack or objectstack-ai/objectui issue (invented placeholders, measured evidence, the version in the title) and link it in the row. Do not build an app-side editor and do not move metadata into data to dodge the gap — the matrix is the deliverable; the gaps are the platform's.
Close with a one-paragraph verdict at the top: what a customer can do alone today, and the shortest list of platform fixes that would make the rest possible.
Not in this card
Any code change to the app beyond what the measurement itself requires (none expected).
Claim: PM loop round 1
Session: session_011HyoSXGRy6L13mYq1Hp4n1
Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-as72tp (platform-assigned card-thread branch; the card thread may push only this branch)
Worktree: duly-issue-129
Domain: n/a — objectstack-ai/duly is a single-lane app repo (no domain:*); the duly lane seat does first-touch itself
Seat: repo:duly#1
File surface: docs/product/configurability.md (new) only; no app code (stop on breach; explain in the report)
Container & model: M, mode:thread, model: TIER_DEFAULT (hand-derived: dispatch-gates answers only objectstack's tree), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Premise: holds
Serial constraints cleared: none — surface disjoint from #132 and #133
Triage (first touch, 2026-10-26T06:39Z): lands in objectstack-ai/duly; rationale: epic #127 item, maintainer ruling quoted in the epic body; type Task; ungraded (this repo has no priority:p2 label yet, noted for the round report).
{
"issue": 129,
"status": "done",
"branch": "claude/project-thread-as72tp",
"pr": "https://github.com/objectstack-ai/duly/pull/140",
"session": "session_014zY3sFHEDCS4iGfZUa9x33",
"premise_still_valid": true,
"summary": "Committed docs/product/configurability.md: a measured matrix on @objectstack/* 17.3.0 (lockfile; 18.1.0 latest on npm, not measured), 16 rows, verdict paragraph at top. Catalog items, per-record cadence, business units and membership, positions (data door) and cloned permission sets are editable data and survive objectstack build + restart. Select vocabularies, field defaults, progress phrases, stagnation thresholds (dataset/page), flow and job timing and the locale list are not reachable: PUT meta answers 403 NOT_OVERRIDABLE (org overlay allowed only for view, dashboard, report, translation, email_template) and Studio lists Duly as Read-only browsable. Dashboard/view/email-template/translation texts are writable through the metadata API only, no console screen; three platform findings recorded with evidence. Premise held: nothing in the card was already done.",
"tests": "No code change, no test added. Measurement scripts (scratchpad, not committed): REST writes + readback via GET /api/v1/meta/TYPE/NAME, /layers and sys_* rows, Playwright screenshots (11 kept in project files duly-129-configurability/), then server stopped, objectstack build exit 0, reboot on same SQLite, snapshot diff: data rows identical; position meta-door edits appeared only after boot; email_template meta-door edits reverted in sys_email_template while /layers still effective. No ablation: docs-only diff.",
"gates": "Local, worktree duly-issue-129 at head ba7155f, exit captured before any pipe: pnpm validate EXIT=0 (expected hierarchy-security warning only); pnpm typecheck EXIT=0; pnpm test EXIT=0 (Test Files 35 passed (35), Tests 885 passed (885)); pnpm build EXIT=0. dispatch-gates.mjs not run: it answers only objectstack's tree; duly gate list hand-derived from AGENTS.md (the four gates). PR check-runs: in_progress at report time, not awaited.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm; duly has no dogfood battery",
"mcp_calls": "5 — mcp__github__issue_read x5 (get #129, get_comments #129 x3, get #127); zero write tools",
"api_writes": "3 — relay pr_create: POST /repos/objectstack-ai/duly/pulls (draft, #140) + POST /repos/objectstack-ai/duly/issues/140/assignees (os-warren); post-stamped comment POST /repos/objectstack-ai/duly/issues/129/comments (this report). git push is not counted.",
"open_questions": [],
"deviations": [
"Measurement boot (read-only to tracked files; dist/ and OS_HOME scratch only) started before the Claim landed; the first tracked edit came after reading Claim comment 6409898761 naming this branch.",
"Worktree: the platform branch was checked out on the shared checkout, so that checkout was detached and the branch added as worktree ../duly-issue-129; the dev servers ran from the shared checkout (same commit 004380e).",
"PR body line 1 is the harness attribution block, Fixes #129 follows it on line 3 (os-dev exception for the harness attribution line); the order asked for line 1.",
"Session context asked to request os-warren as reviewer via MCP update_pull_request; not done (order forbids MCP writes). The seat can request it.",
"Screenshots per row are in /mnt/project-files/duly-129-configurability/, not committed (file surface is the one doc); the doc names console screens by URL and label instead."
],
"out_of_scope_findings": [
"class: a · reach: PUT /api/v1/meta/dashboard/duly_duty_health 200 'Saved customization overlay', GET same item and the console keep serving the package widget title, /layers effective carries the edit; same on view duly_task.default label · evidence: RestServer.translateMetaItem applies translateMetadataDocument after the overlay and passes packagedBase for object only (rest 17.3.0 dist index.js ~75127) · Seam: runtime: RestServer.translateMetaItem | renderer: console dashboard · dedupe words: overlay shadowed by translation, dashboard widget title overlay ignored, translateMetaItem packagedBase, view label overlay",
"class: a · reach: PUT /api/v1/meta/email_template/duly.task_overdue 200 projectionApplied, sys_email_template row changed; after objectstack build + restart the row is back to package text (updated_at = boot) while /layers effective and the active sys_metadata overlay still claim the edit; a second PUT with locale zh-CN replaced the en overlay of the same name · evidence: matrix row 'Email template subject / body' · dedupe words: email template overlay lost on restart, sys_email_template projection reverted, email_template overlay locale, projectionApplied",
"class: a · reach: PUT /api/v1/meta/position/acme_auditor 200 'Saved position … state=active', GET /api/v1/data/sys_position (Setup → Positions) omits it until the next boot; label edit on duly_member same; permission PUT on the same store projects at once · dedupe words: position projection sys_position, metadata position not listed, position overlay boot only",
"class: gap (card-requested filing, not a/b/c) · reach: PUT /api/v1/meta/object/duly_duty with full authored object 403 NOT_OVERRIDABLE; PUT /api/v1/meta/field/duly_task.progress 403 not_overridable · G1 package object select options and defaultValue not org-overridable (frequency vocabulary, default lead/grace, progress phrases) · dedupe words: org overlay object select options, picklist extension package object, field defaultValue overlay",
"class: gap (card-requested filing) · reach: PUT /api/v1/meta/dataset/duly_stagnation and /page/duly_member 403 NOT_OVERRIDABLE · G2 dataset and page not org-overridable, so the 14-day threshold cannot move in one place · dedupe words: dataset allowOrgOverride, page overlay NOT_OVERRIDABLE, dataset measure parameter",
"class: gap (card-requested filing, objectui) · reach: no Setup sidebar entry or edit control for translation or email_template overlays; Email Template list only at /_console/apps/setup/sys_email_template by URL; dashboard page shows no edit control · G3 · dedupe words: translation editor Setup, email template Setup navigation, dashboard edit control",
"class: gap (card-requested filing) · reach: PUT /api/v1/meta/translation/duly_fr 200 stored, Accept-Language fr served English · G4 supportedLocales compile-time · dedupe words: add locale runtime, supportedLocales Setup, translation fallback unsupported locale",
"class: gap (card-requested filing) · reach: PUT /api/v1/meta/job/duly_dispatch 403 not_overridable; registry flow allowOrgOverride false · G5 flow schedule offsets and job cron not tunable per deployment · dedupe words: flow schedule override, job cron org override, time_relative offsetDays configurable"
]
}
Activity
objectstack-fleet commentedon Oct 26, 2026
Claim: PM loop round 1
Session:
session_011HyoSXGRy6L13mYq1Hp4n1Account:
os-warren(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-as72tp(platform-assigned card-thread branch; the card thread may push only this branch)Worktree:
duly-issue-129Domain: n/a — objectstack-ai/duly is a single-lane app repo (no
domain:*); the duly lane seat does first-touch itselfSeat:
repo:duly#1File surface:
docs/product/configurability.md(new) only; no app code (stop on breach; explain in the report)Container & model:
M,mode:thread,model: TIER_DEFAULT (hand-derived: dispatch-gates answers only objectstack's tree),effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Premise: holds
Serial constraints cleared: none — surface disjoint from #132 and #133
Triage (first touch, 2026-10-26T06:39Z): lands in objectstack-ai/duly; rationale: epic #127 item, maintainer ruling quoted in the epic body; type Task; ungraded (this repo has no
priority:p2label yet, noted for the round report).Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 129, "status": "done", "branch": "claude/project-thread-as72tp", "pr": "https://github.com/objectstack-ai/duly/pull/140", "session": "session_014zY3sFHEDCS4iGfZUa9x33", "premise_still_valid": true, "summary": "Committed docs/product/configurability.md: a measured matrix on @objectstack/* 17.3.0 (lockfile; 18.1.0 latest on npm, not measured), 16 rows, verdict paragraph at top. Catalog items, per-record cadence, business units and membership, positions (data door) and cloned permission sets are editable data and survive objectstack build + restart. Select vocabularies, field defaults, progress phrases, stagnation thresholds (dataset/page), flow and job timing and the locale list are not reachable: PUT meta answers 403 NOT_OVERRIDABLE (org overlay allowed only for view, dashboard, report, translation, email_template) and Studio lists Duly as Read-only browsable. Dashboard/view/email-template/translation texts are writable through the metadata API only, no console screen; three platform findings recorded with evidence. Premise held: nothing in the card was already done.", "tests": "No code change, no test added. Measurement scripts (scratchpad, not committed): REST writes + readback via GET /api/v1/meta/TYPE/NAME, /layers and sys_* rows, Playwright screenshots (11 kept in project files duly-129-configurability/), then server stopped, objectstack build exit 0, reboot on same SQLite, snapshot diff: data rows identical; position meta-door edits appeared only after boot; email_template meta-door edits reverted in sys_email_template while /layers still effective. No ablation: docs-only diff.", "gates": "Local, worktree duly-issue-129 at head ba7155f, exit captured before any pipe: pnpm validate EXIT=0 (expected hierarchy-security warning only); pnpm typecheck EXIT=0; pnpm test EXIT=0 (Test Files 35 passed (35), Tests 885 passed (885)); pnpm build EXIT=0. dispatch-gates.mjs not run: it answers only objectstack's tree; duly gate list hand-derived from AGENTS.md (the four gates). PR check-runs: in_progress at report time, not awaited.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm; duly has no dogfood battery", "mcp_calls": "5 — mcp__github__issue_read x5 (get #129, get_comments #129 x3, get #127); zero write tools", "api_writes": "3 — relay pr_create: POST /repos/objectstack-ai/duly/pulls (draft, #140) + POST /repos/objectstack-ai/duly/issues/140/assignees (os-warren); post-stamped comment POST /repos/objectstack-ai/duly/issues/129/comments (this report). git push is not counted.", "open_questions": [], "deviations": [ "Measurement boot (read-only to tracked files; dist/ and OS_HOME scratch only) started before the Claim landed; the first tracked edit came after reading Claim comment 6409898761 naming this branch.", "Worktree: the platform branch was checked out on the shared checkout, so that checkout was detached and the branch added as worktree ../duly-issue-129; the dev servers ran from the shared checkout (same commit 004380e).", "PR body line 1 is the harness attribution block, Fixes #129 follows it on line 3 (os-dev exception for the harness attribution line); the order asked for line 1.", "Session context asked to request os-warren as reviewer via MCP update_pull_request; not done (order forbids MCP writes). The seat can request it.", "Screenshots per row are in /mnt/project-files/duly-129-configurability/, not committed (file surface is the one doc); the doc names console screens by URL and label instead." ], "out_of_scope_findings": [ "class: a · reach: PUT /api/v1/meta/dashboard/duly_duty_health 200 'Saved customization overlay', GET same item and the console keep serving the package widget title, /layers effective carries the edit; same on view duly_task.default label · evidence: RestServer.translateMetaItem applies translateMetadataDocument after the overlay and passes packagedBase for object only (rest 17.3.0 dist index.js ~75127) · Seam: runtime: RestServer.translateMetaItem | renderer: console dashboard · dedupe words: overlay shadowed by translation, dashboard widget title overlay ignored, translateMetaItem packagedBase, view label overlay", "class: a · reach: PUT /api/v1/meta/email_template/duly.task_overdue 200 projectionApplied, sys_email_template row changed; after objectstack build + restart the row is back to package text (updated_at = boot) while /layers effective and the active sys_metadata overlay still claim the edit; a second PUT with locale zh-CN replaced the en overlay of the same name · evidence: matrix row 'Email template subject / body' · dedupe words: email template overlay lost on restart, sys_email_template projection reverted, email_template overlay locale, projectionApplied", "class: a · reach: PUT /api/v1/meta/position/acme_auditor 200 'Saved position … state=active', GET /api/v1/data/sys_position (Setup → Positions) omits it until the next boot; label edit on duly_member same; permission PUT on the same store projects at once · dedupe words: position projection sys_position, metadata position not listed, position overlay boot only", "class: gap (card-requested filing, not a/b/c) · reach: PUT /api/v1/meta/object/duly_duty with full authored object 403 NOT_OVERRIDABLE; PUT /api/v1/meta/field/duly_task.progress 403 not_overridable · G1 package object select options and defaultValue not org-overridable (frequency vocabulary, default lead/grace, progress phrases) · dedupe words: org overlay object select options, picklist extension package object, field defaultValue overlay", "class: gap (card-requested filing) · reach: PUT /api/v1/meta/dataset/duly_stagnation and /page/duly_member 403 NOT_OVERRIDABLE · G2 dataset and page not org-overridable, so the 14-day threshold cannot move in one place · dedupe words: dataset allowOrgOverride, page overlay NOT_OVERRIDABLE, dataset measure parameter", "class: gap (card-requested filing, objectui) · reach: no Setup sidebar entry or edit control for translation or email_template overlays; Email Template list only at /_console/apps/setup/sys_email_template by URL; dashboard page shows no edit control · G3 · dedupe words: translation editor Setup, email template Setup navigation, dashboard edit control", "class: gap (card-requested filing) · reach: PUT /api/v1/meta/translation/duly_fr 200 stored, Accept-Language fr served English · G4 supportedLocales compile-time · dedupe words: add locale runtime, supportedLocales Setup, translation fallback unsupported locale", "class: gap (card-requested filing) · reach: PUT /api/v1/meta/job/duly_dispatch 403 not_overridable; registry flow allowOrgOverride false · G5 flow schedule offsets and job cron not tunable per deployment · dedupe words: flow schedule override, job cron org override, time_relative offsetDays configurable" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
ACCEPT → PR #140 comment 6410123441 (2026-10-26T06:57Z). PR flipped ready, review requested from the maintainer; lands when the maintainer merges.
Generated by Claude Code