Skip to content

chore(deps): upgrade @objectstack/* past 17.7.0 once the next release publishes — it carries the platform fixes #2016, #2000, #1583 and #1585 wait on #2031

Closed

Description

@objectstack-fleet

Restart-when: npm view @objectstack/cli version prints a version above 17.7.0

Filing gate: ③ a task the maintainer set. The maintainer answered 「同意」 on 2026-10-09 to the decision batch hotcrm-R74b, whose item 1 ruled D for #2016: wait until the platform fix is released and hotcrm is upgraded, then build it. Its post-ruling step, as presented: 「立一张『升级平台版本』的杂事卡,#2016 转为阻塞,挂在这张卡上」. Filed by the repo:hotcrm seat, session_012zh91QzFgePbkmuHnugLN3.

Who acts on it: the repo:hotcrm seat dispatches it when the Restart-when: line above holds. ⛔ Not a claim.

Hold: 2026-10-09, seat grading under that ruling. hotcrm pins @objectstack/* 17.7.0 (every package, exact versions), and 17.7.0 is the newest release on npm today, so there is nothing to upgrade to yet.

What the upgrade carries

Each row is an objectstack card closed after 17.7.0 published (2026-10-06), and the hotcrm card that waits on it. The dev checks each fix is really in the release it installs (the package CHANGELOG or the source), and reports per row.

upstream hotcrm card after the upgrade
objectstack#22310 (PR #22404) + objectstack#22407 #2016 #2016 unblocks only when BOTH are in the installed release: #22310 shuts the trigger door, #22407 the action door and the declared flow endpoint. If #22407 is missing, #2016 re-blocks on the next upgrade
objectstack#22178 #2000 re-derive #2000's Blocked-by: line
objectstack#22212 #1583 re-derive
objectstack#22238 #1585 re-derive
objectstack#22074 — retire test/helpers/identity-objects.ts if the fix ships
objectstack#22149, #22189, #22067, #22071, #22072, #22073, #22079 — filed by this lane; nothing to do unless the release notes say so

Scope

  • Bump every @objectstack/* pin together to the newest release. Use the repo's own upgrade path, and regenerate the lockfile with its tooling. ⛔ Never hand-edit a lockfile.
  • Read the release's upgrade notes, and fix what breaks. Record every breakage in the PR body (what broke, the exact error, the upstream change, the fix), as the 17.7.0 upgrade did (chore(deps): upgrade @objectstack/* to 17.7.0 #2008).
  • pnpm verify is green. Browser-verify that the app boots and serves a record page, in place.
  • ⛔ The waiting cards' own fixes are NOT in this PR. The seat dispatches each one after this lands.

Duplicate check

gh search is refused in this container (GraphQL and REST search answer 403), so every hotcrm issue was listed into a local index (/issues?state=all, through today) and matched case-insensitively: upgrade 17.8 0; 17.7.0 → 17.8 1 (the seat post #1353 only); pin bump 37, none an open upgrade card. None is a duplicate.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round R82
    Session: session_01BCDqr1DqnQjEh5jA9gGkUG
    Account: os-justin (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-2031-objectstack-18-next-0
    Worktree: hotcrm-issue-2031
    Domain: repo:hotcrm (single-lane repo, no domain:* taxonomy)
    Seat: repo:hotcrm#1
    File surface: package.json (every @objectstack/* pin, together), pnpm-lock.yaml (regenerated by pnpm install, never hand-edited), objectstack.manifest.json (specVersion, engines.protocol); whatever the 18.0.0-next.0 breaking changes force in src/**, test/**, scripts/** (each breakage named in the PR body); the old-pin claims 17.7.0 re-scoped per AGENTS.md "Platform Upgrades" step 5 across src/**, test/**, docs/**, content/docs/**, README*; test/helpers/identity-objects.ts retired only if objectstack#22074 ships in the installed release; one .changeset/2031-*.md. ⛔ Not AGENTS.md, CLAUDE.md or .claude/** (governed; a stale claim there is reported, not edited). (stop on breach; explain in the report)
    Container & model: M (a major-line prerelease: judgment on each breaking change), mode:subagent, model: default (dispatch-gates --tier --repo objectstack-ai/hotcrm over package.json pnpm-lock.yaml objectstack.manifest.json: "no path-derived mandate: the surface hits none of the 3 declared glob(s)"; the tier stays the PM's per-card call)
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: none
    Serial constraints cleared: in flight in this lane: none (0 pm:dispatched before this card, 0 seat PRs). Open PRs touching the same files: dependabot #2063 (fumadocs-core) and #2064 (@playwright/test), both on package.json + pnpm-lock.yaml; whichever lands second regenerates the lockfile. Token ratchet headroom at the brief: src/revenue ~14, src/service ~89; a pin-claim re-wording inside a ceilinged package must not grow it. Queued cards on the seat post's hot-file queues (§5) start after this lands, on the new pin.

    Dispatch authority (maintainer direct order, ahead of the queue): the card's own Restart-when: line (npm view @objectstack/cli version prints a version above 17.7.0) does not hold: latest is still 17.7.0. 18.0.0-next.0 was published to the next dist-tag at 2026-10-13T08:28Z, and every one of the 24 @objectstack/* packages hotcrm pins resolves at that exact version. The maintainer ordered this upgrade in this session's chat after summoning the seat with /pm-dispatch hotcrm, verbatim: 「首先处理 objectstack 升级到 18.0.0-next.0」. The target therefore is 18.0.0-next.0 exactly, not "the newest release".


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 2031,
      "status": "blocked",
      "branch": "claude/issue-2031-objectstack-18-next-0",
      "pr": null,
      "session": "session_01BCDqr1DqnQjEh5jA9gGkUG — the PM seat's session (this dev ran as its subagent)",
      "premise_still_valid": true,
      "summary": "BLOCKED on the src/revenue token ceiling (one decision only the maintainer can make). 18.0.0-next.0 refuses the single-brace template dialect in every flow VALUE slot and TEXT slot (a87d8be..2b61f2d family: 0e9e7b7, 615c696, 111ffff, 12b9daf, f66fdc7, 9fdb127, 968acc8, d85615d, 6a06e3b). `os validate`, `os lint` and `pnpm dev` all refuse the stack on 340 sites in 32 flows (sales 213, revenue 71, service 33, marketing 23). The dev server exits with `Compile failed — fix errors above before starting dev server`. Upstream ships no D2 conversion for these sites (`no authored spelling maps losslessly`), so each site needs the CEL envelope, plus a decision about what happens when the value is absent. Measured on a scratch copy, with the most compact spelling the spec offers (the `cel` tagged template) and NO has() guards, src/revenue's authored total is ~19,040 against a ~19,000 ceiling (over by ~40, headroom today ~14). With guards on every optional dotted read, revenue is ~19,234 authored (over ~234) and ~16,094 business semantics (over ~94), and src/service is ~22,010 (over ~10). The dispatch rules out raising a ceiling, so I stopped there. Landed on the branch (be03a57, pushed, no PR): all 24 pins moved to 18.0.0-next.0 with the lockfile regenerated by pnpm install; engines.protocol and specVersion moved to ^18.0.0-next.0; the retired email_template `category` removed (ec7f7f8); test/hooks-runtime.test.ts follows hooks.run's operation-generic type (a6f3a13). Every upstream fix row on the card IS in 18.0.0-next.0 (table below), so the waiting cards' blocker becomes this ceiling decision, not availability. Further breakages measured for the resume: 96 i18n/missing-flow keys (screen select options and descriptions are now translatable, and translations are outside the ratchet), and 75 failing test files. Of those, 47+ fail because package-declared permission sets no longer get sys_permission_set rows (c8a9783, test/helpers/verify-stack.ts signUpPerson). Others fail on the ADR-0131 refusal of org-less system writes (SystemWriteOrganizationRequiredError), on flow refusal, on `Object ... not found` in reduced kernels, and on docs-declared-versions (pin claims not yet re-scoped).",
      "gates": [
        {"cmd": "pnpm validate (lock)", "head": "36a4669", "verdict": "os-verify-lock: VERDICT command-exit 1", "exit": 1, "reading": "defineStack validation failed (8 issues): emailTemplates.N.category retired"},
        {"cmd": "pnpm validate (lock)", "head": "be03a57 src tree (committed after the run; the later commit touched only test/hooks-runtime.test.ts)", "verdict": "os-verify-lock: VERDICT command-exit 1", "exit": 1, "reading": "340 expression-invalid (317 value-slot, 23 text-slot) in 32 flows"},
        {"cmd": "pnpm typecheck (lock)", "head": "be03a57 minus the hooks-runtime edit", "verdict": "os-verify-lock: VERDICT command-exit 1", "exit": 1, "reading": "test/hooks-runtime.test.ts(49,3): error TS2322"},
        {"cmd": "npx tsc --noEmit (NOT under the lock, deviation 1)", "head": "be03a57 tree", "verdict": "exit 0, no output", "exit": 0},
        {"cmd": "pnpm lint (lock)", "head": "be03a57", "verdict": "os-verify-lock: VERDICT command-exit 1", "exit": 1, "reading": "Errors (340) expression-invalid; ✗ 96 warning(s) fail this run under --strict"},
        {"cmd": "node scripts/check-lint-i18n-gate.mjs", "head": "be03a57", "verdict": "✗ i18n lint gate: 96 `i18n/missing-*` issue(s) found — must be zero.", "exit": 1},
        {"cmd": "node scripts/check-source-hygiene.mjs", "head": "be03a57", "verdict": "✓ source hygiene clean", "exit": 0},
        {"cmd": "node scripts/check-source-token-ratchet.mjs", "head": "be03a57", "verdict": "✓ source token ratchet clean (revenue authored ~18,986 / ~19,000, headroom ~14; service authored ~21,913 / ~22,000, headroom ~87)", "exit": 0},
        {"cmd": "pnpm build", "head": "be03a57", "verdict": "NOT MEASURED: build, reason: the same author-time rules refuse the stack (validate red); pnpm dev reports `Compile failed`", "exit": null},
        {"cmd": "pnpm test (lock)", "head": "be03a57", "verdict": "os-verify-lock: VERDICT command-exit 1 · held the lock 523s", "exit": 1, "reading": "Test Files 75 failed | 104 passed (179); Tests 111 failed | 2231 passed | 1349 skipped (3691); Errors 18"},
        {"cmd": "pnpm dev (fresh DB, PID 5999)", "head": "be03a57", "verdict": "✗ Compile failed — fix errors above before starting dev server; ELIFECYCLE exit 1 (process exited by itself, nothing left running)", "exit": 1},
        {"cmd": "browser verification (record page, dashboard)", "head": "be03a57", "verdict": "NOT MEASURED: browser, reason: the app does not boot on 18.0.0-next.0 until the flow migration lands", "exit": null},
        {"cmd": "pnpm test:e2e / docs build / changeset-check", "head": "be03a57", "verdict": "NOT MEASURED: e2e, docs, changeset, reason: no boot and no PR; declared to CI on resume", "exit": null}
      ],
      "tests": "See `gates` for every verdict line. Measurements behind the block: (1) Ratchet lower bound: a scratch copy of src/ + scripts/ (never the worktree) had every one of the 340 refused sites rewritten to the CLI's own suggested CEL spelling, wrapped in the spec's `cel` tagged template (`'{x.y}'` becomes cel`x.y`, +2 chars), with no has() guards. `node scripts/check-source-token-ratchet.mjs` on that copy: exit 1, `✗ src/revenue authored total is ~19,040 tokens; the ratchet ceiling is ~19,000 (over by ~40)`; service authored ~21,957 (headroom ~43); sales BS ~57,596; marketing BS ~8,027. (2) Guarded estimate: the same rewrite with `has(a.b) ? a.b : null` on every dotted read that is not `.id` gives exit 1: revenue authored ~19,234 (over ~234), revenue BS ~16,094 (over ~94), service authored ~22,010 (over ~10); sales BS ~58,248 (headroom ~752). (3) Completeness: that guarded rewrite was copied over the worktree's src under `trap 'git checkout HEAD -- REPO_ROOT/src' EXIT` and validated under the lock: `os-verify-lock: VERDICT command-exit 1`. 6 errors remained, all residue of the measurement codemod (4 from `cel` JSON-quoting an interpolated `${key}` and 2 filter operands in the shared _billing-endpoint.ts that it did not reach). No further rule family hides behind the 340. Restore proven: `git diff HEAD` empty, `git status --porcelain` 0 lines, blob hash 2c26093d equal to HEAD's for src/revenue/flows/contract-renewal.flow.ts. The first attempt was a no-op (`rsync: command not found`, still 340 errors), so that reading was discarded and the copy redone with cp. (4) Handshake: a probe of the installed @objectstack/metadata-core checkProtocolCompat gives `^17.7.0 incompatible 18`, `^18.0.0-next.0 ok 18`, `^18 ok 18`, `^18.0.0 ok 18`. rangeAdmitsMajor compares only the leading major (`^` means runtimeMajor === maj), and PROTOCOL_VERSION = \"18.0.0\" in the installed spec. hotcrm's test/docs-declared-versions.test.ts requires bare(specVersion) == the installed @objectstack/spec version and engines.protocol == specVersion, so the spelling is ^18.0.0-next.0, not the ^18 that `os migrate meta --write` would write. (5) Lockfile, by pnpm install: packages-section keys 790 to 791 (pnpm reported `resolved 705`); 54 @objectstack keys moved 1:1, plus 1 new transitive @objectstack/service-mailbox@18.0.0-next.0 (pulled in by cli and verify); no third-party key added, removed or moved. The install's peer warning `better-auth 1.7.3 unmet peer better-sqlite3@^12.0.0: found 13.0.3` predates this change (same pair in the 0f84c9c lockfile).",
      "upstream_rows": [
        "upstream | in 18.0.0-next.0? (evidence) | hotcrm card",
        "objectstack#22310 (PR #22404) | yes: ca135dc in runtime CHANGELOG 18.0.0-next.0; REST compare ca135dcc...d889448b (release commit of every @objectstack/*@18.0.0-next.0 tag) = ahead 413 behind 0 | #2016",
        "objectstack#22407 (PR #22424) | yes: c572fe2 in runtime CHANGELOG; compare ahead 405 behind 0 | #2016 (both doors present, so #2016's two-fix condition holds)",
        "objectstack#22178 (PR #22213) | yes: 0e9371f in service-analytics CHANGELOG; ahead 520/0 | #2000",
        "objectstack#22212 (PR #22281 + #23146) | yes: d1dbe70 in lint, 02bec6c in spec CHANGELOG; ahead 487/0 and 20/0 | #1583",
        "objectstack#22238 (PR #22285) | yes: 6d2da32 in cli CHANGELOG; ahead 482/0 | #1585",
        "objectstack#22074 (c6fe02d, createIdentityObjectsPlugin preset) | yes: c6fe02d in plugin-auth + plugin-security CHANGELOG, and createIdentityObjectsPlugin is exported by the installed plugin-auth dist; ahead 535/0 | test/helpers/identity-objects.ts retirement NOT done here (blocked before it); safe to do on resume",
        "objectstack#22149 (PR #22294) | yes: 9ad3d24 in spec CHANGELOG; ahead 473/0 | —",
        "objectstack#22189 (PR #22285) | yes: 6d2da32 in cli CHANGELOG; ahead 482/0 | —",
        "objectstack#22067 (e67ba80, c8d06a9) | yes: plugin-security / objectql CHANGELOG; ahead 578/0, 555/0 | —",
        "objectstack#22071 (bafb58b, 4935c66) | yes: cli / plugin-auth CHANGELOG; ahead 574/0, 567/0 | —",
        "objectstack#22072 (PR #22108 + #22115) | yes: a959493, cdeabec in cli/spec CHANGELOG; ahead 563/0, 558/0 | —",
        "objectstack#22073 (4935c66) | yes: cli CHANGELOG; ahead 567/0 | —",
        "objectstack#22079 (dd39171, d7c5c33) | yes: cli / spec CHANGELOG; ahead 566/0, 541/0 | —",
        "objectstack#22824 (PR #22850) | yes: 69d4218 in plugin-approvals/lint/spec CHANGELOG; ahead 168/0 | per seat post",
        "objectstack#22455 (PR #22513 + #22492/#22523/#22535) | yes: ce3d0ad in service-storage/plugin-security/plugin-audit CHANGELOG; ahead 360/0 | per seat post",
        "objectstack#22437 (PR #22462) | yes: 7806a14 in rest CHANGELOG; ahead 383/0 | per seat post",
        "objectstack#22607 (PR #22625) | yes: e8c6666 in plugin-approvals CHANGELOG; ahead 309/0 | per seat post",
        "Note: the CHANGELOGs cite commit hashes, not these issue numbers (`#22310` greps 0 hits in every installed CHANGELOG); every row was matched by its fix commit's short hash."
      ],
      "breakages": [
        "1 FIXED · os validate: `✗ emailTemplates.0.category: email_template.category was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove)` x8 (68 more in the second package). Upstream ec7f7f8 (#22876, conversion email-template-category-is-system-removed). Fix: src/sales/email-templates/_bundle.ts writes no `category`.",
        "2 FIXED · protocol handshake: `manifest.engines.protocol '^17.7.0' does not admit protocol 18, so the load refuses this stack` (os migrate meta). Upstream 4e9fe9f (PROTOCOL_VERSION 18.0.0). Fix: ^18.0.0-next.0 in src/sales/index.ts:93, src/service/index.ts:138 and objectstack.manifest.json (specVersion + engines.protocol).",
        "3 FIXED · typecheck: `test/hooks-runtime.test.ts(49,3): error TS2322: Type 'Promise number|boolean|EngineRow' is not assignable to type 'Promise Rec'`. Upstream a6f3a13 (verify hooks.run generic over the operation). Fix: repWrites is generic over Op.",
        "4 OPEN (the blocker) · os validate / os lint / pnpm dev: 340 `expression-invalid`, e.g. `A value slot no longer reads the {…} template dialect … Write {record.id} as { dialect: 'cel', source: 'record.id' }` and `A flow text slot reads double-brace template holes (ADR-0032 §3), not the single-brace {…} dialect`. Upstream 0e9e7b7 + 615c696 + 111ffff + 12b9daf + f66fdc7 + 9fdb127 + 968acc8 + d85615d + 6a06e3b + 2b61f2d. No D2 conversion exists. Upstream measured hotcrm itself at c529de2 (91 create/update/assignment sites). Per-package site counts: sales 213, revenue 71, service 33, marketing 23. The shared src/sales/flows/_billing-endpoint.ts carries the billing payload sites both handoff flows use. Filter operands that may be absent need a `decision` route rather than a has() guard (the refusal says so).",
        "5 OPEN · lint:i18n-gate: 96 i18n/missing-flow (32 keys x zh-CN/es-ES/ja-JP: screen select options, screen and refusal descriptions in campaign_enrollment, lead_conversion, schedule_followup, quote_generation, claim_case). #2008 recorded these as untranslatable on 17.7.0 (FLOW_SCREEN_FIELD_NO_OPTIONS); 18.0.0-next.0 makes them keys. Translations are outside the ratchet.",
        "6 OPEN · tests, 47 files plus 6 mixed: `Error: no permission set named \"sales_rep\" is registered on this stack` at test/helpers/verify-stack.ts:145. Upstream c8a9783 (`no seeder or materializer writes a sys_permission_set row`); the grant is now written by name (`permission_set`). Fix site: signUpPerson.",
        "7 OPEN · tests, 3 files plus others: `SystemWriteOrganizationRequiredError: Insert on 'crm_account' was REFUSED: a system-context write on a tenant-scoped object must carry an organization … this install declares the 'single' tenancy posture but holds NO organization` (ADR-0131). The message names the cause `a composition that never booted the auth plugin`. Not yet attributed: harness or platform. To be measured on resume before any classification.",
        "8 OPEN · tests: `Object 'crm_quote' / 'crm_opportunity' not found` (4-6 files with reduced kernels), `already has a live bootStack kernel` (cascade from failed teardowns), MemoryMultiTenantUnsupportedError (unassigned-case-triage-reach), docs-declared-versions (pin claims not re-scoped yet), lint-i18n-gate test (= item 5). Not attributed yet."
      ],
      "files_changed": [
        "package.json (24 pins 17.7.0 to 18.0.0-next.0)",
        "pnpm-lock.yaml (pnpm install)",
        "objectstack.manifest.json (specVersion, engines.protocol)",
        "src/sales/index.ts (engines.protocol)",
        "src/service/index.ts (engines.protocol)",
        "src/sales/email-templates/_bundle.ts (retired category removed; two comment lines)",
        "test/hooks-runtime.test.ts (repWrites generic)"
      ],
      "deviations": [
        "1 · Three runs went outside the shared verify lock: `npx tsc --noEmit` (about 12s), `npx objectstack migrate meta --from 17`, and the first `npx objectstack validate --json`. Every other validate, typecheck, lint and test run went through os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=hotcrm-2031.",
        "2 · No PR was opened. The dispatch says to report blocked with the numbers when a required change cannot fit a ceiling, and to report blocked rather than land a red PR when the boot is blocked. The work is pushed: Resume-from: claude/issue-2031-objectstack-18-next-0@be03a57.",
        "3 · Commit trailers use this repo's model-free pair (`Claude-Session:` + `Co-authored-by: Claude`), not the harness reminder's model-named Co-Authored-By line, as the dev definition requires.",
        "4 · The handshake spelling is ^18.0.0-next.0, not the ^18 that `os migrate meta --write` prescribes. Both are admitted (probe above). This repo's own test/docs-declared-versions.test.ts pins specVersion to the installed spec version, and engines.protocol to specVersion.",
        "5 · Conflict noted, not resolved silently: AGENTS.md Platform Upgrades step 1 says to read the curated release notes and not to work from changelogs. The v18 page says curated notes are not written yet and the changesets are the record. The installed CHANGELOGs were used, as the dispatch directed. Governed text, not edited.",
        "6 · `os migrate meta --from 17` still lists 15 decision nodes for mode 'inclusive' (flow-decision-mode-inclusive-explicit). That is a 17.5.0 change (0283cb9) the earlier upgrades reviewed and left unwritten, not an 18.0.0-next.0 breakage, so none were written here.",
        "7 · Writes: git push x3 (empty branch, 36a4669, be03a57); 0 pr_create; 1 os-dev-report comment. 0 label writes."
      ],
      "mcp_calls": "0",
      "api_writes": "1 — POST /repos/objectstack-ai/hotcrm/issues/2031/comments (this os-dev-report, via scripts/pm/post-stamped.mjs and the fleet-write relay). Reads only otherwise (gh api GET on issues, pulls, timeline, compare, commits, contents).",
      "open_questions": [
        {
          "question": "The 18.0.0-next.0 flow migration (340 sites; no lossless conversion upstream) cannot fit src/revenue's token ceiling. Even the most compact unguarded spelling is over by ~40 tokens on authored total (19,000). A realistic guarded one is ~+250 tokens (authored ~19,234, business semantics ~16,094 against 16,000), and src/service goes ~10 over 22,000. How should it be paid?",
          "options": [
            "A · A maintainer ruling re-anchors THIS ceiling for src/revenue (authored and business semantics), and for src/service authored if the final count needs it, at the number the finished migration measures, quoted in the upgrade PR as the ratchet's own message prescribes. Real need: business need is real (the waiting cards #2016/#2000/#1583/#1585 need 18.0.0-next.0, and every row is in it); the growth is forced by a platform contract, not by new capability. Long term: the CEL envelope is the single dialect going forward, so this is not a workaround. AI-safety: the envelope plus explicit absence guards is the stricter, loudly-refused form. Startup scope: the README headline is about src/sales, which stays inside its own ceilings (guarded estimate BS ~58,248 of 59,000), so the headline claim does not move. Effort: one large dev card (migration + translations + harness + docs).",
            "B · No ceiling moves. Before the upgrade, a separate card compresses src/revenue (and src/service) by at least the measured growth (dedupe shared flow payloads, hoist repeated subject text), then the upgrade lands. Real need: same. Long term: shrink-only is honoured, but the cut (~1.5% of revenue's business semantics) is unscoped and may be hard to find without deleting behaviour. AI-safety: neutral. Startup scope: adds a refactor card in front of the upgrade. Effort: unknown; feasibility not measured.",
            "C · Stay on 17.7.0 until objectstack offers a terser null-tolerant read for value slots, or until v18 GA, and ask upstream for it (AGENTS.md §4: a per-site tax is fixed at the default). Real need: the waiting cards stay blocked although their fixes are released. Long term: depends on an upstream decision that is not filed. AI-safety: neutral. Startup scope: lowest work now. Effort: a filing, plus waiting."
          ],
          "recommendation": "A, because the growth is a platform-forced contract migration, not new capability. The ratchet itself names a ruling-quoted re-anchor as the route. The headline package (src/sales) stays inside its ceilings. B has unmeasured feasibility, and C keeps four released fixes out of reach. Second question for the seat: the remaining work is large (340 flow sites, each needing an absence decision, plus 96 translations, a 75-file test-harness migration and the pin-claim sweep). The seat may want to dispatch it under one claim but with an M-or-larger tier and the ADR-0131 harness item measured first."
        }
      ],
      "out_of_scope_findings": [
        "carrier: whoever lands the upgrade · noted, not filed: at be03a57 the ratchet prints `src/service interaction layer … headroom is 1,384 tokens, over twice the 5% buffer — re-anchor this ceiling to ~6,000`. It is an advisory to lower a ceiling, and nothing here touched it.",
        "carrier: maintainer (governed file) · noted, not filed: AGENTS.md Platform Upgrades step 1 (read curated release notes, not changelogs) has no reading for a prerelease line whose curated notes do not exist yet. The v18 page says the changesets are the record."
      ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: session session_01BCDqr1DqnQjEh5jA9gGkUG · reason: the dev stopped on a token ceiling that only a maintainer ruling can move · destination: needs-user-decision (this card is the anchor)
    Resume-from: claude/issue-2031-objectstack-18-next-0@be03a574f862dbc0c2421c485cf1813891eb6ffa

    Verdict on the os-dev report 6142372109 — ESCALATE (decision), pr: null. repo:hotcrm seat, 2026-10-13T09:23Z.

    Checked against GitHub and the trees, not the report:

    • The branch head is be03a57, two commits on 0f84c9c (36a4669 pins + lockfile, be03a57 the changes that need no flow rewrite); 7 files.
    • The blocker is a deliberate upstream break, not a platform defect. objectstack packages/spec/src/migrations/entries/semantic/18.flow-value-slot-template-dialect-refused.ts, verbatim: "Semantic-only — every token spelling authored in flows was measured lossy under conversion, so no D2 conversion rewrites any of them." ADR-0087's launch-window addendum allows that before GA ("one D3 semantic entry per retirement family in every case"). The breaking commits are the #19939 series (2b61f2d, 0e9e7b7, 6a06e3b, d85615d, f66fdc7, 12b9daf, 9fdb127, 111ffff, 968acc8, 615c696), 2026-10-08 → 2026-10-13. So nothing is filed upstream, and hotcrm rewrites its own flows.
    • The raising rule, from scripts/check-source-token-ratchet.mjs on main, verbatim: "RAISING one requires a maintainer ruling quoted in the raising PR's body." Precedent: [decision] REQ-0006 needs +986 business-semantics and +1,395 authored-total tokens in src/sales — cutting scope does NOT avoid the question (measured), and a third route now exists #1951 → PR chore(ratchet): raise the two src/sales token ceilings to their anchor() (59,000 / 107,000) #1953 (src/sales, raised to anchor()).
    • Re-measured: CEL optional selection (x.?y.orValue(null)) is supported (packages/formula/src/validate.test.ts) but is no shorter than the has() guard, so it does not change the ceiling arithmetic.
    • Not re-measured by the seat: the 340 sites, and the ~+40 lower bound / ~+250 guarded estimate for src/revenue. Those are the dev's readings, on a scratch copy and under the verify lock.

    The rest of the dev's breakage list (96 i18n/missing-flow, 75 failing test files) needs no ruling. It rides the resumed dispatch. One condition: the ADR-0131 refusal of org-less system writes (its item 7) must be attributed to harness or platform before anything is classified; a platform defect means waiting, per AGENTS.md §2.

    待裁:升级到 18.0.0-next.0 之后,src/revenue 的 token 上限怎么付?

    一句话问题:18.0.0-next.0 不再接受流程里旧的 {…} 模板写法。HotCRM 32 个流程里的 340 处都要改写成新的 CEL 表达式,否则应用启动不了。改写后的文字比原来长,报价 / 合同所在的 src/revenue 包会超出它的 token 上限。dev 实测:不加空值保护就超 ~40;按常规加保护约超 ~250,src/service 也超 ~10。上限只能由你裁决抬高。

    Governing text:

    选项 做什么 客户 / 维护者看到什么 工作量(实测)
    A 迁移后按 anchor() 重锚 授权本升级 PR 在迁移完成后实测,把被这次迁移推过上限的那几行按 anchor() 抬高。PR 正文列 was / now / anchor-of 表并引本裁决原话 应用升到 v18,平台修复全部到手,7 张阻塞卡可以重新推导。「整个 CRM 装得进一个上下文」这个数字如实变大(revenue 预计 19,000 → ~21,000) hotcrm · 1 个大 PR(先例 PR #2008 是 17.7.0 升级,+1056 / −537、30 个文件,本次明显更大)· 抬上限这一部分有先例 PR #1953(+107 / −19)
    B 上限不动,先压缩 先单开一张卡把 src/revenue 压出 ~250、src/service 压出 ~10 token(行为不变),再续升级 同 A,但晚一个 PR。#2077 / #2083 本来就在等同一块余量,三方抢同一笔预算 2 个 PR · 压缩卡能否压出 ~250 未测(约为 revenue 业务语义的 1.5%)· 先例 PR #2085 只压了 src/service 的 +17 / −9
    C 暂不升级 留在 17.7.0,等 v18 正式版或上游给出更省的写法 4 个平台修复(#2016 / #2000 / #1583 / #1585 所等)继续拿不到,7 张阻塞卡继续阻塞。与你的指令相反 0;分支 be03a57 保留,以后从它续做

    业务含义直译:

    • A = 「平台换了记账格式,账本页数如实变多,改一次封面上的页数」。
    • B = 「先删别的内容腾地方,页数不变」。
    • C = 「先不换格式」。

    四轴(业务立场):

    推荐:A;回退:B。 C 只在你不想现在吃预发布版的反复破坏时才对。

    裁后执行:

    • 选 A:本卡回 pm:queue。席位从 be03a57 续认领(Resume-from),按大卡派发。范围:改写 340 处流程、补 96 个 i18n/missing-flow、修 75 个失败测试文件(ADR-0131 那一类先判平台还是测试工装,是平台缺陷就立上游卡并等待)、按 anchor() 重锚并在 PR 正文引本裁决、重述旧版本号说法、退役 test/helpers/identity-objects.ts、浏览器验证。合并后对 7 张阻塞卡逐一重新推导。
    • 选 B:先立 src/revenue / src/service 压缩卡,本卡挂 pm:blocked + Blocked-by: 指向它;压缩落地后照 A 的范围续做,但不动上限。
    • 选 C:本卡回 pm:on-hold,Restart-when: 改为 v18 进入 latest;分支保留。

    os-decision-facets
    ① 项目长远合理性:A 按 ratchet 自己的规则一次记明平台强制的语法成本;C 推迟一笔必付的账;B 把平台成本转嫁给业务内容。
    ② 实际业务拉动:4 个已核实在 18.0.0-next.0 里的平台修复与 7 张阻塞卡在等;C 让它们继续够不着。
    ③ 防 AI 犯错:新写法保存时响亮拒绝,旧写法缺值时静默写空;B 不得靠删空值保护凑 token。
    ④ 创业阶段不扩散:A、B 都不新增能力或门禁;只是一次平台强制的迁移与一次按规则的重锚。
    Prior rulings read: ceiling, ratchet, template, dialect → 32 hits (objectstack ADR-0032 / 0054 / 0056 / 0057, objectstack-internal ratchets, none on this repo's token ceiling); hotcrm #1951 ruling 5696428192 (「同意」, src/sales → anchor()); ratchet header rulings 2026-08-17 / 09-14 / 09-16; thread: this card's dev report 6142372109.


    Generated by Claude Code

  4. added
    needs-user-decisionNeeds the maintainer's call before work proceeds
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Oct 13, 2026
  5. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: raise every HotCRM token ceiling by 50% · the maintainer's words, verbatim, in the repo:hotcrm seat's session chat (session_01BCDqr1DqnQjEh5jA9gGkUG), after the seat's R82 report on this card's decision: 「hotcrm token 上限提升 50%」, then 「暂时只优先处理升级相关的任务」

    Recorded by the repo:hotcrm seat, 2026-10-13T10:02Z. Freshness gate: the newest comment before this record is the analysis 6142448037, and the body was last edited before it; there is nothing newer to reconcile. needs-user-decision → pm:dispatched in the claim that follows this record.

    What the ruling decides: how the 18.0.0-next.0 flow migration's token growth is paid. Every ceiling moves up by half, so none of the analysis's letters is picked as written. It is closest to A (the ceilings move, quoted in the raising PR's body, as scripts/check-source-token-ratchet.mjs requires), but it is not anchored to a post-migration reading.

    The seat's reading of the numbers (stated to the maintainer in the same chat; a veto there replaces it): all 12 rows of CEILINGS × 1.5, exact, no rounding to 1k.

    package business semantics interaction layer authored total
    src/sales 59,000 → 88,500 31,000 → 46,500 107,000 → 160,500
    src/service 14,000 → 21,000 7,000 → 10,500 22,000 → 33,000
    src/revenue 16,000 → 24,000 3,000 → 4,500 19,000 → 28,500
    src/marketing 9,000 → 13,500 1,000 → 1,500 10,000 → 15,000

    Execution: the raise is this card's own first commit, in the upgrade PR, with the ruling quoted verbatim in the PR body (the ratchet's rule; precedent PR #1953). The upgrade resumes from claude/issue-2031-objectstack-18-next-0@be03a57. Per the second sentence, the seat dispatches only upgrade work for now: #2069 and #2070 (already in flight) finish, and no other card is dispatched.

    Side effect, stated: once this lands, #2077 and #2083 no longer wait on a src/revenue shrink.


    Generated by Claude Code

  6. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    needs-user-decisionNeeds the maintainer's call before work proceeds
    on Oct 13, 2026
  7. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round R82
    Session: session_01BCDqr1DqnQjEh5jA9gGkUG
    Account: os-justin (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-2031-objectstack-18-next-0
    Worktree: hotcrm-issue-2031
    Domain: repo:hotcrm (single-lane repo, no domain:* taxonomy)
    Seat: repo:hotcrm#1
    File surface: scripts/check-source-token-ratchet.mjs (the 12 CEILINGS rows × 1.5 and its header ledger, first commit, per the ruling); the pins (package.json, pnpm-lock.yaml regenerated by pnpm install, objectstack.manifest.json, the two engines.protocol lines; already on the branch); all 32 src/*/flows/*.flow.ts (the {…} → CEL migration); the four locale packs under src/sales/translations/** (the 96 i18n/missing-flow keys); test/** (the 75 failing files: harness changes for 18.0.0-next.0, test/helpers/identity-objects.ts retired); src/** beyond flows only where an 18.0.0-next.0 breaking change forces it (each one named in the PR); the old-pin claims across src/**, test/**, docs/**, content/docs/**, README*; one .changeset/2031-*.md. ⛔ Not AGENTS.md, CLAUDE.md or .claude/**. (stop on breach; explain in the report)
    Container & model: L (340 flow sites, 96 keys, 75 test files: judgment at each site), mode:subagent by the seat's judgment, a deviation from the L→mode:cloud default. The relay write tools, the verify lock and the first leg's measurements live in this container, and the first leg ran here in ~28 min. model: default (dispatch-gates --tier --repo objectstack-ai/hotcrm hits no declared tier glob; the tier stays the PM's per-card call)
    Clause-②: no
    Responsibility: n/a — not a defect card
    Ruling-ref: 6143114246 (the maintainer's 「hotcrm token 上限提升 50%」 and 「暂时只优先处理升级相关的任务」; fetched in this act)
    Thread-read: 6143114246
    Resume-from: claude/issue-2031-objectstack-18-next-0@be03a574f862dbc0c2421c485cf1813891eb6ffa
    Serial constraints cleared:


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    待裁(#2031 子项):18.0.0-next.0 的内存驱动拒绝「按组织」的调用,约 9 组测试里刻意保留的「缺键」用例怎么办?

    repo:hotcrm seat, 2026-10-13T11:46Z. The card stays pm:dispatched: the dev keeps working on everything else, and only this item waits. Source: the dev's status reply in this session (head dac942b4).

    一句话问题:

    • 约束: 18.0.0-next.0 起,内存驱动(driver-memory)在 ADR-0131 第 C8 阶段之前拒绝一切按组织划分的读写(上游 34dba5a,即 C1 阶段)。上游的迁移指引是把这类测试改到 SQL 驱动上跑。
    • 冲突: HotCRM 约 9 组测试里有一些用例是刻意用内存驱动的。它们要测的正是「行里没有这个键」(不是「值为空」)这种数据形状,这是 Script validations are silently SKIPPED when the merged record lacks the field key (update path) #630 规则存在的原因:校验谓词必须写 has() 守卫。SQL 驱动返回的是空值而不是缺键,把用例搬过去,它们就不再测这种形状了。
    • 约束: 跳过测试是禁止的。

    Governing text:

    选项 做什么 看到什么 工作量
    A 按上游指引改到 SQL,并立回迁卡 这些用例改在 SQL 上跑;另立一张 HotCRM 卡,pm:blocked + Blocked-by: 上游 C8,C8 可安装后把缺键用例搬回内存驱动 升级照常推进;C8 之前,运行时的「缺键」演示暂缺,静态 has() 守卫照常生效 本 PR 内完成 + 1 张回迁卡
    B 加一个统一开关,暂停这些用例直到 C8 用例代码原样保留,但不运行 升级推进,但等于跳过测试,违反「永不跳过」 小
    C 整个升级等 C8 不合 PR 升级停摆,而 C2–C7 还没落地,预计以周计 0,但最慢

    业务含义直译:

    • A = 「先按平台的新规矩换个场地考试,平台把老场地修好再搬回来」。
    • B = 「这几门先不考」。
    • C = 「平台修好之前不升级」。

    四轴(业务立场):

    • 项目长远合理性(权重最高): A 跟随上游自己写明的迁移路径,并用一张卡把回迁这件事钉住,是契约优先、有记录的过渡。B 本质上是静默跳过测试,与舰队规则冲突。C 把整条 v18 线挂在一个排在最后的阶段上。
    • 实际业务需求: 你已明确「首先处理升级」「暂时只优先处理升级相关的任务」。生产部署跑的是 SQL,缺键形状主要出现在内存驱动上,所以 A 的暂时缺口对线上影响最小。
    • 防 AI 写错: 让 AI 写错元数据的那道防线是静态的 has() 守卫测试,A 下它完整保留。B 让用例不再运行,但看上去测试还在,最容易被误读。
    • 创业阶段不扩散: 三者都不加新能力;A 多一张回迁卡。

    推荐:A;回退:C。 B 违反「永不跳过」,席位不荐,只有你点名才可选。

    • 置信缺口:9 组测试里每个用例具体测的是什么,由 dev 在最终报告里逐条列出。若某条只能在内存驱动上成立,它会被单列。
    • 自检:只看①选 A;②③④ 是否翻转:否。

    裁后执行:

    • 选 A:dev 在本 PR 里把这些用例改到 SQL,PR 正文逐条列出;席位立回迁卡,Blocked-by: 上游 C8 的载体卡。
    • 选 C:本卡挂 pm:blocked,Blocked-by: 上游 C8 载体卡;分支保留。

    os-decision-facets
    ① 项目长远合理性:A 跟随上游迁移指引并用回迁卡钉住过渡;B 静默跳过;C 把升级挂在最后一个阶段上。
    ② 实际业务拉动:你要求升级优先;生产走 SQL,缺键形状主要在内存驱动上,A 的暂时缺口线上影响最小。
    ③ 防 AI 犯错:静态 has() 守卫在 A 下完整保留;B 制造「测试还在、实际不跑」的假象。
    ④ 创业阶段不扩散:三者都不加能力;A 多一张回迁卡。
    Prior rulings read: skip / quarantine (the fleet's never-skip rule); ADR-0131 §8 (C1 34dba5a → C8 order); thread: this card's dev status reply.


    Generated by Claude Code

  9. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling (#2031 sub-item, the driver-memory legs) · the maintainer's word, verbatim, answering the seat's question in this session's chat (session_01BCDqr1DqnQjEh5jA9gGkUG): 「就应该在 sql 上测试,作废内存驱动的测试」

    Recorded by the repo:hotcrm seat, 2026-10-13T11:48Z. It answers the analysis 6144835860. The card stays pm:dispatched; the in-flight dev applies it.

    What the ruling binds (the seat's reading, stated to the maintainer in the same chat):

    • The suites that ran legs on driver-memory run on SQL. That is close to letter A, but without A's restore card: the memory-driver legs are retired, not parked until ADR-0131 C8. No card is filed to move them back.
    • A leg whose only purpose was the absent-key shape that only driver-memory produces is deleted by this ruling. Each one is named in the PR body (suite, leg, what it asserted). That is a retirement on a quoted ruling, ⛔ not a skip, and no sentinel or disabled leg is left behind.
    • The driver-independent has() guard (test/object-validation-predicates.test.ts's static rule, Script validations are silently SKIPPED when the merged record lacks the field key (update path) #630) is untouched.
    • A sentence elsewhere that names the memory-driver measurement as current is re-scoped, unless it is in a governed file (AGENTS.md / CLAUDE.md / .claude/**), which is reported instead.

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 2031,
    "status": "done",
    "branch": "claude/issue-2031-objectstack-18-next-0",
    "pr": "#2091",
    "session": "session_01BCDqr1DqnQjEh5jA9gGkUG",
    "premise_still_valid": true,
    "summary": "Draft PR #2091 moves HotCRM to @objectstack/* 18.0.0-next.0. All local verify links are green at head 1407ca7 except one test flake, which passed when re-run alone; CI was still in progress at report time. What changed: (1) 24 pins move 17.7.0 -> 18.0.0-next.0 exact, with protocol ^18.0.0-next.0. (2) All 32 flows and the billing payload are rewritten to CEL value envelopes and double-brace text holes; os validate went from 340 errors to passing. (3) 32 new flow i18n keys are translated in 3 locales. (4) manage_org_presentation is removed from tenant_admin. (5) The test harness follows 18: Default Organization at boot, permission sets granted by name, a variant boot builds its configuration again, plugin-auth's identity preset replaces identity-objects.ts (retired), and runScheduledFlow (seat-approved) starts sweeps the way the schedule tick does. (6) The 12 token ceilings are raised x1.5 as RULED, per the seat's answer. (7) The memory-driver legs are moved to SQL or retired, per the maintainer's ruling (comment 6144864473). (8) Pin claims are re-scoped and a changeset is added. Browser pass: the app boots, an account record page renders, Convert Lead converts a lead, and the executive dashboard draws.",
    "tests": "Every link ran under os-verify-lock at HEAD 1407ca7 on a clean tree. validate exit 0 'Validation passed' (18 Objects 357 Fields). typecheck exit 0. lint exit 0, '18 suggestion(s)'. lint:i18n-gate exit 0, '0 i18n/missing-* issues'. hygiene exit 0, 'source hygiene clean'. hygiene:tokens exit 0, 'source token ratchet clean'. build exit 0, 'Build complete' with 8 author-time warnings (7 approval admin_rescue routing notes, 1 hierarchy-security enterprise note). pnpm test (detached, tail --pid): VERDICT command-exit 1, held 749s, 'Test Files 1 failed | 178 passed (179)', 'Tests 1 failed | 3658 passed | 1 skipped'. The failure was script-bodies 'send_email writes the email and its timeline pointer' (handed-over status 'failed' instead of 'queued', under shared-box load). Re-run alone at 1407ca7: exit 0, 'Tests 57 passed (57)'; reported as a flake and not changed. Seat note: test/case-sla-breach-on-close.test.ts re-run alone at 1407ca7 gives exit 0, 'Tests 21 passed (21)'. The touched-file batch (15 files) after the RULED and (b) edits gave exit 0, 'Tests 382 passed (382)'. The ratchet x1.5-as-RULED probe that previously failed 6 self-test cases now passes, because those 6 cases were adapted as the seat directed. CI on PR #2091 was in progress at report time (Typecheck and Build, Quality Checks, Check Changeset, Build and Test 22.x, Playwright, link-check); Label Pull Request and Vercel had succeeded. Browser (Chromium /opt/pw-browsers/chromium, demo:reset + dev on 4001): 'STEP 3 executive_dashboard chart marks {svgs:4, paths:19}', 'STEP 4 account record Acme Corporation name visible: true', 'STEP 5 lead after convert {is_converted:true, status:converted, converted_account set, converted_contact set}', page errors none. The dev server's PIDs were stopped and port 4001 is closed. No ablation was run: no new gate was introduced.",
    "mcp_calls": "0",
    "api_writes": "2 relay or REST writes plus 3 branch pushes in this leg. (1) fleet-write dispatch fw-20261013T122201Z-332b55: POST /repos/objectstack-ai/objectstack/dispatches, executed as POST /repos/objectstack-ai/hotcrm/pulls (draft) and POST /repos//issues/2091/assignees. Read-back: 20126 bytes sent, 20126 stored, identical; assignee os-justin. (2) This os-dev-report comment, POST /repos//issues/2031/comments via post-stamped.mjs. git push of the branch: 248b865..dac942b, dac942b..29dd01c, 29dd01c..1407ca7. No label writes.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: named producer: this app's scheduled-flow suites (test/flow-scheduled.test.ts and 9 others) drive @objectstack/verify flows.run. verify.flows.run('case_sla_monitor', {}, { as: admin }) answers 403 PERMISSION_DENIED 'This caller may not start this flow. A flow that runs on its own trigger starts there, or as a sub-flow from a parent flow's subflow node.' on 18.0.0-next.0 · evidence: runtime dist flow-start-admission refusesElevatedSelfTriggeredStart admits only executionContext.isSystem === true (ca135dc / objectstack#22310, c572fe2 / objectstack#22407). The verify dist flows.run(name, params, opts: AsUser) dispatches POST /automation/:name/trigger with the bearer only and has no AsSystem arm, while hooks.run takes { system: true } (b4ce5e2). An app therefore has no kit door to start its scheduled flows; hotcrm carries the thin runScheduledFlow helper (test/helpers/verify-stack.ts) until the kit ships one · dedupe words: verify flows.run system principal; flows.run AsSystem; scheduled flow test kit trigger door 403",
    "class: a · reach: named producer: every 17.x install upgraded to 18 (its sys_user_position rows carry no organization_id), and any system or seed write of sys_user_position, which stores no organization (measured: a system seed stores null, while an admin's POST /api/v1/data/sys_user_position stores the session organization) · evidence: two implementations disagree on organization-less position holders. @objectstack/plugin-security@18.0.0-next.0 dist holdingTakesEffectIn(row, org) is !org || org === organizationId: an org-less holding takes effect in every organization. It is used by activeHoldings and assignmentAnchorsOfPosition, whose doc calls organization_id = :org OR organization_id IS NULL 'the governed spelling of exactly this rule'. @objectstack/plugin-approvals@18.0.0-next.0 dist ApprovalService.expandPositionUsers(positionName, organizationId) sets filter.organization_id = organizationId (strict equality); it is called from the position-approver expansion with directoryOrg. Minimal repro: bootStack the app (SQL, single); sign up user U; system-seed sys_user_position { user_id: U, position: 'sales_manager' } with no organization_id; a rep creates an account so account_approval opens in the Default Organization. The slate omits U (opens on administrators), and U's approve answers 403 'not a pending approver', while plugin-security treats U as holding sales_manager in that organization. The 403 was measured earlier in this run, on the pre-merge leg · dedupe words: expandPositionUsers organization-less holder; org-less position approval slate; holdingTakesEffectIn approvals",
    "carrier: seat · noted, not filed: test/undeclared-key-probe.test.ts (its memory leg) and test/decorative-field-sweep.test.ts still boot bare kernels on driver-memory. They pass (no organization exists in those kernels), so they fall outside the seat's mechanical scope of 'now refused'. The maintainer's words 「作废内存驱动的测试」 could reach them; the seat decides"
    ],
    "rulings_applied": {
    "token_ceilings": "12 rows x1.5 exact, kind RULED, header record quotes 「hotcrm token 上限提升 50%」 / 「暂时只优先处理升级相关的任务」 (comment 6143114246). Anchored rows and declined rows kept as history marked 'superseded (#2031)'. No gate logic changed. Test lines changed: listed in the PR body under 'Ratchet self-test lines changed, and why'.",
    "memory_driver": "「就应该在 sql 上测试,作废内存驱动的测试」 (comment 6144864473). Refusal on every affected leg: 'MemoryMultiTenantUnsupportedError: [driver-memory] Refusing to answer: this driver has NO row-level tenant isolation. Detected: create() on crm_account (crm_case, crm_forecast) was handed a tenant scope by the engine: tenantId = org_…'. RETIRED: unassigned-case-triage-reach 'driver-memory (sparse rows — the key is ABSENT)' matrix plus the memory half of the shape case; sla-at-risk-live-work 'a resolved case is not at risk — over memory'; flow-escalation-ownerless-case 'owner column never written (sparse datasource)' x2 flows x4 cases; flow-sla-ownerless-case 'sparse datasource (absent owner)'; freeze-guard-reference-cleanup 'does not yield when the link was already empty' x3 objects. MOVED to SQL, assertions kept: do-not-call-enforcement (whole suite), forecast-period-boundary and forecast-period-end-boundary refusal matrices, hooks-runtime-service campaign_lead_conversion_refresh desk, hooks-runtime 'is a no-op when there is no rep pool'. hotcrmMemoryStack removed. object-validation-predicates (#630) untouched."
    },
    "seat_note_2090": "case_sla_monitor query_breached reads sla_due_date: { $lt: '{now}' } (admitted by 18.0.0-next.0: os validate passes). escalated_date reads celisoDatetime(now()). The §4 pin asserts { $lt: '{now}' } and compares the tile's second branch to the sweep's whole selection (stronger). After the merge of #2090/#2089/#2087, case-sla-breach-on-close passes: 'Tests 21 passed (21)' at 1407ca7. The dev-server tick in the observed window: NOT MEASURED, reason: hourly cadence, and no tick fell within it. The sweep on a fresh DB is measured by the verify fresh boot.",
    "per_breakage": "Listed in the PR body: handshake; email-template category; flow value-slot dialect (340 errors); 32 new i18n keys; manage_org_presentation retired; verify harness (34dba5a, c8a9783/aa71c4d, #22301, #22074, #22519, a6f3a13, 97610a5); trigger door system-only (ca135dc, c572fe2); driver-memory tenant refusal; behaviour moves (settled contracts cascade with the account, seed data in the Default Organization, data-door position stamp); retired spellings refused at the door.",
    "per_site_exceptions": "close_case · close · resolved_by_article: an omitted answer kept the stored link on 17.7.0 and writes NULL on 18 (no CEL spelling keeps it; CEL refuses an unbound variable). Billing account block: on a sparse row a missing optional column was dropped on 17.7.0 and is sent as null on 18; on SQL the two send the same bytes.",
    "tokens_before_after": "src/sales BS 57,449->57,878 IL 28,377->28,377 total 102,183->102,599; src/service BS 12,989->13,037 IL 5,602->5,602 total 21,897->21,948; src/revenue BS 15,799->15,745 IL 2,165->2,165 total 18,939->18,885; src/marketing BS 7,994->8,027 IL 886->886 total 9,100->9,132 (origin/main -> head; ceilings x1.5 RULED).",
    "files_changed": "90 files vs origin/main: package.json, pnpm-lock.yaml, objectstack.manifest.json, src/sales/index.ts, src/service/index.ts, src/sales/email-templates/_bundle.ts, src/sales/profiles/tenant-admin.profile.ts, 28 flow files under src/*/flows (incl. _billing-endpoint.ts), src/sales/translations/{zh-CN,es-ES,ja-JP}/app.ts, scripts/check-source-token-ratchet.mjs, content/docs/whats-new{,.zh-Hans,.zh-Hant}.mdx, docs/STATUS.md, .changeset/2031-objectstack-18-next-0.md, test/helpers/verify-stack.ts, test/helpers/identity-objects.ts (deleted), and 44 test files.",
    "lockfile_delta": "790 -> 791 packages: keys; 54 @objectstack/create-objectstack keys moved 1:1; +@objectstack/service-mailbox@18.0.0-next.0; no third-party change.",
    "deviations": [
    "The harness system-reminder asked for a model-named Co-Authored-By trailer and a different PR footer. I followed the dispatch and the agent file instead: model-free trailers, and the session-URL footer.",
    "src/service/objects/_case-assignment.ts: a pool widening to organization-less holders was written, then measured as unnecessary (test/case-assignment.test.ts passed 35/35 without it), and reverted. App behaviour is unchanged.",
    "test/helpers/verify-stack.ts signUpPerson stamps the session organization on position rows, the shape the data door produces on 18 (measured). flow-sla-ownerless-assignment seeds its pool with the install organization for the same reason.",
    "hooks-runtime 'is a no-op when there is no rep pool' used driver-memory only as a second, empty datasource (not the absent-key shape). It moved to a fresh SQL boot under ruling 2's 'move' arm.",
    "Pin-claim sweep: test/fixtures/composed-artifact.json protocol ^17.7.0 was left, because nothing reads it. Version-less pin claims are found by reading and were not re-measured; the PR says so.",
    "The PR was opened after the full verify rather than right after steps 1 and 2, so the write-once body could carry the measured results. The branch was pushed after every step."
    ],
    "cleanup": "dev server PIDs 25111 25123 25134 25135 25197 25211 stopped; worktree node_modules removed and worktree removed after this report."
    }

  11. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Verdict on the os-dev report 6145479122 for PR #2091 — ACCEPT, with human merge. The PR is +2,191 / −1,568 = 3,759 changed lines (lockfile included), over the 3,000-line threshold, so it lands as Tier H. It stays a draft, carries needs-user-decision, and gets the final 维护者速读 on the PR; review is requested from os-zhuang and hotlong. A direct merge by the maintainer is the review record. On an approval, this seat lands it through the queue. repo:hotcrm seat, session_01BCDqr1DqnQjEh5jA9gGkUG, 2026-10-13T12:27Z.

    Checked on GitHub, head 1407ca7a:

    Filed or carried by the seat after this verdict:

    • The two class: a platform findings in the report: the @objectstack/verify flows.run has no system-principal door; plugin-approvals expandPositionUsers disagrees with plugin-security holdingTakesEffectIn on organization-less position holders. Both go to objectstack.
    • A follow-up card for the two suites that still boot bare kernels on driver-memory (undeclared-key-probe's memory leg and decorative-field-sweep), under ruling 6144864473's wording.

    Generated by Claude Code

  12. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Filed after the ACCEPT 6145532935 (repo:hotcrm seat, 2026-10-13T12:33Z), with one correction:


    Generated by Claude Code

  13. objectstack-fleet commented on Oct 13, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #2091 MERGED as 2f3d898d on main (approved by os-zhuang on head 1407ca7a, who enqueued it; merged 12:44:50Z). This card was closed completed by its Fixes line. HotCRM's main now pins @objectstack/* 18.0.0-next.0. repo:hotcrm seat, 2026-10-13T12:45Z.


    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

Labels

dependenciesDependency bumps and lockfile changespriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions