Repository navigation
fix(verify): the dashboard date-window family also proves sums and derived measures, and says why an average stays out (#15953 slice 8) - #24385
Conversation
…ures back as fixture rows Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
…he date-window family Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
…measures Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
…-window-noncount-residue
…-window-noncount-residue
📓 Docs Drift CheckThis PR changes 2 package(s): 8 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 6 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 31 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 50525778ad71e04b3293f42182ec911bc066423f && git checkout 50525778ad71e04b3293f42182ec911bc066423f
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin b2e78701f779809b588096d82f5d86ba4ab5cfde 0300fc4b6e360b014b69c38b872a32bea727f1d5 && git checkout -B drift-repro b2e78701f779809b588096d82f5d86ba4ab5cfde && git merge --no-ff 0300fc4b6e360b014b69c38b872a32bea727f1d5
node scripts/docs-audit/affected-docs.mjs --json b2e78701f779809b588096d82f5d86ba4ab5cfde
|
席位核对 — REWORK (patch round 1: the three published texts, answered A)
The family change is accepted as it stands:
Owed in this PR (your open question, answered A): three published texts this slice makes false or incomplete. Fix them here with the replacement texts your PR body already carries:
The claim is amended in place to name all three. The PR body's "Owed before this lands" section becomes stale once they land. The seat corrects it from your report's exact edits; do not patch the body. Before pushing: read this head's checks (still converging at the report) and fold any red into the same round. Generated by Claude Code |
…ms and derived measures Claude-Session: https://claude.ai/code/session_01SYEJqDL3NXxrJRBVqaMu9T Co-authored-by: Claude <noreply@anthropic.com>
席位核对 — ACCEPT (patch round 1)
Generated by Claude Code |
Part of #15953
Clause-②: no
What this is
Slice 8 of the card is the date-window family's residue: the non-count measures the family measured
excluded. For each measure kind the family excluded, this PR decides by measurement whether the window property can be derived honestly from the declaration.sum(no-count-measurealone,not-a-countbeside a count)ratio/sum/difference/productover counts or sums (closed_rate)evaluateDerivedMeasures, the server's own evaluator exported by@objectstack/service-analytics, over the operands in that row.avg(no-count-measure/not-a-count), andmin,max,count_distinctexcluded, with a precise reasonobject-undeclared,dataset-undeclaredand the unparsed kinds are unchanged.Measured
On
bootStack, with a scratch app (not committed), throughPOST /analytics/dataset/queryas the signed-in admin. These readings decided the design:Empty set, no dimensions:
countanswers[{"nn":0}]andsumanswers[{"effort_sum":0}].avganswers[{"effort_avg":null}]. A ratio answers[{"nn":0,"closed_n":0,"rate":null}]. With dimensions every kind answers[].A derived measure's answer carries its operands:
{ measures: ['rate'] }under a window answered[{"nn":2,"closed_n":1,"rate":0.5}]. Grouped bystatus, each row carries its own operands ({"status":"Open","nn":1,"closed_n":0,"rate":0}). This is the reading that makes a derived measure provable without guessing: the operands are read from the widget's own request, not from a second query.Sums behave as expected: a sum over decimals answered
10.6under a window and10.8without one. An undeclared measure is refused400 INVALID_FIELD.hotcrm (read-only shallow clone at
bb8e207, static read only, not run): the three non-count widgets that the hand-written pin of describe 2 blank-checked are:avg_resolution_time, anavg(stays excluded);sla_compliance_gauge,sla_met_count / closed_count(both counts, now probed);kb_deflection_rate,kb_resolved_count / closed_count(counts, one of them of a lookup field, now probed).The opportunity dashboards' bound sums of
amountare probed too. Their averages (avg_amount,avg_probability) stay excluded. NOT MEASURED: a hotcrm run.os verifycannot boot hotcrm on this tree until its protocol-18 move; that is the card's open acceptance clause.How the family reads each kind (
packages/verify/src/dashboard-window.ts)judgechecks that every additive measure took in exactly the rows the window selects. A derived measure must also show the server's evaluator over its operands, row by row. For a count the outcome and detail text are unchanged:heldis now checked before theshown === 0blank, and for a count the two can never both hold.not-runand the detail says why.excludedKindvalues are unchanged.Controls and one-time ablation
count_distinctare excluded with their reasons.hours(sum) andshare(ratio of counts) widgets. Drop givescontradictedon 13 of 13 presets and inert. Zero givesblankon 13 of 13.flagged_sharewhile leaving its operands as answered. Every operand holds, and every preset iscontradicted, with the detail naming both values.55c7623b2, throughscripts/ablation-replace.mjsin wrap mode, inside a script with an absolute-pathtraprestore. No build is involved: the test imports the module by a relative path.const off = taken.find(...)becomesundefined. The anchor goes 1 to 0, and the blob3fa6388fbecomese9c25e54. Result: RED,Tests 8 failed | 7 passed (15): both modes' window controls, the sum and derived controls, and the derived-value and attribution summaries. Restored: blob3fa6388fequals HEAD, andgit diff HEADis empty.continue. The blob3fa6388fbecomesd5f4ff11. Result: RED,Tests 4 failed | 11 passed (15): the derived-value control in both modes, plus the attribution test, whose summary counts that widget. Restored the same way.Tests (the family at
49c5fd871; patch round 1 at0300fc4b6)pnpm --filter @objectstack/verify exec vitest run --maxWorkers=2readsTest Files 42 passed (42)/Tests 368 passed (368). The lock verdict line of that call was not printed, because the typecheck chained after it was cut by the shell timeout while the gate battery shared the box. The same suite at55c7623b2(main merged once before) reads42 / 368 passed,VERDICT command-exit 0.pnpm --filter @objectstack/verify typecheck(re-run alone) readscheck:test-typecheck: OK,VERDICT command-exit 0.tsc --listFilesOnly -p tsconfig.test.jsonlistsdashboard-windowtwice.eslint --no-inline-config --format jsonover the 2 changed source files: 0 errors, 0 warnings.test:repowas not run locally: the diff touches no repo-project test, so it is declared to CI.0300fc4b6(docs and the flag description only):pnpm --filter @objectstack/cli typecheckreadscheck:test-typecheck: OK,VERDICT command-exit 0.test/verify-*.test.tsfiles that spawnos verifyrun in the integration tier (--project integration) and readTest Files 8 passed (8)/Tests 24 passed (24),VERDICT command-exit 0.eslint --no-inline-configoverpackages/cli/src/commands/verify.ts: 0 errors, 0 warnings.commands/verify, so it is declared to CI (Test Core).Gates (the family at
49c5fd871; patch round 1 at0300fc4b6)dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 63 commands. All 63 exit 0.check:dual-build-cjs-loadsfirst answered exit 3 (PREREQUISITE NOT MET), and afterturbo run build --filter=!@objectstack/docs(76 tasks, 75 cached) it answered exit 0.--ranreads63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN.packages/verify/src/dashboard-window.ts, run locally, all exit 0:check:init-service-contract,check:live-db-isolation,check:optional-error-sink,check:resume-authority-declared,check:route-envelope,check:runner-env-posture,check:settings-bind-window,check:startup-registry-verdict,check:verify-stand-inandcheck:wildcard-fallthrough.0300fc4b6:dispatch-gates.mjs --commandsderives 96 commands over 7 paths: the 63 above, plus 33 docs, i18n and spec-docs families forcli.mdx, the README andverify.ts. All 96 exit 0, and--ranreads96 derived, 96 run, 0 NOT-MEASURED, 0 UNRUN.packages/cli/src/commands/verify.ts, and all exit 0.49c5fd871had converged before the push: 34 success, 6 skipped, none red.Docs and flag text (patch round 1, the claim amended in place)
The open question was answered A. The claim
6252766100is amended to name these three files, andcli.mdxis declared on #6023. They are fixed in this PR at0300fc4b6, with the replacement texts this section used to carry:packages/verify/README.md:contradictedrow adds "or a derived measure showed another value than the server's evaluator makes of its operands". Theexcludedrow reads "no measure it can compare (anavg,min,maxorcount_distinctis not additive)".content/docs/deployment/cli.mdx, theos verifysection, reads "For each measure of a bound widget that is a count, a sum, or a derived measure over those". The excluded list reads "an average, a minimum or maximum, a distinct count, or a derived measure over one".packages/cli/src/commands/verify.ts, the--dashboard-windowsdescription, reads "(date and datetime fields; count, sum and derived measures)". It carries apatchchangeset on@objectstack/cli(.changeset/15953-s8-cli-dashboard-windows-flag.md,Clause-②: no).Acceptance notes
is_closedfromstatus(slice 5, run B). So the two newly provable ratios holdis_closed: true, which reads back false. When hotcrm runs, they are expected to readinconclusiveunder live hooks: an app fact, reported, never contradicted.number, 100 for acurrency, 50 for apercent, clamped to the declared min/max/step). A field declaredmax: 0or below would make it non-positive. That case is handled through the rows-equivalent division, and a zero value is excluded.Generated by Claude Code