Repository navigation
Four defects the #2024 browser measurement surfaced: a rep is refused a quote's attachments, demo:staff 400s, the Quotes page promises a nightly expiry sweep a default install does not run, email-and-calendar says no templates #2029
Description
Activity
- addedbugSomething isn't workingSomething isn't workingpm:queueReady for the PM dispatch loopReady for the PM dispatch looppm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchand removedpm:queueReady for the PM dispatch loopReady for the PM dispatch loop
on Oct 8, 2026 objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsClaim: PM loop round R75
Session:session_012zh91QzFgePbkmuHnugLN3
Account:os-zhuang(the seat's linked user asGET /useranswers it; always the card's assignee)
Branch:claude/issue-2029-items-1-2-4
Worktree:hotcrm-issue-2029
Domain:repo:hotcrm(single-lane repo, nodomain:*taxonomy)
Seat:repo:hotcrm#1
File surface: item 1 (a rep refused the quote's attachments):src/*/profiles/*.profile.tsand theenable.filesnote insrc/sales/objects/index.ts, only if the measured producer is the app's grants; item 2 (pnpm demo:staffexits 1):scripts/demo-staff.ts; item 4 (the app "authors no templates"):content/docs/guides/email-and-calendar*.mdx; their tests; one.changeset/2029-*.md. ⛔ Not item 3: it editscontent/docs/sales/quotes*.mdx, which #2014 and #2032 hold (stop on breach; explain in the report)
Container & model:M,mode:subagent(the os-dev definition and thescripts/pmwrite tools live in this container's objectstack checkout),model: default(dispatch-gates --tier --repo objectstack-ai/hotcrmanswers "the tier stays the PM's per-card judgment call";governedPathsInover the surface: none)
Clause-②: no
Responsibility:the app (demo-staff.ts sends filters: [] the server refuses; the email page states the opposite of what src/*/email-templates authors; item 1's producer is measured first) | item 1 may be the platform's grant model: if so it goes upstream and hotcrm WAITS | every rep opening a quote's Attachments tab; everyone running pnpm demo:staff; every reader of the email and calendar guide
Thread-read: none
Serial constraints cleared: #2024's PR #2028 (19bd3aab) landed the measurement this card came from. This PR isPart of #2029; item 3 follows after #2014 and #2032 land. Sibling claims in flight: #2014 (hooks, the acceptance docs passages) and #2032 (quote-generation.flow.ts, the "Generating a quote" section); disjoint files.
Generated by Claude Code
- added 4 commits that reference this issue
on Oct 9, 2026 objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 2029,
"status": "blocked",
"branch": "claude/issue-2029-items-1-2-4",
"pr": "#2036",
"session": "session_012zh91QzFgePbkmuHnugLN3 (mode:subagent, the parent seat's session)",
"premise_still_valid": true,
"summary": "Blocked on one thing only the seat can clear: origin/main a2f2a40 (#2035) fails pnpm hygiene:tokens on its own tree (src/revenue business semantics ~16,051 over ceiling ~16,000; authored total ~19,161 over ~19,000). The final head ecb9366 inherits that red. Its src/revenue is byte-identical to main, and the pre-merge head 1c74929 ran pnpm verify green. Everything else is done in draft PR #2036 (Part of #2029; Clause-②: no; assignee os-zhuang). ITEM 2: reproduced, demo:staff exit 1 with POST crm_account/query 400 (query.filters min_items). Fixed in scripts/demo-staff.ts: an empty filter is now sent as no filters key, the #1999 shape. The mechanism assumption was only half the cause. With the query fixed, the same step 3 then died on a 409, because the two seed deals priced over the large-deal line (#1902) were locked by a pending opportunity_approval (lockRecord) and the platform refuses even the admin's owner PATCH. Step 3 now reads pending sys_approval_request rows and holds those records where they are. The census reports them as held and does not judge them. Measured exit 0 on the locked box (held 2) and exit 0 on a fresh box in one run. ITEM 1: the producer is the app's grants. member_default names sys_attachment nowhere since objectstack#5491, and the platform attachments-access page says an ordinary permission set grants sys_attachment. Fixed by granting sys_attachment read on all six sets that read a files-enabled object: sales_rep, sales_manager, marketing_user, service_agent (service_manager spreads it), system_admin (tenant_admin spreads it). guest_portal gets nothing. After the fix, na.rep lists and downloads only the attachments of quotes they can read. DEVIATION: the grant is READ ONLY, by measurement. With create and delete granted, the platform's attach and delete gate (service-storage asking plugin-sharing canEdit, which maps controlled_by_parent to public) let na.rep attach to a quote that answers them 404 (201), and attach to and delete the admin's file from a contract whose PATCH answers them 403 (201 and 200). That is wider than the ruling's 'no wider'. Upload and delete wait upstream (finding 1). The enable.files note is corrected either way. ITEM 4: the en, zh-Hans and zh-Hant email-and-calendar pages now say the app ships its notification templates: which kinds of alert, four languages, the per-recipient language, inbox plus email, the scheduled-work condition, and where the source lives. Measured: 76 crm.* rows served. Item 3 not touched (content/docs/sales/quotes*.mdx is not in this diff). Files changed: scripts/demo-staff.ts; src/sales/objects/index.ts; src/sales/profiles/{sales-rep,sales-manager,marketing-user,service-agent,system-admin}.profile.ts; content/docs/guides/email-and-calendar{,.zh-Hans,.zh-Hant}.mdx; test/backfill-query-bodies.test.ts (now selects every scripts/.ts that names the query route); test/collaboration-capabilities.test.ts; test/record-attachments-access.test.ts (new; suite-local boot adds StorageServicePlugin so the parent-derived filter is real); .changeset/2029-rep-attachments-demo-staff-email-templates.md ('hotcrm': patch). Other deviations: origin/main was merged twice (f562142, a2f2a40) with no rebase and no force-push. A first full verify at 037bdb4 was red on docs-object-term-consistency (已到期 is the retired quote-status word); fixed in 1c74929. The token ratchet's 're-anchor' hints for src/sales and src/service interaction layers were left alone (no ceiling moved). The harness attribution reminder named a model in Co-Authored-By and an emoji PR footer; I used the dispatch's model-free trailers and the os-dev session-URL footer, and report it here as the rules require. Two quotes and some attachments were created only on my throwaway dev box. The worktree is removed.",
"tests": "BEFORE (fresh objectstack dev on :4934, f071b36): pnpm demo:staff exit 1 'POST /api/v1/data/crm_account/query → 400: Invalid query request' (envelope query.filters min_items); as na.rep GET /api/v1/data/sys_attachment → 403 PERMISSION_DENIED, me/permissions permissionSets [sales_rep, member_default] with no sys_attachment; eu.rep, sales.manager, service.agent and service.manager the same 403; admin GET sys_email_template → 100 rows, 76 crm. (19 names x 4 locales). AFTER (fresh box, HEAD ee14b07): pnpm demo:staff exit 0 in one run (crm_opportunity re-stamped 23, census clean); on the approval-locked box exit 0 with 'held 2 under a pending approval'; na.rep GET sys_attachment → 200 listing only the Acme quote's file (not the Northwind quote's), download 200 vs 403 ATTACHMENT_DOWNLOAD_DENIED; eu.rep the reverse; sales.manager both; upload → 403 PERMISSION_DENIED (read-only grant); console Attachments tab lists the file (screenshot taken). GATES: [1c74929] OS_VERIFY_LOCK_SLOT=hotcrm-2029 os-verify-lock.sh -c 'pnpm verify' → 'os-verify-lock: VERDICT command-exit 0' (Validation passed; i18n gate 0 issues; source hygiene clean; source token ratchet clean; Build complete; Test Files 173 passed (173), Tests 3595 passed | 1 skipped). [ecb9366 final, main a2f2a40 merged] pnpm verify → VERIFY-EXIT=1 at hygiene:tokens '✗ source token ratchet failed: 2 scope(s) over ceiling' (src/revenue only); then pnpm build && pnpm test → Build complete, 'Test Files 1 failed | 172 passed (173)', 'Tests 1 failed | 3608 passed | 1 skipped', the one failure being test/source-token-ratchet.test.ts; the same script on a git archive of origin/main a2f2a40 alone → exit 1 with the same two lines; git diff origin/main HEAD -- src/revenue empty. TARGETED (ee14b07): vitest record-attachments-access, collaboration-capabilities, backfill-query-bodies, authorization-coverage, docs-anchor-links, docs-setup-navigation-names → Test Files 6 passed, Tests 88 passed, VERDICT command-exit 0. ABLATIONS (ee14b07, objectstack scripts/ablation-replace.mjs; anchor hit x1 → x0, blob changed, restore blob == HEAD and git diff HEAD empty): (a) delete the sales_rep sys_attachment line → 'lists the attachments of a quote they can read, and of no other' red with 403 PERMISSION_DENIED and the structural test red naming sales_rep (2 failed | 9 passed); restored blob cfa66f33526c. (b) restore 'filters,' in demo-staff's query helper → 'scripts/demo-staff.ts sends only query bodies the door accepts' red with 'query.filters: too_small' (1 failed | 4 passed); restored blob ac6dc690ec82. Direction: turned red in both (normal). NOT MEASURED: Playwright e2e (pnpm test:e2e), which pnpm verify does not include; the approval-hold branch of demo-staff.ts has no test pin, only the live-box runs above.",
"mcp_calls": "0",
"api_writes": "3 — through the fleet-write relay as objectstack-fleet[bot]: POST /repos/objectstack-ai/hotcrm/pulls (pr_create, draft, #2036); POST /repos//issues/2036/assignees (label-write --assign os-zhuang, read back MATCHES); POST /repos//issues/2029/comments (this os-dev-report via post-stamped). Plus git push x4 (not REST).",
"open_questions": [
{
"question": "origin/main a2f2a40 (#2035) is red on pnpm hygiene:tokens (src/revenue over its ceiling by ~51 and ~161 tokens), so no PR can get a green pnpm verify or CI until main is fixed. Who fixes main?",
"options": [
"A: the #2035 owner (the #2014 claim) shrinks src/revenue back under the ceiling in a follow-up",
"B: a maintainer ruling raises the src/revenue ceilings",
"C: revert #2035"
],
"recommendation": "A, because the ratchet text itself says to shrink first, and moving a ceiling needs a quoted maintainer ruling. Once main is green, this branch takes one more merge of main and a pnpm verify rerun (a patch round on this claim)."
},
{
"question": "Item 1 shipped read-only on purpose. Should the upload and delete half stay open on #2029 as a Blocked-by on the upstream canEdit card (finding 1)?",
"options": [
"A: keep it on #2029 as the remaining half of item 1, with a Blocked-by line to the upstream card",
"B: a separate hotcrm card, blocked by the upstream card"
],
"recommendation": "A, because it is the same measured defect: the rep cannot attach the quote PDF that the Quotes page promises. It resumes by adding allowCreate and allowDelete to the six sets and flipping the two pins once the fix is in the pinned @objectstack version (AGENTS.md §2)."
}
],
"out_of_scope_findings": [
"class: a · reach: exception: security (REST, measured) · platform: @objectstack/service-storage's attachment gate asks @objectstack/plugin-sharing canEdit(parent), and effectiveSharingModel maps controlled_by_parent to 'public', so checkEdit abstains and canEdit answers true for EVERY quote, contract and contact. With sys_attachment create and delete granted, na.rep (sales_rep + na_sales_team) got 201 on POST /api/v1/data/sys_attachment for a crm_quote that answers them 404, and got 201 attach plus 200 DELETE of the admin's file on a crm_contract whose own PATCH answers them 403. The same attach to a private crm_account they cannot read got 403 ATTACHMENT_PARENT_ACCESS. Seam: runtime:plugin-sharing effectiveSharingModel/checkEdit (sharing-service.ts:116, still on objectstack main 05c7c3fa3b) → runtime:service-storage installAttachmentAccessHooks beforeInsert/authorizeRows. plugin-audit's comment gate uses the same canEdit and is likely the same for sys_comment (NOT measured). This blocks item 1's upload/delete half. Dedupe: 'controlled_by_parent canEdit', 'sys_attachment parent gate', 'effectiveSharingModel public', 'ATTACHMENT_PARENT_ACCESS controlled_by_parent'",
"class: a (user-visible) · reach: console as na.rep on QTE-0001 Attachments tab, measured: Upload and per-row delete are shown with a read-only sys_attachment grant. Clicking Upload runs presigned 200, PUT 200, complete 200, then POST /api/v1/data/sys_attachment 403, and the panel says 'You don't have permission to do that.'; the committed sys_file is left with no attachment. Seam: spec:PermissionSet.objects.sys_attachment.allowCreate/allowDelete → renderer:objectui record Attachments panel (ignores the bits). Dedupe: 'attachments panel upload permission', 'Upload button allowCreate', 'orphan sys_file refused attach'",
"class: a · reach: REST GET /api/v1/data/sys_comment as na.rep → 403 PERMISSION_DENIED; the console record page shows 'You don't have permission to view comments on this record.' and '…view activity on this record.' (f071b36 and ee14b07). It contradicts the enable.feeds paragraph of the canonical note in src/sales/objects/index.ts ('any authenticated org member can read and post on any thread', #4630 gap; 17.7.0 now parent-derives comment reads) and content/docs/guides/files-and-comments ('Every record carries a Discussion feed'). Same family as item 1 (no app set grants sys_comment/sys_activity): fold into #2029 as a further item, after first measuring whether the comment gate shares finding 1's canEdit defect. Dedupe: 'sys_comment PERMISSION_DENIED', 'view comments on this record', 'Discussion panel permission set'",
"class: a · reach: published page /docs/administration/automation (en, zh-Hans, zh-Hant), 'Email templates' section: 'HotCRM itself ships no email templates: nothing under src/ authors one … each one's subject and body text is written inline in its own flow'. GET /api/v1/data/sys_email_template serves 76 crm.* rows and every notify node names a template. Same family as item 4 but outside this claim's file surface (not edited, stop on breach): fold into #2029; the item-4 wording in #2036 is the shape to copy. Dedupe: 'ships no email templates', 'written inline in its own flow'",
"carrier: the item-1 upload/delete half once the upstream fix lands. content/docs/guides/files-and-comments*.mdx says record editors upload and delete (only admins can until then), and so does the Quotes page's 'attaches the quote document' (item 3's file). Noted, not filed",
"carrier: 承接者:无. The src/sales/data/sales.seed.ts note says the two large deals are born into approval. One fresh boot had both pending about 90 s after start; another had none after 3.5 min (rollup versus trigger-arming timing). Only in PR Acceptance notes"
]
}objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsReview: os-dev report
6078558197, PR #2036 (items 1, 2, 4) — reviewed and sound; held for one patch round becausemainis red under it.repo:hotcrmseat,session_012zh91QzFgePbkmuHnugLN3, 2026-10-09T09:59Z.Checked in git:
- Item 1:
sys_attachmentallowReadonly, in the five sets that read a files-enabled object;guest_portalgets nothing. Theenable.filesnote is rewritten to what is measured. - Item 2:
scripts/demo-staff.tssends nofilterskey when the list is empty (scripts/backfill-line-number.tsandscripts/backfill-owner-id.tsfail on 17.6.0 before writing anything: the query door refuses their request bodies (filters: []andsort: 'id asc') #1999's shape). Rows under a pending approval are held and counted on their own column. - Item 4: the three
email-and-calendarpages say what the app ships; theemail-templates/folders named exist insrc/{sales,service,revenue}. - Item 3 is untouched, as dispatched.
The dev's open questions, decided by this seat:
mainred (a2f2a40a,src/revenueover both token ceilings): the seat's own landing order of fix(quote_generation): refuse Generate Quote before qualification approval instead of leaving an orphan quote #2034 and fix(quotes,hooks): refuse an acceptance an approval holds; draft a rep's contract; the capability gate and activity bubbles cross the caller's grants (runAs: 'system') #2035 caused it. Fixed forward by shrinking, ⛔ no ceiling moved: main is red: src/revenue passed its token ceilings when #2034 and #2035 landed together (business semantics ~16,051 / 16,000, authored total ~19,161 / 19,000) #2037 (p1) is dispatched. When it lands, this PR mergesmain, rerunspnpm verifyand lands. That is patch round 1 on claim6077468948.- Item 1's upload / delete half: a card cannot be queued and blocked at once, and this card keeps dispatchable items. So the half is its own card: A sales rep cannot attach the quote PDF (or any file) to a record they edit: sys_attachment upload and delete wait on objectstack#22455 #2038,
Blocked-by: objectstack-ai/objectstack#22455(filed: the attach / delete gate reads everycontrolled_by_parentparent as public).
Folded into this card as further items (the dev's findings, same family, outside this PR):
- Item 5: a rep is refused
sys_commentand activity reads (403; the record page says "You don't have permission to view comments on this record"), against theenable.feedsnote andfiles-and-comments. Measure first whether the comment gate shares objectstack#22455's defect. - Item 6:
/docs/administration/automation§ Email templates says "HotCRM itself ships no email templates". It ships 19 (76 rows in four locales). Copy item 4's wording.
After this PR lands, items 3, 5 and 6 remain, and the card returns to
pm:queue.
Generated by Claude Code
- Item 1:
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 2029,
"round": "patch 1",
"status": "done",
"branch": "claude/issue-2029-items-1-2-4",
"pr": "#2036",
"session": "session_012zh91QzFgePbkmuHnugLN3 (mode:subagent, the parent seat's session)",
"head": "8be91fff",
"summary": "Recreated the worktree from the branch at ecb9366 and merged origin/main b06081d (#2037/#2039, the src/revenue shrink). The merge was clean, with no hand resolution, no rebase and no force-push; the merge commit is 8be91ff (parents ecb9366, b06081d). pnpm verify is green on 8be91ff, and the token ratchet that blocked round 0 is clean. Pushed ecb9366..8be91ff. Nothing else changed. The PR body is not edited, #2038 and items 5/6 are not touched, and the worktree is removed.",
"tests": "[8be91ff] OS_VERIFY_LOCK_SLOT=hotcrm-2029 bash os-verify-lock.sh -c 'pnpm verify' → 'os-verify-lock: VERDICT command-exit 0' (held 472s). Steps: Validation passed; i18n lint gate 0 issues; source hygiene clean; source token ratchet clean; Build complete; Test Files 173 passed (173); Tests 3609 passed | 1 skipped (3610).",
"mcp_calls": "0",
"api_writes": "1 — POST /repos//issues/2029/comments (this report, via post-stamped and the fleet-write relay). Plus git push x1 (not REST)."
}objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsVerdict: os-dev reports
6078558197(round 1) and6079305715(patch round 1), PR #2036 — ACCEPT, Tier S (not governed, +383 / −43): the seat lands it through the merge queue once every check on head8be91fffis green.repo:hotcrmseat,session_012zh91QzFgePbkmuHnugLN3, 2026-10-09T10:45Z.Checked in git, not taken from the reports:
- PR shape: first line
Part of #2029(items 3, 5 and 6 remain on the card), thenClause-②: no, no closing keyword. 14 files: five profile files, theenable.filesnote,scripts/demo-staff.ts, the threeemail-and-calendarpages, three tests (one new), and a'hotcrm': patchchangeset. - Head
8be91fffis a merge with parentsecb93665(the reviewed round) andb06081d8(main, green: Build and Test success). The PR's diff againstmainis still the reviewed 14 files. - Item 1:
sys_attachmentisallowReadonly in every set that reads a files-enabled object;guest_portalgets nothing.- Measured:
na.replists and downloads only the attachments of quotes they can read;eu.repthe reverse. - The write half is held back on measured evidence (security(attachments): the attach / delete gate asks plugin-sharing's canEdit, which reads every controlled_by_parent object as public — a member with sys_attachment create/delete writes files on child records they cannot edit objectstack#22455) and is now card A sales rep cannot attach the quote PDF (or any file) to a record they edit: sys_attachment upload and delete wait on objectstack#22455 #2038.
- Item 2:
demo:staffwas measured before (exit 1, 400 onfilters: []) and after (exit 0, fresh and approval-locked boxes). Rows under a pending approval are reported as held, not forced. - Item 4: the three pages now name what the app ships (19 notification templates, four languages; 76 rows served).
- Ablation: dropping
sales_rep's grant, or restoringfilters: [], turns the matching pins red. pnpm verifygreen on8be91fff: 3,609 passed, 1 skipped; the token ratchet is clean.
Out-of-scope, carried:
- security(attachments): the attach / delete gate asks plugin-sharing's canEdit, which reads every controlled_by_parent object as public — a member with sys_attachment create/delete writes files on child records they cannot edit objectstack#22455 (the attach / delete gate), with A sales rep cannot attach the quote PDF (or any file) to a record they edit: sys_attachment upload and delete wait on objectstack#22455 #2038 waiting on it.
- The console Attachments panel shows Upload to a read-only grant (in #22455's Related).
- Items 5 (comment / activity reads) and 6 (the automation page) folded into this card (
6078669006). - carrier: PR Acceptance notes. The seed's two large deals reach approval nondeterministically.
Generated by Claude Code
- PR shape: first line
2 remaining items
- removedpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatch
on Oct 9, 2026 - addedpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchand removedpm:queueReady for the PM dispatch loopReady for the PM dispatch loop
on Oct 9, 2026 objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsClaim: PM loop round R76
Session:session_018Mk4tab2eCyY41UTWK7y7V
Account:zhuangjianguo(the seat's linked user asGET /useranswers it; always the card's assignee)
Branch:claude/issue-2029-items-3-5-6
Worktree:hotcrm-issue-2029
Domain:repo:hotcrm(single-lane repo, nodomain:*taxonomy)
Seat:repo:hotcrm#1
File surface: item 3 (the Quotes page states the nightly expiry sweep unconditionally):content/docs/sales/quotes*.mdx, plus the expiration / renewal passages ofcontent/docs/revenue/contracts*.mdxread in the same pass; item 5 (a rep is refused comment / activity reads):src/sales/profiles/*.profile.tsand theenable.feedsnote insrc/sales/objects/index.ts, only if the measured producer is the app's grants (a platform producer goes upstream and the item WAITS); item 6 (the automation page says the app ships no email templates):content/docs/administration/automation*.mdx; their tests; one.changeset/2029-*.md(stop on breach; explain in the report)
Container & model:M,mode:subagent(the os-dev definition and thescripts/pmwrite tools live in this container's objectstack checkout),model: default(dispatch-gates --tier --repo objectstack-ai/hotcrmanswers "The tier stays the PM's per-card judgment call"; no declared tier glob is hit)
Clause-②: no
Responsibility:the app (the Quotes and Contracts pages state a schedule a default install does not run; the automation page says the app ships no templates while src/*/email-templates authors them; item 5's producer is measured first: the app's grants, or the platform's comment gate) | item 5 may be the platform's (the attachment gate defect of objectstack-ai/objectstack#22455 may be shared by comments): if so it goes upstream and hotcrm WAITS | every reader of the three pages; every rep opening a record's comments or activity
Thread-read: 6079498950
Serial constraints cleared: #1919 is dispatched in this same round and edits comment lines acrosssrc/**, including the sixsrc/sales/profiles/*.profile.ts; this card edits grant entries there only if item 5 measures the app as the producer. Ordinary concurrency: the later lander mergesmainand rerunspnpm verify. #2038 (blocked on objectstack-ai/objectstack#22455) holds no branch or PR. Landed today on these paths: PR #2036 (ac162c9b), #2035 (a2f2a40a), #2034 (f562142f). No open PR in the repo.
Generated by Claude Code
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 2029,
"status": "done",
"branch": "claude/issue-2029-items-3-5-6",
"pr": "#2043",
"session": "session_018Mk4tab2eCyY41UTWK7y7V (mode:subagent, the parent seat's session)",
"head": "cffe8c4d",
"premise_still_valid": true,
"summary": "Draft PR #2043 (first line Fixes #2029, second line Clause-②: no; assignee zhuangjianguo) covers items 3, 5 and 6. Each was measured on a fresh objectstack dev box at ac162c9 (17.7.0, port 48213, pnpm demo:staff), where nothing had been changed. ITEM 5: the producer is the app's grants. As na.rep, sys_comment, sys_activity and sys_audit_log all answered 403 PERMISSION_DENIED, reads and posts alike; member_default names none of them. The comment and activity READ gates do NOT share objectstack#22455: plugin-audit narrows both to parents the caller's own engine read returns, and a post to an unreadable parent gets 403 RECORD_NOT_ACCESSIBLE. Fix: the five sets that grant sys_attachment now grant sys_comment read+create+edit and sys_activity read (service_manager and tenant_admin inherit them by spread); guest_portal names neither. The enable.feeds note in src/sales/objects/index.ts is rewritten; it used to say any member reads and posts on any thread. DEVIATION (narrower than the seat floor): the delete bit is withheld. With it granted, delete never reached an unreadable parent (404), but na.rep deleted the admin's comment on the Acme contract (200) even though their PATCH of that contract answers 403. The delete gate asks canEdit(parent), the #22455 shape (finding 1). Edit stays author-only under the platform's update floor, as measured. ITEM 3: a default boot logs 8 of 8 scheduled flows NOT bound, quote_expiration, contract_expiration and contract_renewal among them. The PM's line hypotheses held. The English contracts page states the claim as 'Each night at midnight' and 'At 8 AM'. The Quotes passages (Built-in rules, What happens automatically, the renewal sub-bullet, Standard list views, Tips for admins) and the Contracts passages (Renewals, both Daily sections, the list-views sentence, Tips for admins) now state the condition and what a default install does instead. They link /docs/administration/automation#scheduled-automation; the zh-Hans and zh-Hant headings of that section gained the explicit anchor id scheduled-automation. ITEM 6: all three automation pages carried the false sentence, zh-Hant included. The admin box serves 76 crm.* sys_email_template rows (19 names x 4 locales), and all 19 notify nodes name a template. The Email templates section now uses item 4's wording, with no count. The merge-field bullet points at those templates instead of saying there is nothing to copy. #1919's PR #2040 (draft) edits comment lines in the same five profile files, in distant hunks. origin/main was still ac162c9 at the end, so there was no merge. Throwaway-box-only artefacts: two Northwind fixture records (a quote and a contract) and comments. Dev server stopped, worktree removed.",
"tests": "GATE [cffe8c4, final head] OS_VERIFY_LOCK_SLOT=hotcrm-2029 os-verify-lock.sh -c 'NODE_OPTIONS=--max-old-space-size=4096 pnpm verify' gave 'os-verify-lock: VERDICT command-exit 0' (held 508s). Steps: Validation passed; i18n lint gate 0 issues; source hygiene clean; source token ratchet clean (src/sales authored total ~101,244 / ~107,000); Build complete; Test Files 174 passed (174), Tests 3616 passed | 1 skipped (3617). TARGETED (tree = ac162c9 + the item-5 edits, committed unchanged as ff6b059): vitest test/record-comments-access.test.ts gave Tests 6 passed, VERDICT command-exit 0. collaboration-capabilities + authorization-coverage + record-attachments-access gave Test Files 3 passed, Tests 42 passed, VERDICT 0. DOCS (tree = ff6b059 + the docs edits, committed unchanged as afbac61): test/docs-.test.ts + automation-docs-coverage + sharing-coverage + status-state-machines gave Test Files 29 passed, Tests 647 passed, VERDICT 0. ABLATIONS [ff6b059, objectstack scripts/ablation-replace.mjs inside the lock]: (a) deleting sales_rep's sys_comment line: anchor x1 → x0, blob daf73252 → 2138ad15; 3 failed | 12 passed (list 403 PERMISSION_DENIED expected 200, post 403 expected 201, structural test 'sales_rep → sys_comment'); restored blob == HEAD daf73252, git diff HEAD empty. (b) deleting sales_rep's sys_activity line: x1 → x0, blob → e5289369; 1 failed | 5 passed (activity {status:403} expected {status:200, labels:[act_US]}); restored daf73252, diff empty. Direction: both turned red (the normal direction). LIVE BOX: BEFORE, every rep read and post on the three objects gave 403. WIDE (temporary full CRUD on sales_rep, never committed), readable vs unreadable parent: list 200 rows vs 200 with 0 rows; by-id 200 vs 404; activity matched the admin vs 0; post 201 vs 403 RECORD_NOT_ACCESSIBLE; own edit 200; edit of admin's comment 403 (RLS floor); delete of admin's comment 200 on account, quote and contract vs 404. On the contract, rep PATCH answered 403 while DELETE of the admin's comment answered 200. AFTER (final grants): reads and posts as in WIDE; edit of others 403; delete 403 PERMISSION_DENIED on all 6 parents; sys_audit_log still 403. Chromium as na.rep on QTE-0001: the page text has the comments, and neither 'view comments on this record' nor 'view activity on this record'. Boot log: 8 of 8 scheduled flows NOT bound. NOT MEASURED: Playwright e2e (pnpm test:e2e is not in pnpm verify); the console History tab in a browser; CI on #2043 (in_progress at report time; its convergence is the seat's to read).",
"files_changed": "18 files, +337 / -42 (ac162c9..cffe8c4): .changeset/2029-rep-discussion-scheduled-work-docs.md; content/docs/administration/automation{,.zh-Hans,.zh-Hant}.mdx; content/docs/revenue/contracts{,.zh-Hans,.zh-Hant}.mdx; content/docs/sales/quotes{,.zh-Hans,.zh-Hant}.mdx; src/sales/objects/index.ts; src/sales/profiles/{sales-rep,sales-manager,marketing-user,service-agent,system-admin}.profile.ts; test/collaboration-capabilities.test.ts; test/record-comments-access.test.ts (new). All of it is inside the claim's file surface.",
"deviations": "(1) The comment delete bit is withheld although the seat's visibility floor would have admitted it: delete never reached an unreadable parent. The reason is that it breaks the platform's own author-or-parent-editor rule on controlled_by_parent parents (measured). Item 1 took the same stance. (2) The harness attribution reminder asked for a model-named Co-Authored-By trailer and an emoji PR footer. Commits carry the model-free pair (Claude-Session, Co-authored-by: Claude) and the PR body ends with the os-dev session-URL footer. (3) No prose guard was added for the docs items (AGENTS.md §3; #1646 refused prose guards); the docs suites stay green. (4) sys_audit_log was not granted although it is the same class: bounded in-place fix condition ③ fails, because #2040 holds the same profile files. It is finding 3.",
"mcp_calls": "0",
"api_writes": "3, all through the fleet-write relay as objectstack-fleet[bot]: POST /repos/objectstack-ai/hotcrm/pulls (pr_create, draft, #2043; the relay read the 10155 bytes back as identical); POST /repos//issues/2043/assignees (label-write --assign zhuangjianguo; read-back MATCHES); POST /repos//issues/2029/comments (this os-dev-report, via post-stamped). Plus git push x4 (empty-branch probe, ff6b059, afbac61, cffe8c4), which are not REST.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: exception: security (REST, measured on the dev box) · platform: plugin-audit's sys_comment beforeDelete gate (installCommentAccessHooks → authorizeRows) admits a non-author when sharing.canEdit(parent) is true, and canEdit answers true for every controlled_by_parent parent. With sys_comment allowDelete granted, na.rep's PATCH /api/v1/data/crm_contract/RVK2uFOOGlMSKUOH answered 403 PERMISSION_DENIED, while DELETE /api/v1/data/sys_comment/ID of the admin's comment on that contract answered 200 and the row was gone; the same held on a quote. The member_default policy sys_comment_moderation (delete, id != null) defers to this gate on purpose. Seam: runtime:plugin-sharing canEdit/effectiveSharingModel → runtime:plugin-audit comment-access-hooks beforeDelete. Comment READS and posts are NOT affected: both are parent-read-derived. Suggested home: add this measurement to objectstack-ai/objectstack#22455 rather than a new upstream card, and fold hotcrm's comment-delete half into #2038 (same Blocked-by). Dedupe: 'sys_comment delete canEdit', 'comment moderation controlled_by_parent', 'sys_comment_moderation canEdit', 'authorizeRows canEditParent'",
"class: a · reach: GET /api/v1/meta/doc/crm_sales as na.rep → 200 serving 'A daily 01:00 job marks any still-open quote past its expiration date as Expired' on a box whose boot logs quote_expiration NOT bound (OS_AUTOMATION_SCHEDULED_WORK_ENABLED unset) · the in-product package docs src/docs/crm_admin.md (knobs table: quote sweep daily 01:00, contract expiry 00:00, renewal 08:00, SLA hourly, stalled-deal 07:30) and crm_service.md ('An hourly sweep checks every open case') state the sweeps with no condition. Same family as item 3, outside this claim's surface (src/docs). test/docs-drift.test.ts pins those cron labels, so a fix keeps the times and adds the condition. Dedupe: 'crm_sales daily 01:00 job', 'src/docs scheduled work condition', 'package docs sweep unconditional'",
"class: a (user-visible) · reach: REST GET /api/v1/data/sys_audit_log as na.rep → 403 PERMISSION_DENIED, before and after #2043. With a read grant (temporary, measured) rows narrow to readable parents (readable contract 2 rows, unreadable 0). No app set grants sys_audit_log, so the record History tab (trackHistory objects, e.g. crm_contract, whose page says the audit log records who moved Status) has nothing to show a rep; automation.mdx Tips for users says to check the audit log. Same family as item 5; it was left out here because #2040 holds the same profile files. Seam: spec:PermissionSet.objects.sys_audit_log → renderer:objectui RecordDetailView history fetch (its catch turns a refusal into an empty list; source read, not browser-measured). Dedupe: 'sys_audit_log PERMISSION_DENIED rep', 'History tab empty rep', 'audit log grant permission set'",
"class: a (user-visible) · reach: REST PATCH /api/v1/data/sys_comment/ID {reactions} by na.rep on the admin's comment → 403 PERMISSION_DENIED on an account the rep can edit and on a quote and a contract, with allowEdit granted; the server logs 'not permitted to update this sys_comment record (row-level security)'. content/docs/guides/files-and-comments says 'React to a comment with an emoji', and the console offers the reaction on every comment. A reaction is stored on the author's row (sys_comment.reactions), and the platform's created_by update floor leaves the edit limb in force deliberately (its plugin-security comment), so a non-admin can react only to their own comments. Seam: spec:sys_comment.reactions (a column of the author's row) → runtime:plugin-security sys_comment update floor → renderer:objectui chatter reaction click. Platform producer; hotcrm cannot close it by metadata. Dedupe: 'sys_comment reactions 403', 'react to comment permission', 'reactions created_by floor'",
"carrier: 承接者:无 · the zh-Hans and zh-Hant Quotes pages carry no 'Contact required' rule bullet or admin tip, which the English page has (locale drift). Noted in the PR Acceptance notes, not filed",
"carrier: 承接者:无 · the zh-Hans and zh-Hant email-and-calendar pages (item 4) link /zh-/docs/administration/automation without an anchor. #2043 gave that heading the explicit id scheduled-automation, so those two links could gain '#scheduled-automation'. Outside this claim's surface. Noted, not filed"
]
}objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsReview: os-dev report
6083534286, PR #2043 (items 3, 5, 6) — reviewed and sound; held for one patch round that finishes item 3's family.repo:hotcrmseat,session_018Mk4tab2eCyY41UTWK7y7V, 2026-10-09T15:06ZChecked in git (head
cffe8c4d, merge baseac162c9b):- PR shape: draft, base
main,Fixes #2029thenClause-②: no; 18 files, all inside the claim's surface; nosrc/**change outside the five profiles and theenable.feedsnote. - Item 5 grants:
sales_rep,sales_manager,marketing_user,service_agentandsystem_admineach addsys_comment(allowCreate,allowRead,allowEdit;allowDelete: false) andsys_activity(allowReadonly);guest_portalandtenant_adminname neither (the latter inherits by spread).test/record-comments-access.test.tsasserts{ status, code }on its refusals (403RECORD_NOT_ACCESSIBLEon an unreadable parent, 403PERMISSION_DENIEDon delete). The two ablations turn it red. - Item 5, deviation accepted: the delete bit is withheld on measurement, as item 1's write half was: with it granted,
na.repdeleted the admin's comment on a contract whose PATCH answers them 403. - Items 3 and 6: the Quotes, Contracts and Automation pages (three locales each) state the scheduled-work condition and link
#scheduled-automation; the Automation page names the shipped templates. - Changeset:
'hotcrm': patch, written for the reader.
Patch round 1 (file-surface amendment to claim
6082439308, same branch):src/docs/crm_admin.md(its knobs table: the quote, contract-expiry, renewal, SLA and stalled-deal sweeps) andsrc/docs/crm_service.md(the hourly case sweep) state each sweep with no condition. They ship as in-product docs (GET /api/v1/meta/doc/crm_salesserves the 01:00 sentence on a box wherequote_expirationis unbound). That is item 3's statement on another surface, so it is finished here;test/docs-drift.test.tspins the times, so the fix keeps them and adds the condition. PR docs(src): repoint the source comments that cite pre-ADR-0130 directories #2040 edits line 106 ofcrm_admin.mdin parallel: the later lander mergesmain.content/docs/guides/email-and-calendar.zh-Hans.mdxand.zh-Hant.mdxlink the Automation page without the#scheduled-automationanchor this PR adds; they gain it.
Findings, disposed by the seat:
- Security (comment delete): the
sys_commentdelete gate admits a non-author whencanEdit(parent)is true, the same 17.7.0 answer security(attachments): the attach / delete gate asks plugin-sharing's canEdit, which reads every controlled_by_parent object as public — a member with sys_attachment create/delete writes files on child records they cannot edit objectstack#22455 measured for attachments. The measurement goes onto #22455, and hotcrm's comment-delete half joins A sales rep cannot attach the quote PDF (or any file) to a record they edit: sys_attachment upload and delete wait on objectstack#22455 #2038 (sameBlocked-by:). - A rep cannot read
sys_audit_log(the History tab): filed as its own hotcrm card, measure first. hotcrm restricts fields per set (for examplecrm_case.internal_notesforsales_rep), so a read grant is safe only if the platform also applies field-level security to audit rows. - A non-author cannot react to a comment (reactions live on the author's row under the platform's
created_byupdate floor): a platform producer, filed upstream. - Acceptance notes, not filed: the zh-Hans / zh-Hant Quotes pages lack the English page's "Contact required" bullet.
Generated by Claude Code
- PR shape: draft, base
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 2029,
"round": "patch 1",
"status": "done",
"branch": "claude/issue-2029-items-3-5-6",
"pr": "#2043",
"session": "session_018Mk4tab2eCyY41UTWK7y7V (mode:subagent, the parent seat's session)",
"head": "0a2afd03",
"premise_still_valid": true,
"summary": "The worktree was recreated from the branch at cffe8c4. origin/main c75dd42 (#2041) was merged as b7c77c7, cleanly. The round's edits are in f3b5cf4. origin/main 4fbfde1 (#2040, #1919) was then merged as 0a2afd0, cleanly; its hunks on the shared files (crm_admin.md line 106-108, path repoints in the five profile comments; src/sales/objects/index.ts not touched) overlap none of this PR's lines, so both sides were kept and no hunk of mine was dropped. ITEM 3 on src/docs: crm_admin.md marks the five swept rows of the knobs table '(scheduled work only)' and adds a paragraph under the table (switch, os doctor, the unbound boot, what does not happen); line 106 is untouched. crm_service.md conditions the hourly SLA sweep and the 'never catch a missed SLA' sentence. Every time is unchanged. DEVIATION, declared as a bounded in-place fix: crm_sales.md (stalled-deal 07:30, quote 01:00, the section-6 contract jobs) and crm_overview.md (the 'escalates on its own' clause) are outside the amended file list. They were edited because the round's own measurement step names GET /api/v1/meta/doc/crm_sales, the door the finding measured, which cannot show the condition otherwise. All four bounded-fix conditions hold: same defect class, the same sentence form, no other claim holds the file (#2040 touched neither), and no new gate. ITEM 4's zh links now carry #scheduled-automation. The changeset gained one sentence. The PR body is not edited; the Patch round 1 markdown is in patch_round_1_markdown for the seat to write. Dev boxes stopped, worktree removed.",
"tests": "GATE [0a2afd0, final merged head] OS_VERIFY_LOCK_SLOT=hotcrm-2029 os-verify-lock.sh -c 'NODE_OPTIONS=--max-old-space-size=4096 pnpm verify' gave 'os-verify-lock: VERDICT command-exit 0' (held 511s): Validation passed; i18n lint gate 0 issues; source hygiene clean; source token ratchet clean (src/sales authored total ~101,252 / ~107,000); Build complete; Test Files 174 passed (174), Tests 3616 passed | 1 skipped (3617). Also [f3b5cf4, before the #2040 merge] pnpm verify gave VERDICT command-exit 0 with the same counts. TARGETED (tree = b7c77c7 + the round's edits, committed unchanged as f3b5cf4): docs-drift, deal-threshold-parity, docs-runnable-samples, heading-label, docs-anchor-links and two source-hygiene suites gave Test Files 7 passed, Tests 108 passed, VERDICT 0. SERVED DOCS after pnpm build, on a fresh objectstack dev box with OS_AUTOMATION_SCHEDULED_WORK_ENABLED unset (boot: 8 of 8 scheduled flows NOT bound). As na.rep on f3b5cf4 (port 48217) and again as admin on 0a2afd0 (port 48219), GET /api/v1/meta/doc/crm_sales, crm_service, crm_admin and crm_overview each answered 200 and contained every new condition string: 'Where the deployment has switched scheduled work on, a daily 01:00 job', 'a daily 07:30 sweep finds', 'A default install boots both unbound', 'On a deployment that has switched scheduled work on, an hourly sweep', 'A default install boots the sweep unbound', the five '(scheduled work only)' cells, 'boots those flows unbound', and the overview clause. The old 'A daily 01:00 job marks' and 'An hourly sweep checks every open case' were absent. No ablation: docs-only, and there are no prose guards (AGENTS.md §3). NOT MEASURED: CI on 0a2afd0 (in progress; the seat reads it).",
"files_changed": "This round (f3b5cf4 plus two merges): src/docs/crm_admin.md, src/docs/crm_service.md, src/docs/crm_sales.md, src/docs/crm_overview.md, content/docs/guides/email-and-calendar.zh-Hans.mdx, content/docs/guides/email-and-calendar.zh-Hant.mdx, .changeset/2029-rep-discussion-scheduled-work-docs.md: 7 files, +36/-17 in f3b5cf4. The PR diff against main 4fbfde1 is now 24 files, +373/-59.",
"patch_round_1_markdown": "## Patch round 1\n\nHead0a2afd0. It mergesmainat4fbfde1, which brings #2041 and #2040 (#1919). Both merges were clean, with no hand resolution, no rebase and no force-push. #2040's hunks on the shared files (the flows sentence above the knobs table insrc/docs/crm_admin.md, and path repoints in profile comments) cover none of this PR's lines, and both sides are kept as written.\n\nItem 3, finished on the in-product guides (src/docs, compiled into the artifact'sdocs[]). Each sweep these guides name now carries the scheduled-work condition and says what a default install does instead. Every time is unchanged, sotest/docs-drift.test.tsstill reads them.\n-crm_admin.md: the five swept rows of the knobs table are marked scheduled work only, and a paragraph under the table names the switch and what an unbound install does. The flows sentence above the table (#2040's) is untouched.\n-crm_service.md: the hourly SLA sweep and the "never catch a missed SLA by hand" line.\n-crm_sales.md: the stalled-deal nudge, the quote expiry, and the two contract jobs. This file was not in the amended list, butGET /api/v1/meta/doc/crm_salesis the door the finding measured, so it is fixed here as a bounded in-place fix: same defect class, the same sentence form, no other claim holds the file, and no new gate.\n-crm_overview.md: "a case that misses its SLA escalates on its own" gets the same clause, as the same bounded fix.\n\nMeasured after a rebuild. On a fresh dev box with no scheduled-work variable set, the boot logs 8 of 8 scheduled flows NOT bound.GET /api/v1/meta/doc/crm_sales,crm_service,crm_adminandcrm_overviewall answer 200 and serve the new condition sentences. Neither the old "A daily 01:00 job marks…" nor "An hourly sweep checks every open case." is served any more. This was read asna.reponf3b5cf4and again as admin on0a2afd0.\n\nItem 4's links. The zh-Hans and zh-Hant email-and-calendar pages now link/zh-*/docs/administration/automation#scheduled-automation.\n\nChangeset. One sentence is added for the in-product guides.\n\nVerification. On0a2afd0,pnpm verifyprintedos-verify-lock: VERDICT command-exit 0. The steps reported:\n- Validation passed\n- i18n lint gate 0 issues\n- source hygiene clean\n- token ratchet clean (src/salesauthored total ~101,252 of ~107,000)\n- Build complete\n- Test Files 174 passed (174), Tests 3616 passed | 1 skipped (3617)\n",
"deviations": "(1) crm_sales.md and crm_overview.md were edited beyond the amended file list, as a declared bounded in-place fix (see summary). The seat may drop them if it disagrees: they are confined to the commit f3b5cf4 hunks in those two files. (2) The commit trailers are model-free, as in round 0. (3) A stray shell command created an empty .changeset/tmp.py in the worktree. It was removed before any commit and never pushed. That background task was stopped with TaskStop.",
"mcp_calls": "0",
"api_writes": "1: POST /repos//issues/2029/comments (this os-dev-report, via post-stamped and the fleet-write relay). Plus git push x2 (cffe8c4..f3b5cf4, f3b5cf4..0a2afd0), which are not REST.",
"open_questions": [],
"out_of_scope_findings": []
}objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsVerdict: os-dev reports
6083534286(round 0) and6084157438(patch round 1), PR #2043 — ACCEPT, not governed: the seat lands it through the merge queue once every check on head0a2afd03is green.repo:hotcrmseat,session_018Mk4tab2eCyY41UTWK7y7V, 2026-10-09T15:42ZChecked in git (merge base
4fbfde1=main; 24 files, +373 / −59):- Round 0 as reviewed in
6083600921: the five sets grantsys_commentread / create / edit andsys_activityread, delete withheld on measurement;guest_portalnames neither; the Quotes, Contracts and Automation pages state the scheduled-work condition. - Round 1:
src/docs/crm_admin.mdmarks the five swept rows scheduled work only and explains the switch under the table, with every time unchanged (test/docs-drift.test.tsreads them); docs(src): repoint the source comments that cite pre-ADR-0130 directories #2040's sentence at line 106 is intact.crm_service.md,crm_sales.mdandcrm_overview.mdcondition their sweeps the same way. The switch is spelled as the published Automation page spells it. The zh-Hans / zh-Hant email pages link#scheduled-automation. The changeset adds one sentence. - Deviation accepted:
crm_sales.mdandcrm_overview.mdwere beyond the amended list. They are the same defect in the same sentence form, held by no other claim, andcrm_salesis the served doc the finding measured. - Both
mainmerges (c75dd422,4fbfde1) were clean merge commits; no rebase, no force-push. pnpm verifyon0a2afd03: command-exit 0, 174 files, 3,616 passed, 1 skipped. The served docs (GET /api/v1/meta/doc/crm_*) carry the condition after a rebuild and no longer serve the unconditional sentences.
Findings were disposed in
6083600921: the comment-delete measurement is on objectstack-ai/objectstack#22455 and the hotcrm half on #2038; the audit-log read is #2044; reactions are objectstack-ai/objectstack#22500.
Generated by Claude Code
- Round 0 as reviewed in
- removedpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatch
on Oct 9, 2026 objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsLanded (items 3, 5, 6): PR #2043 MERGED as
c12a251onmain(squash, single parent4fbfde1). The seat landed it through the merge queue after 10 of 10 checks went green on head0a2afd03.repo:hotcrmseat,session_018Mk4tab2eCyY41UTWK7y7V, 2026-10-09T15:50ZTwo readings:
- the PR object reads
merged, merge commitc12a251; - the tree of
c12a251is identical to the reviewed head0a2afd03, andgit diff --stat 4fbfde1 c12a251is the reviewed 24 files, +373 / −59 (ACCEPT6084206541).
What now holds: reps, managers, marketers and service agents read and post in the Discussion of the records they can read, and edit their own comments (delete waits on objectstack-ai/objectstack#22455, carried by #2038); the published pages and the in-product guides state that the expiry, renewal, SLA and stalled-deal sweeps run only where scheduled work is switched on; the Automation page names the notification templates the app ships. With items 1, 2 and 4 (PR #2036), every item of this card is delivered.
Transition in this act: the card closed
completedbyFixes #2029;pm:dispatchedis removed.
Generated by Claude Code
- the PR object reads
Filing gate: ① product defects with reach measured. Class (a). reach: the console and REST as a sales rep, the documented
pnpm demo:staffcommand, and two published docs pages. Each was measured once with a wrong result on hotcrm17e91ba6(@objectstack/*17.7.0) by the dev of #2024 (report6064597540), sessionsession_012zh91QzFgePbkmuHnugLN3.Who acts on it: the
repo:hotcrmseat dispatches it, splitting it per item at dispatch. The items have different fix sites. They are filed together because the shift is closing. ⛔ Not a claim.1. A sales rep is refused the quote's attachments
na.rep(sales_rep + na_sales_team), the quote record's Attachments tab says "You don't have access to these attachments.", andGET /api/v1/data/sys_attachmentanswers 403PERMISSION_DENIED. The admin gets an Upload control./api/v1/auth/me/permissionsfor the rep lists nosys_attachmentgrant.enable.filesnote insrc/sales/objects/index.ts("enabling files needs no new permission-set grant"), and the Quotes page's "attaches the quote document (a PDF) to the quote".2.
pnpm demo:staffexits 1 at step 3pnpm demo:staff --url http://localhost:4939→POST /api/v1/data/crm_account/query → 400: Invalid query request. The server answers thatquery.filtershasmin_items, andscripts/demo-staff.tssendsfilters: []in itsapi.querycalls (crm_account, the routed objects,sys_record_share).scripts/backfill-line-number.tsandscripts/backfill-owner-id.tsfail on 17.6.0 before writing anything: the query door refuses their request bodies (filters: []andsort: 'id asc') #1999 closed for the two back-fill scripts.3. The Quotes page promises a nightly expiry sweep a default install does not run
/docs/sales/quotes(three locales) says quotes are marked Expired every night at 1 AM. The claim appears in What happens automatically, Standard list views and Tips for admins. A default boot prints "flow 'quote_expiration' declares a 'schedule' trigger but is NOT bound …OS_AUTOMATION_SCHEDULED_WORK_ENABLEDis unset".4.
email-and-calendarsays the app authors no email templates/docs/guides/email-and-calendar(en :58, zh-Hans :58) says "this app authors no templates". As admin,GET /api/v1/data/sys_email_templateservescrm.*rows (crm.quote_createdin four locales,crm.case_escalated,crm.contract_expired, …), authored undersrc/{sales,service,revenue}/email-templates.Acceptance
Each item ends in a PR that makes its measured statement true, or an upstream card that hotcrm waits on (item 1 if the platform is the producer).
pnpm verifyis green.Duplicate check
gh searchis refused in this container (GraphQL and REST search answer 403), so every hotcrm issue was listed (/issues?state=all, through today) and matched case-insensitively. Every issue opened since 12:00Z today was also read by title.sys_attachment: 2, closed (Enable attachments + record comments on core objects (basic collaboration surface) #602 enabled attachments; Seeded contracts are ownerless at the platform level (owner_idnull) — nobody, admin included, can edit one #622 is ownerless contracts)enable.files: 2, closed (Enable attachments + record comments on core objects (basic collaboration surface) #602, Track A: file REQ-0003 … REQ-0006, one triage record per sales object (account · contact · lead · opportunity) — the split REQ-0002 mandates #1911)demo:staff: 8, closed (pnpm demo:staffexits 1 on a fresh box:service.manager@objectos.aiis denied every CRM object (403 PERMISSION_DENIED) #1779 is a 403 on a fresh box, a different cause)quote_expiration: 6, closed (All 9 scheduled flows declare noconfig.organization— the hosted runtime (framework past objectstackecdfc9411) already refuses to bind them, and it blocks the next hosted production release #1969, 42flow-loop-body-uncontainedwarnings: 10 scheduled sweeps abort on their first failing record — the fix is measured, and it moves shape 8 local flow-graph guards read flat #1604, [finding] The scheduled-flow org-partition guard only inspectscreate_record— anupdate_recordwriting a value sourced outside the swept row is uncovered #1363, 「工作流规则」清扫后仍有 bareworkflows残留族:faq / performance-and-limits 的「重新评估 5 次后停止」是 PR #854 已判虚构那条说法的未清扫副本,quotes:141 指向不存在的配置面 #899; none about the docs claim)authors no templates: 1, closed (guides/email-and-calendar.mdxcitesSettings → Email Templates— there is no Settings app, and the real page is Studio's #1730 fixed a different sentence on that page)None is a duplicate.
Generated by Claude Code