1 Commits

Author SHA1 Message Date
Mert Koseoglu 4f58e4fea1 fix(hooks): commit message capture + symmetric rollup stamp (Bug 1+2)
Two coupled bugs reported via the platform-side handoff produced misleading
analytics:

Bug 1 — extractGit() returned data=match.operation ("commit"/"push"/"diff")
instead of the actual commit subject. Platform commit_message column
inherited the operation name, which is meaningless. Fix: hand-rolled
shell-like argv tokenizer (no regex) parses -m / -am / --message= /
--message ARG forms, returns the captured subject as event.data. When a
message is captured, the event surfaces as type='git_commit' so the rollup
aggregator can distinguish actual commits from other git ops. Falls back
to operation name when no message is present (--amend / --no-edit / -F).

Bug 2 — rollup query stamped has_commit=1 onto every event in a commit-
bearing session (via SUM(category='git')>0), but commit_message lived only
on per-event git rows. Asymmetric — ~92% of has_commit=1 rows on platform
arrived with commit_message=NULL. Fix: SessionDB.getSessionRollup now
includes the latest commit_message from session's type='git_commit' events
via a separate prepared statement; has_commit SQL changed from
category='git' to type='git_commit' for accurate semantics. session-loaders
enrichment gates per-event commit_message/has_commit on type='git_commit'
instead of category='git'. Spread order makes rollup authoritative for
non-git events while git_commit events stay marked.

ALGORITHMIC parsing, not regex:
- tokenizeCommand: pure char loop, single/double quotes, backslash escapes,
  POSIX-style adjacent merging (a"b c"d → "ab cd")
- extractCommitMessageFromCommand: linear scan for --message=value,
  --message value, or -m/-am/cluster-flag-ending-in-m followed by value
- isLowerAlphaRun: char-code check (97-122) for cluster validation

Tests (TDD, vertical slices, RED→GREEN per behavior):
- tests/session/extract-git-commit.test.ts (11 tests): tracer + 10 edge
  cases — single/double quotes, --message= attached, --message separate,
  -am combined flag, --amend fallback, empty -m "" fallback, non-commit
  unchanged, special chars, env-prefixed invocation, type discriminator.
- tests/integration/commit-message-symmetry.test.ts (1 test): session
  with 1 git_commit + 3 non-git events → all 4 captured POST bodies carry
  commit_message symmetric with has_commit=1.

Empirical proof: live E2E against real platform — 4/4 POSTs status 201,
4/4 has_commit=1, 4/4 commit_message populated symmetrically. Bug 1 and
Bug 2 both verified fixed end-to-end with rebuilt bundles.

Regression matrix: 1210 pass, 5 skipped, 1 pre-existing failure
(project-dir-strict — stale, unrelated). Existing tests using
type='git' updated to type='git_commit' where the fixture represents
an actual commit (session-extract test, seed-parity-coverage two fixtures).

Refs platform-bridge.mjs envelope ABI (PRD §5.4), bridge stays a dumb pipe;
all enrichment upstream in session-loaders. NO release — push next only.
2026-06-02 13:07:39 +03:00