Skip to content

fix(cli,rest)!: os package install takes -u/--url and -t/--token; the /meta permission refusal is localized - #30792

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-nhel89
Nov 6, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/project-thread-nhel89

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

domain:server#4 · os-elon-musk · session_016WV4cxrNurGFU9PsE6NwNT

Fixes #30126

Clause-②: yes (narrowing)
Metadata-protocol: none

维护者速读

  • 改了什么:os package install 的服务器参数从 -r/--runtime 改名为 -u/--url(无别名),并新增 -t/--token,与 os package export 等命令写法一致;打开无权访问的应用、仪表盘、列表视图时,403 拒绝文案改为按调用者语言输出(中文控制台显示「您没有执行此操作的权限,如需访问请联系管理员。」)。
  • 为什么改:Console and CLI polish from the real-user walkthrough #30126 第 13 行(裁决 A:统一服务器与凭据写法)和第 12 行(Setup 应用拒绝文案是英文,还带着 com.objectstack.setup 这种 API 名)。
  • 风险与回滚:破坏性变更,只影响传 -r/--runtime 的脚本,会被当作未知参数拒绝;只设 OS_RUNTIME_URL 的脚本不受影响。拒绝文案不再含条目名,两条 meta apps by-name route: answer an explicit permission-denied envelope for an unauthorized session, instead of being indistinguishable from "not published" (backend half of objectui#4252) #8013 断言随之改写,请在合约评审中确认。回滚即撤本 PR。
  • 先看:packages/cli/src/commands/package/install.ts 的 url / token 参数;packages/rest/src/meta-item-read-gate.ts 的 permissionDeniedMessage。
  • 两分钟验证:pnpm --filter @objectstack/cli exec vitest run test/package-install-url-token-flags.test.ts(8 条全绿);pnpm --filter @objectstack/rest exec vitest run src/meta-permission-refusal-locale.test.ts(9 条全绿)。
  • 需要你做的:标题带 !,入队前需要你对本 PR 点头,并完成合约评审(收窄面)。落地由席位负责。

What changes

  • Row 13, @objectstack/cli (BREAKING). os package install names its server -u, --url (env OS_RUNTIME_URL, default http://localhost:3000, both unchanged) in place of -r, --runtime, with no alias. A script that passes -r or --runtime is refused as an unknown flag. A new -t, --token (env OS_RUNTIME_TOKEN) sends a token the target runtime issued as Authorization: Bearer on the install request, with no sign-in round trip; --email / --password still work. Passing a token together with --email / --password is refused before any request. These are the spellings os package export and about twenty other server-talking commands use. packages/cli has no shared flag helper to reuse, so the two flags are declared inline with the same shape as export's.
  • Docs and templates. content/docs/deployment/cli.mdx (example, flag table, credential paragraph), content/docs/deployment/publish-and-preview.mdx, packages/cli/README.md, and the create-objectstack scaffold's AGENTS.md and blank README.md now say --url. The scaffold's two lines were outside the claimed surface but would have become false, so they are fixed here, with a create-objectstack patch in the changeset.
  • Row 12, @objectstack/rest. The /meta read gate's three 403 PERMISSION_DENIED refusals (app, dashboard, list view) rendered fixed English sentences naming the item's API name. They now render the operation catalog's permission_denied (renderOperationMessage, @objectstack/spec/system) in the caller's ExecutionContext.locale. That is the catalog and key plugin-security's object and capability refusals already use. The REST door also hands in the errors.* override lookup, so a deployment's errors.permission_denied translation applies here as it does there. The runtime dispatcher calls the same gate and gets the built-in catalog in the caller's locale; it hands no override lookup, because packages/runtime is outside this claim. Status, code and envelope are unchanged.

Tests

  • packages/cli/test/package-install-url-token-flags.test.ts (new, 8): --url / -u reach the request URL; --runtime and -r are refused before any request; --token, -t and OS_RUNTIME_TOKEN send Authorization: Bearer; no token sends no header; token plus email/password is refused with exit 1 before any request.
  • Sixteen existing CLI test files pass --url where they passed --runtime, including seven integration files that spawn the CLI.
  • packages/rest/src/meta-permission-refusal-locale.test.ts (new, 9): a zh-CN caller reads the Chinese sentence on all three refusals; a caller with no locale reads the English one, which carries no API name; a deployment override wins; a lookup that echoes the key is no override; a lookup that throws keeps the built-in sentence and the 403.
  • meta-app-publish-gate.test.ts and meta-item-absent-404.test.ts: the two meta apps by-name route: answer an explicit permission-denied envelope for an unauthorized session, instead of being indistinguishable from "not published" (backend half of objectui#4252) #8013 assertions message toContain('finance') now assert the catalog sentence. Status and code assertions are unchanged.
  • Ablations through scripts/ablation-replace.mjs, each restored with blob == HEAD: the token/email refusal guard disabled → 1 of 8 failed; the locale dropped from renderOperationMessage → 6 of 9 failed.

Acceptance notes

  • The refusal no longer names the item. The permission_denied key takes no placeholders on purpose (operation-message.ts), and the name the gate had was the API name (com.objectstack.setup), which is what row 12 reported. Keeping a name would need a new catalog key in packages/spec, which this claim forbids. The Console's "You don't have access" page shows the server sentence (ui/packages/app-shell CHANGELOG notes it named the item); it now shows the localized sentence. This is the point for the contract review to confirm.
  • createMetaItemReadGate's name parameter is now read by no gate. It is kept (as _name) so neither transport's call changes.
  • Row 9: ruling A, no change. Row 16: ruling A, filed by the seat as its own card.

Out of scope

  • skills/objectstack-platform/references/operations.md:106 still says --runtime for os package install. The seat files it as a skills-lane card, serial behind this PR.

Verification

Derived gates and suites
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 6a2119cc: 97 commands, each run with its exit code captured before any pipe. 95 exit 0 on the first pass; two exit 3 (prerequisite) and exit 0 after their named builds: check:skill-examples (after building @objectstack/client-react: 283 prose examples type-check) and check:dual-build-cjs-loads (after building the six packages it named).
  • dispatch-gates --ran: 97 derived, 97 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. Changed lines: 470 (+421 / -49, 30 files).
  • check-adr-0087-registration: one declared-breaking changeset, disposition not-required (no-migration-prescription).
  • pnpm --filter @objectstack/cli typecheck, pnpm --filter @objectstack/rest typecheck: exit 0.
  • @objectstack/cli unit layer: 388 files / 5415 tests passed. The seven touched integration files: 7 files / 77 tests passed.
  • @objectstack/rest full suite: 396 files. The first run failed the two meta apps by-name route: answer an explicit permission-denied envelope for an unauthorized session, instead of being indistinguishable from "not published" (backend half of objectui#4252) #8013 assertions above; after updating them, those two files pass 53/53.
  • @objectstack/runtime read-gate parity, app package-id and dispatcher tests: 3 files / 381 tests passed.
  • Dogfood (title carries !): pnpm --filter @objectstack/dogfood test on 6a2119cc, 422 files passed / 3 skipped, 3527 tests passed / 41 skipped.
  • Merged origin/main before the gate sweep; the incoming commits touch neither packages/cli, packages/rest nor packages/spec.

Generated by Claude Code

-r/--runtime is retired with no alias; --url keeps OS_RUNTIME_URL, and
--token (OS_RUNTIME_TOKEN) sends a bearer token instead of signing in
with --email/--password. Docs and scaffold templates follow.

Claude-Session: https://claude.ai/code/session_016WV4cxrNurGFU9PsE6NwNT
Co-authored-by: Claude <noreply@anthropic.com>
…'s locale

An app, dashboard or list view the caller may not open is refused with the
operation catalog's permission_denied sentence in ExecutionContext.locale,
as plugin-security's refusals are; REST hands in the errors.* override
lookup. Adds the changeset for both halves of this change.

Claude-Session: https://claude.ai/code/session_016WV4cxrNurGFU9PsE6NwNT
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface labels Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/cli, create-objectstack, objectstack-blank, @objectstack/rest, touching 19 documentable anchor(s). ⚠️ 3 changed file(s) yielded no anchor (packages/cli/README.md, packages/create-objectstack/src/templates/AGENTS.md, packages/create-objectstack/src/templates/blank/README.md), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

23 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: node scripts/docs-audit/affected-docs.mjs --json 612468cc20e4d4adeba047d2416126ec9a8cc077.

⛔ 9 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails.

What this run could not see
  • 3 changed file(s) yielded no anchor (packages/cli/README.md, packages/create-objectstack/src/templates/AGENTS.md, packages/create-objectstack/src/templates/blank/README.md) — pages documenting those are invisible to this run
  • 2 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 63 of 221 client-bound route-ledger rows — the other 158 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 158: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 103 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 51 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 612468cc20e4d4adeba047d2416126ec9a8cc077 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from e7a773d00ccaef5e6816046e132a7db30420efa4 — the merge of head 6a2119cc920c077d610923e9fa7dceece3005f50 into base 612468cc20e4d4adeba047d2416126ec9a8cc077, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin e7a773d00ccaef5e6816046e132a7db30420efa4 && git checkout e7a773d00ccaef5e6816046e132a7db30420efa4
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 612468cc20e4d4adeba047d2416126ec9a8cc077 6a2119cc920c077d610923e9fa7dceece3005f50 && git checkout -B drift-repro 612468cc20e4d4adeba047d2416126ec9a8cc077 && git merge --no-ff 6a2119cc920c077d610923e9fa7dceece3005f50

node scripts/docs-audit/affected-docs.mjs --json 612468cc20e4d4adeba047d2416126ec9a8cc077

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 612468cc20e4d4adeba047d2416126ec9a8cc077 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4

Contract review for card #30126 (rows 12, 13) · narrowing face (Clause-②: yes (narrowing)) · read-only reviewer at the contract-review tier, brief per record-recognisers --brief-template --face narrowing · 2026-11-06T03:29Z

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 6a2119cc920c077d610923e9fa7dceece3005f50
Local-runs: none
Scope: packages/cli/src/commands/package/install.ts, packages/cli/test/package-install-.test.ts (17 files), packages/cli/test/exit-signal.pin.test.ts, packages/cli/test/package-export.test.ts, packages/create-objectstack/src/templates/AGENTS.md, packages/create-objectstack/src/templates/blank/README.md, packages/rest/src/meta-item-read-gate.ts, packages/rest/src/rest-server.ts, packages/rest/src/meta-.test.ts (4 files) + packages/spec/src/system/operation-message.ts, packages/spec/src/kernel/execution-context.zod.ts, packages/plugins/plugin-security/src/security-plugin-authz-middleware.ts, packages/runtime/src/domains/meta.ts, packages/runtime/src/security/resolve-execution-context.ts, packages/cloud-connection/src/marketplace-install-local-plugin.ts, packages/cli/src/commands/package/export.ts, packages/cli/src/commands/login.ts, packages/cli/src/commands/package/publish.ts, ui/packages/data-objectstack/src/index.ts, ui/packages/app-shell/src/views/DashboardView.tsx, skills/objectstack-platform/references/operations.md, scripts/check-adr-0087-registration.mjs (prose read, not reviewed: the changeset, content/docs/deployment/cli.mdx, content/docs/deployment/publish-and-preview.mdx, packages/cli/README.md)

① Derived judgments

  • os package install drops -r/--runtime with no alias — right (ruling 6674432613, row 13 A). The oclif parser refuses the old spelling before any request is sent. Both --runtime and -r are pinned with zero requests sent.
  • -u/--url and -t/--token are added — right. They use the same letters as export.ts and login.ts. The token rides as Authorization: Bearer with no sign-in round trip. A token together with --email/--password is refused with exit 1 before any request.
  • Env vars — right. OS_RUNTIME_URL is unchanged (os login -u reads the same one). The new OS_RUNTIME_TOKEN follows install's OS_RUNTIME_* family and Prime Directive 9. OS_TOKEN and OS_CLOUD_API_KEY are correctly not reused, because a cloud token must never be sent to a runtime.
  • The token is enforced at the consumer. marketplace-install-local-plugin.ts resolves the caller through resolveAuthzContext, which admits an osk_ key as Bearer and judges manage_metadata.
  • Row 12 — right. The app refusal and the dashboard/view audience refusal now render the spec catalog's permission_denied in ExecutionContext.locale. Status 403, code PERMISSION_DENIED, reason and the envelope keys are unchanged. Overrides go through resolveMessageTranslator, with the same fallback and catch discipline as plugin-security's userFacingDenialMessage.
  • The sentence names no item — right, by the spec's own design. operation-message.ts declares that permission_denied takes no placeholders, so that no API name reaches a person. The Console classifies the denial by code and only displays message.
  • Exported surfaces — right. createMetaItemReadGate keeps its signature for both transports. resolveMessageTranslator? and MetaReadGateMessageTranslator are additive and optional.
  • Residual callers: on this head, no code, script, workflow, test or template still passes -r/--runtime to os package install.

② Semver level

The changeset names @objectstack/cli, @objectstack/rest and create-objectstack, all at patch. That is right for Metadata-protocol: none and a non-protocol breaking change. Both declarations are line-initial and identical in the PR body and the changeset. The changeset carries the BREAKING banner, the FROM → TO line (-r/--runtime <url> → -u/--url <url>) and exactly one ADR-0087 marker, not-required (no-migration-prescription). Check Changeset is green. The title is fix(cli,rest)!:. The create-objectstack bump is owed because the two templates ship in that package. Matches.

③ Boundary flags

  1. Row 12 no longer names the item — acceptable, and it must not change. Keeping the name would need a second catalog (Prime Directive 12) or a new spec key, which the claim forbids. The sibling refusals name nothing either.
  2. The runtime dispatcher door gets the built-in catalog but no errors.* override — acceptable here. packages/runtime/** was barred by the claim. This is a should-fix, carried to a follow-up card.
  3. The create-objectstack templates were fixed outside the claimed surface — acceptable. Left alone, the scaffold would teach a refused flag (Prime Directive 10). The patch is present, and the seat amends the claim.
  4. The skills line is left out, as skills: operations.md still names --runtime for os package install after #30126 row 13 renames it to -u/--url #30772 — acceptable. It is Tier H. skills: operations.md still names --runtime for os package install after #30126 row 13 renames it to -u/--url #30772 must land before the next release.
  5. open_questions: none.

④ Design judgment

The narrowing. It takes away exactly the declared -r, --runtime and nothing else. The value, the default and the env var survive. The replacement is the spelling about 20 sibling commands already use. Row 12 removes no capability: it makes the spec's own refusal real on this gate. "Localize" is met on all three refusals, with zh-CN, English fallback, override and a throwing lookup each pinned.

Attempts to break it:

  • A token with --email/--password is refused.
  • OS_RUNTIME_EMAIL/OS_RUNTIME_PASSWORD exported in the shell, plus --token, is also refused, but the refusal names only OS_RUNTIME_TOKEN. This is deliberate (one credential per call) and documented in cli.mdx. The wording is a should-fix.
  • A password with no email and no token still falls through unauthenticated, as on main. Not this PR's.
  • The install-local 401 still names both credential forms.

Findings: none must-fix. Should-fix, all as follow-ups:

  • (a) packages/runtime/src/domains/meta.ts should hand resolveMessageTranslator, so a deployment's errors.permission_denied override applies on the dispatcher door too.
  • (b) The token-conflict refusal at install.ts:191 should say that OS_RUNTIME_EMAIL/OS_RUNTIME_PASSWORD count as --email/--password.
  • (c) ui prose residues: a stale -r in a doc comment in MarketplacePackagePage.offlineLocalMenu-11627.test.tsx:84, and the old refusal sentence quoted in ui/packages/data-objectstack/README.md:913 and src/index.ts:1167.
  • (d) skills: operations.md still names --runtime for os package install after #30126 row 13 renames it to -u/--url #30772 lands before the next release.

Check-runs at review time: no failure. Several jobs were still in progress; Check Changeset and Governed Surface Queue Guard were green.

Implemented-by: claude/project-thread-nhel89
Reviewed-by: session_016WV4czvZykUqhYxYXSSDt4

VERDICT: PASS

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4

维护者速读

  1. 改了什么:os package install 指定服务器的参数从 -r/--runtime 改成 -u/--url,和其他约 20 个命令一致;同时新增 -t/--token,可直接用 API key 安装。旧写法立即退役,不留别名(破坏性)。另外,没有权限打开 Setup 应用或看板/视图时,拒绝文字改用规范目录里的 permission_denied,按调用者的语言显示。
  2. 为什么改:Console and CLI polish from the real-user walkthrough #30126 第 13 行、第 12 行,按你的裁定 A(记录 6674432613)。
  3. 风险:中低。用 -r 或 --runtime 的脚本会直接报「未知参数」,迁移只需换一个参数,changeset 写了 FROM → TO。拒绝的状态码、错误码和响应结构都不变,句子里不再出现应用的 API 名。
  4. 先看:packages/cli/src/commands/package/install.ts 的 flags;packages/rest/src/meta-item-read-gate.ts 两处拒绝。
  5. 两分钟验证:pnpm --filter @objectstack/cli exec vitest run test/package-install-url-token-flags.test.ts。
  6. 需要你做的:这是破坏性改动,请在席位线程的决策卡上点头。契约复核 PASS 见评论 6676098596(Head-sha 6a2119cc)。你同意后由席位入队落地。不属 Tier H,470 行 ≤ 3000。

席位意见:ACCEPT(#30126 第 12、13 行)。

席位核对

Head-sha: 6a2119cc920c077d610923e9fa7dceece3005f50 · read 2026-11-06T03:38Z

Item Reading
Shape Draft → main; Fixes #30126 (rows 8 and 15 landed in PR #30688; row 9 A needs no change; row 16 A is #30771). 30 files, +421/−49. Title fix(cli,rest)!:. ⛔ packages/spec/**, packages/runtime/**, ui/**, skills/**.
Seat diff read install.ts declares url (-u, OS_RUNTIME_URL) and token (-t, OS_RUNTIME_TOKEN). runtime and -r are gone, with no alias. A token plus --email/--password is refused before any request. The REST read gate's app refusal and audience refusal render permission_denied in ctx.locale through resolveMessageTranslator, falling back to the built-in catalog; the status, code and envelope are unchanged. Docs, the CLI README and the create-objectstack templates say --url.
Evidence New flag pins (both retired spellings refused with zero requests sent; token as Bearer; conflict refused). Locale pins (zh-CN, English fallback, override, a throwing lookup). cli unit 5415, the 7 touched integration files (77), the rest suite and runtime parity (381) pass; typechecks 0; dispatch-gates 97/97; dogfood 422 files / 3527 tests (os-dev-report 6675927362). Contract review PASS 6676098596, no must-fix.
Gates (check-runs on this head) 52 completed, 0 failed. mergeable_state clean.
Accepted deviations The create-objectstack AGENTS.md and blank/README.md, with 'create-objectstack': patch (amendment, so the scaffold does not teach a refused flag).
Out of scope skills/objectstack-platform/references/operations.md:106 → #30772 (Tier H, lands before the next release). The review's should-fix items → #30797 (runtime-door override lookup, token-conflict wording, ui prose residues). Skills-docs: #30772.
Semver @objectstack/cli, @objectstack/rest, create-objectstack: patch. Clause-②: yes (narrowing), Metadata-protocol: none, BREAKING banner with FROM → TO, ADR-0087 not-required (no-migration-prescription).
Landing Not governed (check-governed-merges --pr 30792: NOT governed), 470 lines ≤ 3000, BREAKING. ⛔ Not queued until the maintainer gives the per-PR word. Then the seat lands it: pr_ready + automerge_enable on this head, or a re-review if the head moves.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4

Maintainer's per-PR word (BREAKING) · 2026-11-06T03:50Z

Elon: 「同意」, in the #30126 card thread, 2026-11-06T03:50:14Z, for this PR at head 6a2119cc (the -r/--runtime → -u/--url rename). The seat lands this head now: pr_ready + automerge_enable.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 6, 2026 03:51
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 6, 2026 03:51
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit 2fbddd4 Nov 6, 2026
53 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-nhel89 branch November 6, 2026 04:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling Fix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Console and CLI polish from the real-user walkthrough

2 participants