Skip to content

Re-verify the premise of all 37 open findings against current main — which were silently fixed by today's 15 PRs? #1106

Description

@huangyiirene

Queue-hygiene card, filed by the PM after the dispatch queue emptied on 2026-08-11. This is a measurement task, not an implementation task — it is expected to produce no code change.

Why this exists

The finding backlog stands at 37 open cards, against a trigger line of 15. A triage sweep earlier today read their titles and labels only and produced a useful grouping (see the cluster analysis on #1018), but explicitly did not do the expensive half: reading each body and checking whether its premise still holds.

15 PRs merged to main today. Several of them touched exactly the surfaces these findings describe. Nobody knows which findings are now stale.

⚠️ The case that makes this urgent is #1091. It sat in the backlog looking rigorous — a nine-row measurement table with a reproduce command — and its premise was empty: the command was grep -cE '\b[FP]\.', which matches dot-notation only, while F and P are tagged-template functions invoked as F`...`. It returned 0 whether the symbols were used or not. A measurement that cannot fail is not a measurement, and one of those was in this backlog for a week. There is no reason to think it was the only one.

Scope

For each open issue labelled finding, read the full body (⚠️ and its comments — several carry PM triage that changes the card) and determine, against main at 14d43d1a or later:

  1. Does the described defect still exist? Re-run the card's own reproduction where it has one. ⚠️ Check the reproduction itself, not just its output — that is the Nine object files import F, P from @objectstack/spec and never use them — three of them above the license header #1091 lesson: a repro that structurally cannot fail proves nothing, and its zero looks exactly like a passing check.
  2. Was it silently fixed? Today's merges included forecast validation (forecast_derive_period:手填 period_start 时 period_end 按「起点 + 3 个月」推导,可越出它自己标注的季度 #1008), discount governance (Discount governance: ceiling validation + approval routing; one definition of "large deal" #599), billing hand-off flows (Billing hand-off: declare outbound webhooks on closed-won and contract activation — CRM scope ends at the contract #600), campaign member lifecycle (Campaign member lifecycle: support contacts, live metrics, and trim tracker fields that have no writer #597), case intake + escalation routing (Case intake: round-robin assignment + triage view so web-to-case never lands ownerless #596, Escalation does not reassign: route an escalated case to the service_manager pool #1070), knowledge deflection (Knowledge loop: case→article resolution link, deflection metric, share-link publishing for public articles #601), two i18n gates (守卫能力:objectstack lint 的 warning 不 gate(exit 0)——warning 级缺陷在 pnpm verify 里永远不会红,只能靠人眼或逐条复刻成测试 #1018, 67 form/detail section headings have no name, so they render in English in every locale #1100) and a placeholder retirement (Replace the placeholder competitors picklist (Competitor A/B/C shipped as production metadata) — split from #594 #1061). Several findings sit on those surfaces.
  3. Has it been superseded or duplicated by a card filed since?

Output — a report, not a PR

Post the result as a single issue comment on this card, as a table with one row per finding:

# verdict evidence
… keep / close-stale / promote / duplicate-of #N one line: what you ran or read, and what it showed
  • close-stale ⇒ the premise no longer holds. Say what fixed it.
  • promote ⇒ still real and worth queueing now. ⚠️ Reserve this — a finding being real is not the same as being worth doing.
  • duplicate-of ⇒ name the survivor.

⛔ Do not change any label or close any issue yourself. The PM applies the verdicts after reading them. A wrong close on a real defect is expensive and silent.

⛔ Do not re-rule product direction. Several findings carry maintainer decisions. Your verdict is about whether the premise still holds, never about whether the decision was right.

⛔ Do not fix anything. If you find something urgent, say so in the row and let the PM dispatch it.

Known inputs

Acceptance

  • Every one of the 37 has a row. ⛔ A partial sweep that silently stops is worse than none — if you run short, say which ones you did not reach.
  • Every close-stale names the change that fixed it.
  • No labels changed, no issues closed, no code changed.

Activity

  1. self-assigned this
    on Aug 11, 2026
  2. added
    metadataDeclarative metadata — schema, security posture, UI surfaces
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Aug 11, 2026
  3. huangyiirene commented on Aug 11, 2026

    @huangyiirene
    CollaboratorAuthor

    os-dev-report

    Finding backlog re-verification against main @ 14d43d1a

    The count is 34, not 37. list_issues(labels: [finding], state: OPEN) returns totalCount: 34. The other three were presumably closed between the PM's count and this sweep (#1091 by PR #1095 is one of them). All 34 have a row — none skipped.

    Method: full body + comments read for each; every card's own reproduction re-run where it had one; metadata/gate claims re-read against the tree at 14d43d1a; two engine probes written, run and deleted (nothing committed, no labels touched, no issues closed, no code changed).

    Verdicts

    # verdict evidence
    1102 keep test/demo-staffing.test.ts:133-134 still lists service_manager / service_agent in DELIBERATELY_UNSTAFFED; both routing hooks still take the no-op path. Parked on a maintainer decision, as the card says.
    1094 keep Card's own repro re-run: the same 8 files still open with an import above the copyright header. PR #1095 fixed only #1091's 3. Repro is sound — it can fail, and did shrink from 11 to 8.
    1093 promote Reproduced end-to-end (probe on InMemoryDriver + the real forecast_derive_period): insert of period: quarter / period_start: 2026-07-01 / hand-typed period_end: 2027-05-15 was ADMITTED, stored with period_label: "Q3 2026". Control without period_end derives 2026-09-30. Nothing refuses that write, so the PM's own unverified claim holds. Extra measurement for the option choice: src/data/revenue.seed.ts:339,378,393 do set period_end by hand, so the card's own rule ("(1) if nothing writes it by hand, (2) if something does") points at option 2.
    1086 promote Walk-around confirmed. crm_quote validations: expiration_after_quote, discount_within_ceiling, quote_status_progression; the ceiling predicate reads only has(record.discount) && record.discount != null && record.discount > 60. crm_quote_line_item validations: unit_price_positive only; its discount field carries max: 100 and nothing else. Nothing gates presented on line discount. A quote at discount: 0 with every line at 90% still clears.
    1082 keep src/flows/forecast-snapshot.flow.ts:83-88 still windows by containment only (period_start lte TODAY, period_end gte TODAY, no source discriminator) and write_snapshot still stamps source: 'scheduled'. Unchanged by #1008/#1081. Still not driven through a real flow run — same caveat the card states.
    1062 keep Parked by maintainer ruling with an explicit pull condition; nothing in today's merges supplies it.
    1016 keep Neither test/helpers/hook-harness.ts nor test/helpers/action-sandbox.ts asserts anything about lookup value shape — the only lookup/reference hits in both files are prose.
    1003 keep The persona rule is still walkDocs('content/docs') in test/docs-drift.test.ts:976; the src/ pin (test/metadata-references.test.ts:789) is still the single-card pin #1002 added.
    986 keep — re-verified on a newer platform The repo moved to @objectstack/spec@17.0.0-rc.6 today (#1066), so this was re-measured rather than assumed: ComponentPropsMap (dist/ui/index.d.ts:4787) still has no record:reference_rail key — the only rc.6 hits for that string are the component-type enum — and there is still no ReferenceRailEntry type. A filter on an entry still parses, typechecks, validates and does nothing.
    982 keep The "ship with the system" half-sentence is still at :56 of all three guides/search-and-navigation pages, unchanged.
    981 keep quick-tour.mdx:40 still shows /screenshots/hotcrm/sales-dashboard/en.jpg, and ## 1. The home dashboard spans lines 10-42, so it is still inside section 1. quick-tour.zh-Hant.mdx still has zero screenshots, and assets/screenshots/hotcrm/ still holds no executive-dashboard asset.
    980 keep src/translations/en.ts: :1405 and :1433 read "at each sales stage", :1420 (executive) still reads "by sales stage"; the factory (shared-widgets.ts:35) says "at each sales stage". Today's two i18n gates close missing keys, not drifting text.
    970 keep escalated_date still appears nowhere in src/pages/case_detail.page.ts or the form sections of src/views/case.view.ts (only in a comment); fieldGroups still 6. #596/#1070 added routing, not display.
    966 keep case_metrics dimensions are still status / priority / origin / type / created_date — plus resolved_article newly added by #601, but still no owner_id — while service.dashboard.ts:76-83 still binds the Agent filter to owner_id. The browser measurement the card asks for is still owed.
    964 keep relatedListColumns still appears nowhere in src/ (only in the explanatory comments PR #957 wrote), and EventAttendeeViews.list is still declared. PR #1077 changed attendee_type semantics, not the consumption path.
    949 keep DOC_PAGES (docs-drift.test.ts:562-566) is still the three analytics/dashboards pages; TILE_WORDS (:595) is still ['tiles','tile','磁贴','磁貼']. content/docs/service/cases.zh-Hant.mdx still uses 磁磚 3 times, and 7 service pages carry tile references outside the scanned set.
    935 keep headingLabel at docs-drift.test.ts:580 is still h.replace(/^[^A-Za-z]+/, '').trim() — trailing explicit ids still break it.
    931 keep All four comments still name metadata-references.test.ts: opportunity.view.ts:311, task.view.ts:174, service.dashboard.ts:72, bulk-action-dispatch.test.ts:86.
    909 keep Card's repro re-run: grep -rli "MCP|Connect an Agent|Datasource" content/docs is still zero hits. Sound repro (it would hit if the docs covered either surface).
    873 keep payment_terms still appears nowhere in src/objects/quote.hook.ts; the drafted contract still hardcodes contract_term_months and contract_type: 'subscription'. #600's billing hand-off (PR #1089) added a downstream hand-off, it did not touch the quote-to-contract copy.
    867 keep (partially re-measured — stated honestly) The guard-absence half re-verified: .github/workflows/link-check.yml:31 still sets file-extension: '.md' while every product doc is .mdx, so that workflow is still vacuous. I did not re-count the 36 anchored links / 22 dangling — too expensive for this sweep, and the existing-defect half is accounted in #749/#764/#866 anyway.
    856 keep — and slightly worse AGENTS.md now carries four singular *.action.ts spellings (:86, :102, :119, :175) against one plural at :38; on disk it is 7:0 in favour of *.actions.ts (was 6:0).
    853 promote (flagged) Premise holds and the drift spread today: PR #1089 (#600) added a new 流程监控器 reference at content/docs/revenue/billing-handoff.zh-Hans.mdx:163 (and the zh-Hant twin) — a Setup page name that has zero hits in the platform packages. Now 8 files. ⚠️ Promoting is only a statement that the cost is growing; the editorial decision the card names (platform's real name vs a productised alias) is still the maintainer's and I have not touched it.
    838 keep scripts/check-source-hygiene.mjs: SCANNED = ['src','test','e2e','scripts'] (:142), TEXT_SCANNED = ['content','.changeset'] (:175). docs/, .github/, .claude/ and the root first-class files (incl. objectstack.config.ts, vitest.config.ts, playwright.config.ts) are still outside every check. ⚠️ Repro note: this card's grep -rlaP command returns zero whether or not the gap exists — its zero is not evidence for the claim. The card says so itself ("纯覆盖缺口"), and the claim is carried by the two constants above, which I read directly.
    837 keep — and slightly worse 工单 is now on 27 zh-Hans pages (was 25), 案例 on 14; src/translations/zh-CN.ts:654 still says 服务案例. Three names, still no guard.
    809 keep test/sharing-coverage.test.ts still has multi-locale describes only for the OWD table, the related-list table and parent-derived reach; the built-in-rules table guard (:225) still reads the English SHARING_DOC alone.
    806 keep src/pages/lead_detail.page.ts still contains zero occurrences of notes and of duplicate_of_lead; the three-way grouping split stands.
    802 keep Still no guard anywhere reads src/translations/* to check doc wording; docs-drift.test.ts has no reference to the language packs. The two open design questions in the body are still unanswered, so it is still not actionable as written.
    788 keep, halved — scope now point 1 only Re-measured on rc.6 (the card measured rc.2). Point 2 is FIXED upstream: stripReadonlyFields now guards with if (!Object.is(result[name], supplied[name])) continue; and takes suppliedValues (values, not keys), so a hook-written stamp is no longer deleted by the caller echoing the field. Point 1 is still live: probe with a non-system context inserted published_at: "2024-03-01T00:00:00.000Z" on crm_knowledge_article (field readonly: true) and it stored as given, no warning; the two stripReadonlyFields call sites in rc.6 are still both on the update branch. Suggest the PM re-scope the card to the insert path.
    786 close-stale Fixed upstream by the platform bumps (#1056 rc.5 / #1066 rc.6), not by a hotcrm PR. rc.6 replaced the recogniser with FILTER_TOKEN_WRAPPED_RE = /^\$?\{([^{}]+)\}$/ — exactly the card's option 1. Probe on rc.6: classifyFilterToken('{TODAY()}') now returns {"kind":"unknown","token":"TODAY()"} (was null), and find(due_date < '{TODAY()}') now THROWS UnknownFilterTokenError / FILTER_TOKEN_UNKNOWN instead of returning all 4 rows. The exact failure mode the card documented is gone.
    760 keep src/views/opportunity.view.ts:75 still reads label: 'Closing Soon' on the closing tab; the one-look browser check the card asks for is still the blocker, not the metadata.
    753 keep Both workflows still name the step Source hygiene (console.log / TODO / file size) (ci.yml:40, code-quality.yml:45) while the script runs four check(...) calls — the fourth being "no raw control bytes in first-party files".
    695 keep src/sharing/opportunity.sharing.ts:16 and :34 still author !(record.stage in ["closed_won","closed_lost"]) && record.amount gte LARGE_DEAL_AMOUNT. Not re-run against a booted memory driver this round; the authored form the card blames is unchanged.
    655 keep Still no duplicate detection of any kind on crm_account (no hook, no suspected shape, no review view); the fresh-installs-only premise that bounds it is unchanged.

    Summary

    Repro-quality audit (the #1091 habit)

    Asking of each card that hands over a command: what would it print if the defect did not exist?

    Two things for the PM, filed nowhere and fixed nowhere

    1. A hand-filled period_end walks around #1008's calendar-boundary fix — a row labelled Q3 2026 can still span ten months #1093's option choice is already measured. The seeds do write period_end by hand, so making the field readonly would break them. If that card is queued, it should be scoped to option 2.
    2. ⚠️ An open question, asserted as a question and not as a defect. rc.6 now throws on {TODAY()} at the ObjectQL filter layer (see [平台侧观察] UnknownFilterTokenError 覆盖不到含非 word 字符的类占位符串:{TODAY()} 不报错,原样下发按字面串比较(匹配全部行) #786 above), and 29 sites in src/ use that spelling — including live flow filters such as forecast-snapshot.flow.ts:86-87. Flows appear to resolve TODAY() on their own path (test/account-name-normalized-match.test.ts:42, and the platform's own lint hint recommends that spelling for flow filters), so I am not claiming breakage; test/forecast-seeds.test.ts:201 only asserts the filter's literal shape, never executes it. Nobody has run a flow filter carrying that token through rc.6 end-to-end. Worth one dispatched check.

    No labels changed, no issues closed, no code changed; both probe files were deleted and the worktree is clean.


    Generated by Claude Code

  4. os-warren commented on Aug 24, 2026

    @os-warren
    Collaborator

    Closing — the deliverable was delivered 13 days ago and the card was never closed out.

    Half-state cleanup by the repo:hotcrm PM seat on resuming. This card asked for one thing — a re-verification pass over the open findings against main — and the dev returned it in full on 2026-08-11: 34 cards, every one with a row, verdicts of keep / promote / close-stale, plus a repro-quality audit. Nothing was left owed.

    What was never done is the close-out: assignee still set, pm:dispatched still on, card still open. So for 13 days it has read as work in flight to every query, while the work was finished and sitting in a comment above.

    Closing as completed and dropping the assignee. ⛔ Not a judgement on the report, which was thorough.

    ⚠️ Its verdict table is now 13 days old — use it as a lead, not as a reading

    This matters more than the cleanup, because the table is exactly the kind of artefact that gets quoted forward. It was measured against main @ 14d43d1a. Since then main has moved a long way, including a 3.0.0 release cut (#1242) and, on 2026-08-23 alone, seven merges (#1232, #1250, #1251, #1254, #1256, #1261, #1263) plus three more this round (#1267, #1270, and #1266 pending).

    This seat has now been bitten twice in one round by treating an older reading as current:

    Both were caught by re-measuring per symptom against origin/main, not by consulting a table. So: a keep in that table means "still true on 2026-08-11", which is not a claim about today. Any finding graded off it gets its own fresh premise check first — that is the standing grading discipline for this seat and this table is not an exception to it.

    The two items the report handed to the PM, still open and still worth acting on

    Recording them so they are not lost with the card:

    1. A hand-filled period_end walks around #1008's calendar-boundary fix — a row labelled Q3 2026 can still span ten months #1093's option choice is already measured. src/data/revenue.seed.ts writes period_end by hand at three sites, so making the field readonly would break the seeds — the card's own rule points at option 2. Whoever queues that card should scope it that way rather than re-deriving the choice.
    2. An open question, correctly stated as a question and not a defect: rc.6 began throwing on {TODAY()} at the ObjectQL filter layer, and 29 sites in src/ use that spelling, including live flow filters. Flows appear to resolve TODAY() on their own path, so no breakage was claimed — but nobody has run a flow filter carrying that token end-to-end on the pinned version. ⚠️ Note the version drift: that was written about rc.6 and this repo now pins 17.1.0, so the question needs re-asking against the pin before it is worth a dispatch.

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    metadataDeclarative metadata — schema, security posture, UI surfaces

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions