fix: escalate the symptom phrasing people actually use, and never clear a reported symptom (#21) #77
Closed
rockachopa
wants to merge 0 commits from
timmy/21-escalation-regression into main
pull from: timmy/21-escalation-regression
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/37-grounded-chat-citations
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#77
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 #21
Outcome
Deterministic escalation now fires for the phrasing people actually use, and no reported
symptom can be silently cleared on the way to the check.
What the expanded suite found
The detector only matched a narrow set of literal phrases. Probing real clinical wording
against
mainshowed 18 of 18 checked phrasings missing, including:There is blood when I wipe,bleeding from my back passage,blood mixed in my pooI have tarry stools,my stool looks like tar,my poop is very dark redmy temperature is 103,I have a high temperatureI have severe pain in my belly,the pain in my stomach is severeI am not passing any gas,I have not passed gas all dayThose turns reached the Hermes provider instead of the fixed medical guidance.
Acceptance criteria
near-miss wording that must stay quiet: a paper cut, blood pressure, ink on paper, black
beans, black pants, dark red wine, "the road looks like tar", a 98.6/37 temperature,
feverfew, severe knee or back pain, mild stomach pain, "I passed gas this morning",
"I have not passed my driving test", "the car has no gas".
mergeVisualSuggestionstill movesonly form and colour; a schema-valid reply carrying
symptoms,urgent,diagnosis, or areplacement
warningcannot reach the user.confidence,observations, and the warningremain Timmy's own contract.
flag produces byte-identical copy, each flag phrase is intercepted at the gateway with
safetyOverride, and a provider that is missing, throwing, or insisting "no need to see adoctor" never changes the reply the user sees.
Also fixed
detectUrgentFlagsread only the literal booleantrue, so a symptom reported as1,"yes", or"true"was read as not reported — a silently cleared symptom, the onedirection this boundary may never fail in. The gateway ledger sanitizer had the same strict
check, which could clear a browser-supplied ledger symptom before the escalation check.
Both now share
isReportedSymptom; only an explicit clear (false, 0, "no", blank, absent)stays quiet.
Evidence
tests/escalation-regression.test.js(16 tests), registered in the default unit gate andpinned in
tests/ci-workflow.test.js.truthy-symptom tests were each observed failing before implementation. The five boundary and
determinism tests (
tests 12-16) passed on first write and are reported as hold-out pins,not as RED cycles.
npm test173/173 in 9 consecutive full runs;npm run check:syntax,npm run check:diff,python3 tests/staging-deploy.test.py -v(20 tests), and all ten browser acceptance scripts(
test:ui,test:photo,test:mobile-capture,test:sleek,test:manual-fallback,test:provisional,test:followup,test:vision-refusal,test:worker-readiness,test:pattern-summary) pass.the same turn; the test name was not captured and it did not reproduce in 9 subsequent runs.
Demonstration path (updated, not asserted on paper)
scripts/record_release_demo.mjsnow typesThere is blood when I wipeandI have tarry stoolsin the real chat, then seeds a fictional ledger whose note isstool was tarry yesterdayand asks an innocuous question. Each scene asserts in the browser that exactly onenew Timmy bubble carries
Pause and get medical help..., that the copy is the app's own fixedstring, and that
hermesCallsnever moves. Three new captions are required release gates inscripts/build_release.py, andtests/release-demo.test.jspins the new scene.all 17 required captions, so tomorrow's release job can record this path as-is.
Boundary
Unchanged: no new inference, no diagnosis, no claim from the image, no production service
touched. Escalation only ever gets broader on what the person reports.
Follow-up noted, not done here
A provider can still put medical reassurance into the free-text
observationsstring that thesuggestion card renders (escaped, and beside Timmy's fixed warning). That is a vision-response
hardening item for the corpus/boundary work (#16/#18), not escalation detection, so it is
deliberately out of this change.
Also pre-existing and untouched:
fevermatches "fever blister". It escalates too eagerly onmain already; over-triggering is the safe direction, and narrowing it is a copy question, not
this issue.
Pull request closed