Review findings on the --attribution PR:
- Privacy: sessions whose project path no longer resolves inherited the
cwd-fallback repo identity, egressing whatever (possibly confidential)
repo the user pushes from and falsely attributing its commits.
buildRepoGroups now tracks per-session identity provenance; the
attribution path excludes fallback sessions from commit attribution
entirely (no repo, no commits, PR links only) — they also can no
longer steal a commit from a genuine session's window.
- Privacy: Windows drive-letter paths (C:/..., C:\..., drive-relative)
parsed as scp-like remotes, emitting local filesystem paths as repo
identities. normalizeRemoteUrl rejects drive letters and
single-character hosts (dotless intranet hosts still accepted).
- Hardening: PR links are shape-checked before sending (https,
/org/repo/pull/N path, <=256 chars, max 20 per session) — upstream
parsers only truthiness-check them.
- Safety valve: MAX_ATTRIBUTION_PER_PUSH (10k) caps a first
--since all --attribution push; dry-run reports the cap.
- Tests: adversarial normalize corpus, cwd-fallback egress repro,
commit-stealing prevention, PR-link sanitization, and CLI-level tests
(mock IdP + collector): dry-run sends nothing to the traces endpoint,
flag-off emits no attribution span names on the wire.
- Docs: reconciled the 'never sent' wording with reality (PR links ride
even when repo is null; device_id/methodology/timestamps disclosed).
CHANGELOG Unreleased entry added.
AI-Origin: human
observe() classified a stable unparseable session-refresh.lock body as the
terminal 'unavailable'. parseAllSessions routes that to a read-only parse, so a
zero-byte or truncated lock froze warm-cache ingestion permanently across every
later run while each command still exited successfully.
A corrupt body is now a recoverable observation carrying a real mtime, and is
recovered only through the UNMODIFIED staleness gate — tryTakeover and the age
check are byte-identical to main. sameObservation gains an explicit null/non-null
boundary and a sha1 of the raw bytes, because two corrupt bodies have no tokens
to compare and mtime granularity is coarse on some filesystems.
The heartbeat deliberately does NOT rewrite a body it cannot prove is its own.
An owner that cannot prove ownership ends its ownership: mtime stops advancing,
the publication fence refuses, and a successor recovers the lock one staleMs
later. Losing that parse is the price of never having two owners.
* cache: strict cross-process gate for the warm session-cache refresh transaction (#645)
* lock: serialize the fence against the owner's own heartbeat
verifyStillOwner and the heartbeat tick both take the takeover guard;
without in-process serialization the fence could observe its own
heartbeat's guard file, read it as displacement, and abort a legitimate
publication. Fail-safe, but it discarded the parse the lock exists to
protect (~6% of verifies at a 1ms heartbeat in the repro). Owner-side
guard operations now run through one serializer; cross-process guard
semantics are unchanged. Regression test at heartbeatMs 1, mutation-
verified against the unserialized code.
---------
Co-authored-by: Aditya Vikram Singh <247195684+avs-io@users.noreply.github.com>
Co-authored-by: reviewer <review@local>
Resolves menubar-json conflicts: main's granular-history timeline
param unions cleanly with this branch's providerDetails and currency
payload additions; both new tests kept.
Before-merge items:
1. HTTPS enforced on every remote endpoint (RFC 8252 §8.3): baseUrl,
issuer, authorization/token/revocation endpoints, and the traces
endpoint all reject non-https, with a loopback (127.0.0.1/::1/
localhost) exception for offline tests and local dev. Enforcement is
central (assertHttps) — the browser-open guard is no longer the only
check whose failure was swallowed.
2. Credential store test isolation: CODEBURN_SYNC_TOKEN_STORE=file
forces the file store (honors HOME) so the offline suite never
touches the real macOS login keychain. Set in the e2e suite.
3. Golden pins for deriveSpanId/deriveTraceId/deriveDeviceId with fixed
inputs and expected hex — the idempotency contract depends on these
encodings being stable across releases; a green-tests encoding change
would silently double-count history on span-ID-keyed backends.
getDeviceId refactored over a pure deriveDeviceId(host, user).
Smaller review items:
- Callback server: ready promise resolves the actually-bound port from
the listening event (kills the 100ms-sleep race after port fallback);
Connection: close on all responses + closeAllConnections() on
shutdown (pooled keep-alive sockets from a closed server could
swallow requests aimed at a later server on the same port); error
handler guarded so a post-bind error can never rebind to a different
port than advertised; optional ports param ([0] = ephemeral) removes
fixed-port contention between parallel test workers.
- fetchOidcConfig verifies the issuer claim matches the fetch origin
(OIDC Discovery §4.3 mix-up defense).
- partialSuccess.rejectedSpans wrapped in Number() — proto3 int64 JSON
mapping sends strings from strict protojson servers; += would
concatenate.
- Ledger writes are atomic (temp + rename); corrupt-ledger recovery and
no-tmp-left-behind tests added; XDG_CACHE_HOME honored (ledger is
reconstructible state, not config).
- Mock IdP now implements /oauth2/authorize (registers PKCE challenge,
302s to redirect_uri) and verifies S256 code_verifier + single-use
codes at the token endpoint. The e2e drives the real redirect flow
and asserts wrong-verifier and code-reuse are rejected — PKCE binding
is now exercised end to end.
- sync reset calls clearLedger() instead of reimplementing the path.
- push sets exit code 1 on rate-limited/server-error outcomes so cron
and script callers can detect incomplete pushes.
Deferred (noted for fast-follow): macOS 'security -i' stdin mode
(untestable on this Linux box), ai.cost_estimated as a real
ParsedApiCall flag (touches core parser types).
Sync suite: 81 passing (5x stable), 5 developer-only.
AI-Origin: human
Addresses T1 review: discovery.ts logs mDNS bind errors to stderr and returns
already-found devices instead of masking failures as empty; spend-flow uses a
collision-proof "other" sentinel and a local-date period label; the spend/date
flags get friendly error handling; devices-json tests are deterministic (mocked
discovery) and assert the read-only mutation guards. 13 tests green, tsc clean.
Implemented by Codex gpt-5.5 (high); committed by Fable (git blocked in Codex sandbox).
* fix(antigravity): read current agy antigravity-cli on-disk layout
* fix(antigravity): propagate SQLITE_BUSY from the .db read so the run retries
---------
Co-authored-by: AgentSeal <hello@agentseal.org>
* fix(cursor-agent): ingest workspace-less CLI transcript layout
* fix(cursor-agent): bump parse version so cached sessions pick up the new ingestion
---------
Co-authored-by: AgentSeal <hello@agentseal.org>
Three PoC fixtures (tool name, bash command, model name) reproduce
the audit's HIGH-1 attack. Tests assert Object.prototype.calls stays
undefined after parsing. They fail against current parser.ts -- Task 3
will close the pollution sink with Object.create(null).