docs/rationale/parse-sh-database-product.md
parse-sh first landed on the 4.2.0-rc branch as a pure filter: it
emitted the documented execution-event stream, and the documented usage
was a three-stage pipe, make -n | bear parse-sh | bear semantic. A
pre-release review questioned that shape. Every issue driving the
feature (#284, #287, #219, #644, #456, #404) asks for
compile_commands.json; none asks for the intermediate stream. Bear's
headline UX elsewhere is one command in, database out (bear -- make),
and forcing every dry-run user through the split pipeline exposed an
implementer's seam as the user interface.
Shapes considered for shortening the usage to make -n | bear parse-sh:
parse-sh (database by default, events on
request). Rejected: the flag would flip both the meaning and the
default of the output destination, and would make configuration
validity conditional on another flag - two personalities in one
subcommand.parse-sh producing the database,
parse-sh-events keeping the filter. Statically clean - each command
one personality - but rejected as speculative surface: no user has
asked for the raw stream.intercept / semantic split do not
transfer: an intercepted event file is precious because re-running the
build is expensive, while dry-run text is cheap to keep and re-parse,
so caching the intermediate saves nothing. Debug visibility does not
need it either - skip reporting is loud on stderr by default, and
per-candidate debug logging can show what the parser reconstructed
without a second output format.The timing argument settled it: 4.2.0 was not yet released. Adding a public events output later is a compatible addition; shipping one and removing it later is a breaking change. Pre-release is the only moment the minimal surface is free.
parse-sh is a single subcommand whose only product is the compilation
database: shell text in (stdin by default), compile_commands.json out
(default destination), with configuration, append, and
standard-output streaming behaving as in the other database-producing
modes. The reconstructed executions remain the internal seam between
the parser and the unchanged semantic stage; they are never serialized
or exposed.
make -n | bear parse-sh.parse-sh (it runs the semantic stage),
inverting the earlier reject-config rule that guarded the pure
filter.bear intercept is the only Bear producer of the events file. The
interchange format keeps its documented value for third-party
producers feeding bear semantic; what weakens is only the
"second in-tree producer validates the seam" argument from
parse-sh-producer - the parser still targets
the same execution model internally.interception-shell-text-parsing
(the contract this reshapes).