Skip to content

refactor(revenue): shrink src/revenue back under both token ceilings, behaviour unchanged (#2037) - #2039

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-2037-revenue-token-ceiling
Oct 9, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-2037-revenue-token-ceiling

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #2037
Clause-②: no

What was measured before the fix

main at a2f2a40a is red at the door this gate guards. node scripts/check-source-token-ratchet.mjs (pnpm hygiene:tokens, also a step of CI Build and Test) exits 1, reproduced on this branch before any edit:

  • ✗ src/revenue business semantics is ~16,051 tokens; the ratchet ceiling is ~16,000 (over by ~51)
  • ✗ src/revenue authored total is ~19,161 tokens; the ratchet ceiling is ~19,000 (over by ~161)

PR #2034 (quote-generation.flow.ts) and PR #2035 (quote.hook.ts) each fit alone and together crossed both lines. Where the src/revenue budget goes, measured with the ratchet's own authoredText() counter (comment- and blank-stripped chars, ~tokens = chars / 4), the twelve largest files on a2f2a40a:

file chars ~tokens
objects/quote.hook.ts 7,733 1,933
flows/contract-renewal.flow.ts 6,619 1,655
objects/quote.object.ts 6,012 1,503
objects/contract.object.ts 5,860 1,465
flows/quote-generation.flow.ts 5,277 1,319
objects/contract.hook.ts 4,254 1,064
flows/billing-handoff-contract-activated.flow.ts 3,915 979
objects/product.object.ts 3,754 939
views/contract.view.ts 3,356 839
objects/quote_line_item.object.ts 3,138 785
views/quote.view.ts 2,983 746
objects/quote_line_item.hook.ts 2,892 723

The fix: shrink, no ceiling moves

1,637 authored chars (~409 tokens) removed, all from duplicated or dead code in five hooks and one flow. No ceiling, no ratchet config, no test file and no user-facing sentence was touched.

src/revenue scope before after ceiling headroom after
business semantics ~16,051 ~15,641 ~16,000 ~359
interaction layer ~2,136 ~2,136 ~3,000 ~864 (unchanged)
authored total ~19,161 ~18,752 ~19,000 ~248
file (authored chars) before after delta
objects/contract.hook.ts 4,254 3,676 -578
objects/quote_line_item.hook.ts 2,892 2,477 -415
objects/product.hook.ts 2,471 2,215 -256
flows/quote-generation.flow.ts 5,277 5,063 -214
objects/opportunity_line_item.hook.ts 2,397 2,248 -149
objects/quote.hook.ts 7,733 7,708 -25

What was compressed, and why it changes nothing at runtime:

  1. Dead code (contract.hook.ts). contract_on_activation computed an endDate it never read. It was left behind when the renewal task moved to the contract_renewal flow (the note at the end of that handler records the move). The same move made the hook's description, "On activation: stamp signed_date, promote account, schedule renewal task.", untrue. The description now drops that last clause. It is the only text change, and no test or docs page quotes it.
  2. A hand-kept De Morgan copy (quote-generation.flow.ts). Edge e4b's condition was written out as the negation of edge e4a's. Both edges now take one CEL fragment, ADVANCE: e4a is expression(ADVANCE, 'cel') and e4b is expression(`!(${ADVANCE})`, 'cel'). This is the same function-form splice the file already uses for DISCOUNT; the P tag JSON-quotes an interpolated string, so it cannot splice a fragment. The two branches now partition by construction. Before, they partitioned only because someone had negated the condition correctly by hand.
  3. Repeated reads (hooks). Five handlers now destructure previous together with input. The patch-value-else-stored-value reads are written [patch, stored].find(...), the idiom quote_accepted_contract_draft already uses: contract_validation (start date, end date, term), contract_on_activation (id, account) and product_catalog (list price, cost). The two line-item rollups share one num() reader in place of six copies of the same typeof ternary.

Why this is the minimal change: removing dead or duplicated code shortens nothing a user reads. Every refusal message, refusal code and stored value is byte-for-byte the same, so no test pin had to change. Shortening user-facing copy would have bought the same tokens, but only by re-pinning messages.

What pins it

  • The business fact is the ratchet itself: both src/revenue lines are now ✓ in pnpm hygiene:tokens (✓ source token ratchet clean), and test/source-token-ratchet.test.ts is green.
  • pnpm verify green on 19db7fa4 (the final commit), run through the shared verify lock. It ended with VERDICT command-exit 0, and the test step reported Test Files 172 passed (172) and Tests 3601 passed | 1 skipped (3602). The suite includes flow-quote.test.ts (both stage branches, including a deal awaiting approval), flow-variable-conditions.test.ts (condition totality), metadata-references.test.ts (every condition reaches CEL), refusal-envelope.test.ts, freeze-guard-reference-cleanup.test.ts, and the contract, product and line-item hook suites.
  • No test was re-pinned: no exact string was shortened.
  • Equivalence proofs, run once and not committed:
    • e4a / e4b: the old conditions from a2f2a40a and the new ones from the shipped flow module were evaluated by the platform's own ExpressionEngine (@objectstack/formula 17.7.0), in the scope shape of AutomationEngine.celScope. The 53 oppRecord states were unbound, null, empty, and every combination of stage (8 values, absent, null) with approval status (absent, null, pending, approved, rejected). Result: EQUIVALENT: 53 cases x 2 edges, 0 diffs, 0 partition overlaps. A negative control that swaps the old pair reports NOT EQUIVALENT: 106 diffs.
    • The rewritten JS reads: the old and new expressions were compared with Object.is over every patch/stored value pair (undefined, null, empty string, strings, 0, -0, NaN, numbers, booleans, an object, and an absent pre-image). Result: EQUIVALENT: 923 cases, 0 diffs.

Acceptance notes

  • One edit was refused and reverted. Renaming the destructured key in the line-number hook (const { event, input, previous: prev } = ctx in _line-item-price-fill.ts) was refused by pnpm lint (os lint --strict) with hook 'quote_line_item_line_number' cannot be lowered to a metadata-only body: it references the identifier previous, which is not in scope inside the sandbox. The lowering reads a renamed destructuring key as a free identifier. That file is byte-identical to main again. The platform side goes to the seat in the dev report and is not filed from here.
  • Changeset: an empty-frontmatter .changeset/2037-revenue-token-shrink.md. This PR releases nothing a CRM user would notice.
  • Headroom after this PR: ~248 tokens on the authored total and ~359 on business semantics.

Generated by Claude Code

claude added 4 commits October 9, 2026 10:03
… behaviour unchanged (#2037)

- contract_on_activation: drop the dead `endDate` local (left behind when the
  renewal task moved to the contract_renewal flow) and the stale "schedule
  renewal task" clause in its description
- quote_generation: edge e4b is edge e4a's predicate negated whole, spliced
  from one `ADVANCE` fragment like `DISCOUNT`, instead of a hand-kept
  De Morgan copy
- hooks: destructure `previous` with `input`; read patch-else-stored values
  with `[patch, stored].find(...)` (the idiom quote.hook already uses); one
  `num()` reader in the two line-item rollups

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
…t still lowers (#2037)

`const { previous: prev } = ctx` is refused by `os lint --strict`
(hook-body/not-lowerable: "references the identifier previous") — the
lowering reads the renamed property key as a free identifier. Back to the
base's two-line read; the file is byte-identical to main again.

Claude-Session: https://claude.ai/code/session_012zh91QzFgePbkmuHnugLN3
Co-authored-by: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
hotcrm Ignored Ignored Oct 9, 2026 10:23am UTC

Request Review

@github-actions github-actions Bot added metadata Declarative metadata — schema, security posture, UI surfaces backend Server-side behaviour — hooks, flows, actions labels Oct 9, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 9, 2026 10:33
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 9, 2026
Merged via the queue into main with commit b06081d Oct 9, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Server-side behaviour — hooks, flows, actions metadata Declarative metadata — schema, security posture, UI surfaces

Projects

None yet

2 participants