Skip to content

feat: --word-gate shows the numbers the rules decided on - #239

Open
znat wants to merge 1 commit into
mainfrom
feat/the-rank-shows-its-scores
Open

znat wants to merge 1 commit into
mainfrom
feat/the-rank-shows-its-scores

Conversation

@znat

@znat znat commented Aug 30, 2026

Copy link
Copy Markdown
Owner

The command said which way each rule went and never what it read. That is
enough while the rules agree with you and useless the moment one does not.

Three readings are printed now, and nothing decides on any of them.

Every word with the score the rank sorted on

rank       0 of 15
  →  0  Versailles          -13.74
     1  Versal              -12.71
     2  Mirza                -9.06
     3  deploying            -8.33
    ...
    15  the                  -0.16

One nat between the word the rule calls wrong and the word that actually is.
The four weakest are all proper nouns. The rank reads a place and not a gap,
and this is that stated as a number rather than as a worry.

The ten words the slot's tag came from

slot       Noun
  fills    Windsor (Noun/PlaceName), White (Noun/OrganizationName), Vatican
           (Noun/OrganizationName), Prague (Noun/PlaceName), Edinburgh
           (Noun/PlaceName), Kremlin (Noun/OrganizationName), …

"Determiner" means nothing until second, my, your, any sits under it. And
Noun hides the difference between a list of castles and a list of deployment
platforms, which is exactly the difference the rule needs and does not have —
I deploy my app on ___ predicts Android, localhost, GitHub, Linux, Docker,
Kubernetes, and NLTagger calls almost none of them names.

What the slot makes of the two readings

  slot says  here -14.95   there -9.89   it prefers the term

Printed with a caveat attached. A vocabulary term is by construction a word
nobody knows, so the tokenizer splits it and this number is its first
fragment's. Red Cross and Redcrawl score identically because both start
with Red. It is shown because seeing that is how the trap gets found, not
because it can be read as evidence.

Notes

SlotGate.weakest and .wants keep their shapes and delegate to ranked and
tagged, which return the same answers with the working shown. make test
green.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NMVgtb4jmhQtvWtSJr1bce

The command said which way each rule went and never what it read. That is
enough while the rules agree with you and useless the moment one does not: a
rank of 0 is a place in a queue, and it says nothing about the gap to the word
behind it — which is the whole of what the rank rule gets wrong.

Three readings are printed now, and nothing decides on any of them.

**Every word with the score the rank sorted on**, least expected first, the
span marked:

    rank       0 of 15
      →  0  Versailles          -13.74
         1  Versal              -12.71
         2  Mirza                -9.06
        ...
        15  the                  -0.16

One nat between the word the rule calls wrong and the word that actually is.
The four weakest are all proper nouns, which is the confound stated as a
number rather than as a worry.

**The ten words the slot's tag was taken from**, with their name type where
NLTagger has one. "Determiner" means nothing until `second, my, your, any` sits
under it, and `Noun` hides the difference between a list of castles and a list
of deployment platforms — which is the difference the rule needs and does not
have.

**What the slot makes of the two readings**, its log-probability for the word
present against the term. This one is printed with a caveat attached: a
vocabulary term is by construction a word nobody knows, so the tokenizer splits
it and the number is its first fragment's. `Red Cross` and `Redcrawl` score
identically because both start with `Red`. It is shown because seeing that is
how the trap gets found, not because it can be read as evidence.

`SlotGate.weakest` and `.wants` keep their shapes and now delegate to `ranked`
and `tagged`, which return the same answers with the working shown.

`make test` green.

Signed-off-by: Nathan Zylbersztejn <nathan.zylbersztejn@gmail.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NMVgtb4jmhQtvWtSJr1bce
@greptile-apps

greptile-apps Bot commented Aug 30, 2026

Copy link
Copy Markdown

Greptile Summary

The change expands --word-gate output with slot details and ranked score diagnostics. Two reproduced diagnostic problems remain: repeated words can be mapped to the wrong sentence occurrence, and a reported rank can depend on an adjacent-word window that is not displayed. These issues do not alter gate decisions, but they make the diagnostic output misleading when investigating a result.

Confidence Score: 4/5

The gate's decision behavior is unchanged, but the new diagnostic output can misidentify the relevant word and omit information needed to explain a reported rank.

Focused executable reproductions confirmed both reported failures with concrete duplicate-token and adjacent-window ranking inputs.

Files Needing Attention: Sources/ParrotFlow/WordGateCommand.swift needs occurrence-preserving ranked entries; Sources/ParrotFlow/SlotGate.swift needs to expose the window contribution to its returned rank.

T-Rex T-Rex Logs

What T-Rex did

  • Generated a finding-comment proof for a posted P2 finding, including the executable duplicate-token rank-arrow reproduction source and supporting value-based and original-index lookup artifacts.
  • Generated a second finding-comment proof for a posted P2 finding, including the focused SlotGate rank and payload reproduction source, and the related rank-output logs.
  • Generated a third finding-comment-proof for a posted P2 finding.
  • Validated contract behavior with a focused executable mirror of the rank sorting and duplicate-token arrow lookup using duplicate-span-arrow-00-repro.py, showing the index-preserving approach.
  • Validated the harness behavior before and after capture, observing rank and queue details, with harness assertions passing (exit code 0).

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. General comment

    P2 Ranked duplicate words are marked using their first sentence occurrence

    • Bug
      • WordGateCommand.printSlot determines mine with allWords.firstIndex(of: entry.word). Since SlotGate.ranked emits multiple entries with the same word but different original positions, every duplicate resolves to the first occurrence. The report therefore omits the arrow when the selected span is a later duplicate, or marks multiple rows when the selected span is the first duplicate.
    • Cause
      • The ranked payload discards each entry's original word index (byWord.map { (words[$0], scores[$0]) }), and the consumer attempts to reconstruct identity from a non-unique string value.
    • Fix
      • Return the original index with each ranked entry (for example (index: $0, word: words[$0], score: scores[$0])) and use span.contains(entry.index) when rendering the arrow.

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P2 Word-gate rank cannot be reconciled with its printed score evidence

    • Bug
      • ranked derives word from the sorted individual scores and pair from sorted adjacent-window sums, then returns max(word, pair). Its payload returns only byWord.map { (word, score) }, and WordGateCommand prints only that payload. When pair > word, the displayed word-score position differs from the reported rank with no displayed window score or pair rank to explain it.
    • Cause
      • The diagnostic return value omits windows, byWindow, and/or the selected pair rank even though pair ranking contributes to the returned rank.
    • Fix
      • Include the adjacent-window scores and their ordering (marking windows that overlap the span), or at minimum print both word and pair ranks and clearly identify max(word, pair) as the reported rank.

    T-Rex Ran code and verified through T-Rex

Fix all with Greploop Fix All in Claude Code

Reviews (1): Last reviewed commit: "feat: --word-gate shows the numbers the ..." | Re-trigger Greptile

if reading.rank != nil {
if let ranked = try? gate.ranked(allWords, at: span) {
for (index, entry) in ranked.1.enumerated() {
let mine = span.contains(allWords.firstIndex(of: entry.word) ?? -1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Duplicate words lose occurrence identity

ranked can return multiple equal word values from different sentence positions, but firstIndex(of:) resolves every one to the first matching position. A span on a later duplicate therefore receives no arrow, while a span on the first duplicate marks every duplicate row. Preserve the original word index in each ranked entry and use that index to test membership in span.

Artifacts

Executable duplicate-token rank-arrow reproduction source

  • This focused script mirrors the exact sorted rank payload and `firstIndex` lookup, then compares it with original-index mapping; it provides a runnable reproduction of the identity loss.

Value-based lookup with duplicate tokens

  • This executed legacy-path capture shows no arrow for a span on the second duplicate and two arrows for a span on the first duplicate, confirming incorrect row identification.

Original-index mapping with duplicate tokens

  • This executed index-preserving comparison capture shows exactly one arrow on the actual duplicate occurrence in both span positions, demonstrating the needed correction.

View artifacts

T-Rex Ran code and verified through T-Rex

Fix in Claude Code

Comment on lines +249 to +250
(max(word, pair), windows.count),
byWord.map { (words[$0], scores[$0]) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Reported rank omits its window evidence

The returned rank is max(word, pair), where pair comes from sorted adjacent-window sums, but the diagnostic payload contains only individual word scores. When the window rank exceeds the word rank, the marked word's displayed position disagrees with rank and the output does not show the score or window ordering that explains it. Include overlapping-window scores and ordering, or print both component ranks and explain that the reported value is their maximum.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Artifacts

Focused SlotGate rank and payload reproduction source

  • A minimal Python harness mirrors SlotGate.swift lines 241-250 with concrete individual scores and adjacent-window sums, ending with the pair-rank mismatch assertion.

Captured focused reproduction source command and contents

  • The executed capture command prints the complete focused harness source and exits successfully, establishing exactly what was run.

Parent-style rank output before the diagnostic payload

  • The before-mode execution reports the computed rank without score evidence, providing the requested baseline.

PR-style rank output with unreconcilable individual-score payload

  • The after-mode execution reports word rank 0, pair rank 1, and returned rank 1 while printing only individual scores, proving the omitted pair evidence.

View artifacts

T-Rex Ran code and verified through T-Rex

Fix in Claude Code

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