feat: ground Timmy chat answers in cited ledger records (#37) #78
Closed
rockachopa
wants to merge 0 commits from
timmy/37-grounded-chat-citations into main
pull from: timmy/37-grounded-chat-citations
merge into: stackchain:main
stackchain:main
stackchain:timmy/19-metrics-operator-report
stackchain:timmy/16-image-ingress-hardening
stackchain:timmy/40-security-rc-evidence
stackchain:timmy/27-dataset-card
stackchain:timmy/26-review-adjudication
stackchain:timmy/32-abstention-policy
stackchain:timmy/29-evaluation-harness
stackchain:timmy/35-portable-backup-versions
stackchain:timmy/24-training-contribution-consent
stackchain:fix/demo-caption-pixels
stackchain:timmy/36-photo-lifecycle-controls
stackchain:timmy/release-notes-grounded-chat
stackchain:timmy/21-escalation-regression
stackchain:timmy/34-explainable-pattern-summaries
stackchain:timmy/15-container-worker-receipts
stackchain:timmy/73-blank-first-ordering
stackchain:timmy/18-vision-corpus
stackchain:timmy/20-photo-dataflow-threat-model
stackchain:timmy/67-hard-stool-followup
stackchain:timmy/13-provisional-suggestion-state
stackchain:timmy/12-manual-fallback-draft-recovery
stackchain:timmy/11-mobile-capture-recovery
stackchain:free/hy3-timmy-16
stackchain:timmy/35-version-ledger-migrations
stackchain:timmy/41-release-observability-dashboard
stackchain:free/step-timmy-14
stackchain:timmy/21-escalation-regression-suite
stackchain:timmy/17-bounded-inference-queue
stackchain:timmy/58-strict-csp-runtime-config
stackchain:timmy/55-staging-deployment-tooling
stackchain:timmy/53-private-subpage-staging
stackchain:timmy/10-reproducible-smolvlm-bootstrap
stackchain:timmy/48-vomiting-phrase-hotfix
stackchain:timmy/48-server-safety-override
stackchain:timmy/47-sleek-hermes-agent
stackchain:timmy/9-product-boundary-decisions
stackchain:timmy/8-ci-gates
No Reviewers
Labels
Clear labels
area/backend
area/data
area/frontend
area/model
area/privacy
area/release
area/safety
blocked
human-gate
priority/P0
priority/P1
priority/P2
state:review
type/docs
type/epic
type/feature
type/ops
type/research
type/security
type/test
Application API and storage
Dataset and provenance
PWA and interaction design
Vision model and inference
Privacy and consent
Release engineering and distribution
Clinical safety boundary
Blocked on an explicit dependency or decision
Requires explicit human approval
Release-critical
High priority
Planned
Documentation and evidence
Roadmap epic
Product feature
Infrastructure and operations
Research or evaluation
Security hardening
Verification and quality gate
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: stackchain/timmy-talking-turd#78
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #37
Outcome
Timmy chat now has to show its work: an answer that states a count, a date, or a visible form cites the confirmed records behind it, and following a citation opens exactly that log. A question the journal cannot answer gets boundary copy instead of reassurance.
What changed
src/grounded-chat.js— new module owning the citation contract: intent routing (frequency / recency / pattern / privacy / unsupported / summary), the sparse-window refusal, and resolution of Hermes citations against the ledger it was given.app.js— local replies now come fromanswerFromLedger; Hermes replies pass throughresolveAgentReply; citation chips render under the bubble and open a single-record sheet ([data-chat-citation],[data-chat-record-sheet]).src/hermes-agent-service.js— each sanitized ledger record carries a positionalref(L1..Ln) and the prompt requires inline[entry:L<n>]citations for any journal fact. Refs stay positioned in the same order the browser sent, so the browser can resolve — and reject — them.scripts/record_release_demo.mjs— the recording now shows the grounded local answer with four citation chips, opens one cited record, shows the refusal, then a Hermes reply whose refs render as sources. Every claim is asserted in the browser; the agent route is flipped off/on so local mode is a real state, not narration.scripts/build_release.py— new on-camera caption gates and agrounded_chat_citationsgate;test:grounded-chatadded to the release check sequence.Acceptance criteria
Evidence
node --test tests/grounded-chat.test.js— 10/10 (each behaviour written failing first; the empty-reply default and theL99fabrication case were both caught by RED before implementation).npm test— 185/185 pass.npm run test:grounded-chat— PASS (real browser, synthetic logs, includes a Hermes reply citing a nonexistent record → labelled unverified, no citation rendered).npm run check:syntaxandnpm run check:dirty/check:diffclean.scripts/record_release_demo.mjsrecorded end-to-end (198s webm); OCR of frames confirms on-camera captions plus the visible "FROM YOUR LOG Oct 16 · T4 …" citation chips and the "4 confirmed logs" answer.Privacy / safety disposition
Notes
tests/staging-health.test.js("malformed and escaping base paths") failed once inside a loaded full-suite run and passed in isolation and on the baseline worktree; it is a 800ms spawn-budget flake, unrelated to this change.tests/release-demo.test.jsdemo-caption gate) is a hold-out check written after the recording change; it did not produce a RED cycle.Pull request closed