6 Commits

Author SHA1 Message Date
d21ed17310 fix(01-12): brand polish — replace stale 'AI Call Recorder' refs with Mokosh (4 files)
Plan 01-12 D-07 (commit 5efc2a8) migrated manifest.json:name + tooltip
+ extName/extDesc keys to chrome.i18n placeholders + _locales/{en,ru}/
messages.json resolving to 'Mokosh — Session Capture' (EN) / 'Mokosh —
Запись сессии' (RU). However, 4 trailing references to the pre-D-07
literal 'AI Call Recorder' in non-manifest content surfaces were never
propagated. Operator noticed during Plan 01-10 cycle-2 UAT 2026-05-20.

This commit applies the user-approved 4-file surgical rename:

  - src/welcome/copy.ts: welcome.body.cta.toolbar RU CTA
    "иконку AI Call Recorder" → "иконку Mokosh" (matches toolbar tooltip
    i18n key tooltipOff = "Mokosh — щёлкните, чтобы начать запись").
    Inline rationale comment added cross-ref'ing the i18n key + this
    debug session.

  - README.md: H1 + first paragraph rewritten to
    "# Mokosh — Session Capture" + EN tagline line. Rest of README body
    preserved verbatim (technical-stack section historical mentions
    left as project history, not brand surface).

  - package.json: name "ai-call-extension" → "mokosh-session-capture",
    description rewritten to "Mokosh — Session Capture: Chrome MV3
    extension for operator session recording." version, scripts,
    dependencies, devDependencies untouched.

  - tests/i18n/manifest-i18n.test.ts: header comment block rewritten to
    label the "AI Call Recorder" string as Wave-0 historical state +
    describe the post-D-07 regression-pin role. Test bodies + assertions
    unchanged (already pin the post-D-07 canonical state).

Preservation rationale: .planning/intel/* (brand-decisions-v1.md D-07,
design-system.md, brand-identity.md, classifications/README-*.json,
design-incoming/system/bundle/mokosh-handoff/handoff.html) is audit
trail documenting the "why" of D-07 — kept verbatim. _locales/{en,ru}/
messages.json and manifest.json already post-D-07 canonical — untouched.

Acceptance gates (all PASS 2026-05-20):
  - Empirical grep src/ tests/ README.md package.json: ZERO non-historical
    "AI Call Recorder" matches (only the labeled audit anchor in
    tests/i18n/manifest-i18n.test.ts:8).
  - npx tsc --noEmit: clean.
  - npm run build: ✓ built in 5.29s.
  - npx vitest run tests/i18n/manifest-i18n.test.ts: 10/10 GREEN.
  - npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts
    (Tier-1 hook-string grep gate): 13/13 GREEN; FORBIDDEN_HOOK_STRINGS
    list intact.
  - npm test: 151/153 (2 pre-existing ffprobe/ffmpeg timeout flakes in
    webm-remux + webm-playback — verified identical to pristine HEAD
    a2dfc8c via git stash baseline; unrelated to rename).
  - npm run test:uat: 24/24 GREEN.
  - Production bundle grep dist/: ZERO "AI Call Recorder" + ZERO
    "ai-call-extension" matches.

Unblocks Plan 01-10 closure + Phase 1 final closure (REQUIREMENTS /
ROADMAP / STATE marker flip).

Debug record: .planning/debug/resolved/01-12-stale-ai-call-recorder-references.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:49:46 +02:00
96fa8e8e11 chore(01-11): wave-0 — install puppeteer + tsx, add vite.test.config + Tier-1 hook-leak grep gate
Task 1 of Plan 01-11 (Puppeteer UAT harness).

- npm install --save-dev puppeteer@^25.0.2 tsx@^4 @types/node
  resolved: puppeteer@25.x, tsx@4.22.1, @types/node@25.8.0
  pulls ~150MB Chromium binary at install time (T-1-11-03 — accepted,
  package-lock pins resolved hashes via @puppeteer/browsers).
- package.json scripts: add build:test + test:uat (per RESEARCH §10
  two-bundle orchestration); existing dev/build/preview/test untouched.
- vite.test.config.ts: extends ./vite.config.ts via mergeConfig with
  mode:'test' + build.outDir:'dist-test' + emptyOutDir:true. Verified
  npm run build:test produces dist-test/ in 7.93s; npm run build keeps
  producing dist/ in 7.67s (no clobber).
- tsconfig.json `include: ["src"]` already covers src/test-hooks/**/*
  via wildcard — no edit needed.
- tests/background/no-test-hooks-in-prod-bundle.test.ts: Tier-1 gate
  mirroring sw-bundle-import.test.ts's execFile pattern. Greps the
  BUILT dist/ tree for 5 forbidden hook surfaces (one `it` per surface
  for granular failure isolation): __mokoshTest, simulateUserStop,
  getSegmentCount, setCurrentStream, setSegmentCountGetter. All 5
  surfaces absent today (RED-then-GREEN polarity inverted — the gate
  is GREEN now and MUST stay GREEN after Task 2 lands the hooks).
  SKIP_BUILD=1 escape hatch for developer iteration.
- .gitignore: add dist-test/ (no point versioning generated test bundle).

Verification:
- npx tsc --noEmit: exit 0
- npm run build: exit 0; dist/ populated (375.37 kB SW chunk)
- npm run build:test: exit 0; dist-test/ populated (identical chunk sizes —
  the gated dynamic imports do not land until Task 2; this commit only
  proves the two-bundle plumbing)
- SKIP_BUILD=1 npx vitest run tests/background/no-test-hooks-in-prod-bundle.test.ts:
  6/6 GREEN (1 build-sanity + 5 forbidden-surface)
- SKIP_BUILD=1 npx vitest run (full suite): 89/89 GREEN
  (83 baseline + 6 new Tier-1 surfaces = 89)

Working-tree cleanup: a stale 5.4 MB tests/fixtures/last_30sec.webm
(unrelated operator smoke regen present at session spawn) was stashed
before running the baseline — it caused the webm-playback test to time
out at 5s. After stashing back to HEAD's 1.9 MB fixture, baseline passes
cleanly. Not committing the fixture restoration here (pre-existing
working-tree state, not part of Task 1).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 21:42:46 +02:00
dd7bf00d1d fix(01-08): B+ — vite-plugin-node-polyfills for Buffer (resolves runtime ts-ebml crash)
Layer 2 of the extended SW-bundle-import gate caught a runtime
ReferenceError: Buffer is not defined at EBMLDecoder.constructor
(this._buffer = Buffer.alloc(0)). Reached from remuxSegments via
extractFramesFromSegment for every input segment — would crash
the SW on every SAVE_ARCHIVE click in real Chrome.

ts-ebml has a 5-year-old open issue (legokichi/ts-ebml#37,
"Can't use Buffer in browser") acknowledging the incompatibility
with no maintainer fix. The canonical Vite workaround is
vite-plugin-node-polyfills with a narrow Buffer-only config (per
the plugin author's official docs).

Changes:
- vite-plugin-node-polyfills@0.27.0 added as devDependency
- vite.config.ts adds nodePolyfills plugin with narrow config:
  include: ['buffer'], globals.Buffer: true, globals.global: false,
  globals.process: false, protocolImports: false (Buffer only, no
  stdlib pull-in)
- bundle delta: SW chunk 373.05 kB (-0.49 kB vs C-config alone);
  +27.48 kB shared polyfill chunk (index-CgqXENQe.js, used by SW
  and offscreen). Net cost ~26.3 kB for full Buffer support.

Bundle verification:
- bundled EBMLDecoder.js now reads `this._buffer = me.alloc(0)`
  where `me` is the imported polyfill Buffer (was `Buffer.alloc(0)`
  against undefined globalThis.Buffer). Same rewrite applied to
  all 3 Buffer.alloc/Buffer.concat/Buffer.from sites in ts-ebml.
- bundle does NOT depend on globalThis.Buffer (the polyfill
  rewrites references as imports, not as global assignments) —
  Layer 1 of the gate still strips Buffer from globalThis and
  passes, confirming this.

Layer 2 gate: RED → GREEN. resolve.alias.ebml fix from commit
52c7636 preserved — still required for ebml CJS-interop;
the polyfill addresses an orthogonal runtime concern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 12:17:50 +02:00
503531485c feat(01-08): install ts-ebml + webm-muxer; pin SW-compat via deps test
- Add ts-ebml ^3.0.2 (parse half) and webm-muxer ^5.1.4 (write half) per
  CONTEXT.md amendment D-14-remux; both MIT, both verified SW-compatible
  in the d13 debug-session library survey.
- tests/background/webm-remux-deps.test.ts pins two contracts:
  (a) named exports surface (Muxer + ArrayBufferTarget + Decoder).
  (b) both libraries import cleanly when window/document are absent on
      globalThis — guards the published dist against accidentally
      acquiring DOM globals on the hot path that would crash the
      Chrome service-worker runtime.
- Note: webm-muxer 5.1.4 upstream-deprecated in favor of Mediabunny; the
  pinned version still meets the d13 architectural requirement
  (single-EBML output via addVideoChunkRaw). Migration to Mediabunny is
  out of scope for Plan 01-08 and would require a new ADR.
- Baseline 53 GREEN + 2 new GREEN; tsc clean; 2 webm-playback duration
  RED still pending (drive to GREEN in Tasks 3-5).
2026-05-17 09:22:46 +02:00
ebf015aa0d test(01-02): wave-0 setup — install vitest
- Add vitest@^4 to devDependencies (4.1.6 latest stable; 5.x still beta)
- Add "test": "vitest run" npm script
- Run npm install to refresh node_modules and lock file

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 17:22:51 +02:00
555eb0543f chore: import broken Phase-1 extension as received
Snapshot of /home/parf/Downloads/manifest.zip as delivered, before any
GSD-driven remediation. Contains a partially-broken first attempt at the
Russian SPEC "Тз расширение фаза1.md" (Phase 1 of operator-session-recorder).

Source layout:
- manifest.json — MV3 declaration with tabCapture/activeTab/downloads/etc.
- src/background/index.ts — service worker (video buffer + archive packaging)
- src/content/index.ts — rrweb + user-event logger
- src/popup/{index.html,index.ts,style.css} — Russian popup UI
- offscreen/{index.html,index.ts} — orphaned offscreen (see audit)
- vite.config.ts — inline plugin emitting a separate live offscreen.js
- generate-icons.js, icons/ — minimal PNG icons
- "Тз расширение фаза1.md" — authoritative Russian SPEC

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 15:16:23 +02:00