You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Follow-ups from #912: auto-commit refusal hardening and HOME resolution #917
taskId in the blocker summary is not sanitized. The mail path validates message ids, but the Flair task loop takes event.refId ?? event.id, and refId is only type-checked. Validate or sanitize it before it reaches the summary or the error.
The repository path and a spawn error's message enter the error text unsanitized; only the probe's stderr is sanitized.
If publishing the blocker fails, the refusal again ends as a warning and a null PR URL in _runAutoCommitLegacy, after the task was reported complete. Consider failing the task itself.
publishEvent has no timeout; a hang blocks the refusal (it still fails closed).
The sanitizer leaves non-Cc display controls (U+2028/U+2029, bidi overrides U+202A-U+202E and U+2066-U+2069), and .slice(0, 300) can leave a lone surrogate. Decide whether those belong in the replaced set.
Text: the function comment omits the .trim(), and "Remove ANSI CSI escapes" does not cover the 8-bit CSI (U+009B is replaced by a space and its parameter bytes stay as text).
The long-stderr test pins the cap only to about 456 characters; an assertion on the exact length would pin 300.
No real-Flair test covers the blocker event (the test uses a fake publisher).
HOME resolution (#822)
9. About 30 other files under packages/cli/src still resolve paths with os.homedir(). None is reachable from the runtimes changed here, and none is wrong while nothing changes HOME in-process, but consolidating on homeDir() removes the trap that produced #822.
10. bin/tps.ts builds the runtime's mailDir/extraDirs with homedir() at launch; if in-process HOME changes are supported, those stay on the start-up HOME.
11. The Gemini runtime prepends <HOME>/.tps/bin to the child's PATH, so spawn("gemini") also resolves through it; with a per-task, mutable HOME, resolve gemini before prepending.
12. flair-client.tsdefaultFlairKeyPath() still uses homedir() (unreachable from these runtimes, which require flairKeyPath).
On item 1, the shape Sherlock recommended after #912's review: constrain refId once at ingest rather than sanitizing each call site. org-event-read.ts rejects a refId over a bounded length (e.g. 128) or outside a safe character class (no C0/C1 controls, no U+2028/U+2029), with the matching constraint on the Flair OrgEvent schema. That one change covers every summary that interpolates taskId (the refusal blocker, Completed:, PR opened for, Task … failed, both PR creation failed for sites), not only the one #912 touched.
Activity
tps-flint commentedon Nov 10, 2026
On item 1, the shape Sherlock recommended after #912's review: constrain
refIdonce at ingest rather than sanitizing each call site.org-event-read.tsrejects arefIdover a bounded length (e.g. 128) or outside a safe character class (no C0/C1 controls, no U+2028/U+2029), with the matching constraint on the Flair OrgEvent schema. That one change covers every summary that interpolatestaskId(the refusal blocker,Completed:,PR opened for,Task … failed, bothPR creation failed forsites), not only the one #912 touched.