[P0] Canonicalize anonymous SWI dict tags across deterministic runtime identities #154
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
nsaspy/prolog-rlm#154
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Failure
Restoring the real aggregate PlUnit runner in #151/#152 exposed a shared deterministic-normalization defect across multiple merged runtime surfaces.
SWI anonymous dict syntax such as
_{a:1}carries a variable dict tag. Several core canonicalizers preserve that representation-only variable tag or reject the entire otherwise-ground payload as nonground. This makes logically identical values unstable or invalid across repeated calls.Concrete evidence from the restored suite includes:
rlm_authority: two calls torlm_operation_fingerprint/3over the same operation produce different SHA-256 fingerprints;rlm_effect: otherwise-ground requests/options containing anonymous nested dicts fail as nonground/instantiation errors;This is the same representation issue already fixed narrowly for recursive-plan fingerprints in #135, where
canonical_recursive_dict_tag/2maps a variable dict tag to the stable sentinelrlm_anonymous_dict.Root cause pattern
Canonicalizers currently do variants of:
or apply
ground/1to the whole dict term before treating an anonymous tag as representation-only.A variable anonymous tag must not become semantic identity and must not make a closed dict payload fail deterministic normalization.
Required invariant
For closed data APIs, anonymous SWI dict tags are representation-only:
must normalize deterministically to the same closed canonical value on every call. A genuinely variable dict value, list member, compound argument, key-bearing semantic field, or executable field must still fail closed.
Named dict tags remain semantic and must be preserved.
Scope
Audit and fix every deterministic identity/normalization boundary that handles closed runtime data, especially current failures in:
Prefer one small shared helper if it reduces duplicated security-sensitive normalization without creating a generic untyped fact layer. Otherwise apply the same explicit rule at each owning module boundary.
TDD / acceptance
swipl -q -s test/run_tests.plis the merge oracle and cannot be replaced by the focused async runner;Coordination
Base remediation on the #152 runner-integrity head until #152 lands, so failures are measured through the real aggregate gate. Keep #149 ownership untouched.
Discovered during the post-false-green audit of work merged after #60.
Completed on current main through the integrated closed-data boundary in #177. Exact current-main focused verification passed 136/136 across closed-data, authority/effect identity, Spec, prompt compiler, and evolution; full aggregate passed 762/762. PR #155 was closed as superseded.