Commit 2e7a543
committed
fix(attribution): Bug 8 —
Reported alongside Bug 7 ("CRITICAL cross-project attribution"). Empirical
repro found Bug 7 is NOT a bug — existing EVENT_PATH + bridge
resolveProjectIdentity already attribute file_edit on /projB/foo.ts to
projB even when cwd=projA. Bug 8 IS a bug: Bash invocations that scope
via `-C <dir>` (git, make, tar) had no path signal in the canonical event
data and fell back to inputProjectDir (= hook startup cwd), missing the
user's intentional scoping.
ROOT CAUSE
extract.ts:extractGit only ran a regex pattern scan like /\bgit\s+commit\b/,
which doesn't tolerate flags between `git` and the operation. So
`git -C /projB status` returned NO git event AND no cwd hint. Even if a
cwd event had been emitted, the fallbackAttribution path in
project-attribution.ts:fallbackAttribution prefers context.inputProjectDir
over context.lastKnownProjectDir — so the carry-forward from a previous
cwd event in the same batch is silently overridden by the hook's startup
cwd.
FIX — TWO LAYERS, BOTH ALGORITHMIC (NO REGEX)
src/session/extract.ts: new parseGitInvocation() tokenises the Bash
command (reusing tokenizeCommand from v1.0.161 Bug 1 fix), skips env-style
assignments and common runners (sudo/doas/env/exec/time), locates the
`git` token, then scans for `-C` / `--directory` to capture scopedDir and
the first bare token as the operation. Falls back to the legacy regex
scan only when the algorithmic parse can't find a `git` token.
When scopedDir is captured, extractGit now emits a leading cwd event with
the parsed dir BEFORE the git event. The attribution layer then routes
the git event via carry-forward.
src/session/project-attribution.ts: resolveProjectAttributions tracks
whether an in-batch CWD-level event (confidence ≥ 0.9) has explicitly
re-scoped the project. Once true, subsequent events fall back to the
carried-forward lastKnown instead of the original hook inputProjectDir.
This is the architectural minimum needed for "user's intentional cwd
shift wins over hook startup cwd" without bumping CARRY_FORWARD_THRESHOLD
or reordering the fallbackAttribution priority globally (both of which
would have broader regression surface).
TESTS (tests/integration/cross-project-attribution.test.ts, 5 tests)
1. Tracer — Edit on projB's file while cwd=projA → projB ✅ (no-fix, existing path)
2. Batched mixed A+B+B edits → each event attributes independently ✅
3. Bug 8 tracer — `git -C /projB status` via real extractEvents → projB ✅
4. `cd /projB && npm test` (baseline that already worked) → projB ✅
5. Bash without path indicator (df -h) → fallback to cwd ✅
Empirical proof: live E2E against real platform — file_edit on projB,
cwd event, and git event all POST with project=github.com/acme/projB,
status 200 from production endpoint.
REGRESSION
1215 pass, 5 skipped, 1 pre-existing failure (project-dir-strict — stale,
unrelated). The attribution batch-shadow fix does not affect any
existing test fixture — the lastKnown shadowing only kicks in when a
CWD_EVENT-level confidence attribution has carried forward, which the
existing tests don't exercise in mixed batches.
NO release. Push to next only — waiting for user verification + approval.git -C <dir> scope hint flows to attribution1 parent 4f58e4f commit 2e7a543
3 files changed
Lines changed: 399 additions & 5 deletions
File tree
- src/session
- tests/integration
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
340 | 340 | | |
341 | 341 | | |
342 | 342 | | |
343 | | - | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
344 | 358 | | |
345 | 359 | | |
346 | 360 | | |
| |||
354 | 368 | | |
355 | 369 | | |
356 | 370 | | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
357 | 386 | | |
358 | 387 | | |
359 | 388 | | |
360 | | - | |
| 389 | + | |
361 | 390 | | |
362 | 391 | | |
363 | 392 | | |
364 | 393 | | |
365 | | - | |
| 394 | + | |
| 395 | + | |
366 | 396 | | |
367 | 397 | | |
368 | 398 | | |
369 | | - | |
| 399 | + | |
370 | 400 | | |
371 | 401 | | |
372 | 402 | | |
373 | 403 | | |
374 | | - | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
375 | 490 | | |
376 | 491 | | |
377 | 492 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
249 | 249 | | |
250 | 250 | | |
251 | 251 | | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
252 | 261 | | |
253 | 262 | | |
| 263 | + | |
254 | 264 | | |
255 | 265 | | |
| 266 | + | |
256 | 267 | | |
257 | 268 | | |
258 | 269 | | |
259 | 270 | | |
260 | 271 | | |
261 | 272 | | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
262 | 276 | | |
263 | 277 | | |
264 | 278 | | |
| |||
0 commit comments