IdAllocator::suffixed recursed once per taken candidate, and the call was not
in tail position. A document claiming item-1 through item-N aborted the process
on a stack overflow at N of about 11,000 in debug. This answers the Codex P2 on
PR #318. The loop still advances the counter on every candidate it tries.
Three tests are added:
- a long claimed run (20,000), which aborted before the fix;
- claim refusing lookalike virtual ids (_indexer, _measure-1), which the
review's prefix-match rival passed before;
- a display with leading spaces that must not slug into the reserved `_` space.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
- 8jk6.6, the user's ruling on PR #321 ("Add a --strict flag"): the
default stays exit 0 with the counted warning. With --strict, any
skipped record is a refusal that exits 1 and writes nothing. The check
runs before the build and reads ImportPipeline::skip_warning, the same
function the build's warning now comes from.
- 8jk6.17: the headless suite now sees three faults that only io unit
tests caught at efaa5050:
- naming only the first bad formula (two bad --formula flags);
- dropping CSV decimal measures;
- import-json reading a CSV through the JSON constructor.
- Docs record the user's three answers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
At the user's request. Specified as a hybrid (Decimal, boxed Ratio<i128>, f64) and measured against rust_decimal and f64: per-operation cost, 18k/90k SUMs, and overflow rates for margins, sums of ratios, percentages, averages and compound growth. Sums group by denominator. The question 2 recommendation changes from (a) to (d); new question 12 on typing a fraction.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
The ADR 009 agent's independent check found about 40% misses for signed values in ±1,000 at every term count; reproduced here (38-40%). The claim that the f64 accumulator solves large sums now holds only for same-sign data. Both distributions are tabled, and ADR 009's head 8ebcf889 is cited as agreeing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
A decimal Sum is a group only through ADR 005's wide accumulator, used by
both backends. rust_decimal's own + is not associative at its 28-digit
bound. ExactSum does not make = against a typed decimal right: it can miss
in the last bit. The decimal cost cell now uses ADR 005's measurement, and
exact-to-f64 conversion goes through the decimal string.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Exact values are summed in a wide fixed-point integer, because rust_decimal's own add rounds at its bound and so was not order-free (B1, Codex P1). The one conversion to f64 goes through the decimal string, because Decimal::to_f64 is not correctly rounded (B2). Mixed comparison is exact, with a MIN/MAX tie-break; formula literals are Num; a scale-only edit bumps the record's version; parsing refuses rather than rounds. New questions 10 (accumulator width) and 11 (tie-break). Cites improvise-felo.9 and ADR 009 at 25ebf641.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Regenerated with `crate2nix generate` (0.15.0, from the dev shell). The new
file adds the unicase 2.9.0 crate and the improvise-core edge to it. It also
picks up the test-support feature edges that main's Cargo.lock already had
and Cargo.nix was missing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
- 5a: group by context (the stem projection, plus the fold/total projection),
not by record key. The inner WHERE is a filter plus clause 5's join. There is
an integrated per-record stage before the map, and a rule for several writes
to one record. The order key is (context rank, record store order), so the
pre-step-6 re-fold is bit-equal to eager at folds and totals. The first-Err
error channel is kept.
- ExactSum splits weights into chunks of 2^30 and counts magnitude between
carries. The example checks weight 2^33, and 20,000 weighted cases match
exact fractions. The example prints the cost per update.
- Q3(c) states the signed-zero difference and Eager's per-read cost. Q11 is
narrowed: drawn-item order is already in view_shape.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
After merging PR #314, a header-only file's seeded File proposal means the
category check alone no longer refuses an import that kept no record.
nothing_to_import does, and this pins it. The docs now name from_merge
(switched to from_csv in the merge) among the CSV entry points.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
A two-level numeric tower: exact decimals (rust_decimal) by default, inexact f64 by Scheme's contagion rule. Measured against f64, bigdecimal and num-rational, and against ADR 009's exact f64 accumulator. Registered on the doc site.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
context/code/protocol.md gains section 10 and tui.md's colour section now
describes face_style; the pointers to axis_fg, minibuf_fg and AxisColor
elsewhere follow. Evidence for the new tests.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
context/code/formula-and-io.md gains the argument for text-first CSV and for
the two refusals, and puts the partial-skip exit code to the user.
context/code/cli.md §13 states the headless contract. Evidence entries are
added for the new tests, with notes on the three parser entries whose
premise moved.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
context/code/core.md §19 gives the reasoning behind model::id.
context/test-evidence/core.md records, for each test, the rival that was
injected and the test that caught it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
model::id adds slugify, which case folds, turns each run of spaces into one
`_`, strips everything outside a-z, 0-9, `-` and `_`, then drops leading
underscores. It also adds IdAllocator, which keeps one increment-only counter
per document plus every id seen this session; claim admits hand-written ids
verbatim. Full case folding comes from the unicase crate. Nothing calls it yet.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
axis_fg, minibuf_fg, field_kind_fg and mode_style are gone, and AxisColor
leaves improvise-core. The category-add prompt turns green, ADR 004
clause 8's one declared exception.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
churn.csv now has a fixed header. When no file changed in the window,
no model is built and the report says so. docs/*.md, README.md and
RELEASING.md count as prose, and .codex/ as agent docs. The suite no
longer builds improvise itself, because checkers.sh scrubs the linker's
environment.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
- 8jk6.4: the CSV parser yields source text (CsvRecords), and only the
role reads it as a number. A forced category keeps 00565796 and
220944e2 verbatim; measures and analysis read the text through
csv_parser::number_in. CsvRecords reaches a pipeline only through
ImportPipeline::from_csv, so handing CSV text to the JSON constructor
no longer compiles.
- 8jk6.5: an import formula that does not parse is refused by name with
its parse error: the build refuses (headless exits non-zero and writes
nothing), and the wizard keeps it out of the list with the text still
in the buffer.
- 8jk6.6: an import that kept no record refuses and says why, from the
build and from the wizard's review step. A partial skip stays a
warning with a count and exit 0.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
- Reframed: incremental formula evaluation for streamed data (ADR 003) is the
primary benefit, and ADR 008's grid is the second consumer.
- New clause 5a: aggregate over an expression, as a lifted map feeding the
group aggregate, still evaluated by eval_expr.
- Clause 4: ordered state for LAST/FIRST (felo.7) and semi-additive measures
(felo.8). New question 11.
- Clause 8: DBSP alone gives no floating-point benefit. An exact superaccumulator
makes f64 SUM a true group. It is measured in retraction_drift: bit-equal after
1M cycles, about 3.2 ns per update, 568 bytes per group. It is correct against
math.fsum on 20,000 cases, and xsum 0.1.6 is rejected. The principle of
deferring lossy operations, and a table of what each exact domain covers.
Question 3 gains option (c) and recommends it.
No clause or question number moved.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
set-axis reads its axis at parse time, so an unknown keyword is an argument
error. set-axis, set-page, hide-item, show-item, toggle-group and switch-view
refuse an unknown category, item, group or view by name instead of doing
nothing, so a headless run exits non-zero.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
ImportPipeline::from_merge seeds the File items and every file's columns
from Merged::sources, so a header-only CSV keeps its File item and its
columns (unseen columns are proposed as Labels, as an all-null column
is). A file with no measure column gets a records view filtered to it
instead of paging onto another file's hidden measure. Four per-file-view
rules the review found untested now each have a test that fails when
the rule is broken.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze