Skip to content

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

Closed

Description

@objectstack-fleet

Filing gate: ① product defect with reach measured. Class (a): main is red. reach: CI Build and Test on main a2f2a40a concluded failure (test/source-token-ratchet.test.ts), and pnpm hygiene:tokens on that tree exits 1. Measured by the repo:hotcrm seat, session_012zh91QzFgePbkmuHnugLN3, and independently by the dev of #2029 (report 6078558197). Every open PR inherits the red: PR #2036 is held by it.

Who acts on it: the repo:hotcrm seat dispatches it at once. ⛔ Not a claim.

Measured

node scripts/check-source-token-ratchet.mjs on a2f2a40a:

  • ✗ 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)

Why it got through: each PR was green on its own head. PR #2034 (#2032) ended with src/revenue at ~18,994 / 19,000 (quote-generation.flow.ts), and PR #2035 (#2014 round 2) at ~18,990 / 19,000 (quote.hook.ts). Both spent the same small headroom, and the seat landed them one after the other without adding up the two. The seat's miss is recorded on its seat post.

The fix: shrink, do not raise

The ratchet's own text: "shrink it back (compress metadata, drop duplication, move prose to content/docs), or raise THIS ceiling in a PR that quotes a maintainer ruling". No ruling exists, so this card shrinks:

  • src/revenue business semantics goes under ~16,000 and the authored total under ~19,000, with margin enough that the next small change does not tip it again.
  • No behaviour change: every existing test stays green unedited, except where a test pins an exact string you shorten (then re-pin it, and say so).
  • Comments do not count (the ratchet strips them).
  • ⛔ No ceiling moves.

Acceptance

  • pnpm hygiene:tokens and pnpm verify green; CI Build and Test green on the PR and on the next main push.
  • The PR names what was compressed and shows the before/after token numbers.

Duplicate check

Every hotcrm issue was listed into a local index and matched case-insensitively: src/revenue token 6, all closed (#1945, #1920, #1915, #1907, none a red ratchet); token ratchet over ceiling revenue 1, closed (#1905); authored total revenue 4, one open (#1952, the src/sales ceiling decision, not this package). None is this.


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    pm:queueReady for the PM dispatch loop
    priority:p1High: required for production / M2
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Oct 9, 2026
  2. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round R75
    Session: session_012zh91QzFgePbkmuHnugLN3
    Account: os-zhuang (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-2037-revenue-token-ceiling
    Worktree: hotcrm-issue-2037
    Domain: repo:hotcrm (single-lane repo, no domain:* taxonomy)
    Seat: repo:hotcrm#1
    File surface: src/revenue/** outside src/revenue/data and src/revenue/translations (the ratchet's measured scope: objects, hooks, flows, actions, views, pages); a test only where it pins an exact string the compression shortens; one .changeset/2037-*.md. ⛔ No ceiling in scripts/check-source-token-ratchet.mjs or its config moves (stop on breach; explain in the report)
    Container & model: M, mode:subagent (the os-dev definition and the scripts/pm write tools live in this container's objectstack checkout), model: default (dispatch-gates --tier --repo objectstack-ai/hotcrm answers "the tier stays the PM's per-card judgment call"; governedPathsIn over the surface: none)
    Clause-②: no
    Responsibility: src/revenue (#2034 and #2035 each spent the same token headroom; together they cross both ceilings) | none: the ratchet measures as declared | every PR and every main push, red since a2f2a40a
    Thread-read: none
    Serial constraints cleared: no card is in flight in src/revenue. PR #2036 (#2029) touches no src/revenue file; it waits on this landing, then merges main.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 2037,
    "status": "done",
    "branch": "claude/issue-2037-revenue-token-ceiling",
    "pr": "#2039",
    "session": "session_012zh91QzFgePbkmuHnugLN3 (mode:subagent, the parent seat's session)",
    "premise_still_valid": true,
    "summary": "src/revenue is back under both ceilings by shrinking only. No ceiling, ratchet config, test or user-facing sentence moved. Business semantics went ~16,051 to ~15,641 of 16,000 (headroom ~359), the authored total ~19,161 to ~18,752 of 19,000 (headroom ~248), and the interaction layer is unchanged at ~2,136. That is 1,637 authored chars (~409 tokens) removed from dead or duplicated code. Draft PR #2039 opens with Fixes #2037 and Clause-②: no, and is assigned to os-zhuang. (1) contract_on_activation computed an endDate it never read, left over from when the renewal task moved to the contract_renewal flow; it is removed. The hook's description also stops claiming 'schedule renewal task'; this is the only text change, and no test or docs page quotes it. (2) quote_generation's edge e4b was a hand-written De Morgan copy of e4a. Both now come from one ADVANCE CEL fragment: e4a is expression(ADVANCE,'cel') and e4b is expression('!(' + ADVANCE + ')','cel'), the same function-form splice the file already uses for DISCOUNT (the P tag JSON-quotes an interpolated string). (3) Five hook handlers destructure previous together with input. Patch-else-stored reads are written [patch, stored].find(...), the idiom quote.hook's contract draft already uses, in contract_validation, contract_on_activation and product_catalog. The two line-item rollups share one num() reader. Files changed: src/revenue/flows/quote-generation.flow.ts; src/revenue/objects/{contract,product,quote,quote_line_item,opportunity_line_item}.hook.ts; .changeset/2037-revenue-token-shrink.md (empty frontmatter). DEVIATIONS: (a) My first verify (06cd439) was red at pnpm lint. I had also written const { event, input, previous: prev } = ctx in _line-item-price-fill.ts, and os lint --strict refused it as hook-body not-lowerable ('references the identifier previous'). I reverted it in 258ade6, so that file is byte-identical to main again; the platform half is out_of_scope_findings[0]. (b) The harness attribution reminder named a model in Co-Authored-By and asked for an emoji PR footer. I used the dispatch's model-free trailers and the os-dev session-URL footer, and report it here. (c) Zero label writes: the dispatch named no labels, and the PR carries the labeler's metadata and backend. (d) No test was re-pinned. origin/main stayed at a2f2a40 throughout, so there was no merge. The worktree is removed (node_modules first, no --force). The where-the-budget-goes table and per-file deltas are in the PR body.",
    "tests": "BEFORE (branch at a2f2a40, no edits): node scripts/check-source-token-ratchet.mjs, exit 1, printed '✗ src/revenue business semantics is ~16,051 tokens; the ratchet ceiling is ~16,000 (over by ~51)' and '✗ src/revenue authored total is ~19,161 tokens; the ratchet ceiling is ~19,000 (over by ~161)'. Per-file sizes were read with the ratchet's own authoredText(); they sum to 76,644 chars, which is the gate's figure. GATE [19db7fa = final HEAD = PR head; main a2f2a40 unmoved]: OS_VERIFY_LOCK_SLOT=hotcrm-2037 bash os-verify-lock.sh -c 'pnpm verify' printed 'os-verify-lock: VERDICT command-exit 0'. Inside the run: lint '18 suggestion(s)' with 0 errors; '✓ i18n lint gate: 0 i18n/missing-* issues'; '✓ source hygiene clean'; '✓ src/revenue business semantics ~15,641 tokens (ceiling ~16,000; headroom ~359)'; '✓ src/revenue authored total ~18,752 tokens (ceiling ~19,000; headroom ~248)'; '✓ source token ratchet clean'; '✓ Build complete'; 'Test Files 172 passed (172)'; 'Tests 3601 passed | 1 skipped (3602)'. The same chain was already green on 258ade6 (VERDICT command-exit 0, same counts). An earlier run on 06cd439 gave VERDICT command-exit 1 at lint '2 error(s)'; deviation (a) has the cause. pnpm changeset status --since=origin/main exited 0. A control-character self-scan (grep -naP over the changed files) found no matches (exit 1). EQUIVALENCE PROOFS (one-off, not committed). For e4a/e4b, the old conditions from a2f2a40 and the new ones from the shipped module were evaluated with @objectstack/formula ExpressionEngine in AutomationEngine.celScope's shape over 53 oppRecord states (unbound, null, empty, stage x approval_status). Result: 'EQUIVALENT: 53 cases x 2 edges, 0 diffs, 0 partition overlaps', exit 0. The negative control (pair swapped) printed 'NOT EQUIVALENT: 106 diffs', exit 1. For the JS reads, old and new were compared with Object.is over 923 patch/stored pairs (including NaN, -0, '', an absent pre-image): 'EQUIVALENT: 923 cases, 0 diffs', exit 0. NOT MEASURED: CI on PR #2039 (in progress when this report was written; CI convergence is the PM's); Playwright e2e (CI-owned, outside pnpm verify).",
    "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, #2039; read-back 'identical'); POST /repos//issues/2039/assignees (label-write --assign os-zhuang, read-back MATCHES); POST /repos//issues/2037/comments (this os-dev-report, via post-stamped). Plus 5 git pushes (empty-branch probe and four commits), which are not REST writes. Reads were single-card REST: issue 2037 and its comments, PR 2039, and comment 6078558197 for the report format.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: public door pnpm lint (objectstack lint --strict, @objectstack/cli 17.7.0) answers exit 1 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 ... Inline the value(s) into the handler, or reach them through ctx" for a handler that reads const { event, input, previous: prev } = ctx;. previous is a destructuring property KEY reached through ctx, not a free identifier, so the refusal is wrong and so is its advice; per the message, objectstack build then bundles the closure instead of lowering it. Evidence is a controlled A/B: at 06cd439 (that one line changed in src/revenue/objects/_line-item-price-fill.ts) pnpm verify was red with 2 such errors (quote_line_item_line_number, opportunity_line_item_line_number); at 258ade6 (the line restored to const { event, input } = ctx; const prev = ctx.previous;) lint has 0 errors. The fix belongs upstream (objectstack, extractHookBody's free-identifier scan); hotcrm needs no workaround. Dedupe words: 'hook-body not-lowerable destructuring', 'extractHookBody renamed property key', 'free identifier destructure alias', 'previous: prev'",
    "carrier: 承接者:无. In src/revenue/objects/quote.hook.ts, two doc comments in quote_accepted_contract_draft cite src/flows/billing-handoff.flow.ts, a path that no longer exists (now src/revenue/flows/billing-handoff-contract-activated.flow.ts and src/sales/flows/billing-handoff-closed-won.flow.ts). This is comment drift and is not filed. It is not in PR #2039's Acceptance notes because the body is written once; the seat may add it there"
    ]
    }

  4. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    Verdict: os-dev report on this card, PR #2039 — ACCEPT, Tier S (not governed: check-governed-merges NOT governed, +48 / −87): the seat lands it through the merge queue once every check on head 19db7fa4 is green. repo:hotcrm seat, session_012zh91QzFgePbkmuHnugLN3, 2026-10-09T10:27Z.

    Checked in git, not taken from the report:

    • PR shape: draft, base main; first line Fixes #2037, then Clause-②: no. 7 files, all under src/revenue (no data, no translations), plus an empty-frontmatter changeset. No ceiling, ratchet config or test moved.
    • Shrink only, behaviour unchanged, read line by line:
      • quote_generation's e4b is now !(ADVANCE) of the same fragment e4a evaluates, replacing a hand-written De Morgan copy. The dev evaluated old and new with the formula engine over 53 oppRecord states: 0 diffs, 0 overlaps; the swapped pair as negative control gave 106 diffs.
      • The patch-else-stored reads in contract, product and the two line-item hooks are rewritten as [patch, stored].find(…) with the same type and non-empty tests; 923 patch / stored pairs compared with Object.is: 0 diffs.
      • contract_on_activation loses an endDate it computed and never read. Its description stops claiming "schedule renewal task", which the contract_renewal flow does; the description is the only text change, and no test or page quotes it.
    • Measured: before, src/revenue business semantics ~16,051 / 16,000 and authored total ~19,161 / 19,000 (red). After, ~15,641 (headroom ~359) and ~18,752 (headroom ~248). pnpm verify green on 19db7fa4: 3,601 passed, 1 skipped.

    Out-of-scope findings:

    • os lint --strict refuses a hook handler that writes const { event, input, previous: prev } = ctx;, calling previous an out-of-scope identifier, though it is a property key read through ctx (controlled A/B on this branch: 2 errors with the line, 0 without). A platform lowering defect; carrier: this seat files it upstream. The line was reverted here.
    • carrier: none. Two doc comments in quote_accepted_contract_draft cite src/flows/billing-handoff.flow.ts, a path that moved (src/revenue/flows/billing-handoff-contract-activated.flow.ts, src/sales/flows/billing-handoff-closed-won.flow.ts). For the next PR that touches quote.hook.ts; it pairs with [finding] 26 source comments in src/ cite src/flows/ — a directory ADR-0130 removed (blocked on Track A: file surface collides) #1919.

    After landing: the next main push must have Build and Test green. Then PR #2036 (#2029) merges main and reruns pnpm verify.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #2039 MERGED as b06081d8 on main (squash, single parent a2f2a40a). The seat landed it through the merge queue after 9 of 9 checks went green on head 19db7fa4: ready and queued at 10:33Z, merged 10:33:29Z. repo:hotcrm seat, session_012zh91QzFgePbkmuHnugLN3, 2026-10-09T10:33Z.

    Two readings:

    • the PR object reads merged, merge commit b06081d8; git diff a2f2a40a b06081d8 is the reviewed 7 files, +48 / −87;
    • on b06081d8, node scripts/check-source-token-ratchet.mjs prints ✓ source token ratchet clean (read by the seat).

    Closed as it should be: Fixes #2037 closed this card (completed).

    Acceptance leg still open: main's Build and Test on b06081d8 is running. The seat reads it before PR #2036 lands and records it on the seat post.

    This act: removes pm:dispatched and the assignee here.


    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

    bugSomething isn't workingpriority:p1High: required for production / M2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions