Repository navigation
Give the six declared-but-unnamed fields the consumer they should already have — clear 6 of the 12 field-no-consumers warnings blocking #1581 (epic #1579) #1826
Description
Activity
- addedpm:epicParent delegated to a dedicated epic PM — other PMs never dispatch into its subtreeParent delegated to a dedicated epic PM — other PMs never dispatch into its subtree
on Sep 9, 2026 Claim:session_01DuzfS5chho38Yx1jxx9DEj→ branchclaude/issue-1826-field-consumers-sixDispatched by the epic PM for #1579. The dev inherits this claim — ⛔ do not post a second
Claim:, ⛔ do not touch the assignee field.Base off
mainat965933bor later.⚠️ 965933bis where PR #1814 (the 17.4.0 migration) landed; anything older still carries the pre-migrationrefreshIntervalcarrier and the old readonly semantics, and the 13 warnings will not measure the same. ⛔ Do not branch fromclaude/issue-1581-lint-strict-flip— it is polluted by #1806's superseded bump commits.Model: Opus, on the maintainer's ruling 「没有 fable 派 opus」.
Deliverable: a draft PR. 「等总监复审」 — ⛔ do not mark ready for review, ⛔ do not enable auto-merge. The PR stops at draft and waits for the director.
Generated by Claude Code
os-dev-report
{ "issue": 1826, "status": "needs_decision", "branch": "claude/issue-1826-field-consumers-six", "pr": "https://github.com/objectstack-ai/hotcrm/pull/1831", "premise_still_valid": true, "summary": "The card's gating premise HELD and is verified: a metadata binding does clear field-no-consumers. 4 of the 6 fields are cleared with the consumer named; 2 are reported standing because each needs a product decision, which the card named as an acceptable result. pnpm verify is green end to end and the PR is a draft awaiting the director. Base 965933b (= origin/main tip, where PR #1814 landed). One per-field candidate in the card body was falsified: crm_quote_line_item.line_number cannot take a view column or sort key, because the field has NO writer at all — a column would render blank on every line a user creates and carry a number only on the 19 demo seed rows. crm_article_feedback.comment has neither a writer nor a reader: the two feedback actions are one-click header buttons that never ask for a note, so its description ('read by the article's author') promises a surface that does not exist on either side. Nothing was suppressed, whitelisted, re-severitied or deleted. The #1216 component-props-unknown-key warning and the mailing_*/seed_key groups were not touched.", "tests": "pnpm verify GREEN end to end under the container's shared verify lock (os-verify-lock VERDICT command-exit 0, held 161s). pnpm test: 165 test files passed, 3454 passed, 1 skipped, 0 failed — unchanged from base; no test added, per AGENTS.md scope rule 3 (this repo does not grow a gate farm for a platform rule). pnpm lint --json triples, parsed with raw_decode from the first '{': BASE 965933b = errors 0 / warnings 13 / suggestions 12. AFTER-ONE-FIELD probe (crm_campaign.description added to the basic form section) = errors 0 / warnings 12 / suggestions 12, and objects[2].fields.description left the issue list — the empirical check the card gated on, and it held. FINAL = errors 0 / warnings 9 / suggestions 12, passed true; field-no-consumers 12 -> 8, component-props-unknown-key 1 -> 1. pnpm lint:i18n-gate: 0 i18n/missing-* issues — no new locale key was needed (all four fields already carry labels in en/zh-CN/es-ES/ja-JP, every form section reused is an existing _sections key, relatedListColumns adds no translatable surface). pnpm hygiene + hygiene:tokens clean, no ceiling moved (authored total ~137,818 of ~140,000). No ablation applicable: this card adds metadata bindings, it builds no gate.", "mcp_calls": "4 — two targeted search_issues (duplicate check before filing) and two issue creates. CHANNEL SWITCH DECLARED: the REST /search/issues endpoint is blocked in this container ('sessions are bound to their configured repositories'), including for the control probe, so the duplicate check fell back to MCP search_issues as the rules prescribe. All reads (issue body, comments, PR #1814 body, PR read-back) went over repo-scoped REST at 0 MCP cost; the PR create and this report comment went over repo-scoped REST too.", "open_questions": [ { "question": "crm_quote_line_item.line_number — the field has no writer in the app at all. readonly:true, no hook, no flow node, no action writes it; quote_generation creates the quote and no line items, so quote lines are only ever created by hand; and since objectql 17.4.0 a static readonly field is stripped from a non-system caller's INSERT too, so a rep cannot seed it either. Only the 19 seed rows carry values (test/seed-consistency.test.ts pins those 1..n per parent — a fixture pin, not a runtime writer). What should happen to the ordinal?", "options": [ "A — Give it a writer: a per-parent ordinal assigner on insert, in the shape src/objects/_line-item-price-fill.ts already establishes for this pair of objects. Because the field is readonly the writer must be system-context, which puts it under AGENTS.md house rule 9 (elevate as little as possible) — the same question #1807 settled for crm_campaign_member.added_date. Cost: a new hook plus the elevation review; then a related-list column becomes truthful and clears the warning.", "B — Retire the ordinal and its 23 carrier sites (4 locale labels + 19 seed values), and drop the key from billing-handoff's LINE_ITEM_FIELDS and the three billing-handoff doc pages. Cost: the billing payload loses a line ordinal it never really carried.", "C — Add the view column anyway. REJECTED here: it renders blank on every line a user creates and shows a number only on demo data, which is the fabricated surface the card ranks below an honest standing warning." ], "recommendation": "A, because the twin object makes it load-bearing rather than cosmetic: crm_opportunity_line_item.line_number has the identical gap AND billing-handoff.flow.ts ships it in the billing payload on every won deal, so the app currently hands the billing system a field that is null on every non-seed row. Filed as #1828 with that measurement. Whichever answer is chosen should cover both line-item objects, since they deliberately mirror each other." }, { "question": "crm_article_feedback.comment — the column has neither a writer nor a reader. The only creators of feedback rows are mark_article_helpful / mark_article_not_helpful, one-click header buttons whose bodies write crm_knowledge_article, verdict and owner_id and nothing else, so a reader is never asked for a note; and its own description promises 'Optional note explaining the verdict — read by the article's author' while no surface routes an author to it. Build the promise, or retire it?", "options": [ "A — Build what the description promises: a capture step plus an author-facing surface. Note the capture cannot be a type:'script' action — those bodies collect no input — so the one-click thumb would have to become a screen flow, and the author surface needs somewhere on the knowledge article to read the notes.", "B — Retire the column and its 4 carrier sites, and delete the false promise in the description with it." ], "recommendation": "No recommendation — this is a genuine product decision and I decline to dress a guess as one, per the card. The trade-off to weigh: this object exists to make helpful_count / not_helpful_count trustworthy (its docblock is explicit that a two-valued verdict was chosen deliberately, and that 'a vocabulary nothing reads would recreate the very defect it is fixing'). Interposing a note prompt between the reader and the thumb suppresses votes, which is a direct cost to the counters the object was built for. If the article author is not actually asking for prose, B is the honest answer and matches the object's own stated design philosophy. Not retired here, per the card's explicit instruction." } ], "out_of_scope_findings": [ "filed as #1828: crm_opportunity_line_item.line_number has no writer either, yet billing-handoff.flow.ts ships it in LINE_ITEM_FIELDS — the billing payload carries a field that is null on every line item created in the product, non-null only on demo seed rows, and content/docs/revenue/billing-handoff.mdx documents it with a worked example value.", "filed as #1829: content/docs/marketing/campaign-members.mdx and its two Chinese siblings still document First Opened / First Clicked fields and Opened / Clicked / Bounced statuses that #597 removed from crm_campaign_member — and then derive Open rate and Click rate from those phantom statuses. #961 corrected a different paragraph on the same page without reaching these.", "not filed, noted only: src/views/account.view.ts's file docblock lists 'gallery — branded account cards with brand_color highlights', which described the cards before this PR gave them a logo cover; corrected in place as part of this change, not a separate card." ] }
Generated by Claude Code
- removedpm:epicParent delegated to a dedicated epic PM — other PMs never dispatch into its subtreeParent delegated to a dedicated epic PM — other PMs never dispatch into its subtree
on Oct 8, 2026 objectstack-fleet commented
on Oct 8, 2026 ContributorMore actionsRuling: batch hotcrm-R74 item 1 · letter A · maintainer 「同意」 2026-10-08T03:06Z
repo:hotcrmseat,session_012zh91QzFgePbkmuHnugLN3. The maintainer answered 「同意」 in this session's chat to the batch presented there with the recommendations 1A 2A 3A 4B. Item 1 is this card's last open question:crm_article_feedback.comment.The decision as presented: keep the field and close this card (A). The fallback was B, retire the field; C was to build a guided capture step after the vote.
The premise was refreshed before presenting. The 2026-09-09 report said the field had "neither a writer nor a reader". On
origin/mainc967803that no longer holds:- Reader: PR feat(metadata): quote-line subtotal and feedback comment reach their related-list panels (#1199) #1958 (merged 2026-09-25) shows
commentin the article's feedback panel throughrelatedListColumns: ['verdict', 'owner_id', 'comment']. So the field's description, "read by the article's author", is now true. - Writer: the generic record form. All five profiles grant
allowEditoncrm_article_feedback. The two vote buttons still write the verdict only, and the one-click vote is kept on purpose.
Disposition of all six fields, so the card closes complete:
- Four were cleared by PR feat(metadata): give four declared-but-unnamed fields the consumer they should already have #1831.
crm_quote_line_item.line_numbergot its writer undercrm_opportunity_line_item.line_numberhas no writer, yet the billing hand-off payload ships it on every won deal #1828.crm_article_feedback.commentstands as it is, under this ruling.
Release: the epic-PM claim
5603053957(sessionsession_01DuzfS5chho38Yx1jxx9DEj, assigneeos-steve) is released with this close. Source: the maintainer's 「同意」 above, in this session's chat; epic #1579 is dissolved by item 4 of the same batch. Destination: closedcompleted;pm:epicand the assignee are removed in the same act.
Generated by Claude Code
- Reader: PR feat(metadata): quote-line subtotal and feedback comment reach their related-list panels (#1199) #1958 (merged 2026-09-25) shows
Filed by the epic PM (
session_01DuzfS5chho38Yx1jxx9DEj) on the maintainer's instruction, 2026-09-09, verbatim: 「继续处理所有相关任务」.pm:epicreserves it for the epic PM.#1581 is gated on this. Its acceptance needs
errors: 0andwarnings: 0. Errors are 0 since the 17.4.0 migration (#1807 / PR #1814,main965933b). 13 warnings stand — and until they reach 0,os lint --strictcannot flip, which in turn blocks six family cards (#1582–#1587). This card takes 6 of the 12.Where the 12 came from
field-no-consumersis a new rule in@objectstack/lint@17.4.0. It fires on a declared field that no metadata names — its own wording: "no view column, form section, page binding, flow node, dataset, widget, formula, validation, hook or action names it."⭐ The reading that governs all twelve, and it is not the obvious one. Every one of the 12 carries a
group, every group is a declaredfieldGroup, and each object renders through the synthesized detail/form layout rather than an authored*.page.ts. A synthesized layout names nothing. ⇒ "no consumer" here means "not named in metadata", ⛔ not "unreachable by a user" — all twelve are on screen and editable in the product today.⛔ That is why none of these is a deletion. The per-field analysis is written up in PR #1814's body ("The 12
field-no-consumerswarnings — per-field disposition"); ⛔ do not re-derive it, read it.The six in this card
crm_account.logobrandinggroup besidebrand_color. No list column shows it;account_detail.page.tsdoes not bind it. Candidate: the account detail header.crm_campaign.descriptionbasicgroup; seven seed campaigns fill it. On no view column, and no campaign detail page exists.crm_campaign_member.added_datecrm_campaign_member— makes the audit stamp legible and settles the rule in one move.crm_contract.descriptioncrm_contractalso declaresspecial_terms, which is consumed — so which of the two markdown bodies a reader is meant to use is a real question, not an accident. Answer it or say you could not.crm_quote_line_item.line_numberreadonlyordinal in thebasicgroup. Nothing orders or displays by it — the line-item related list uses it as neither sort key nor column, which is probably the actual defect.crm_article_feedback.commentdescriptionstates a consumer that does not exist: "Optional note explaining the verdict — read by the article's author." Nothing surfaces it to the author. ⇒ Either build that surface, or the column collects text nobody reads and thedescriptionis a false promise. This one may legitimately come back as "retire the column" — say which, with the reason.⛔ How to do it, and how NOT to
os lint --strictin this repo's verify chain and prove the gate reds (epic #1579, step 2b — the half that needs a release) #1581's flip meaningless.Acceptance
pnpm lint --jsonbefore and after on your own base SHA and report both triples. ⭐ The claim "adding a view column clearsfield-no-consumers" is the PM's reading of the rule's wording — ⛔ verify it empirically on the first field you fix and say whether it held. If it does not clear the rule, STOP and report: the remedy is then wrong for all six.pnpm verifygreen end to end.⛔ Not in this card
crm_contact.mailing_*fields — a separate product question (they are import-mapping targets the CSV importer fills; see the companion card).crm_forecast.seed_key— correctly unconsumed by design (hidden: true, seeder-only upsert identity); raised upstream as objectstack#17135.component-props-unknown-key×1 — The Sales Home AI card's paragraph never reaches the screen:descriptionis not a proppage:carddeclares, and #1002's guard pins the copy there #1216's, ⛔ never fixed here.--strictflip itself — Turn onos lint --strictin this repo's verify chain and prove the gate reds (epic #1579, step 2b — the half that needs a release) #1581.Refs: #1579 (epic) · #1581 (the gate this unblocks) · #1807 / PR #1814 (where the 12 were measured and dispositioned) · #1667 (
added_dateruled readonly) · objectstack#17135.