Commit Graph

29 Commits

Author SHA1 Message Date
6f73b8551c fix: close second hostile-review round on ledger portability
All checks were successful
Quality gates / quality (pull_request) Successful in 4m14s
- collision-safe ID repair: duplicate ids inside stored data are repaired
  deterministically (first keeps id, twins get id#2, id#3, ... scanning past
  owned suffixes); every distinct local record survives, never dropped or
  silently merged; hostile id types (Symbol/BigInt/objects) repair onto
  fresh deterministic ids instead of throwing
- transactional import: parse+merge into a candidate ledger, persist first,
  then commit memory; quota/error rolls back in-memory state and localStorage
  together with explicit user feedback; total 16MiB portability budget
  enforced before mutation on export, import (post-migration expansion), and
  storage writes
- strict Timmy legacy contract for bare top-level arrays: nonempty array of
  plain rows each carrying a nonempty string id and integer Bristol 1-7;
  arbitrary unrelated arrays are rejected wholesale - no invented medical
  defaults from foreign JSON
- canonical raster photo validation: strict JPEG/PNG/WebP grammar, canonical
  base64 (linear scan, no regex on multi-MB strings), atob round-trip decode,
  declared-format magic bytes, 32B-4MiB decoded bounds; mislabeled SVG/HTML
  and noncanonical tiny junk are stripped while genuine photos survive
  byte-for-byte
- migrateStoredLedger: localStorage is validated and migrated before render;
  invalid dates become safe ISO timestamps, duplicate ids repaired, junk rows
  dropped (never fabricated into default records); healthy storage is
  byte-stable and never rewritten
- sanitizeEntry absorbs Symbol/BigInt/hostile dates/throwing toString,
  valueOf, getTime, toJSON without throwing; results stay serializable
- browser regression suite: quota rollback, pre-render migration, array
  rejection, photo contract, duplicate-ID preservation in the real app flow
- staging-health startup-rejection budget anchored to measured server
  cold-start instead of a fixed 800ms (fixes load-sensitive flake)
2026-08-22 23:47:25 +00:00
dd86d6675d fix: close hostile-review blockers in ledger portability
Some checks failed
Quality gates / quality (pull_request) Failing after 1m28s
- provenance origin set is own-safe exact membership (Set.has); inherited
  toString/constructor/__proto__ names can never become origins
- import/export symmetry restored with an explicit bounded policy:
  MAX_IMPORT_BYTES raised 2 MiB -> 16 MiB UTF-8 bytes, above any export
  this app can produce (photos capped at 4 MiB binary), so valid exports
  always re-import without silent data loss while hostile files stay bounded
- byte limit is byte-exact now: utf8ByteLength() measures real UTF-8 bytes
  (multibyte boundaries tested), and the browser rejects oversized files
  by File.size BEFORE File.text() reads user data
- collision-safe deterministic mergeLedgers(): existing user-owned rows
  win, incoming rows only ever added for new ids, intra-file duplicates
  collapse deterministically, every collision reported explicitly in the
  import toast (no duplicate/overwrite/shadow of user records)
- base-path Delete Everything is namespace-scoped: root still cleans/
  migrates the legacy store to prevent resurrection, /timmy-staging no
  longer erases another namespace's global legacy ledger (browser
  regression covers deletion with root legacy data present)
- strict current-schema values: Bristol 1-7 / urgency 0-4 / discomfort
  0-4 must be true integers (out-of-range falls back instead of silent
  clamping), photos restricted to JPEG/PNG/WebP base64 raster data URLs
  (SVG/GIF/non-base64 dropped), invalid dates never throw or persist
  Invalid Date values

Verification: npm test 91/91, test:ui/test:photo/test:sleek/test:portability
PASS, staging-deploy 20/20 OK, check:syntax clean, npm audit 0 high,
check_diff clean, adversarial probe battery (exact-byte boundary at cap,
prototype pollution via JSON, lone surrogates, data-URL strictness) green.
2026-08-22 21:53:08 +00:00
b8532f587d feat: version ledger migrations and hardened JSON portability
All checks were successful
Quality gates / quality (pull_request) Successful in 1m42s
Implements #35.

- importLedger migrates prior schema versions (v0 bare-array legacy
  exports and the v1 envelope) and fails safely on future versions,
  malformed JSON, wrong-product envelopes, and oversized files with a
  new 2 MiB MAX_IMPORT_BYTES guard applied before parsing.
- exportLedger normalizes entries through sanitizeEntry so confirmed
  values and bounded provenance round-trip while smuggled secrets and
  unknown fields never enter the portable file.
- Entries may carry a whitelisted provenance origin ('user' or
  'ai-suggestion'); mergeVisualSuggestion records 'ai-suggestion' only
  when a suggestion is actually applied, keeping nonvisual fields
  user-owned.
- App import now merges into the existing ledger instead of replacing
  it, so a failed or partial import can never silently drop
  user-owned records.
- Service-worker shell cache bumped to v6 (per base-path namespace)
  so installed PWAs receive the migration code; old v5 caches are
  purged on activation.
- New tests/ledger-portability.acceptance.mjs browser gate covers
  export round trip, merge import, safe-failure surfacing, root vs
  /timmy-staging storage isolation, and Delete Everything for both
  namespaces; wired into package.json test:portability and CI quality.yml.

Deterministic medical safety unchanged: urgent-flag detection, red-flag
copy, and chat escalation paths are untouched; all fixtures synthetic.
2026-08-22 20:32:57 +00:00
47294a98aa Merge pull request 'Make staging runtime configuration compatible with strict CSP' (#59) from timmy/58-strict-csp-runtime-config into main
All checks were successful
Quality gates / quality (push) Successful in 1m56s
2026-08-21 15:04:43 +00:00
877b8a01f3 fix: make staging compatible with strict CSP
All checks were successful
Quality gates / quality (pull_request) Successful in 1m37s
2026-08-21 15:01:05 +00:00
067afaed4c Merge pull request 'Hardened atomic private-staging deployment tooling' (#56) from timmy/55-staging-deployment-tooling into main
All checks were successful
Quality gates / quality (push) Successful in 1m41s
2026-08-21 14:54:11 +00:00
f8f01c4b2e feat: add hardened atomic staging deployment
All checks were successful
Quality gates / quality (pull_request) Successful in 1m28s
2026-08-21 14:49:28 +00:00
fc763fb758 Merge pull request 'Private subpage staging foundation' (#54) from timmy/53-private-subpage-staging into main
All checks were successful
Quality gates / quality (push) Successful in 2m7s
2026-08-21 14:16:15 +00:00
7e11154302 feat: add private subpage staging slice
All checks were successful
Quality gates / quality (pull_request) Successful in 1m43s
2026-08-21 14:12:17 +00:00
11d1b364ab fix: gate bootstrap syntax in release build
All checks were successful
Quality gates / quality (push) Successful in 1m45s
2026-08-21 12:56:48 +00:00
8e3c2f8889 Merge pull request #52 from timmy/10-reproducible-smolvlm-bootstrap
Some checks failed
Quality gates / quality (push) Has been cancelled
Merge pull request #52: Package pinned self-hosted SmolVLM2 bootstrap
2026-08-21 12:55:18 +00:00
982fab273c feat: package pinned self-host vision bootstrap
All checks were successful
Quality gates / quality (pull_request) Successful in 1m30s
2026-08-21 08:15:32 +00:00
ca31e6d38b Merge pull request 'Hotfix: recognize past-tense vomiting in deterministic chat safety' (#51) from timmy/48-vomiting-phrase-hotfix into main
All checks were successful
Quality gates / quality (push) Successful in 1m26s
2026-08-20 17:17:33 +00:00
0f3104ebde fix: recognize past-tense vomiting in chat safety
All checks were successful
Quality gates / quality (pull_request) Successful in 1m21s
2026-08-20 17:14:20 +00:00
cc1fc6ee36 Merge pull request 'Hotfix: enforce deterministic urgent-symptom override at the server boundary' (#50) from timmy/48-server-safety-override into main
All checks were successful
Quality gates / quality (push) Successful in 1m24s
2026-08-20 16:48:02 +00:00
05b4bafd96 fix: enforce urgent chat override server-side
All checks were successful
Quality gates / quality (pull_request) Successful in 1m25s
2026-08-20 16:41:35 +00:00
09f9528434 Merge pull request 'Sleek Timmy mobile shell and secure Hermes Agent chat' (#49) from timmy/47-sleek-hermes-agent into main
All checks were successful
Quality gates / quality (push) Successful in 1m32s
2026-08-20 16:25:47 +00:00
a50afa6722 feat: simplify Timmy and add secure Hermes chat
All checks were successful
Quality gates / quality (pull_request) Successful in 1m24s
2026-08-20 16:21:00 +00:00
930f156590 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
2026-08-20 13:15:22 +00:00
3c51308a9e docs: fix product boundary and release authority
All checks were successful
Quality gates / quality (pull_request) Successful in 1m14s
2026-08-20 08:32:16 +00:00
8ab1e85bd1 Merge pull request #45: enforce reproducible quality gates
All checks were successful
Quality gates / quality (push) Successful in 1m18s
2026-08-19 12:06:38 +00:00
47eec47a31 ci: install pinned image test dependency
All checks were successful
Quality gates / quality (pull_request) Successful in 1m12s
2026-08-19 08:14:43 +00:00
29ba8594b8 ci: enforce reproducible quality gates
Some checks failed
Quality gates / quality (pull_request) Failing after 1m56s
2026-08-19 08:09:38 +00:00
535834c060 feat: require verified feature demo video in every release 2026-08-19 03:36:04 +00:00
ce84ea577c test: isolate photo acceptance from service workers 2026-08-19 03:02:33 +00:00
3899eac34f fix: start isolated server for release acceptance gates 2026-08-19 03:01:28 +00:00
074f52fddc build: add gated reproducible review releases 2026-08-19 03:00:54 +00:00
0ecf1d1205 docs: add Gitea roadmap and epic map 2026-08-19 02:00:40 +00:00
58906f11d0 feat: ship photo-first Timmy prototype and sovereign vision spike 2026-08-19 01:54:29 +00:00