Skip to content

mine: --json, --themes, --solutions, --max infinity and an --interactive shell (0.18.0) - #25

Merged
osick merged 17 commits into
mainfrom
feature/mine-interactive
Sep 10, 2026
Merged

osick merged 17 commits into
mainfrom
feature/mine-interactive

Conversation

@osick

@osick osick commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Summary

helpmate mine result sets you can hold, annotate, narrow and export.

  • --max infinity (or inf): no cap on hits.
  • --themes: annotate every hit with all non-parametric themes it shows; --solutions: every optimal solution as SAN. In text mode these print as indented lines under the FEN; the default output is byte-identical to 0.17.0.
  • --json: one document (material, filter, max, skipped_saturated, positions[]), built with nlohmann::ordered_json. A saturated hit carries "exhaustive": false.
  • --interactive (alias --tui): a std::getline shell over the held set — theme/not theme/count/starts/ends narrow without rescanning, back/reset, list/show, themes histogram, save FILE as JSON or FENs. Prompt and notes on stderr, results on stdout, so piped sessions leave a clean file.
  • Core: new units MineSet (probe/mine_set.h, lazy cached enrichment, narrowing returns a new set) and run_mine_shell (probe/mine_shell.h), both Catch2-tested through string streams; Tablebase::shows_theme shares the ThemeInput construction with themes_of.
  • mine --themes is now a real flag (used to be rejected as a typo for --theme); negative --max is now rejected.
  • Version 0.18.0 in VERSION, the three pyproject files, both package __init__ modules and the helpmate-api pin. CHANGELOG, USAGE, ROADMAP and README (with a screenshot of a real session) updated.

Design: docs/superpowers/specs/2026-09-10-mine-interactive-design.md; plan: docs/superpowers/plans/2026-09-10-mine-interactive.md.

Test plan

  • make test 332/332 on the final tree (core Catch2 incl. 25 new [mine_set]/[mine_shell] cases; 67 cli_* ctests incl. the pinned output modes and a stdin-driven shell session)
  • make format-check BASE=main exit 0, make lint clean
  • Line coverage of the new units, targeted run: mine_set.cpp 94 %, mine_shell.cpp 92 %
  • Tried by hand on the ~/tb corpus (KRvkb h#3, 2000 hits: histogram, narrowing, show, save)
  • Full make coverage refresh of the whole-repo number (about two hours on the dev box; not blocking)

🤖 Generated with Claude Code

https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW

osick and others added 17 commits September 10, 2026 11:41
… and --interactive

Brainstormed 2026-09-10. Decisions: new core unit MineSet beside Tablebase,
plain std::getline shell in the C++ binary, `--json --themes` flag shape,
FEN-then-indented text layout, `--max infinity|inf`. Bindings/API untouched
this round.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…infinity/--interactive

Nine TDD tasks: Tablebase::shows_theme + spec amendments, MineSet (skeleton,
enrichment, narrowing/histogram, JSON+text), stream-driven shell, CLI flags,
end-to-end shell ctest, docs/changelog/0.18.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…le marking

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…e histogram

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
… list, show, themes, save)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…an, dynamic histogram count

Review round 1: std::left leaked from the themes branch into list (adjustfield
is sticky); reformatted with the CI-pinned clang-format; the histogram test no
longer hard-codes the non-parametric theme count.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…ed output)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…save)

Adds cli_mine_shell: a piped-stdin session against the KQvk table that
pins the [N] mine> prompt, theme/count narrowing tallies (580/477/257),
the themes histogram, back/list/show, and save's JSON output, plus a
second session proving unknown themes/commands/hits don't end the loop
and EOF exits 0.

Also carries three test-strength edits to verify_mine_outputs.cmake from
Task 7's review:
- check 2 now pins the actual --max error text ("--max expects an
  integer" and the quoted "inf") instead of bare "infinity", which the
  usage banner alone would also satisfy.
- check 3's "themes" key assertion is restricted to the part of the
  output from the first "positions" occurrence onward (like check 4
  already does), since the top-level filter block always carries its
  own "themes" key regardless of the --themes facet.
- two new cases: --max 0 --json yields an empty positions array, and
  --max infinity --json records max as "infinity" and carries all 580
  fen entries.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…positions

Review finding: "${saved}" MATCHES "\"themes\"" was vacuous the same way
check 3 in verify_mine_outputs.cmake was -- the top-level filter object
always carries its own themes key (the --theme name-list filter)
regardless of whether save actually attached per-position theme data.
Restrict the themes match to the substring from the first "positions"
occurrence onward, mirroring verify_mine_outputs.cmake's check 3a/4.
Also adds the missing "# 3a." label there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…ty/--interactive

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…hecked save

Twelve findings from the whole-branch review of `mine --interactive`.

The shell now tells the user when enrichment could not annotate a position:
every narrowing and the `themes` tally compare `unavailable_count()` before
and after and print one stderr note naming the `helpmate gen` command that
fixes it -- `cmd_mine` already did this for the non-interactive path, and
the shell (where a long session hides it best) did not. That note needs the
tables directory, so `run_mine_shell` takes it as a parameter.

`show` used to enrich a COPY of the hit and throw the work away, while
USAGE.md promised caching; it now enriches the hit IN the set through a new
`MineSet::hit(i)`, so a second `show` and a later `save` are free. The
per-hit text layout it renders was also a second, drifting copy of
`to_text`'s: both now go through one `MineSet::write_hit`, and `to_text`
adds only the blank line between hits (byte-identical output).

`save` reported success without ever checking the write: it now flushes and
tests the stream before printing "saved", and takes the whole rest of the
line as the path, so `save my file.json` no longer writes a file called
"my" and reports that name. On an empty set it no longer claims "(json,
themes)" -- an empty set trivially "has all themes".

A saturated position has no countable solution set, but JSON reported the
`starts`/`ends` of its first 100 solutions as if it were the whole set;
it now says `"exhaustive": false` and omits them, and the text output notes
the cap under the solutions.

Also: `UnsupportedTableVersionError` is absorbed like `MissingTableError`
instead of escaping the shell mid-narrowing; a negative `--max` is rejected
(exit 3) rather than silently behaving like `--max 0`; and the progress note
fires every 100 hits OR every second, as the spec says, worded the same
("evaluating: D/T") in the shell and in `cmd_mine`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
USAGE.md: `line --max` also takes `infinity`/`inf` (the flag is shared with
`mine`, and only mine's section said so); the shell table lists `exit`
beside `quit`, and spells out that only a lowercase `.json` suffix selects
JSON for `save` and that the rest of the line is the path; the JSON section
documents `"exhaustive": false`.

tablebase.h: `themes_of`'s comment still claimed to be THE one place a
ThemeInput is built -- that has been `with_theme_input` since `shows_theme`
arrived, so it now points there.

CHANGELOG: the `exhaustive` key and the rejected negative `--max`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
`show` filled themes and solutions but never the shape, so the "(solution
count saturated: first 100 solutions only)" line that `to_text` and
`to_json` now print for an uncountable hit was invisible in the one command
a user reaches for to inspect a single position. One `ensure_shape` fixes
it, and the three renderings agree again.

The spec's progress sentence follows the implementation to the neutral
`evaluating: 400/1234` wording, and now states the rule as "every 100 hits
or every second, whichever comes first" rather than the parenthetical
"(or 1 s)".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
…, the interactive shell with a screenshot

The screenshot is a real session (KRvkb h#3, 2000 hits, themes histogram,
narrowed to 53 unique model mates without a mirror mate, one shown, saved as
JSON), rendered from the captured stdout/stderr to docs/images/mine-shell.png.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFQB6YogM3gaauunTfMuxW
@osick
osick merged commit bcaece6 into main Sep 10, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant