docs/requirements/interception-events-format.md
Bear's intercept mode writes a JSON Lines file of captured executions
to a file the user names, and Bear's semantic mode reads the same
file to produce a compilation database. The two modes already
ship and work today. What is missing is a written contract: users and
third-party tooling cannot tell which fields are stable, what guarantees
the format makes, or how to produce a synthetic events file (for example,
to convert an existing build log into a compilation database without
re-running the build).
The user expects the events file to be a documented interchange format: schema, encoding rules, and stability promise written down so external tools can produce or consume it without reverse-engineering Bear's sources.
Each event object has exactly these four keys. All four are required:
a line missing any of them, or carrying one with the wrong JSON type, is
a non-conforming line. The source-of-truth type is intercept::Execution
in crates/intercept/src/lib.rs.
| JSON key | Type | Meaning |
|---|---|---|
executable | string (filesystem path) | Path to the program run. May be absolute or a bare name, as the caller spelled it. |
arguments | array of strings | The argument vector; element zero is the program name (argv[0]). |
working_dir | string (filesystem path) | Absolute working directory the program ran in. |
environment | object (string->string) | Environment variables in effect for the program. |
The stable subset is the four key names and their JSON types: changing
any of them requires a major-version bump of the format, and across
major versions compatibility is explicitly allowed to break. Within that
promise, the contents of environment are advisory, not stable. Every
Bear producer applies one shared filter before writing an event: the
captured variables are reduced to the build-relevant subset - those that
can influence which build tool runs or how it compiles. Which variables
qualify is an implementation detail that may change between releases,
with one fixed guarantee: PATH, when present in the captured
environment, survives the filter, so bare executable names remain
resolvable by the consumer. Beyond that, a consumer must not assume any
particular variable is present, and a third-party producer may include
or omit variables freely. Bear's own semantic analysis never resolves a
bare executable -- the recorded compiler keeps the observed spelling --
so a consumer that needs the concrete binary resolves the name in its own
environment.
\n); no comments; no trailing comma; UTF-8
encoded.bear semantic, reading a named events file, accepts any file
conforming to the documented schema. The producer of the file does not
need to be Bear.bear semantic is order-independent across event lines: the
same set of events in any order yields a compile_commands.json with
the same set of entries (modulo append-order semantics defined by
output-append).cli-exit-codes. (A mode that reconstructs
executions from other input - shell text parsing - applies the same
skip-and-continue rule to that input; see
interception-shell-text-parsing.)bear semantic reads the event stream from standard input by default
(naming an input file is the explicit case), and any non-executing
producer may write the stream to standard output, so the format is
pipeable with no flags. Diagnostics go
to stderr, keeping stdout machine-readable. An interactive or empty
event stream produces a stderr notice - either one is almost always a
plumbing mistake.bear intercept writes events only to a file - and because
no stream fallback exists, it has
no default destination either: the event file must be named
explicitly, and omitting it is a usage error reported before the
build runs.bear intercept must
always be accepted by bear semantic. A regression in either
direction is a bug.Given a synthetic events file produced by a third-party tool that conforms to the schema:
When the user runs
bear semantic --input synthetic.json -o cdb.json, thencdb.jsoncontains one compilation entry per recognizable compiler invocation in the synthetic file.
Given a Bear-produced events file from a successful bear intercept
run -- produced by the same Bear, or by any earlier Bear release within
the same major-version line of the format (the schema section above owns
that stability promise):
When the user runs
bear semantic --input events.jsonagainst it, then the run succeeds and the resulting compilation database is identical to the one produced by an equivalentbear -- <build>run.
Given the same three compilation events written to one file in order and to a second file reversed:
When the user runs
bear semanticover each file, then the two compilation databases contain the same set of three entries; only their order may differ.
Given an events file with one malformed line in the middle:
When the user runs
bear semantic --input broken.json, then Bear reports the line number and parse reason, processes the surrounding valid lines, and writes a compilation database from the valid subset.
Given a producer piped directly into bear semantic with no input
file named:
When the user runs
<producer> | bear semantic -o cdb.json, then the event stream is read from standard input andcdb.jsoncontains one entry per recognizable compiler invocation.
Given bear semantic reading standard input with nothing piped in:
When the user runs
bear semantic -o cdb.jsonon the empty stream, thenbearexits0,cdb.jsonis written as an empty database, and a stderr notice reports that the stream contained no events.
Given bear intercept invoked without naming an event file:
When the user runs
bear intercept -- <build>, then Bear exits with a usage error before running the build.
Given bear intercept asked to write events to the standard stream:
When the user runs
bear intercept --output - -- <build>, then Bear exits with a usage error before running the build, the error explains that events cannot go to standard output, and no file literally named-is created.
interception-shell-text-parsing)
reconstructs executions on the same execution model but produces the
compilation database directly and does not write this file; the events
file is the interchange surface for bear intercept and third-party
producers.event-file-defaults - why
intercept has no default event-file name and semantic reads
standard input by default.