Did you know ... Search Documentation:
Pack hornguard -- profiles/REVIEWS.md

Profile reviews

An entry in a profile is an attestation that a predicate is pure under adversarial use on a given engine. Generation (`make gen-profiles`) produces the candidate list; a review is a person reading it against the engine it was generated from. This file is the record. It is not generated.

Profile(s)Generated againstGeneratedReviewed byReviewedNotes
iso, prologue, pinnedhand-written2026-09-18Nicholas Wright (DataGrout)2026-09-22ISO builtins less mutation, I/O, loading, flags, reflection; prologue as in the Prolog prologue proposal; pins by name where a single arity would be the whole game
swi, swi_lists, swi_apply, swi_aggregate, swi_solution_sequences, swi_strings, swi_pairs, swi_ordsets, swi_assoc, swi_terms, swi_error, swi_random, swi_backcompSWI-Prolog 9.2.92026-09-22Nicholas Wright (DataGrout)2026-09-22Read against the sandbox differential (zero unexplained disagreements) and the exclusion table; swi_random admits randomness deliberately
swi_solution_sequences, swi_termsSWI-Prolog 9.2.9, differential run on 10.0 and 10.12026-09-24Nicholas Wright (DataGrout)2026-09-24reduced/1, reduced/3, term_factorized/3 excluded: SWI 10's sandbox refuses them (trie-backed), so the profile no longer admits what the deployed engine would refuse. 10.x also has foldall/4, ord_range/4, string/4 sandbox-safe and unknown here; refused as unknown until a 10.x generation
engine_scryer, engine_trealla manifestsprobe run inside each engine2026-09-19Nicholas Wright (DataGrout)2026-09-22Existence only; meta specs on these backends come from the profiles and must be complete
engine_scryer, engine_trealla manifestsScryer 0.10.0, Trealla 3.10.412026-09-22Nicholas Wright (DataGrout)2026-09-22Regenerated after the engine attestation: variant/2 leaves the Scryer manifest (reported built-in, not defined as started); call_residue_vars/2 joins the Trealla manifest (pinned deferred_execution)

A regeneration that changes an entry needs a new row, and the differential (`make test-differential`) is the check that says whether the engine or the file moved.

Attested by experiment

`make attest` calls every allowed predicate with tripwires around it (tools/attest.pl); `make attest-engines` does the same inside Scryer and Trealla with the tripwires those engines can express (tools/attest_engine.pl). A review reads the list; this runs it.

EngineDateResultFindings
SWI-Prolog 9.2.92026-09-22313 pure, 10 declared (swi_random), 0 undeclared, 2 skipped (maplist/6, maplist/7 not defined on this engine)write_ln/1 writes: pinned. eval_license/0, hash/1, index/1 print: excluded from the generated profile. A list in goal position is consult/1: pinned under loading.
SWI-Prolog 9.2.9, positional sweep2026-09-23312 pure, 10 declared, 0 undeclared after the pin; 1 findingnormalize_space/2 writes to a stream given as its first argument (user_error, user_output); SWI's sandbox declares it safe. Pinned under streams.
Scryer Prolog 0.10.02026-09-2269 allowed predicates the manifest names: 69 pure, 0 impure, 1 not definedvariant/2: predicate_property/2 says built-in, a call raises an existence error. Removed from the manifest by the generator's phantom list.
SWI-Prolog 10.0.2 (Docker)2026-09-24full attestation test passes; bounded_number/3 purenone
SWI-Prolog 10.1.14 (development, Docker)2026-09-24engine crashes during bounded_number/3: a caught type error with a compound global set frees an invalid pointerreported upstream; the development CI job is advisory
Trealla Prolog 3.10.412026-09-22109 allowed predicates the manifest names: 109 pure, 0 impure, 0 not definednone

`make fuzz` is the inverse: terms the judge admits, run with the same tripwires, with pinned canaries placed where a judge can lose a goal. 400 terms at seed 20260922 and 200 at seed 7 on SWI-Prolog 9.2.9, 2026-09-23: no composition failure, no judge miss.