Commit Graph

4 Commits

Author SHA1 Message Date
A.Shakhmatov
b481f39ca3 docs/plan: all 19 aggregate skips are environmental, not 13
The scorecard collapses a whole-file skip into a single `*` line, so counting
the reason lines undercounted the cases they cover. Every one of the 19 is
version- or topology-gated, which is why the gate reads *0 fail* rather than
*all pass*.
2026-08-09 19:40:47 +03:00
A.Shakhmatov
7ae81b8179 plan: M2 splits in two (amendment A6)
The design review found the milestone's gate names a corpus that is not there:
`mongodb/specifications` has no aggregation suite, and the thirteen
`aggregate-*.json` files this project runs live inside `crud` and test the
aggregate *command*, not stages. One name was covering two milestones.

M2 becomes the command surface -- $out, $merge, db.aggregate(), collation,
let -- gated on the corpus that already exists, at 0 fail. M2.5 becomes the
engine: expression evaluator, per-stage document iterator, accumulators,
$unwind; $lookup and $facet explicitly out of the first cut, gated on a
corpus this project writes with every expectation measured against mongod.

Command surface first, engine second, chosen with the cost stated: the engine
is what gives wrong answers now -- six of eight probed pipelines answer ok:1
with a wrong result -- so this order leaves them alive a milestone longer.
Which is why M2 carries the refusals: every unimplemented construct stops
answering 0 and starts answering an error with a measured code, the same move
expectEvents made before the free list in M1. It will push the scorecard down,
and that is the point.

The review keeps its pre-decision recommendation verbatim, so the argument the
decision overrode stays legible.
2026-08-09 19:40:03 +03:00
A.Shakhmatov
37211a6cda docs: M2 design review
PLAN §3 gives M2 one line of scope and one line of gate, and §6 lists the three
questions it deferred. This answers them, and reports one finding that has to
be settled before the rest is worth discussing: the gate named in the plan does
not exist. `mongodb/specifications` has no aggregation suite -- the thirteen
`aggregate-*.json` files we run live inside `crud` and test the aggregate
*command* surface, not stages. $lookup, $unwind, $facet, $addFields and
$replaceRoot appear nowhere in the pinned corpus.

Measured, not recalled. Seven stages exist, not the nine an earlier note in
this project claimed -- $set and $unset are update operators. There is no
expression engine: $field paths are open-coded in two places inside run_group
and $sum is the only accumulator. Probed on a live server, six of eight
pipelines answer ok:1 with a wrong result -- $avg, $max and $push all return
0, a compound _id groups everything into one bucket keyed by the unevaluated
expression, $literal is echoed back, and a $match after a $project still sees
the projected-away field. Only $addFields fails honestly.

That drives the tiering. M2 is not "add stages to the chain": the stream is a
materialized window and each stage moves its bounds, which cannot express
1->N ($unwind), a second collection ($lookup), or sub-pipelines ($facet), and
$project is not a stage transform at all. Six tiers proposed, four gate options
priced, and a recommendation: Tier 0 (refuse what is not implemented) alone
first, for the same reason expectEvents preceded the free list in M1 -- it will
move the scorecard down, and that is the point.

No decision is recorded in PLAN.md yet; that is what the review is for.
2026-08-09 19:32:29 +03:00
86ae8fa8af style: adopt TigerStyle across src/; add docs/TIGER_STYLE.md
Wrap signatures and long expressions to the 100-column limit and make every
file zig fmt clean. Semantics-preserving throughout: ignoring whitespace and
the trailing commas that wrapping introduces, every file here is byte-identical
to its predecessor, and the one apparent exception is a warning string split
with `++`, which concatenates at comptime to the same bytes.

src/index.zig and src/commands.zig are reformatted in the commits that follow,
because their reformat is interleaved with in-flight changes to them and
separating the two would need the reformat re-derived rather than moved.
2026-08-03 17:08:21 +03:00