Merge pull request 'Document product boundary and release authority' (#46) from timmy/9-product-boundary-decisions into main
All checks were successful
Quality gates / quality (push) Successful in 1m26s
All checks were successful
Quality gates / quality (push) Successful in 1m26s
This commit is contained in:
commit
930f156590
|
|
@ -4,6 +4,7 @@ A working mobile-first bowel diary with an optional **photo-first AI assist**:
|
|||
|
||||
- [Product roadmap and live Gitea epic map](ROADMAP.md)
|
||||
- [Product and safety boundary](PRODUCT.md)
|
||||
- [Product boundary and release authority decision](docs/PRODUCT-DECISIONS.md)
|
||||
- [Self-hosted stool-vision decision](research/SELF-HOSTED-STOOL-VISION.md)
|
||||
|
||||
## Build a gated review release
|
||||
|
|
|
|||
51
docs/PRODUCT-DECISIONS.md
Normal file
51
docs/PRODUCT-DECISIONS.md
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# Product Boundary and Release Authority Decision
|
||||
|
||||
- **Status:** Accepted
|
||||
- **Date:** 2026-08-20
|
||||
- **Scope:** Photo-assisted bowel logging and release governance
|
||||
|
||||
## Context
|
||||
|
||||
Timmy can make a conservative visual suggestion from a user-selected image, but the available general-purpose model is not clinically validated. The product must preserve manual logging, deterministic red-flag escalation, and user control regardless of model availability or output.
|
||||
|
||||
## Decision
|
||||
|
||||
### Observable AI fields
|
||||
|
||||
AI may suggest only:
|
||||
|
||||
- visible Bristol form (Types 1–7);
|
||||
- broad color;
|
||||
- image quality.
|
||||
|
||||
Every suggestion is provisional, may abstain, and requires user review or correction before it can enter the journal. Symptoms remain user-entered, and journal saving is separate from training contribution consent.
|
||||
|
||||
### Prohibited inferences
|
||||
|
||||
AI must not infer or claim disease, bleeding, pain, urgency, fever, vomiting, treatment, causation, or whether a food is safe. It must not replace professional care, suppress deterministic red-flag escalation, or present a suggestion as a diagnosis.
|
||||
|
||||
### Release authority
|
||||
|
||||
Hermes/Timmy is the release authority for routine engineering, test, build, deployment, and release-candidate preparation. Automated evidence must remain reproducible and must not overstate model accuracy or safety.
|
||||
|
||||
### Human gates
|
||||
|
||||
Human gates are limited to:
|
||||
|
||||
1. clinical and privacy review when language or policy crosses those boundaries;
|
||||
2. beta consent before participation;
|
||||
3. RC approval before shipping a release candidate.
|
||||
|
||||
Routine provisioning, deployment, label sweeps, and release-candidate assembly are not human-operated gates.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Model output is assistive and fail-closed, never authoritative.
|
||||
- A generic open-weight VLM can support bootstrap experiments but cannot become the production Bristol classifier without the documented calibration and evaluation evidence.
|
||||
- Release evidence and demonstrations must use fictional or synthetic data and state the non-diagnostic boundary honestly.
|
||||
|
||||
## Evidence and governing references
|
||||
|
||||
- [Product brief and safety boundary](../PRODUCT.md)
|
||||
- [AI execution evidence](../AI-EVIDENCE.md)
|
||||
- [Sovereign vision decision and measured limitations](../research/SELF-HOSTED-STOOL-VISION.md)
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "node --test tests/domain.test.js tests/analysis.test.js tests/vision-service.test.js tests/vision-config.test.js tests/training-ingest.test.js tests/ci-workflow.test.js tests/release-demo.test.js",
|
||||
"test": "node --test tests/domain.test.js tests/analysis.test.js tests/vision-service.test.js tests/vision-config.test.js tests/training-ingest.test.js tests/ci-workflow.test.js tests/product-decisions.test.js tests/release-demo.test.js",
|
||||
"test:ui": "node tests/ui.acceptance.mjs",
|
||||
"test:photo": "node tests/photo-first.acceptance.mjs",
|
||||
"check:syntax": "node --check app.js && node --check server.mjs && node --check service-worker.js && node --check src/analysis.js && node --check src/domain.js && node --check src/vision-config.js && node --check src/vision-service.js && node --check scripts/record_release_demo.mjs && bash -n scripts/run_selfhost_smolvlm.sh && python3 -m py_compile scripts/ingest_training_photo.py scripts/build_release.py",
|
||||
|
|
|
|||
|
|
@ -97,10 +97,11 @@ await caption('The photo stays unsaved until explicit consent', 1300);
|
|||
await page.locator('#ai-consent').check();
|
||||
await tap('#analyze-photo', 500);
|
||||
await page.getByText(/83% confidence/i).waitFor();
|
||||
await caption('Timmy suggests only visible form and broad color', 1500);
|
||||
await caption('AI may suggest visible form, broad color, and image quality — never symptoms or diagnosis', 1900);
|
||||
await tap('#use-suggestion', 600);
|
||||
await caption('Nothing persists until the user reviews or corrects it', 1500);
|
||||
await page.locator('[data-type="4"]').scrollIntoViewIfNeeded();
|
||||
await caption('Release gates: clinical/privacy review, beta consent, and RC approval', 1800);
|
||||
await sleep(700);
|
||||
await page.evaluate(() => {
|
||||
document.querySelector('#demo-caption')?.remove();
|
||||
|
|
|
|||
17
tests/product-decisions.test.js
Normal file
17
tests/product-decisions.test.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
|
||||
const decisionPath = new URL('../docs/PRODUCT-DECISIONS.md', import.meta.url);
|
||||
|
||||
test('product decision record fixes the AI boundary and release authority', async () => {
|
||||
const decision = await readFile(decisionPath, 'utf8');
|
||||
|
||||
assert.match(decision, /Observable AI fields[\s\S]*Bristol form[\s\S]*broad color[\s\S]*image quality/i);
|
||||
assert.match(decision, /Prohibited inferences[\s\S]*disease[\s\S]*bleeding[\s\S]*pain[\s\S]*urgency[\s\S]*fever[\s\S]*vomiting[\s\S]*food/i);
|
||||
assert.match(decision, /Hermes\/Timmy[\s\S]*release authority/i);
|
||||
assert.match(decision, /Human gates[\s\S]*clinical and privacy review[\s\S]*beta consent[\s\S]*RC approval/i);
|
||||
assert.match(decision, /\.\.\/PRODUCT\.md/);
|
||||
assert.match(decision, /\.\.\/AI-EVIDENCE\.md/);
|
||||
assert.match(decision, /\.\.\/research\/SELF-HOSTED-STOOL-VISION\.md/);
|
||||
});
|
||||
|
|
@ -9,5 +9,7 @@ test('release demo visibly explains the CI-protected browser path without overst
|
|||
|
||||
assert.match(demo, /Automated checks replay this synthetic path before review/);
|
||||
assert.match(demo, /tests\/fixtures\/synthetic-type4\.jpg/);
|
||||
assert.match(demo, /AI may suggest visible form, broad color, and image quality — never symptoms or diagnosis/);
|
||||
assert.match(demo, /Release gates: clinical\/privacy review, beta consent, and RC approval/);
|
||||
assert.match(demo, /Visual assistance — never a diagnosis\./);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user