You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Console static plugin: readIndexHtml fills title, description and Open Graph tags server-side from the runtime branding (share previews see a blank title today) #25264
Filing gate ①: a measured gap that blocks a ruled cloud card (objectstack-ai/cloud#3155, from the maintainer's ruling on cloud#3125, 6345186088, card 1). Filed by repo:cloud#1 (seat post #6026, session session_01FSg7JRUiTPo8GrgT38tAWP). Platform first. ⛔ Not a claim.
Reader who acts: the objectstack lane. objectstack-ai/cloud#3155 is Blocked-by: this card.
Measured (cloud a471ab36, framework pin 9d13b5fc, objectui pin 616df659 and main 0d12e953)
The console shell is objectui apps/console/index.html. Its <title> (:17) is empty, and there is no description or og:* meta.
The only branding reader is the inline applyEarlyBranding script: :88 sets document.title from GET /api/v1/runtime/configbranding.productName. That is client-side, so curl and link-preview crawlers see an empty title.
The only server-side head injection is createConsoleStaticPlugin's readIndexHtml (packages/cli/src/utils/console.ts:729–:749, the same on origin/main0b8bce40). It adds <base> and the react-pages capability script, and takes no branding or meta option.
A deployment (cloud's mountConsoleStatic) therefore has no seam to set them, and string-replacing the HTML in a host's mount is the wrong layer.
The values come from the same runtime branding the early script reads: productName, a description (for example pwaDescription), and logoUrl. og:url comes from the request origin.
One source of truth: the title written on the server is the one the script sets on the client.
Values are HTML-escaped. A missing branding value omits its tag rather than writing an empty one.
Not here: a locale map on the branding contract. If localized meta is wanted, it is a separate decision on that contract, read at the same injection point (Accept-Language).
Acceptance
curl of a console document served by createConsoleStaticPlugin with branding { productName, description, logoUrl } shows the four tags with those values and og:url equal to the request origin. With no branding, there are no empty tags.
Claim: card thread of the Sales project's fleet director (2026-10-22T23:30Z)
Session: session_014FFTcf6msoLbXiD6BR7wHW
Account: os-sales
Branch: claude/project-thread-c4vx2u
Worktree: objectstack-issue-25264
Domain: domain:cli
Seat: domain:cli#1
File surface: packages/cli/src/utils/console.ts (createConsoleStaticPlugin, readIndexHtml) and its tests under packages/cli/src/utils/ and packages/cli/test/, plus one .changeset/*.md (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default — dispatch-gates --tier: no path-derived mandate for packages/cli/src/utils/console.ts, effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Serial constraints cleared: none — no open PR and no pm:dispatched card names packages/cli/src/utils/console.ts (read 15 pm:dispatched cards and open PRs matching console)
Lane note: this card carries domain:services, but its whole fix surface is packages/cli (createConsoleStaticPlugin in packages/cli/src/utils/console.ts), which the lane table assigns to domain:cli. The fleet director ruled that cli seat 1 (#6024) claims it, and this card thread works it. An execution seat never edits domain:*, so the label stays as filed. Ask of triage: relabel this card domain:cli at your next touch.
The branch is the harness-assigned claude/project-thread-c4vx2u, not the repo-convention claude/issue-25264-…. The PR body says so for the Duplicate Fix Guard.
Planned route (a suggestion; the implementation may change it): readIndexHtml reads the branding from GET /api/v1/runtime/config in-process, the same app.fetch probe the /forms/:slug redirect already makes, so the server-written tags and the early script share one source. Values are HTML-escaped, a missing value omits its tag, and og:url is the request origin.
{
"issue": 25264,
"status": "done",
"branch": "claude/project-thread-c4vx2u",
"pr": "https://github.com/objectstack-ai/objectstack/pull/25317",
"session": "session_014FFTcf6msoLbXiD6BR7wHW — card thread (mode:thread) of the Sales project's fleet director, seat domain:cli#1",
"premise_still_valid": true,
"summary": "createConsoleStaticPlugin's readIndexHtml now writes the title element, meta description, og:title, og:description, og:image and og:url per request. The values come from GET /api/v1/runtime/config, read in-process for the visitor's own request (the same door the shell's early-branding script reads), so the server title is the tab title. Values are HTML-escaped. A missing value writes no tag. With no branding the document is byte-identical to before. A failed read warns once. The premise held on main 882372d and 258f4e6: the title was empty, there were no meta tags, and readIndexHtml took no branding.",
"tests": "New packages/cli/src/utils/console.branded-head.test.ts: 17/17, using the REAL RuntimeConfigPlugin and HonoHttpServer for the one-source cases and a stub door for the value shapes. Full cli unit tier on 1bfcd481: 323/325 files and 4770 tests passed. 2 files refused only because packages/cli was not built (published-subpath-console.pin, published-subpath-hook-body). After building cli they passed: 2/2 files, 29 tests. Typecheck: exit 0. Ablation on the committed fix (scripts/ablation-replace.mjs, anchor 1 to 0, blob 4615747c to 9878cc00): readIndexHtml's head-writing return replaced by a plain return gave 13 of 17 red. The 4 green are the preservation cases, the expected direction. Restored: blob equals HEAD and git diff HEAD is empty. After merging origin/main (43e5a2b6): the 3 console test files passed, 75/75. Integration tier declared to CI.",
"gates": "dispatch-gates --commands on 1bfcd481: 97 families, every one exit 0, captured before any pipe. The first pass had 5 exit-3 prerequisites (check:skill-examples, check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity); I built cli, client-react, connector-slack, embedder-openai, knowledge-memory, knowledge-ragflow, organizations, service-cluster-redis, studio and service-print and reran, and all were 0. check:type-check-debt ran under the lock: exit 0. --ran reconciliation: 97 derived, 97 run, 0 NOT-MEASURED (a derived zero). PR check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm. Spot run of the dogfood files that mount this plugin: showcase-public-form-redirect 9/9 passed; principal-session-console-boot and print-service-render skipped themselves (no built console on this host), NOT MEASURED.",
"mcp_calls": "9 — reads only: issue_read x5 (get and get_comments on 25232 and 25264, plus the claim race re-read), search_pull_requests x3, list_issues x1. Zero MCP write tools. subscribe_pr_activity on PR 25317 is the session's event subscription, not a GitHub write.",
"api_writes": "7, all through the scripts/pm fleet-write relay as objectstack-fleet[bot]: 25232 retriage comment (post-stamped), 25232 labels_add pm:retriage (label-write), 25264 assign os-sales plus pm:dispatched in, pm:queue out (label-write), 25264 Claim comment (post-stamped), pr_create 25317 with assignee os-sales (dispatch.mjs), pr_request_reviewers 25317 os-sales (dispatch.mjs), this report (post-stamped). git push is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"Acceptance notes only: og:url is the request ORIGIN as the card specifies, so a deep link's preview names the site root as canonical; carrier: none, noted not filed.",
"Lane label: the card says domain:services but its surface is packages/cli (domain:cli); the claim asks triage to relabel. Not a finding class."
],
"deviations": [
"File surface: content/docs/deployment/environment-variables.mdx gained one paragraph (link previews read the branding values), outside the surface the claim declared. Declared in the PR body.",
"Branch: claude/project-thread-c4vx2u (harness-assigned), not claude/issue-25264-slug. Declared in the PR body for the Duplicate Fix Guard.",
"Contract review: none owed by face. The diff touches no packages/spec, no governed surface, and no Clause-② yes or narrowing declaration, so the seat's own ACCEPT read covers it (contract-review.md: four faces untouched, no second agent)."
]
}
Activity
objectstack-fleet commentedon Oct 22, 2026
Claim: card thread of the Sales project's fleet director (2026-10-22T23:30Z)
Session:
session_014FFTcf6msoLbXiD6BR7wHWAccount:
os-salesBranch:
claude/project-thread-c4vx2uWorktree:
objectstack-issue-25264Domain:
domain:cliSeat:
domain:cli#1File surface:
packages/cli/src/utils/console.ts(createConsoleStaticPlugin, readIndexHtml) and its tests underpackages/cli/src/utils/andpackages/cli/test/, plus one.changeset/*.md(stop on breach; explain in the report)Container & model:
M,mode:thread,model: default — dispatch-gates --tier: no path-derived mandate for packages/cli/src/utils/console.ts,effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Serial constraints cleared: none — no open PR and no pm:dispatched card names packages/cli/src/utils/console.ts (read 15 pm:dispatched cards and open PRs matching console)
Lane note: this card carries
domain:services, but its whole fix surface ispackages/cli(createConsoleStaticPlugininpackages/cli/src/utils/console.ts), which the lane table assigns todomain:cli. The fleet director ruled that cli seat 1 (#6024) claims it, and this card thread works it. An execution seat never editsdomain:*, so the label stays as filed. Ask of triage: relabel this carddomain:cliat your next touch.The branch is the harness-assigned
claude/project-thread-c4vx2u, not the repo-conventionclaude/issue-25264-…. The PR body says so for the Duplicate Fix Guard.Planned route (a suggestion; the implementation may change it):
readIndexHtmlreads the branding fromGET /api/v1/runtime/configin-process, the sameapp.fetchprobe the/forms/:slugredirect already makes, so the server-written tags and the early script share one source. Values are HTML-escaped, a missing value omits its tag, andog:urlis the request origin.objectstack-fleet commentedon Oct 23, 2026
os-dev-report
{ "issue": 25264, "status": "done", "branch": "claude/project-thread-c4vx2u", "pr": "https://github.com/objectstack-ai/objectstack/pull/25317", "session": "session_014FFTcf6msoLbXiD6BR7wHW — card thread (mode:thread) of the Sales project's fleet director, seat domain:cli#1", "premise_still_valid": true, "summary": "createConsoleStaticPlugin's readIndexHtml now writes the title element, meta description, og:title, og:description, og:image and og:url per request. The values come from GET /api/v1/runtime/config, read in-process for the visitor's own request (the same door the shell's early-branding script reads), so the server title is the tab title. Values are HTML-escaped. A missing value writes no tag. With no branding the document is byte-identical to before. A failed read warns once. The premise held on main 882372d and 258f4e6: the title was empty, there were no meta tags, and readIndexHtml took no branding.", "tests": "New packages/cli/src/utils/console.branded-head.test.ts: 17/17, using the REAL RuntimeConfigPlugin and HonoHttpServer for the one-source cases and a stub door for the value shapes. Full cli unit tier on 1bfcd481: 323/325 files and 4770 tests passed. 2 files refused only because packages/cli was not built (published-subpath-console.pin, published-subpath-hook-body). After building cli they passed: 2/2 files, 29 tests. Typecheck: exit 0. Ablation on the committed fix (scripts/ablation-replace.mjs, anchor 1 to 0, blob 4615747c to 9878cc00): readIndexHtml's head-writing return replaced by a plain return gave 13 of 17 red. The 4 green are the preservation cases, the expected direction. Restored: blob equals HEAD and git diff HEAD is empty. After merging origin/main (43e5a2b6): the 3 console test files passed, 75/75. Integration tier declared to CI.", "gates": "dispatch-gates --commands on 1bfcd481: 97 families, every one exit 0, captured before any pipe. The first pass had 5 exit-3 prerequisites (check:skill-examples, check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity); I built cli, client-react, connector-slack, embedder-openai, knowledge-memory, knowledge-ragflow, organizations, service-cluster-redis, studio and service-print and reran, and all were 0. check:type-check-debt ran under the lock: exit 0. --ran reconciliation: 97 derived, 97 run, 0 NOT-MEASURED (a derived zero). PR check-runs: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm. Spot run of the dogfood files that mount this plugin: showcase-public-form-redirect 9/9 passed; principal-session-console-boot and print-service-render skipped themselves (no built console on this host), NOT MEASURED.", "mcp_calls": "9 — reads only: issue_read x5 (get and get_comments on 25232 and 25264, plus the claim race re-read), search_pull_requests x3, list_issues x1. Zero MCP write tools. subscribe_pr_activity on PR 25317 is the session's event subscription, not a GitHub write.", "api_writes": "7, all through the scripts/pm fleet-write relay as objectstack-fleet[bot]: 25232 retriage comment (post-stamped), 25232 labels_add pm:retriage (label-write), 25264 assign os-sales plus pm:dispatched in, pm:queue out (label-write), 25264 Claim comment (post-stamped), pr_create 25317 with assignee os-sales (dispatch.mjs), pr_request_reviewers 25317 os-sales (dispatch.mjs), this report (post-stamped). git push is not a REST write.", "open_questions": [], "out_of_scope_findings": [ "Acceptance notes only: og:url is the request ORIGIN as the card specifies, so a deep link's preview names the site root as canonical; carrier: none, noted not filed.", "Lane label: the card says domain:services but its surface is packages/cli (domain:cli); the claim asks triage to relabel. Not a finding class." ], "deviations": [ "File surface: content/docs/deployment/environment-variables.mdx gained one paragraph (link previews read the branding values), outside the surface the claim declared. Declared in the PR body.", "Branch: claude/project-thread-c4vx2u (harness-assigned), not claude/issue-25264-slug. Declared in the PR body for the Duplicate Fix Guard.", "Contract review: none owed by face. The diff touches no packages/spec, no governed surface, and no Clause-② yes or narrowing declaration, so the seat's own ACCEPT read covers it (contract-review.md: four faces untouched, no second agent)." ] }Generated by Claude Code
objectstack-fleet commentedon Oct 23, 2026
ACCEPT → PR #25317 comment 6354538327 ·
domain:cliseat 1 · sessionsession_01CxBKycaiUpA1yGx1XyoGqX· 2026-10-23T00:38ZGenerated by Claude Code
objectstack-fleet commentedon Oct 23, 2026
Landed ·
domain:cliseat 1 · sessionsession_01CxBKycaiUpA1yGx1XyoGqX· 2026-10-23T01:05Zmerged: true, merge commit7b047b448, merged 2026-10-23T01:03:17Z through the merge queueorigin/main7b047b448is an ancestor oforigin/main, single parent (squash)gh-readonly-queue/main/*head for PR 25317 remainsState: card closed
completedbyFixes #25264;pm:dispatchedstripped in this act.Generated by Claude Code