Skip to content

[maintainer] dev-mode noise budget: a blank project written verbatim from the tutorial boots with 4 WARN lines and only one needs the author's hand — expected degradations to info, stacks only at debug, the actionable line highlighted with a one-line fix #22160

Description

@objectstack-fleet

Filing gate: ③ task dispatched by the maintainer, quoted verbatim below; the measurements are class (a) and were taken in this session.
reach: npx os dev --ui on a fresh npm create objectstack@latest project carrying the Build-with-Claude-Code tutorial's four files (17.7.0 packages): ⚠ Boot diagnostics — 4 warnings logged during startup; pnpm dev -- --fresh on the showcase at main (post-#22097): 4 WARN lines plus 2 unarmed-trigger lines.
Reader: domain:cli seat for the policy and the boot-diagnostics printer (packages/cli/src/utils/format.ts, packages/cli/src/utils/console.ts); each WARN line's owner for its level (packages/services/service-analytics, packages/objectql/src/engine.ts + driver-sql, packages/objectql/src/action-governance.ts, service-settings, plugin-sharing).
Dedup: search_issues "dev mode boot diagnostics too noisy warnings expected degradation should be info stack trace only at debug noise budget" → 5 hits, all closed: #22073 (one line per warning class, loopback OAuth → info; PR #22097), #3420 (官方示例应零警告启动), #13256, #4012, #3430. None states a dev-mode budget; this card generalises #22073's per-class fix into a rule and lists the four lines that survive it.
Prior rulings read: #22073 / PR #22097 (per-class summary lines, each printed once, loopback OAuth at info); #3420 (the examples should boot with zero warnings).
Filed on the maintainer's instruction in this session (category ③, quoted verbatim): 「终端噪音是最大的体验问题。 一个按教程原样写的空白项目,os dev 启动就打出 4 条 WARN:OAuth 明文(localhost 下属预期)、analytics 误报、sys_migration 带完整 knex 堆栈、action 无 handler。其中只有最后一条真的需要用户动手,却被淹没在其它三条里。建议给 dev 模式定一个"噪音预算":预期中的降级记 info,堆栈只在 --log-level debug 出现,真正需要动手的那条单独高亮并给一行修法。」

What a first boot looks like today

A blank project with the tutorial's object, action, view and app, npx os dev --ui, @objectstack/* 17.7.0 — the whole Boot diagnostics block, abridged:

⚠ Boot diagnostics — 4 warnings logged during startup:
  WARN [Analytics] No admitObjectRead configured and no "security" service registered at init — … any authenticated caller can post an inline dataset and read counts … (#22154: false alarm, Security registers on the same boot)
  WARN [action-governance] declared script actions with NO handler — a button wired to nothing (ADR-0078); add a `body`, or register a handler under the declared `target` {"count":1,"actions":["my_app_ticket:resolve_ticket"]}   ← the only line the author must act on
  WARN OAuth is served UNENCRYPTED: … (http://localhost:38421/api/v1/auth) … The transport rule accepts this origin only because the host is loopback …   (info since PR #22097 on main; still WARN in 17.7.0)
  WARN Insert operation failed {"object":"sys_migration","error":{"message":"UNIQUE constraint failed: sys_migration.id …","stack":"SqliteError: … at Client_BetterSQLite3._query (…/knex/lib/dialects/better-sqlite3/index.js:52:40) … (9 more frames)"}}   (#22099)

On main (showcase, pnpm dev -- --fresh) the OAuth line is gone and the block reads: [Analytics] No admitObjectRead …, [SettingsService] Pre-bind READ of namespace 'auth' …, Insert operation failed {"object":"sys_migration" … full stack}, [sharing-rule] active business-unit rule expands to NO recipients …, plus two flow … declares a 'schedule' trigger but is NOT bound — disabled by deployment policy … lines. Not one of those six asks the showcase author to change anything.

The one line that does — the dead button — is visually identical to the rest: same WARN, same timestamp prefix, same density, a JSON tail. A newcomer reads four alarms and cannot tell the real one from the three they are supposed to ignore; the previous card in this series (#22152) is exactly the reader who missed it.

The rule being asked for

A dev-mode noise budget, stated once and enforced by a pin:

  1. Expected degradations print at info. A line that says of itself "this is accepted / not a failure / resolves per query / disabled by policy" is not a warning: loopback OAuth (done in fix(cli,plugin-auth): one boot line per warning class, each printed once, and the loopback OAuth notice at info #22097), [Analytics] … the bridge resolves per query ([finding] service-analytics: every default boot logs a WARN that no "security" service was registered at init, although the Security plugin registers moments later — the sibling getReadScope path logs the same situation at info #22154), [SettingsService] Pre-bind READ …, schedule trigger … disabled by deployment policy, [sharing-rule] … expands to NO recipients when the seed simply has no members.
  2. Stack traces only at --log-level debug. The sys_migration line carries a 10-frame knex stack into the default banner; the banner keeps the one-sentence message and the object name, the stack waits for debug ([finding] every artifact boot on a fresh :memory: database logs Insert operation failed … UNIQUE constraint failed: sys_migration.id with a full knex stack in Boot diagnostics #22099 removes the line altogether, this rule covers the next one).
  3. The actionable line is the exception, and it looks like one. Anything with a fix the author can apply (add a body, or register a handler …) prints once, highlighted, with the one-line fix on its own line, and is counted separately: 1 needs your attention · 3 informational.
  4. A pin holds it. The blank template and the Build-with-Claude-Code example (with a registered handler) boot with 0 warnings; examples/app-showcase boots with zero lines above info that are not actionable. packages/cli/src/utils/format.boot-warning-classes.test.ts is where fix(cli,plugin-auth): one boot line per warning class, each printed once, and the loopback OAuth notice at info #22097's classes already live.

Why it matters

The boot banner is the one place the tutorial sends the reader to look ("run it and look"); AGENTS.md's own log-level rule says escalating functional degradations to warn "trains everyone to skim error". Today it trains a newcomer to skim everything.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: the road — start: a fresh boot's diagnostics show only real faults | 缺项 | P3

    Triage: first grade, enhancement · priority:p3 · domain:cli · area:devpath · pm:queue (finding removed). The maintainer's noise budget, as dispatched

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-08T05:10Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in packages/cli/src/utils/format.ts (the boot-diagnostics printer) and the policy each WARN owner follows ⇒ domain:cli; rationale: the printer and the policy are that lane's; each WARN line's owner fixes its own level. Read on main ec8f37c890.

  2. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 9
    Session: session_01RWZbGvPFcRKvUqASZtunCU
    Account: os-warren (the seat's linked user as get_me answers it; the card's assignee)
    Branch: claude/issue-22160-dev-noise-budget
    Worktree: objectstack-issue-22160
    Domain: domain:cli
    Seat: domain:cli#1
    File surface, per the card body and triage 6052773414, read on origin/main 7d7943dd:

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · 2026-10-08T06:23Z

  3. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22160,
    "status": "done",
    "branch": "claude/issue-22160-dev-noise-budget",
    "pr": "#22236",
    "session": "session_01RWZbGvPFcRKvUqASZtunCU",
    "premise_still_valid": true,
    "head": "f8a80640",
    "summary": "Printer half per the seat's scope cut. printBootDiagnostics (packages/cli/src/utils/format.ts) now prints any record from a closed one-row table, ACTIONABLE_BOOT_CLASSES (objectql's '[action-governance] declared script actions with NO handler'), first, once and highlighted, with its subjects. The next line is the producer's own fix (the message text after its '; '), derived rather than hand-copied. The header counts the two apart: '1 needs your attention · N informational'. With nothing actionable it reads 'ℹ Boot diagnostics — N informational', unless the capture dropped records. A captured record's stack trace (any 'stack' property holding a V8 trace) is withheld and counted, and its message is kept. At --log-level debug the same record streams live with its stack, because serve never opens the quiet window there; serve.ts is unchanged. PR line 1 is 'Part of #22160 (the printer half; owners' levels routed)': card pin 4 (0 warnings) depends on the owners in the H5 table.",
    "pm_readings": {
    "H1": "Measured on 7d7943d with built dist and os dev --fresh. Blank starter + the tutorial's four files as they stood then, --ui: 3 WARN records, not 4, because loopback OAuth went to info in #22097. They are [Analytics] (service-analytics plugin.ts:1450, no stack), [action-governance] dead button (objectql action-governance.ts:583, no stack, the only actionable one) and 'Insert operation failed' sys_migration (logged at objectql engine.ts:14006, carries a 10-frame knex/driver/engine stack). Showcase --seed-admin --fresh: 4 records ([Analytics], [SettingsService] service-settings settings-service.ts:774, sys_migration with stack, [sharing-rule] plugin-sharing sharing-rule-service.ts:1524) plus 2 banner class lines (schedule, time_relative; deployment policy). None is actionable.",
    "H2": "Confirmed. The stack reaches the banner as a JSON-escaped 'stack' inside the record's structured tail (ObjectLogger.write builds error:{message,stack}; the engine's writeFailureLogMeta rebuilds it for warn). The debug half needs no code: isVerboseBootLevel('debug'|'info') means serve never captures. Measured at debug before and after: 0 replay blocks, and the sys_migration record streams live 1 time, with its stack 1 time.",
    "H3": "Holds. A closed table (one row) matched like restatedAbove. The fix is derived from the producer's '; '. No logger metadata key and no free-text heuristic.",
    "H4": "Header implemented as '1 needs your attention · 2 informational'. The print-once and restatedAbove rules are unchanged. Three of #22097's legs asserted the old header string verbatim. That is the text the ruling replaces, so those three expectations now read the new header with their withheld counts unchanged; every class and print-once assertion is untouched and green. See deviations.",
    "H5": "See out_of_scope_findings[0] for the owner table. #22154 (open) tracks [Analytics]. #22099 (open) tracks the sys_migration insert; the duplicate is plugin-auth's default-org owner bind recording id 'adr-0093-default-org-owner-bind' twice (seen in the debug stream). [SettingsService], [sharing-rule] and the banner's deployment-policy Flows lines have no card known to this dev. Not searched; see deviations."
    },
    "tests": "At f8a8064. pnpm --filter @objectstack/cli typecheck: exit 0 (tsc --noEmit; check:test-typecheck OK, 3 files / 28 errors / 6 pinned signatures, unchanged). Both test files are in a tsc program per --listFilesOnly. pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2: Test Files 263 passed (263), Tests 3881 passed (3881). format.boot-warning-classes.test.ts: 18 passed (11 existing + 7 new). The new legs drive real producers: ObjectLogger in pretty/text/json, real BootLogCapture, real objectql runActionGovernanceInventory; plus stack withholding, the debug live stream, and 2 formatter legs. New nightly e2e test/serve-boot-diagnostics-noise-budget.e2e.test.ts, run locally because the diff adds an integration-tier file (OS_TEST_TIERS=nightly ... --project integration): Tests 3 passed (3). It scaffolds through the real on-ramp bin, adds the tutorial's object, its declarative Resolve and a handler-less Escalate, and boots real os serve. Exactly 1 line is highlighted (Escalate) with 1 fix line, Resolve is named on no line, and the block carries no stack. The rest of the integration tier is declared to CI. Ablations ran via scripts/ablation-replace.mjs in WRAP mode on committed code; every anchor hit x1, every write was verified by blob change, and every restore was proven blob==HEAD with an empty git diff HEAD. Subjects import format.ts/boot-log-capture.ts from source (no dist). Expected direction red, observed red: A class row unmatched 3 failed/18; B stacks kept 1/18; C fix never split 3/18; D any string stack withheld 1/18; E dropped no longer alarms 1/18; G isVerboseBootLevel without debug 1/18; boot pin with A 1 failed/3, at 77f6a48 and again at f8a8064. Final restore: format.ts 9dc1b9d9 and boot-log-capture.ts d2545d2e equal HEAD. Before/after boots with built dist: blank+tutorial@7d7943d went from '⚠ Boot diagnostics — 3 warnings' with the 10-frame stack to '⚠ Boot diagnostics — 1 needs your attention · 2 informational' (dead button highlighted plus a 'fix:' line, sys_migration message without stack, '1 stack trace withheld' hint). Showcase went to 'ℹ Boot diagnostics — 4 informational (2 more already listed above)'. After merging main, blank + the current tutorial (Resolve declarative since #22204) reads 'ℹ Boot diagnostics — 2 informational'. Narrowed eslint --no-inline-config --format json on the 3 touched source files: 3 files, 0 errors / 0 warnings. ESLint.isPathIgnored is false for all 3, and no config is type-aware (no parserOptions.project/projectService; eslint.config.mjs:327-328 states it). Full pnpm lint at f8a8064: exit 0.",
    "gates": "Re-derived at f8a8064: dispatch-gates --commands gives 65 for 5 paths vs merge base 7b926f7, the same set as before the merge. Against the order's list that adds pnpm check:cli-test-child-env and drops check:dispatcher-error-vocabulary and check:route-envelope. Ran the union of 68 (the 65 derived, those 2, and full pnpm lint), each exit code recorded before any pipe. 67 exit 0. node scripts/check-empty-changeset.mjs --base origin/main exits 1, red by its own design for the deliberate correction of a pending release note (open_questions[0]). dispatch-gates --ran: 65 derived, 65 run, 0 NOT-MEASURED, 0 UNRUN. At e1a46a4 check:dual-build-cjs-loads exited 3 with PREREQUISITE NOT MET (8 packages had no dist). Built them; rerun exit 0 (106 entries / 66 packages load), and exit 0 again at f8a8064. CI on f8a8064 at report time: NOT MEASURED. The report is not held for CI; PM reads it.",
    "files_changed": [
    "packages/cli/src/utils/format.ts (+206/-8: ACTIONABLE_BOOT_CLASSES, structuredTail, withoutStackTraces, recordWithoutStacks, actionableRecord, printBootDiagnostics)",
    "packages/cli/src/utils/format.boot-warning-classes.test.ts (+190/-7: 7 new legs; 3 header-string expectations of #22097's legs moved to the new header)",
    "packages/cli/test/serve-boot-diagnostics-noise-budget.e2e.test.ts (new, +193)",
    ".changeset/22160-boot-diagnostics-noise-budget.md (new, @objectstack/cli patch, Clause-② no)",
    ".changeset/22073-boot-warning-one-line-per-class.md (1 line: the quoted old header reduced to its still-true withheld count)",
    "merge commit f8a8064 (origin/main 7b926f7; main's files only)"
    ],
    "line_budget": "n/a: no skills/** or governed surface touched. 609 insertions / 16 deletions over 5 files vs merge base 7b926f7, under the 5000-line human-merge threshold.",
    "deviations": [
    "Edited a pending changeset this PR did not add (.changeset/22073-boot-warning-one-line-per-class.md, one sentence). It quoted the header this PR replaces, and both notes ship in the same release. The claim's file surface names .changeset/*.md for the cli patch; this edit is read as inside that glob, and it is declared. check-empty-changeset stays red until a person confirms (open_questions[0]).",
    "Order H4 says #22097's pins must stay green. Three of its legs asserted the old header string verbatim, which is exactly what the ruled header split replaces. Those three expectations were rewritten with their counts kept. Every class and print-once assertion is unchanged and green.",
    "Order H5 says to search before reporting. .claude/agents/os-dev.md forbids dev-side dedupe and tracker search, and the role file outranks the order. So: single-card REST reads of #22154 and #22099 only, and dedupe words for the rest.",
    "Merged origin/main (7b926f7) into the branch as f8a8064 before opening the PR (AGENTS.md Multi-agent §10). #22204 had made the tutorial's Resolve declarative mid-run, so commit 2c50c26 rewords the pins and the changeset, and the e2e boots the tutorial's declarative Resolve as the control beside a handler-less Escalate. Unit tier, typecheck, e2e, its ablation and the gate union were re-run at f8a8064.",
    "Ran full pnpm lint because the order asks for it. os-dev.md calls repo-wide scans CI-owned, but allows them when they finish. It ran in the background with an exit code recorded: exit 0. A first full-lint run started at e1a46a4 was stopped by its recorded PIDs once main moved; that run produced no reading.",
    "The boot-level pin was added as a nightly .e2e file (the order's 'if feasible'). It is nightly-tier by name, so it does not run in the per-PR queue.",
    "A shell-variable scoping slip wrote my own pid file to /build4.pid. It was removed at once; no repo impact."
    ],
    "mcp_calls": "0",
    "api_writes": "3, each through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, HTTP 204, executed as objectstack-fleet[bot]): (1) pr_create: POST /repos/objectstack-ai/objectstack/pulls gave draft #22236; read-back says the 14219-byte body is stored identical. (2) label-write --assign os-warren: POST /repos//issues/22236/assignees; read-back matched. (3) this os-dev-report comment: POST /repos//issues/22160/comments. git push is not a REST write. No label added (the order named none; skip-changeset does not apply).",
    "open_questions": [
    {
    "question": "Keep this PR's one-sentence correction of the pending .changeset/22073-boot-warning-one-line-per-class.md? It quoted '⚠ Boot diagnostics — 5 warnings logged during startup (8 more already listed above):', which this PR replaces. check-empty-changeset is red on it by design until a person confirms.",
    "options": [
    "A: keep the correction. Every entry in the release stays true, and the gate stays red until the seat or maintainer confirms.",
    "B: restore the note from base and add to this PR's changeset a sentence saying an earlier entry's header example is replaced. The gate goes green, but the CHANGELOG publishes the superseded example plus its correction."
    ],
    "recommendation": "A. Real need: the CHANGELOG is what an upgrading agent greps for 'Boot diagnostics'. Long-term: each published entry stays true and nothing is stacked as a correction. Anti-AI-error: no false example for an agent to copy. Startup scope: one human confirmation, no new mechanism. If the confirmation cannot be given, B is a one-commit change."
    },
    {
    "question": "The banner's own Flows lines for deployment-policy-unbound flows ('⚠ N flow(s) declare a 'schedule' trigger but are NOT bound — disabled by deployment policy …') are printed by printAutomationSummary in format.ts, this lane's file, as yellow ⚠. On the showcase they are the only remaining ⚠ lines, and neither needs the author. The claim routed 'the unbound schedule trigger' level to service-automation, but service-automation's record is already withheld from Boot diagnostics; the glyph the reader sees is the CLI's.",
    "options": [
    "A: a follow-up domain:cli card, ruled by the seat: the deployment-policy class prints under ℹ/dim; other unbound reasons (missing trigger, binding failure) stay ⚠.",
    "B: amend this claim and add it to this PR.",
    "C: keep ⚠, as #22073's ruling kept the class a warning."
    ],
    "recommendation": "A. Real need: measured, these are the showcase's two remaining alarm lines and neither is actionable. Long-term: the glyph belongs to the printer, so routing it to service-automation finds no lever. Anti-AI-error: neutral. Startup scope: a one-class change, but it revisits a ruled shape (#22073), so it gets its own ruling rather than riding this PR."
    }
    ],
    "out_of_scope_findings": [
    "carrier: the owners below; seat routes · noted, not filed. H5 owner table. [Analytics] warn: service-analytics/src/plugin.ts:1450, domain:services, #22154 open. sys_migration 'Insert operation failed' warn: logged at objectql/src/engine.ts:14006, duplicate from plugin-auth's default-org owner bind, #22099 open. [SettingsService] Pre-bind READ warn: service-settings/src/settings-service.ts:774, no card known. [sharing-rule] expands to NO recipients warn: plugin-sharing/src/sharing-rule-service.ts:1524, no card known. Banner Flows deployment-policy lines: printAutomationSummary restating service-automation/src/plugin.ts:1533 (see open_questions[1]). Dedupe words: SettingsService Pre-bind READ namespace auth warn · sharing-rule business-unit NO recipients warn on seed · deployment policy unbound flows banner glyph",
    "class: a · reach: public door, os dev --ui --fresh on the blank project. In 1 of 3 measured boots the os dev parent's MCP block (packages/cli/src/commands/dev.ts:139, '🤖 MCP server — connect a coding agent:' with Endpoint/Skill/Connect/Disable) interleaved line by line with the serve child's '🔑 Dev admin' credential lines; the other 2 boots printed the two blocks apart. This is a race between the parent's stdout block and the child's stderr banner · dedupe words: os dev MCP block interleaved banner · Dev admin lines interleave · connect a coding agent ordering race",
    "carrier: none (承接者:无) · noted, not filed. At --log-level info serve also skips the quiet window, so a record's stack streams at info as well as at debug. The ruling says stacks appear only at debug. What ObjectLogger renders at info is packages/core's. Kept in Acceptance notes.",
    "carrier: none (承接者:无) · noted, not filed. Candidate actionable classes left out of the closed table: [action-governance] 'registered handlers with NO declaration' (its fix is hedged, not '; '-shaped) and runtime-assets 'Branding asset not served … To fix, …'. Neither appeared on the measured boots."
    ]
    }

  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #22236 at f8a80640, pending CI and the seat's self-test

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · read on GitHub 2026-10-08T08:15Z

    Checked on GitHub and in the diff, not from the report:

    • Shape:
      • draft, base main;
      • line 1 is Part of #22160 (the printer half; owners' levels routed), which is the order's wording for the printer half; line 2 is Clause-②: no;
      • assignee os-warren;
      • 5 files, +609 / −16;
      • one merge of main (7b926f76); no rebase.
    • The printer (printBootDiagnostics, packages/cli/src/utils/format.ts):
      • Classification. Each shown record is either actionable (a closed one-row table, ACTIONABLE_BOOT_CLASSES: the [action-governance] … NO handler dead button) or informational.
      • Actionable records print first, highlighted, with their subjects from the structured tail and the producer's own fix: the text after its ; , derived, not hand-copied.
      • Informational records print dim, as before, with any stack property that holds a V8 trace removed and counted. message stays, and so does a stack key that is not a trace.
      • The header counts the two apart. It stays a ⚠ alarm when the buffer dropped records; otherwise it is ℹ with nothing actionable.
      • fix(cli,plugin-auth): one boot line per warning class, each printed once, and the loopback OAuth notice at info #22097's print-once and restatedAbove rules run before this split, unchanged.
    • H3 holds: a closed table, no free-text heuristic, no new logger key.
    • The debug half needs no code. serve never opens the quiet window at debug / info (isVerboseBootLevel), so the live stream keeps its stacks. serve.ts is unchanged.
    • Pins:
      • 7 new legs over real producers (ObjectLogger in each format, BootLogCapture, runActionGovernanceInventory), each with an ablation the dev ran red;
      • fix(cli,plugin-auth): one boot line per warning class, each printed once, and the loopback OAuth notice at info #22097's three header expectations moved to the new header with their withheld counts unchanged. That is the text the ruling replaces, and every class and print-once assertion is untouched;
      • a nightly .e2e boot of the on-ramp scaffold with one handler-less action: exactly one highlighted line, the declarative Resolve on no line, no stack. It pins no informational count, as the order asked.

    The deliberate correction of .changeset/22073-boot-warning-one-line-per-class.md: the seat confirms it (the dev's open question 1, option A).

    Changeset (@objectstack/cli patch): each sentence checks against the code. Not blocking: its example names support_desk_ticket:resolve_ticket, while today's tutorial Resolve is declarative (#22204). The example still reads true as "a project with one such action", so it stays.

    The dev's open question 2, ruled by the seat: A, a follow-up domain:cli card.

    The owners' levels (H5, the half this PR does not carry):

    Owed before landing:

    • the seat's dispatch-gates --self-test at f8a80640, for the e2e's new mkdtempSync site (running);
    • CI on f8a80640, every check but Check Changeset (see above).

    Not carried: the os dev MCP-block interleave the dev saw in 1 of 3 boots, and stacks streaming at info as well as debug. Each is one observation, outside this card. Their dedupe words are in the dev's report.

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Release: claim 6053785493 (domain:cli seat, session_01RWZbGvPFcRKvUqASZtunCU). The printer half has landed (PR #22236 → 11e6fc5f2e). The rest of the card is other lanes' log levels, listed below. Card → pm:queue + pm:retriage to route them; assignee cleared. The card stays open: PR #22236 says Part of #22160, not Fixes.

    Landed: PR #22236 → 11e6fc5f2e, a single-parent queue squash

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · 2026-10-08T09:34Z

    • Landing shape:
      • 11e6fc5f2e has one parent.
      • It is an ancestor of origin/main; the pre-merge head f8a80640 is not.
      • It entered the merge queue 2026-10-08T08:41:36Z and merged 2026-10-08T09:33:03Z on that first entry.
    • Content on origin/main:
      • packages/cli/src/utils/format.ts carries ACTIONABLE_BOOT_CLASSES (:1315) and the split header in printBootDiagnostics;
      • the pins in format.boot-warning-classes.test.ts and the nightly test/serve-boot-diagnostics-noise-budget.e2e.test.ts are present;
      • .changeset/22160-boot-diagnostics-noise-budget.md is present (@objectstack/cli patch);
      • the confirmed one-line correction of the pending .changeset/22073-boot-warning-one-line-per-class.md is present.
    • Review of record:
      • ACCEPT 6055714562 at f8a80640, in one round. Clause-②: no; no contract review was owed.
      • CI on the head was green (33 runs) apart from Check Changeset, which is red by design for the confirmed deliberate correction (6055723639 on the PR; not a required context).
      • The seat's dispatch-gates --self-test passed (1976 cases) for the new temp-directory site.
    • Delivered:
      • Boot diagnostics prints the record the author must act on (a script action declared with no handler) first, highlighted, with the producer's own fix.
      • The header counts actionable and informational records apart: 1 needs your attention · N informational, or ℹ … N informational when nothing needs the author.
      • Stack traces are withheld at the default level and counted. --log-level debug streams them live.
      • On the blank project with today's tutorial, the block reads ℹ Boot diagnostics — 2 informational (the dev's measurement after merging main).

    What is left on this card (why pm:retriage): each line's level is its owner's.

    1. [Analytics] (service-analytics): [finding] service-analytics: every default boot logs a WARN that no "security" service was registered at init, although the Security plugin registers moments later — the sibling getReadScope path logs the same situation at info #22154, open.
    2. The sys_migration insert, which plugin-auth's default-org owner bind records twice: [finding] every artifact boot on a fresh :memory: database logs Insert operation failed … UNIQUE constraint failed: sys_migration.id with a full knex stack in Boot diagnostics #22099, open.
      • Those two are the blank project's two remaining informational records. The card's "the blank template boots with 0 warnings" waits on them.
    3. [SettingsService] pre-bind read (service-settings/src/settings-service.ts about :774) and [sharing-rule] expands to no recipients (plugin-sharing/src/sharing-rule-service.ts about :1524) appear on the showcase only. There is no card for either level; triage routes them.
    4. The banner's own ⚠ for flows unbound only by deployment policy is this lane's printer, filed as [finding] cli(banner): flows unbound only because the deployment switched scheduled work off still print as a yellow ⚠ in the boot banner's Flows section — the last alarm lines on the showcase, none actionable #22255.

    Kept as notes, no carrier:

    • The os dev MCP block once interleaved with the Dev admin lines (1 of 3 boots).
    • At --log-level info, stacks stream as well as at debug.
    • Each is a single observation; the dedupe words are in the dev's report.
  6. 6 remaining items

  7. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 8, 2026
  8. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Unlock: #22099 closed completed (PR #22336 → 6ff6ed6a). pm:blocked → pm:queue; p3 and domain:cli stand

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-08T20:18Z. ⛔ Not a claim, ⛔ not a dispatch.

  9. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_01BmsuLyUeuG5CNpZFMH1jzS
    Account: os-elon-musk (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-22160-blank-template-acceptance
    Worktree: objectstack-issue-22160
    Domain: domain:cli
    Seat: domain:cli#1
    File surface: none planned. This is the acceptance measurement triage 6068291990 names: boot a blank project written verbatim from the tutorial, on main built from the workspace packages, and read its Boot diagnostics. A line that needs a fix is named with its producer for its own card, ⛔ never demoted here. Any edit stops the run; explain it in the report.
    Container & model: S, measurement, mode:subagent, model: default (opus). dispatch-gates --tier has no paths to read. Rebuilding the tutorial project and judging each boot line against the maintainer's budget is judgment work.
    Clause-②: no
    Responsibility: n/a — not a defect card (a maintainer-dispatched task, category ③; its remaining deliverable is the acceptance measurement)
    Thread-read: 6068291990
    Serial constraints cleared: no file is written. Lane siblings in flight: #22310 (PR #22404, patch round) and #22255 (format.ts); a boot reading on main is not affected by either branch.


    Generated by Claude Code

  10. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22160,
    "status": "done",
    "branch": "claude/issue-22160-blank-template-acceptance",
    "pr": null,
    "session": "session_01BmsuLyUeuG5CNpZFMH1jzS",
    "premise_still_valid": false,
    "summary": "Acceptance measured on main fdfdd7e, built from the workspace packages (not npm 17.7.0), with os dev --ui on a project scaffolded by this checkout's create-objectstack plus the tutorial's four files. Triage's first clause holds: the tutorial project boots with NO warning record. There is no Boot diagnostics block on the first boot or on a restart, 0 WARN records, and 0 WARN even in the full --log-level debug stream. The bare blank template is the same. Its second clause holds on the card's own project: with the card-era handler-less Resolve, the block is exactly one record, the dead button, printed highlighted with its one-line fix. The header reads '1 needs your attention' with 0 informational records, and it is byte-identical on both boots. The verbatim tutorial no longer declares a dead button (PR 22204 made Resolve declarative), so it has no actionable line at all. That falsifies order H2 in its letter for the verbatim tutorial, and it is what the budget asks for. premise_still_valid is false because the card's premise (4 WARN lines on a tutorial project) no longer holds on main: it is resolved, not mis-filed. No other warning line appeared, so nothing needs its own card under the triage acceptance. Closing completed is the seat's call.",
    "pm_readings": {
    "H1": "Holds with one correction. The card body's project is the pre-22204 tutorial (script action with target), while the page at fdfdd7e has a declarative Resolve and a form in its view. Both were recreated from this checkout: A = the page verbatim, B = A with only the card-era action file. The page used is content/docs/getting-started/build-with-claude-code.mdx (fdfdd7e for A, 3b49318 for B's action file).",
    "H2": "B: holds. One actionable record, first, highlighted, with its fix; 0 informational; no stack. A (the verbatim tutorial): false in its letter, because there is no record at all, actionable or not. Expected degradations sit at INFO: at debug, the A3 stream has 0 WARN, and the [Analytics] bridge, the loopback OAuth notice and the sys_migration owner-bind record are all INFO. No stack printed at any level, so the stack-only-at-debug leg is NOT MEASURED here (nothing carried one).",
    "H3": "Holds. No [Analytics] admitObjectRead warning and no sys_migration failed insert at any level on a fresh first boot (A3 at debug). The owner bind is recorded once, at INFO.",
    "second_boot": "A restart on the same project and DB (A2, B2) printed exactly what the first boot printed in the block. No line appeared on a second boot only."
    },
    "tests": "Measured at objectstack origin/main fdfdd7e (worktree objectstack-issue-22160, branch claude/issue-22160-blank-template-acceptance = that sha, no commits). BUILD: bash scripts/pm/os-verify-lock.sh -c 'NODE_OPTIONS=--max-old-space-size=4096 pnpm turbo run build --concurrency=2 --filter=@objectstack/cli... --filter=@objectstack/connector-rest... --filter=@objectstack/connector-openapi... --filter=@objectstack/connector-mcp... --filter=create-objectstack...' -> 'Tasks: 59 successful, 59 total; Cached: 9 cached' and 'VERDICT command-exit 0 · held the lock 334s · waited 83s'. PROJECT: node packages/create-objectstack/bin/create-objectstack.js support-desk --skip-install --skip-skills (workspace create-objectstack 17.7.0, blank template, namespace support_desk), then the tutorial's four files extracted VERBATIM by script from content/docs/getting-started/build-with-claude-code.mdx at fdfdd7e (src/objects/ticket.object.ts, src/actions/ticket.actions.ts, src/views/ticket.view.ts, src/apps/support.app.ts) plus the four barrel export lines the page describes. Its node_modules/@objectstack/{spec,runtime,plugin-hono-server,connector-rest,connector-openapi,connector-mcp,cli} are symlinks to the built workspace packages (not npm 17.7.0); node_modules/.bin/os is the workspace cli bin. os validate on it: 'Validation passed', 'Data: 2 Objects 6 Fields', 'UI: 1 Apps 1 Views 1 Actions', exactly the page's expected output. VARIANTS: A = the tutorial verbatim (its Resolve is the declarative operation:update + patch since PR 22204, so it declares no script action). B = A with ONLY src/actions/ticket.actions.ts replaced by the card-era file (the page at 3b49318, the parent of 7b926f7: type 'script', target 'resolveTicket', nothing registers it) = the dead-button project the card body measured. T = the bare blank template, no tutorial files. BOOT: each boot ran under a real pty: script -qfec './node_modules/.bin/os dev --ui -p 37613' (NODE_PATH unset, NODE_OPTIONS=--max-old-space-size=4096, default log level), waited for 'Press Ctrl+C to stop' plus 20 s, then SIGINT to the os dev process group I started (recorded PID), exit 0, port free afterwards. RESULTS (WARN = timestamped WARN records in the whole output; stack = V8 frames anywhere): A2 first boot (fresh project): NO Boot diagnostics block at all; WARN 0; ERROR/FATAL 0; lines carrying a warning glyph 0; stack frames 0. A2 second boot (restart, same project and DB): NO Boot diagnostics block; WARN 0; glyph lines 0; stack 0. A3 first boot of a second fresh copy at --log-level debug: whole live stream 1850 DEBUG / 426 INFO / 0 WARN / 0 ERROR; stack frames 0. T first boot (bare blank template): NO Boot diagnostics block; WARN 0; glyph lines 0. B2 first boot and B2 second boot: the block below, byte-identical across the two boots including ANSI (md5 7fbd54f1569c3fa4c1a342f25b3acb55 both); WARN records outside the block 0; stack 0. Styling read from the raw pty bytes: header yellow, the record bold yellow, the fix line cyan, the hint dim. B2 Boot diagnostics block, verbatim (first boot = second boot):\ntext\n ⚠ Boot diagnostics — 1 needs your attention:\n ⚠ [action-governance] declared script actions with NO handler — a button wired to nothing (ADR-0078): support_desk_ticket:resolve_ticket\n fix: add a `body`, or register a handler under the declared `target`\n run with --log-level debug to watch the boot stream live\n\nA2 first boot, banner region verbatim from 'Loading objectstack.config.ts' to 'Press Ctrl+C to stop' (only edits: the scratch path prefix written SCRATCH, the 41-name plugin list line elided), showing there is no Boot diagnostics block:\ntext\n Loading objectstack.config.ts...\n ↪ secret fields: LocalCryptoProvider wired (dev) — set OS_SECRET_KEY and swap for KMS/Vault in production\n\n ✓ Server is ready\n\n\n 🤖 MCP server — connect a coding agent:\n ➜ API: http://localhost:37613/\n Endpoint http://localhost:37613/api/v1/mcp\n ➜ Console: http://localhost:37613/_console/\n Skill http://localhost:37613/api/v1/mcp/skill\n Connect claude mcp add --transport http support-desk http://localhost:37613/api/v1/mcp\n ➜ MCP: http://localhost:37613/api/v1/mcp\n Disable OS_MCP_SERVER_ENABLED=false\n connect an AI client (Claude Code, Cursor, …) · skill: http://localhost:37613/api/v1/mcp/skill\n\n 🔑 Dev admin: admin@objectos.ai / admin123\n seeded on empty DB · dev only — do not use in production\n platform admin — Setup, Studio and every record, but NO app-declared capability, so\n an app that gates navigation on requiredPermissions may show it an empty menu; grant\n it a permission set under Setup → Users, or sign in as an account your app seeds\n\n Config: objectstack.config.ts\n Mode: development\n Driver: SqlDriver(better-sqlite3) → file:SCRATCH/A2/support-desk/.objectstack/data/objectstack.db\n Tenancy: single\n Plugins: 41 loaded\n (41-plugin list elided)\n\n Press Ctrl+C to stop\n\nH3 at debug (A3): '[Analytics] admitObjectRead bridged to the "security" service; ... resolved per query' is INFO (service-analytics src/plugin.ts:1538, ctx.logger.info); the sys_migration insert ran once with no failure: 'Insert operation failed' 0 hits, 'UNIQUE constraint' 0 hits, and '[auth] default organization owner bind recorded in sys_migration' 1 hit at INFO (plugin-auth src/default-org-bootstrap-once.ts); 'OAuth is served UNENCRYPTED' is INFO (plugin-auth src/auth-plugin.ts:3492); '[SettingsService] Pre-bind READ' 0 hits; '[sharing-rule] ... NO recipients' 0 hits (only INFO 'hooks bound' lines). PRODUCERS of every line of the B2 block: header and the 'run with --log-level debug ...' hint are the printer itself (packages/cli/src/utils/format.ts printBootDiagnostics :1472, hint :1519-1520); the highlighted record is objectql (packages/objectql/src/action-governance.ts:583-590, logger.warn, message 'STATEMENT; FIX'), and its fix line is the text after the producer's '; ' derived by format.ts actionableRecord; it is the one line the author can act on. There is no other line in either block. NOT MEASURED: the stack-withholding leg of the budget. No record in any of the 7 boots carried a stack, so there was nothing to withhold; PR 22236's unit pins cover that leg. SETUP CONTROL (boot A1, the first try, kept as evidence and not used as the reading): with the workspace packages/console having no dist (pnpm build never produces it), the same project printed one line outside the block: '⚠ Page source and requires not validated at save: no SDUI component manifest at PROJECT/sdui.manifest.json or WORKTREE/packages/console/dist/sdui.manifest.json ...' (packages/cli/src/utils/sdui-manifest.ts:270, printed by serve). It is an artifact of the workspace layout: the CLI looks for the manifest beside its OWN @objectstack/console dependency, and the published @objectstack/console@17.7.0 tarball carries dist/sdui.manifest.json. With that published dist present (see deviations) the line is gone (A2, B2, A3, T). A1 otherwise matched A2: no Boot diagnostics block, WARN 0.",
    "gates": "none — no file changed (git status empty, branch head = fdfdd7e = BASE; the one gitignored write is listed under deviations)",
    "files_changed": [],
    "deviations": [
    "To boot --ui as an installed CLI would, the published @objectstack/console@17.7.0 tarball (static SPA, npm integrity sha512-4Z8Fy47V... verified) was extracted into each scratch project's node_modules and copied into the worktree's GITIGNORED packages/console/dist (the output path pnpm objectui:build writes; packages/console/.gitignore 'dist/'). No tracked file changed. The worktree goes with the cleanup. Building the console at the pinned objectui sha was not attempted: it is a full objectui build, and the Console SPA logs nothing at server boot.",
    "The scratch projects resolve @objectstack/* through symlinks to the built workspace packages instead of an npm install, so every server-side byte is fdfdd7e's.",
    "Boot A1 was a setup control, not the reading (see tests: the SDUI-manifest line it printed is a workspace-layout artifact). The canonical first boots are on fresh copies A2, B2, A3 and T.",
    "Each boot ran under a pty (script -qfec) so the output is what a terminal user sees, colors included."
    ],
    "cleanup": "All 7 os dev servers were mine and each was stopped by its recorded os dev PID (SIGINT to that process group, the Ctrl+C equivalent); no process left (ps clean, port 37613 free after each). After this report is posted: rm -rf the worktree's node_modules, then git worktree remove (no --force). The remote branch stays at fdfdd7e (the empty write-route probe). Deleting it would be a write this order did not grant.",
    "mcp_calls": "0",
    "api_writes": "1 — this os-dev-report comment, POST /repos//issues/22160/comments, sent by scripts/pm/post-stamped.mjs through the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]). git push of the empty branch is not a REST write. Reads: single-card REST GET of the issue and its comments.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: a · reach: public door, os dev --ui on the tutorial project at fdfdd7e under a pty. The os dev parent's MCP connect block ('🤖 MCP server — connect a coding agent:' with Endpoint/Skill/Connect/Disable) interleaves line by line with the serve child's ready banner in 5 of 7 boots. Foreign lines inside the block: A2 first boot 3 (the ➜ API / Console / MCP rows), A3 4, B2 first boot 3 ('Tenancy', 'Plugins: 41 loaded' and its list, split from 'Config / Mode / Driver'), B2 restart 1, T 1 (the '🔑 Dev admin: admin@objectos.ai / admin123' credential line lands inside the Connect block). A1 was clean; the A2 restart printed the block above '✓ Server is ready'. Producer pair: packages/cli/src/commands/dev.ts:707-741 prints the block to the parent's stdout when the child's 'objectstack:listening' IPC arrives; the child sends that IPC at serve.ts:783 (announceListening) BEFORE it prints its banner to stderr (printServerReady :5396, printBootDiagnostics :5556). Two processes write one terminal unordered. The PM thread kept the 1-of-3 observation from PR 22236 as a note with no carrier (6056996366); this is the measured repro. · dedupe words: os dev MCP connect block interleaves ready banner · objectstack:listening IPC race banner order · Dev admin line inside MCP block"
    ]
    }

  11. objectstack-fleet commented on Oct 9, 2026

    @objectstack-fleet
    ContributorAuthor

    Closing completed: the acceptance holds on main

    domain:cli seat (#6024) · session_01BmsuLyUeuG5CNpZFMH1jzS · 2026-10-09T03:37Z. Reviewed against the dev's report 6073744623, not its prose alone.

    Triage's acceptance (6068291990) holds, measured on origin/main fdfdd7e76. The build is from the workspace packages, not npm 17.7.0. The project is scaffolded by this checkout's create-objectstack, plus the four files of content/docs/getting-started/build-with-claude-code.mdx taken verbatim, and booted with os dev --ui under a real terminal.

    • The tutorial as written today: no Boot diagnostics block at all, on the first boot or on a restart, and 0 WARN records. At --log-level debug the whole live stream had 0 WARN and 0 ERROR. The bare blank template gives the same answer.
    • The card's own project (the tutorial's pre-declarative Resolve, a script action whose handler nothing registers): the block is exactly one record, the dead button. It prints first and highlighted, with its one-line fix (fix: add a body, or register a handler under the declared target), under the header 1 needs your attention. It is byte-identical on both boots, so no line appears on a restart only.
    • The four lines the maintainer named are gone or at info:
      • the [Analytics] bridge, the loopback OAuth notice and the sys_migration owner-bind record are INFO;
      • the false sys_migration failed insert does not occur ('Insert operation failed' gives 0 hits);
      • the dead button is the one highlighted actionable record.
    • NOT MEASURED: the stack-only-at-debug leg. No record in any of the 7 boots carried a stack, so there was nothing to withhold. PR feat(cli): Boot diagnostics noise budget, printer half: the line that needs the author first with its fix, stack traces only at debug #22236's unit pins hold that leg.
    • No other warning line appeared, so per the acceptance nothing here needs its own card.

    Delivered across: PR #22236 (the printer half, 11e6fc5f2e), #22154, #22099 (PR #22336), and the tutorial's declarative Resolve (PR #22204).

    Released: the claim 6073488552, a measurement with no file written. The empty branch claude/issue-22160-blank-template-acceptance at fdfdd7e76 carries no commit.

    Filed separately from this measurement: the os dev parent's MCP connect block interleaves with the serve child's ready banner (measured in 5 of 7 boots), which turns a PR #22236 note into a measured repro. It is a separate defect, filed on its own card.


    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

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:clienhancementNew feature or requestpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions