8000 feat: configurable recursion round limit (#861) by adityamukho · Pull Request #875 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

feat: configurable recursion round limit (#861) - #875

Merged
adityamukho merged 1 commit into
v3from
feat/861-max-iterations
Nov 6, 2026
Merged

adityamukho merged 1 commit into
v3from
feat/861-max-iterations

Conversation

@adityamukho
Copy link
Copy Markdown
Collaborator

Refs #861, #862 (no closing keyword: v3 branch; close #861 by hand after merge).

Implements the #861 decisions (issue comment of 2026-11-06), reusing #870's slot and setter code. Plan: docs/superpowers/plans/2026-11-06-861-max-iterations.md.

What changes

  • OpenOptions::max_iterations: the most rounds one stratum of a rule query may run. The default goes from a fixed 1,000 to 1,000,000, the same as max_derived_facts. A stratum only starts another round after deriving a new fact, so at the defaults the derived-facts limit is reached first. This changes answers on v3: a recursion over a chain of more than about 1,000 edges now returns its rows instead of INT-020. It is listed under CHANGELOG Breaking changes.
  • :max-iterations N / $slot: replaces the database value for one query, up or down. INT-012/013/014/015 work as for :max-derived-facts. It is gated by the new Overridable::MaxIterations, which is in DEFAULTS, so it works without configuration, including in BrowserDb.
  • PreparedQuery::with_max_iterations: replaces the database value for one statement. It is not gated, and an allowed keyword still overrides it.
  • Rounds are still counted per stratum.
  • INT-020 round message: now says how to raise the limit (:max-iterations N or OpenOptions::max_iterations).
  • Internal: the database, executor, prepared queries and BrowserDb now pass one engine::Limits value instead of (usize, usize) pairs. The unused DatalogExecutor::new_with_limits is removed.
  • Grammar: grammar.pest, GRAMMAR.md, 6 corpus fixtures, a fuzz seed, and the verifier (41 → 42 tokens).

Verification

  • Ran on the alternate bench machine, because the primary was saturated:
    • plain: 2,083 active / 21 ignored
    • --features test-hooks: 2,118 / 24
    • grammar verifier at bound 4: clean (430 s)
  • The only failure was allow_overrides_test::defaults_read_back_and_compose, which checked for the old two-entry DEFAULTS. I updated it to include MaxIterations, and it now passes in both feature sets.
  • New tests in tests/limit_keywords_test.rs:
    • a 1,500-round chain succeeds at the default
    • the setting, the keyword (including inside a write transaction) and the setter each raise and lower the limit
    • the 4-edge chain's 5-round boundary is checked both ways
    • rounds are counted per stratum: two 5-round strata pass at a limit of 5
    • the keyword is gated (API-025)
    • validation and slot errors
  • Plus a parser unit test, the extended check_overrides order test, a doc test, and a #[wasm_bindgen_test].
  • cargo clippy --all-features -- -D warnings and clippy for both wasm targets: clean.
  • Size: --profile dist grows by +624 B over base 83fbaa8d (measured locally with stable 1.94). Going from feat: :query-memory-limit, limit bind slots and PreparedQuery limit setters (#870) #874's CI number, the binary should stay about 5 KiB under the 1,240 KiB gate, so the gate is not changed.
  • No Codex review: the quota is out until 2026-11-11.

Docs site: the companion PR in project-minigraf/minigraf-docs should merge after this one.

🤖 Generated with Claude Code

https://claude.ai/code/session_01H2a7QoYX6tc5G3sKVzvLjD

OpenOptions::max_iterations sets the most rounds one stratum of a rule
query may run; the default rises from a fixed 1,000 to 1,000,000, equal
to max_derived_facts (a round that continues derived a new fact, so the
derived-facts limit binds first). :max-iterations N|$slot replaces it
per query, gated by Overridable::MaxIterations (in DEFAULTS);
PreparedQuery::with_max_iterations replaces it per statement, ungated.
Rounds stay per stratum. INT-020's round message says how to raise it.
The database, executor, prepared queries and BrowserDb now carry one
engine::Limits. Grammar, GRAMMAR.md, corpus, fuzz seed, verifier (42
tokens), docs and counts updated.

Refs #861, #862

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H2a7QoYX6tc5G3sKVzvLjD
@codecov
codecov Bot commented Nov 6, 2026
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.34146% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/db.rs 95.00% 1 Missing ⚠️
src/query/datalog/parser.rs 94.44% 1 Missing ⚠️
src/query/datalog/types.rs 50.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@adityamukho
adityamukho merged commit 921b393 into v3 Nov 6, 2026
23 checks passed
@adityamukho
adityamukho deleted the feat/861-max-iterations branch November 6, 2026 11:09
adityamukho added a commit to project-minigraf/minigraf-docs that referenced this pull request Nov 6, 2026
…93)

Datalog reference: the keyword, its range, DEFAULTS, the 1,000 -> 1,000,000
default; slot list. Performance tuning: the option, the override table row,
the setter. All under @SInCE v3.0.0.

Refs project-minigraf/minigraf#861, project-minigraf/minigraf#875


Claude-Session: https://claude.ai/code/session_01H2a7QoYX6tc5G3sKVzvLjD

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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

0