Skip to content

release: v0.1.0 — wrkmark-observer first stable release - #9

Merged
AxaySharma merged 22 commits into
mainfrom
develop
Jun 9, 2026
Merged

AxaySharma merged 22 commits into
mainfrom
develop

Conversation

@AxaySharma

Copy link
Copy Markdown
Contributor

v0.1.0 — First stable release

This PR merges the complete wrkmark-observer engine into main.

What's shipping

Core engine

  • AuditLog — tamper-evident SHA256 hash chain
  • SignalAnonymizer — 8 approved signals, everything else rejected
  • Database layer — WAL mode SQLite with typed helpers
  • SignalExtractor — behavioral feature computation
  • SessionManager — full session lifecycle with pause/resume

Collectors

  • VSCodeCollector — VS Code activity via IPC
  • Chrome Extension — AI tool hostname detection, Manifest V3

Public API

  • createObserver() — fully wired in one call
  • VERSION = '0.1.0'

Tests

69/69 root + 17/17 extension = 86 total passing

Privacy

Zero content capture. Enforced structurally, not by policy.
Every observation logged to tamper-evident audit trail.
Raw signals never leave device.

Checklist

  • 69/69 tests passing
  • Zero TypeScript errors
  • CI green on develop
  • WHAT_WE_SEE.md accurate
  • AGENTS.md current
  • README has Quick Start

AxaySharma added 22 commits June 5, 2026 01:29
Merge main into develop so develop has the CI file too
- createDatabase() factory with WAL mode + foreign keys
- Typed query helpers: signals, sessions, features namespaces
- Privacy enforcement: signals.insert() rejects string values
- Foreign key constraint test: orphaned feature vectors rejected
- Tests: 9/9 passing

schema.ts: raw_signals, local_sessions, feature_vectors tables
database.ts: prepared statements, zero raw string queries
- Pin action versions to latest (checkout@v4.2.2, setup-node@v4.4.0, pnpm@v4)
- Set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true env variable
- Add system deps (python3, make, g++) needed to compile better-sqlite3 on Ubuntu
- Use pnpm rebuild after install instead of --build-from-source flag
- Add pnpm cache to speed up future runs
.join('|') returns string not array — fix type annotation
resolves TS2322 and TS2345 strict mode errors
fix: update CI workflow for Node.js 24 + fix better-sqlite3 compilation
Privacy-critical files (anonymizer, audit-log, WHAT_WE_SEE.md)
explicitly listed. Any change to what data is collected must be
approved by @AxaySharma before merging.
chore: add CODEOWNERS — all changes require founder review
- extractFeatures() computes FeatureVector from completed session
- focus_ratio: typing rhythm signals / expected buckets (capped 1.0)
- revision_intensity: (undos + pauses) / duration normalised (capped 1.0)
- used_ai_tools: boolean from ai_tool_opened signal presence
- relative_velocity: 1.0 MVP constant (Phase 2: 30-day baseline)
- Sessions under 5 minutes return focus_ratio: 0

Privacy: all computations use signal counts only.
signal_value never read as string — enforced by comment + test.
Tests: 9 new tests, 28/28 total passing
feat: SignalExtractor - behavioral feature computation
- startSession(): creates session, audits, validates no duplicate
- recordSignal(): anonymizes → stores → increments count → audits
- endSession(): closes session, extracts features, returns CompletedSession
- pause()/resume(): drops signals when paused, session stays alive
- getState(): live ObserverState with sessions_today + hours_today

database.ts: added sessions.getSince() for daily stats computation

Privacy: recordSignal() throws STRING_VALUE_REJECTED if string
value bypasses type system via coercion. Tested explicitly.
Paused signals dropped silently — no session data lost.

Tests: 14 new, 42/42 total passing
feat: SessionManager — central observation orchestrator
- onKeystroke(): timing rhythm in 100ms buckets, never key content
- onPause(): detects thinking pauses > 10s, records duration
- onFileSwitch(): debounced at 500ms, counts switches not filenames
- onAIToolSwitch(): boolean presence detection only
- onUndo(): counts revision events, ignores what was undone
- onBuildRun(): counts build attempts, ignores command content

ICollector interface added to types/index.ts
Collector errors caught and logged — never crash the app
All public methods return silently when not running

Privacy: keystroke characters structurally isolated from
signal pipeline. Content never reaches SessionManager.
Debounce prevents timing attacks via rapid file switches.

Tests: 17 new, 59/59 total passing
feat: VSCodeCollector — first real behavioral collector
Manifest V3, minimum permissions: tabs + activeTab only.
No host_permissions, no scripting — never injects into pages.

background.ts:
- Detects 6 AI tool hostnames: claude.ai, chatgpt.com,
  chat.openai.com, copilot.github.com, gemini.google.com,
  aistudio.google.com
- Hostname extraction only — full URL never stored or logged
- Sends WrkmarkMessage to native host when AI tool detected
- Chrome API errors caught silently — never surfaces to user

vitest.config.ts: exclude extensions/ from root test run
Extension tests run independently from extensions/chrome/

Privacy: no page content, no full URLs, no browsing history.
Only signal: AI tool hostname is currently active tab.

Tests: 17 extension + 59 root = 76 total passing
feat: Chrome extension — AI tool detection
src/index.ts — selective exports, public surface area only:
  Types: SignalType, RawSignal, AnonymizedSignal, ActiveSession,
         CompletedSession, FeatureVector, ObserverStatus,
         ObserverState, ICollector, WrkmarkObserverError
  Classes: AuditLog, SignalAnonymizer, SignalExtractor,
           SessionManager, VSCodeCollector
  Functions: createDatabase, createObserver
  Constants: VERSION = '0.1.0'

createObserver(dbPath): wires all dependencies in one call.
Internal types (AuditEntry, DB row types, schema SQL) not exported.

README: Quick Start + Individual Imports usage examples

Tests: 10 integration tests including full lifecycle smoke test
  (start session → record signals → end session → verify audit chain)

Root: 69/69 passing | Extension: 17/17 passing
feat: public API — createObserver() factory + selective exports
@AxaySharma AxaySharma self-assigned this Jun 9, 2026
@AxaySharma
AxaySharma merged commit 9cb2ac5 into main Jun 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant