docs/rationale/event-file-defaults.md
Through Bear 4.1.x, bear intercept wrote its event stream to
events.json by default and bear semantic read events.json by
default. The paired defaults made the split two-step workflow flagless,
at the price of a magic rendezvous filename in the current working
directory: the two subcommands coordinated through a name neither the
user chose nor any external tool consumes. That carried a real hazard -
a stale events.json from an earlier run could be silently reprocessed
by a bare bear semantic - and a hidden coupling: nothing in either
invocation said the two commands were connected.
Shipping bear parse-sh in 4.2.0 changed the balance. The pipe
bear parse-sh | bear semantic becomes a primary way to feed
semantic, and the events.json default fought it: forgetting
--input - died with a baffling "Event file not found: events.json".
Viewed as a UNIX tool, semantic
is a pure filter - no build, stdout free - and filters read standard
input when no file is named. intercept is the opposite case: it can
never use standard output (the build owns that stream), so no natural
default exists for it at all.
The two file names in play are not equivalent. compile_commands.json
is an ecosystem contract - Clang tooling finds the database by that
exact name - so defaulting to it carries meaning. events.json was a
name Bear invented; no third-party contract depends on it.
Alternatives considered:
semantic --input to - only when stdin is not a TTY.
Rejected: isatty-dependent semantics make the identical command line
behave differently in a terminal and in CI, and CI stdin is often an
empty pipe even when the user meant a file - a silent
empty-database path.intercept a stream default by redirecting the build's own
stdout to stderr, freeing standard output for the event stream.
Rejected: it silently changes observable build behavior - tools that
detect a tty or write results to stdout would break - for a pipeline
no producer needs.--input on semantic too, symmetric with intercept.
Rejected: a pure filter refusing to read stdin by default fights the
convention this redesign invokes, permanently bakes --input - into
the flagship parse-sh pipeline, and diverges from parse-sh, whose
input already defaults to -. The asymmetry with intercept is
principled: require the flag where no natural default exists; use the
conventional default where one does.bear semantic [FILE], stdin when
omitted), the purest filter spelling. Not taken: -i/--input
defaulting to - is equally conventional and keeps semantic
consistent with parse-sh's existing flags.bear intercept requires an explicit --output; there is no default
event-file name. bear semantic --input defaults to -, reading the
event stream from standard input like any filter. The
compile_commands.json output default stays everywhere. Two guards
soften the filter footguns: semantic prints a stderr notice when it
is about to read events from a terminal, and warns when the event
stream turned out empty.
Update (pre-4.2.0 release): parse-sh later stopped emitting the
event stream and produces the database directly
(parse-sh-database-product), so the
parse-sh pipeline this entry cites no longer exists. The decision
stands on its remaining grounds: the stale-rendezvous hazard, and
semantic as the filter fed by bear intercept event files and
third-party producers.
bear semantic is flagless. The confusing
missing-file failure dissolves instead of being papered over with a
hint. (At the time of the decision the flagship pipe was
bear parse-sh | bear semantic; see the update note above.)events.json hazard is gone; an event file is only ever
read because the user named it.bear intercept
without --output is a usage error before the build runs, the best
available failure mode.--output /
--input. This is a deliberate breaking change shipped in 4.2.0,
before parse-sh examples ossify; it only gets more expensive later.bear semantic on a terminal blocks reading stdin like sort
or jq would; the TTY notice names the way out.interception-events-format
(the seam whose endpoints this names).parse-sh-producer (the producer that made
the pipe a first-class feed).bear semantic fed from a pipe
failed with "Event file not found: events.json" instead of reading
standard input.