Skip to content

feat(frontend): render the not-advice caveat on model output surfaces - #3

Closed
OmerHarmankayaC wants to merge 1 commit into
Yigtwxx:mainfrom
OmerHarmankayaC:feat/model-output-disclaimer
Closed

OmerHarmankayaC wants to merge 1 commit into
Yigtwxx:mainfrom
OmerHarmankayaC:feat/model-output-disclaimer

Conversation

@OmerHarmankayaC

@OmerHarmankayaC OmerHarmankayaC commented Aug 19, 2026

Copy link
Copy Markdown

What changed

Adds components/ui/ModelOutputNotice, a one-line caveat rendered by the
client, and attaches it to the three surfaces that carry model output:

Surface Placement
analysis/ReportView under the report body, above the rule
OraclePanel (news verdict) under the coverage line
OracleChatPage under the composer, beside the mode blurb

landing/LandingFooter gets a product-level line instead — it renders no model
output of its own, so the same sentence would not fit.

Why

The prompts already instruct the model to describe its own answers as research
commentary. prompts/chat/system.md, prompts/analysis/stage2_report.md and
prompts/news/system_sentiment.md each carry the line, and
stage2_report.md:114 is explicit:

Close with one line noting this is research commentary, not investment advice.

An instruction is not a guarantee. The three reports committed at
backend/data/analysis_reports.json are the evidence — two of the three do
not contain it
:

Report Length Carries the line
daily 6,606 chars no
weekly 7,212 chars yes
monthly 2,995 chars no

So on a stored daily report the screen today carries no caveat at all. A
fallback provider, a shorter model, or a truncated response reproduces that
outcome anywhere the chain runs. Rendering the line from the client makes it
independent of what the model chose to say.

Before this change the only unconditional caveat in the client was the
provenance footer on the ownership board (OwnershipPage.tsx:203). This follows
that footer's styling rather than introducing a second visual language for the
same idea.

Why not a band in ClientShell

That was the first thing I tried. ClientShell wraps its children in
<main className="flex-1 min-h-0 overflow-hidden"> — a fixed-height,
non-scrolling shell where each route owns its own scroll. A permanent row there
costs height on all thirteen routes, including /heatmap and /live, which
render no model output to caveat. Attaching per surface keeps the cost where the
output is.

Verification

All four gates run locally, against Node 22:

Gate Result
npm run lint clean — only the pre-existing no-img-element warnings in files this PR does not touch
npm run typecheck clean
npm test 15 files, 222 tests passed
npm run build succeeded

Rendering checked by hand against a running stack (backend on a local port,
USE_AI=false, no LLM provider configured):

  • Analysis report — opened the stored daily report; the notice renders
    under the Risk Disclosures section. This is the case the table above
    describes, so it is also the before/after: that report ends without a caveat
    of its own.
  • Chat — the notice sits under the composer. It is deliberately not tied to
    a response, so it is present before the first message and with no provider
    reachable.
  • Landing footer — renders at the foot of the marketing page.

The news verdict panel (OraclePanel) is the one surface I could not exercise:
it needs a completed news analysis, which needs a reachable LLM provider. The
placement there mirrors the report's and is a static child of the same
always-rendered block as the coverage line.

No environment variable is added or changed. No API surface is touched.

chat landing market_inteligence

The prompts already instruct the model to describe its own answers as research
commentary — prompts/chat/system.md, prompts/analysis/stage2_report.md and
prompts/news/system_sentiment.md each carry the line. An instruction is not a
guarantee: a model that omits it, or a fallback provider that phrases it away,
leaves the screen with no caveat at all. Before this change the only caveat the
client rendered unconditionally was the provenance footer on the ownership
board.

ModelOutputNotice renders it from the client, independent of what the model
chose to say, and attaches to the three surfaces that carry model output: the
analysis report, the news verdict panel and the chat composer. Its styling
follows the footer already in OwnershipPage rather than introducing a new one.

Deliberately not a band in ClientShell. That shell is a fixed-height,
non-scrolling layout, so a permanent row would cost height on all thirteen
routes — including the heatmap and the live feed, which render no model output
to caveat.

The landing footer carries no model output either, so it gets a product-level
line rather than the same component.
@Yigtwxx Yigtwxx closed this Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants