Skip to content

Slice 042: rules your decisions imply, never a hint beside a pending one - #98

Merged
HackTuah merged 1 commit into
mainfrom
slice/042-learned-rule-proposals
Sep 25, 2026
Merged

HackTuah merged 1 commit into
mainfrom
slice/042-learned-rule-proposals

Conversation

@HackTuah

Copy link
Copy Markdown
Member

Trinity notices when you have answered the same question the same way enough times, and offers to write the rule so it stops asking. In its own section, read in a calm moment, and never beside a request you are about to decide.

That placement is the whole design

The connectome research report proposed showing a learned recommendation at the arbitration point. Three findings say that is the one place it must not go:

  • Anchoring: a recommendation shown before a person forms their own view moves the decision. Trinity's permission model rests entirely on that decision being independent of what the agent wants.
  • Automation bias: suggestions get accepted without scrutiny, and monitoring stops.
  • Approval fatigue: 49–96% of safety alerts dismissed in the clinical literature; intervention succeeds 9–26% of the time even once a problem surfaces. The cause is volume, so what helps reduces volume rather than annotating it.

So the learned signal is spent on asking less often.

A rule is unanimous or it is not a rule

Nine allows and one refusal proposes nothing — that rule would permit the case you refused. It becomes a divergence to look at instead. Unanimity makes AC3 true by construction rather than by arithmetic.

Two layers hold the placement

  • Trinity.Permissions.Learner is not exported from its boundary, so a direct reference does not compile. The compiler enforces it, not a reviewer — and that is what the planted violation ran into first.
  • Permissions.proposals/1 is the only way in, and a census covers it. Mutation-tested: a leaked_hint/1 planted in approval_components.ex fails the census by name and goes green when removed.

Not behind a flag. A setting that could put a recommendation back on the approval card would be the same harm with a delay.

Accepting is receipted, and rule writes never were

Store.insert_rule/1 inserted and nothing recorded it. An accepted proposal now writes to a new policy chain scope with the count it rested on — its own scope because a rule outlives the session that prompted it, and the count because without it a reader cannot tell a rule you typed from one you accepted.

Carried with this slice

  • CVE-2026-92106 in lazy_html, published today: SVG/MathML script text serialised unescaped. Transitive test dependency, fixed by taking 0.1.13. Slice 120's licence check then caught the stale published list.
  • A correction to slice 120. I read a dangling-path report as two missing files and rewrote references to say so. Both exist under process/; the paths were wrong and the check's regex was reporting a fragment out of the middle of a longer path. It is anchored now, and the references point where the files are.
mix gate
Result: 816 passed (14 properties, 802 tests), 18 excluded

Screenshot in the slice record: fs_read at 14 decisions and session_search at 8 offered as rules; fs_write at 9 allowed / 1 denied reported as a disagreement and deliberately not offered.

🤖 Generated with Claude Code

… one

The connectome research report's A1 and A4, reshaped by the evidence rather than
implemented as written. The report puts a learned recommendation at the arbitration
point, beside the decision the owner is about to make. Anchoring says a
recommendation shown before a person forms their own view moves the decision, and
this project's permission model rests on that decision being the owner's own;
automation bias says suggestions get accepted without scrutiny; approval fatigue
says the cause is volume, so the intervention that helps reduces volume rather than
annotating it.

So the learned signal proposes a rule, reviewed in a calm moment, and reports
divergence after the fact. Both are decisions about the population of future asks
rather than nudges on a pending one.

A rule is proposed only when every past decision agreed. Nine allows and one deny
proposes nothing, because that rule would permit the case the owner refused; it
becomes a divergence instead. Unanimity makes that true by construction rather than
by arithmetic.

Two layers enforce the placement. Trinity.Permissions.Learner is not exported from
its boundary, so a direct reference does not compile and the compiler enforces it
rather than a reviewer. Permissions.proposals/1 is the only way in, and a census
covers that, with a planted violation that annotates a pending approval through the
facade and must be found. Not behind a flag: a setting that could put a
recommendation back on the card would be the harm with a delay.

Accepting writes an ordinary rule through the ordinary path and receipts it in a new
policy chain scope with the count it rested on. Rule writes were not receipted at
all before this. Its own scope because a rule outlives the session that prompted it,
and the count because without it a reader cannot tell a rule the owner typed from
one they accepted.

Carried with it: CVE-2026-92106 in lazy_html, published today, fixed by taking
0.1.13; and a correction to slice 120, where I read a dangling-path report as two
missing files and rewrote references to say so. Both files exist under process/;
the paths were wrong and the check's regex was reporting a fragment. It is anchored
now.

mix gate: 816 passed (14 properties, 802 tests), 18 excluded.

Signed-off-by: Ayla Croft <aylacroft@proton.me>
@HackTuah
HackTuah merged commit 04c921a into main Sep 25, 2026
12 checks passed
@HackTuah
HackTuah deleted the slice/042-learned-rule-proposals branch September 25, 2026 14:25
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