Skip to content

fix(mt#4498): Scope the pre-narration merge evidence and reach the second MCP alias - #3484

Open
minsky-ai[bot] wants to merge 2 commits into
mainfrom
task/mt-4498
Open

fix(mt#4498): Scope the pre-narration merge evidence and reach the second MCP alias#3484
minsky-ai[bot] wants to merge 2 commits into
mainfrom
task/mt-4498

Conversation

@minsky-ai

@minsky-ai minsky-ai Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Summary

The pre-narration detector warns when an agent claims an outcome before verifying it. Two calibration
windows measured its injected residual at 10 of 10 false — every one an agent reporting a result
already in hand.

I measured the cause before changing anything, and it is not what the spec assumed. Replaying the
whole log: the evidence is in the window and requiredTools does not name the tool carrying it.

Replayed through today's detector: 67 still fire, 17 suppressed
   36  review-approved — tool-absent
   18  merged          — tool-absent
   11  pr-created      — tool-absent

What this delivers — read this first

A correctness change, not the false-positive reduction the task set out to make.

baseline         67 firing / 17 suppressed
unscoped (R0)    56 firing / 28 suppressed   ← UNSOUND, withdrawn at review
scoped   (R1)    65 firing / 19 suppressed   ← this PR

2 of 65 eliminated, not 11.

Why scoping costs almost all of it — the structural finding

extractClaimedPrNumber reads the matched phrase. review-approved's dominant pattern is the
bare token /\bAPPROVED\b/, so the phrase is literally "APPROVED" and carries no PR number — the
category cannot be identity-backed as written, and identity-scoping is the only sound form of the
merge evidence. A PR-carrying pattern ordered before the bare one makes a claim that does name its
PR scopeable; that is the 2. Most of the corpus does not, and 16 of the 36 leaks have no tool calls
in window at all
.

This ceiling is now its own task: mt#4810.

The two fixes

1. A merge of PR #N entails the approval of PR #N. session_pr_merge refuses a PR with no
approving review, so the merge proves the approval happened.

R1 corrected this. I first put the merge tools in requiredTools unscoped, arguing a merge is
an action performed rather than a read. True, and it does not license the scope: unscoped, a merge
of PR #100 suppresses a false "PR #200 APPROVED" claim. It also contradicted this file's own stated
principle one list below — "the safe degrade direction is MORE fires, never fewer." Now
identity-scoped.

2. The second MCP server alias was invisible. Matching is exact Set.has; this project runs both
mcp__minsky__ and mcp__minsky-server__, and the detector referenced the former exclusively
(grep -c → 0). Every result claim in a session on the other alias could never be suppressed.

R1 also corrected this. My first fix normalized the two tool-name sets and missed
extractPrNumbersForTools, leaving PR-number correlation one-sided. Both paths now use
bareToolName.

Testing

Execution evidence:

$ bun test ./.minsky/hooks/pre-narration-detector.test.ts
 73 pass / 0 fail

$ bun run test:hooks
 6798 pass / 0 fail across 183 files

test:hooks is explicit — ROOTS excludes .minsky/hooks, so the gated pre-push runner cannot
reach this tree.

Negative controls — three, because the failure mode is a tune that silently disables the
category: a merge of a different PR must not suppress (encodes R1 directly); no evidence must
still fire; an unrelated tool under the alias must not suppress. Each differs from its positive by
one thing.

Verified the suite can fail: reverting the entailment turned exactly one test red and no others.

Reconciled an existing test rather than deleting it — it asserted review-approved has no
identity evidence, true only while merged was the sole category with scoped tools. Its intent was
category keying, so it now asserts a READ backs merged and does not leak into review-approved.

Typecheck: 0 errors, 8 projects. Lint: 0 errors, 0 warnings, 4179 files.

SC4 — resolved by the principal, not deferred

This is the PR's one BLOCKING finding, and it is now answered. The reviewer was right that SC4
(flip log-only → warn) had no disposition at review time.

ask#11118, answered 2026-08-31: "Keep it quiet, I file a task for the real fix." A selected
option label — principal provenance. The detector stays log-only until a tune actually moves the
count; the ask stated the real rate (65 of 167) so the call was made against the honest number, not
the withdrawn one. The follow-up it names is filed as mt#4810.

So SC4 is satisfied by not flipping. Nothing further is owed here.

Not closed here

16 of 36 review-approved leaks have an empty tool window — a result reported in a turn with no
tool calls, referring to something verified more than TRAILING_WINDOW_TURNS = 12 turns back. No
tool-list change reaches them. Owned by mt#4810.

Deploy impact

[no-deploy-impact]isDeploySurfaceFile false for all three changed files, run over the diff.

…missing

Measured before changing anything, by replaying the whole log through today's
detector. The spec framed the residual as the detector being unable to tell
'claim precedes evidence' from 'claim reports evidence in hand'. The measured
cause is narrower and mechanical: the evidence is present in the window and the
requiredTools list does not name the tool carrying it.

Two fixes, both sized before being made.

1. A completed merge entails the approval it merged on. session_pr_merge refuses
a PR with no approving review, so an agent that merged cannot have been
pre-narrating that approval. Of the 36 review-approved fires still leaking, 10
had session_pr_merge in window and no other listed tool - the largest
addressable share of the largest leaking category. Deliberately NOT
identity-scoped, unlike the merged category's read tools: a read of some other
PR says nothing about this one, but a merge is an action performed in this
session and the entailment holds without matching PR numbers. Scoping it would
drop the 6 of 10 whose claim names no PR number.

2. The second MCP server alias was invisible. Matching is exact Set.has, and
this project runs both mcp__minsky__ and mcp__minsky-server__; the detector
referenced the former exclusively, so a session on the other alias emitted tool
names that could never match and every result claim in it fired. Fixed by
registering each observed tool's bare suffix, which makes the bare entries
already present in all four categories do the work and covers future aliases
with no further edit. Measured share: 2 of 65, i.e. 3 percent - recorded with
its size precisely because an earlier draft of this pass was about to fix it as
though it were the cause.

Result on the replayed corpus: 67 still firing to 56, suppressed 17 to 28, and
no claim stopped matching. review-approved tool-absent 36 to 25, pr-created 11
to 10.

Five new tests, three of them controls: an unrelated tool must not suppress, an
unrelated tool under the alias must not suppress, and the same claim with no
tool in window must still fire. Verified the suite can fail - reverting the
entailment turns exactly one test red and no others.

Named residue, not closed here: 16 of the 36 review-approved leaks have an EMPTY
window, a result reported in a turn with no tool calls at all referring to
something verified more than 12 turns back. No tool-list change reaches those.

SC4, the log-only to warn flip, is deliberately NOT in this commit. ask#9335 was
read directly: the principal selected the option labelled 'Leave quiet, tune
first'. The clause about it coming back on once the tune lands sits in that
option's description, which is agent-authored. The tune is authorized; the
posture flip is one confirmation away.
@minsky-reviewer

minsky-reviewer Bot commented Aug 30, 2026

Copy link
Copy Markdown

Minsky Reviewer Status

Review in progress...

@minsky-ai minsky-ai Bot added the authorship/co-authored Co-authored by human and AI agent label Aug 30, 2026

@minsky-reviewer minsky-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: 2


Request changes. The PR improves the suppressor but introduces two new risks and misses a required flip. 1) Over-broad suppression: adding unscoped session_pr_merge as evidence for review-approved will suppress claims about PR B if any PR A was merged in-window; merge-entailment should be identity-scoped when a claim names a PR. 2) Alias handling is not applied to identity-scoped evidence; buildIdentityEvidence still does exact-name matches, so minsky-server alias reads don’t contribute PR numbers. Also, Success Criterion 4 (flip back to warn) is not met — INJECTION_ENABLED remains false — and docs weren’t updated for the new semantics. Please scope merge evidence to the claimed PR (when numbered), extend alias handling to identity-scoped PR-number extraction, either perform the posture flip or adjust the task spec, and update docs accordingly. Overall test additions are solid, but these correctness and compliance gaps must be addressed before merge.

Findings

  • [BLOCKING] .minsky/hooks/pre-narration-detector.ts:322 — Over-broad suppression: unscoped session_pr_merge treats any merge as evidence for any review-approved claim
    You added merge tools to review-approved.requiredTools and explicitly chose NOT to identity-scope them (see the new comment and entries at .minsky/hooks/pre-narration-detector.ts:314-333). As a result, detectPreNarrationWithSuppression() will suppress a review-approved claim whenever ANY merge occurred in-window (sameTurn/inWindow checks), even when the claim names a specific PR number that was not merged. This can mask genuine pre‑narration on PR B simply because PR A was merged earlier in the same session.

  • Evidence of the unscoped addition: .minsky/hooks/pre-narration-detector.ts:314-333 — merge tools added under requiredTools with a comment “NOT identity-scoped”.

  • Suppression path: .minsky/hooks/pre-narration-detector.ts:611-630 — suppression triggers on sameTurn || inWindow over requiredTools with no PR-number check.

Requested fix: Bound the merge‑entailment to the claimed PR when the claim names one. Concretely: for review-approved, treat session_pr_merge/merge_pull_request as evidence only when (a) the claim names a PR number and (b) a merge tool in the window targeted that PR (similar to how merged.identityScopedTools works). When the claim names no PR number, you can keep the current unscoped entailment. Add unit tests for the numbered-PR case to prevent regressions.

  • [BLOCKING] .minsky/hooks/pre-narration-detector.ts:534 — Alias fix not applied to identity-scoped evidence: PR-number correlation misses minsky-server alias tools
    buildIdentityEvidence() derives PR numbers via extractPrNumbersForTools(slice, scoped) where scoped comes directly from category.identityScopedTools (see .minsky/hooks/pre-narration-detector.ts:518-544). extractPrNumbersForTools uses findToolUseInputs(lines, toolName) which requires an exact-name match.

You added withBareToolAliases and applied it to the presence sets (same-turn and window) via extractWindowToolUseNames() and in-turn toolNames (see .minsky/hooks/pre-narration-detector.ts:499-516 and :606-614), but you did NOT apply any aliasing when resolving identity-scoped tool INPUTS. Therefore, a session that emits mcp__minsky-server__session_pr_get or mcp__minsky-server__pull_request_read will not be recognized by identity correlation, because identityScopedTools lists only mcp__minsky__… and the bare names. This silently drops legitimate identity-scoped evidence under the alternate alias — the very invisibility this PR set out to address.

Requested fix: Expand identity-scoped tool-name matching the same way you did for presence sets. Options include: (a) have extractPrNumbersForTools accept a Set from withBareToolAliases(identityScopedTools) and treat observed names by suffix; or (b) pass an expanded name set into buildIdentityEvidence. Add tests proving that mcp__minsky-server__session_pr_get contributes PR numbers to identity evidence.

Spec verification

Criterion Status Evidence
The tune distinguishes report-a-result-in-hand from claim-a-result-not-yet-had, and the discriminator is stated explicitly in the implementation rather than left implicit in a regex. Met .minsky/hooks/pre-narration-detector.ts:481-517 introduces withBareToolAliases and uses explicit tool-presence/evidence semantics; .minsky/hooks/pre-narration-detector.ts:304-333 explicitly encodes merge-entailment as evidence for approvals. The discriminator is tools-in-window (and identity-scoped reads), not regex-only.
Re-run against the captured window: the 10 injected fires drop, and the count of correctly suppressed matches does not fall. A tune that quiets the class by widening suppression until the detector fires on nothing is the failure mode to avoid. Unverifiable This requires rerunning scripts/diagnose-pre-narration-window.ts and comparing counts. The diff does not contain the output artifacts; the PR description reports numbers, but those are out-of-repo execution results. Per the constitution, this cannot be verified from the diff alone.
A negative control is recorded: a genuine pre-narration sentence — a result asserted with no preceding tool return — still fires after the tune. Without this the tune is indistinguishable from disabling the detector. Met .minsky/hooks/pre-narration-detector.test.ts:1049-1067 adds a negative-control test under mt#4498 — a merge entails the approval it merged on ensuring the same claim with NO tool in window still fires. Additional controls for unrelated tools and alias behavior are present at :1069-1117 and :1119-1154.
mt#4286's restore condition is discharged: once this lands, the detector returns from log-only to warn, and the flip is recorded where mt#4286 records the quieting. Not Met INJECTION_ENABLED remains false in .minsky/hooks/pre-narration-detector.ts:69-104. No change to the posture flag or registry wiring is present in the diff. The PR body explicitly defers the flip. This contradicts the Success Criteria’s requirement to restore from log-only to warn upon landing. Either update the task spec to reflect this deferral or add the flip here.

Documentation impact

  • blocking-needs-update — This PR changes suppression semantics (approvals now considered backed by merges; alias handling widened). If any docs describe the pre-narration detector’s evidence sources or suppression logic, they are now stale. I could not find docs updated in this diff; .minsky/hooks/pre-narration-detector.ts comments changed but no docs/ file was touched. At minimum, the architecture doc that explains detector categories and evidence (“hooks/pre-narration-detector” or a shared guard overview) should note merge-entailment and alias handling. Additionally, the task spec’s Success Criteria demanded flipping posture back to warn; since the code leaves INJECTION_ENABLED=false, any doc claiming the detector is live would be wrong and should be aligned with actual behavior or the code should be changed.

…lias on both paths

Both findings were correct. The first is the more interesting one.

BLOCKING 1 - over-broad suppression. I had put the merge tools in requiredTools
UNSCOPED, arguing a merge is an action the agent performed rather than a read, so
the entailment holds without matching PR numbers. That argument is true and does
not license the scope: unscoped, a merge of PR #100 suppresses a false 'PR #200
APPROVED' claim in the same window. It also contradicted this file's own stated
principle one list below - for a suppressor the safe degrade direction is MORE
fires, never fewer. Moved to identityScopedTools.

BLOCKING 2 - the alias fix was one-sided. I normalized the two tool-NAME sets and
not extractPrNumbersForTools, which matches names exactly too, so PR-number
correlation stayed blind to mcp__minsky-server__. Fixed at that function, with a
test asserting identity evidence sees the alias.

Scoping surfaced a real constraint, and it costs most of the gain. Honest
numbers on the replayed corpus:

  baseline        67 firing / 17 suppressed
  unscoped (R0)   56 firing / 28 suppressed   <- unsound, withdrawn
  scoped   (R1)   65 firing / 19 suppressed   <- this commit

Only 2 of 65 eliminated, not 11. The cause is structural: extractClaimedPrNumber
reads the matched PHRASE, and review-approved's dominant pattern is the bare
token APPROVED, so the phrase carries no PR number and can never be
identity-backed. Added a PR-carrying pattern ordered before the bare one so a
claim that DOES name its PR becomes scopeable - that is what the 2 are - but most
of the corpus does not name one, and 16 of the 36 leaks have no tool calls in
window at all.

So this commit is now mostly a correctness change, not the FP reduction the task
set out to make. Saying so plainly rather than reporting the withdrawn 56.

Three new negative controls, one of them encoding R1 directly: a merge of a
DIFFERENT PR must not suppress.

Also reconciled an existing test that asserted review-approved has no identity
evidence - true only while merged was the sole category declaring scoped tools.
Its intent was category keying, so it now asserts a READ backs merged and does
not leak into review-approved, which tests that intent directly.
@minsky-ai minsky-ai Bot changed the title feat(mt#4498): Give the pre-narration suppressor the evidence it was missing fix(mt#4498): Scope the pre-narration merge evidence and reach the second MCP alias Aug 30, 2026

@minsky-reviewer minsky-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: 2


The fix commit addresses the prior blocking issues: merge evidence is now correctly identity-scoped (preventing cross-PR suppression), and alias handling is applied to both window and identity-evidence paths. New tests cover positive cases and multiple negative controls. However, the task spec’s SC4 requires restoring the detector from log-only to warn; the code still sets INJECTION_ENABLED = false, and no registry posture update is present. That leaves SC4 Not Met and is a merge blocker. Please flip the posture per the spec (or amend the spec to defer it with a follow-up), then this should be ready to approve.

Findings

  • [BLOCKING] .minsky/hooks/pre-narration-detector.ts:86 — Spec-required posture flip not implemented — detector remains log-only
    The task spec’s Success Criteria require restoring the pre-narration detector from log-only back to warn once the tune lands. In the current code export const INJECTION_ENABLED = false; remains unchanged (see .minsky/hooks/pre-narration-detector.ts:86 and its Enforcement posture section), and there is no complementary registry or wiring change flipping the posture. The PR description explicitly defers this flip, but the spec is canonical and SC4/ATs require it in this task. Please flip INJECTION_ENABLED back to true and update any registry canary/expectations as needed — or amend the spec to defer SC4 and land it in a follow-up, with tests adjusted accordingly.

Spec verification

Criterion Status Evidence
The tune distinguishes report-a-result-in-hand from claim-a-result-not-yet-had, and the discriminator is stated explicitly in the implementation rather than left implicit in a regex. Met The implementation explicitly adds identity-scoped evidence for approvals via merges and documents the entailment and scope: .minsky/hooks/pre-narration-detector.ts:285-307 adds identityScopedTools for review-approved with a rationale block explaining why merges entail prior approvals and why identity scoping is required. It also adds an ordered pattern /\bPR\s+#?\d+\b[^.!?\n]{0,80}?\bAPPROVED\b/ first so the matched phrase carries the PR number for correlation (:271-285). Alias handling is made explicit via bareToolName/withBareToolAliases and comments (:472-514, :561-637).
Re-run against the captured window: the 10 injected fires drop, and the count of correctly suppressed matches does not fall. A tune that quiets the class by widening suppression until the detector fires on nothing is the failure mode to avoid. Unverifiable This criterion requires executing the replay over .minsky/pre-narration-calibration.jsonl and comparing counts. The diff ships code and tests but not the replay outputs. While scripts/diagnose-pre-narration-window.ts is referenced in the PR description, the verification evidence (before/after counts) is not a repo artifact in this diff, so from code alone I cannot re-run or confirm the numeric result.
A negative control is recorded: a genuine pre-narration sentence — a result asserted with no preceding tool return — still fires after the tune. Without this the tune is indistinguishable from disabling the detector. Met .minsky/hooks/pre-narration-detector.test.ts adds multiple negative controls. Examples: the test "NEGATIVE CONTROL: a merge of a DIFFERENT PR does not suppress" ensures false backing does not silence (:1064-1081), and "NEGATIVE CONTROL: no evidence at all still fires" asserts a claim still fires when no evidence is present (:1083-1092). Additional alias negative control ensures unrelated tools under the alias do not suppress (:1126-1141).
mt#4286's restore condition is discharged: once this lands, the detector returns from log-only to warn, and the flip is recorded where mt#4286 records the quieting. Not Met export const INJECTION_ENABLED = false; remains in .minsky/hooks/pre-narration-detector.ts (near the top, Enforcement posture section). No change flips it back to warn, and no accompanying registry/doc flag change is present in this diff. The spec requires returning from log-only to warn in this task; the PR body explicitly defers this flip, so this criterion is unmet.

Adoption sweep

Symbol Kind Consumers found Classification Notes
.minsky/hooks/pre-narration-detector.ts#bareToolName function .minsky/hooks/pre-narration-detector.test.ts:1049 — assertions on alias handling, Used internally by extractPrNumbersForTools (:238-257) and withBareToolAliases (:496-514) Adopted New helper exported and consumed by tests; also used internally in this module.

Documentation impact

  • no-update-needed — Internal tuning to the pre-narration detector (identity-scoped merge entailment and alias handling) and added tests. No user-facing CLI, API, or documented behavior changed. The enforcement posture flip back to warn was deferred (and is called out as unmet in spec verification), so no posture-doc updates are included or needed in this PR.

@minsky-reviewer minsky-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: 2


Verification pass: the R1 blocking issue remains — the spec-required posture flip back to warn is still not implemented. The code continues to export INJECTION_ENABLED = false, leaving the detector log-only, which leaves Success Criterion 4 Not Met. The rest of the changes look sound: merge evidence is correctly identity-scoped for review-approved, alias handling is applied consistently (including identity evidence), and tests add both positive cases and negative controls. Please implement the posture flip per the current task spec (or amend the spec to defer it with a follow-up), then this should be ready to approve.

Findings

  • [BLOCKING] .minsky/hooks/pre-narration-detector.ts:86 — Spec-required posture flip not implemented — detector remains log-only
    The task spec’s Success Criteria require restoring the pre-narration detector from log-only back to warn once this tune lands. In the current code export const INJECTION_ENABLED = false; remains unchanged in .minsky/hooks/pre-narration-detector.ts (Enforcement posture section near the top), and there is no complementary registry/wiring change to flip posture. The PR description explicitly defers this, but the current spec is canonical and SC4/ATs require it in this pass. Please flip posture to warn (set INJECTION_ENABLED = true) and adjust any registry canary/expectations as needed, or amend the spec to defer SC4 with a follow-up task and matching test updates.

Spec verification

Criterion Status Evidence
The tune distinguishes report-a-result-in-hand from claim-a-result-not-yet-had, and the discriminator is stated explicitly in the implementation rather than left implicit in a regex. Met .minsky/hooks/pre-narration-detector.ts:286-309 adds identityScopedTools for review-approved with explanatory comments that a merge of PR #N entails prior approval of PR #N, and scopes it by PR identity. A new ordered pattern /\bPR\s+#?\d+\b[^.!?\n]{0,80}?\bAPPROVED\b/ is inserted before the bare APPROVED token so the matched phrase carries the PR number for correlation. Alias handling is factored explicitly via bareToolName/withBareToolAliases and applied to both window names and identity evidence (:514-552, :637-645).
Re-run against the captured window: the 10 injected fires drop, and the count of correctly suppressed matches does not fall. A tune that quiets the class by widening suppression until the detector fires on nothing is the failure mode to avoid. Unverifiable The criterion requires executing a replay over .minsky/pre-narration-calibration.jsonl and comparing before/after counts. The diff updates code and tests but does not include replay outputs or CI artifacts of the run; from repository content alone this numeric verification cannot be observed.
A negative control is recorded: a genuine pre-narration sentence — a result asserted with no preceding tool return — still fires after the tune. Without this the tune is indistinguishable from disabling the detector. Met New tests in .minsky/hooks/pre-narration-detector.test.ts cover multiple negative controls: "NEGATIVE CONTROL: a merge of a DIFFERENT PR does not suppress" (:1064-1081), and "NEGATIVE CONTROL: no evidence at all still fires" (:1083-1092). An alias negative control ensures unrelated tools under the alias do not suppress (:1126-1141).
mt#4286's restore condition is discharged: once this lands, the detector returns from log-only to warn, and the flip is recorded where mt#4286 records the quieting. Not Met .minsky/hooks/pre-narration-detector.ts still exports INJECTION_ENABLED = false (see the Enforcement posture section near the top). No complementary registry/wiring change flips posture. The PR description explicitly defers this flip, but the current task spec requires restoring warn posture in this pass; it remains undone and must be completed or the spec amended with a follow-up task.

Documentation impact

  • no-update-needed — Internal detector tuning (identity-scoped merge entailment for review-approved and alias handling) and added tests. No user-facing CLI or API changed. Posture remains log-only in code (flip deferred), so no posture-doc updates accompany this PR.

@minsky-reviewer minsky-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Independent adversarial review (Chinese-wall)
Reviewer: minsky-reviewer[bot] via openai:gpt-5
Tier: 2


R4 verification: the prior BLOCKING finding (SC4 posture flip) remains unresolved — INJECTION_ENABLED is still false and no registry/wiring change restores warn posture, while the current task spec still requires flipping back to warn. The other changes (identity-scoped merge entailment and alias handling) look correct and are well covered by tests with appropriate negative controls. Please either implement the posture flip per the spec or amend the spec to record the principal’s decision and defer SC4; once aligned, this should be ready to approve.

Findings

  • [BLOCKING] .minsky/hooks/pre-narration-detector.ts:103 — Spec-required posture flip not implemented — detector remains log-only
    Success Criterion 4 in the current task spec requires restoring the pre-narration detector from log-only back to warn once this tune lands. In the current code, the enforcement flag remains export const INJECTION_ENABLED = false; (see .minsky/hooks/pre-narration-detector.ts:56-101 for the posture docs and :103 for the flag). No complementary registry/wiring change flips posture. While the PR description cites a principal decision to remain quiet, the spec provided for this review is canonical and still requires the flip. Please either (a) set INJECTION_ENABLED = true and adjust any related canaries/wiring, or (b) amend the task spec to defer SC4 (recording the principal decision) and update tests accordingly.

Spec verification

Criterion Status Evidence
The tune distinguishes report-a-result-in-hand from claim-a-result-not-yet-had, and the discriminator is stated explicitly in the implementation rather than left implicit in a regex. Met .minsky/hooks/pre-narration-detector.ts:286-315 adds identity-scoped evidence for review-approved via merge entailment and documents why identity scoping is required. An ordered PR-number-carrying pattern is inserted before the bare APPROVED token so the matched phrase can be PR-scoped (see :292-305). Alias handling is made explicit via bareToolName/withBareToolAliases and applied on both window and identity-evidence paths (:508-552, :566-574).
Re-run against the captured window: the 10 injected fires drop, and the count of correctly suppressed matches does not fall. A tune that quiets the class by widening suppression until the detector fires on nothing is the failure mode to avoid. Unverifiable This requires executing a replay over .minsky/pre-narration-calibration.jsonl and comparing numeric before/after counts. The diff ships code and tests but no replay outputs; from repository content alone this numerical result cannot be observed.
A negative control is recorded: a genuine pre-narration sentence — a result asserted with no preceding tool return — still fires after the tune. Without this the tune is indistinguishable from disabling the detector. Met .minsky/hooks/pre-narration-detector.test.ts:1091-1109 asserts that a merge of a different PR does not suppress an APPROVED claim; :1111-1119 asserts that with no evidence present the claim still fires. Additional alias negative control at :1162-1177 confirms unrelated tools under the alias do not suppress.
mt#4286's restore condition is discharged: once this lands, the detector returns from log-only to warn, and the flip is recorded where mt#4286 records the quieting. Not Met .minsky/hooks/pre-narration-detector.ts:56-101 documents the quieted posture and :103 still exports INJECTION_ENABLED = false. No complementary registry/wiring change flips posture. The current task spec requires restoring warn posture; this remains undone in this diff.

Adoption sweep

Symbol Kind Consumers found Classification Notes
.minsky/hooks/pre-narration-detector.ts#bareToolName function .minsky/hooks/pre-narration-detector.test.ts:121-139 — alias helper tests, Used internally by extractPrNumbersForTools (:138-156), Used by withBareToolAliases (:530-552) Adopted Helper is exported from the module and exercised by tests; also used internally to normalize tool names for alias handling.

Documentation impact

  • no-update-needed — Internal detector tuning and alias handling; no user-facing CLI or API changed. Posture remains log-only in code (INJECTION_ENABLED = false), and the spec-required flip back to warn is currently unmet — but no existing docs are updated or invalidated by this PR. I checked only this hook’s code and tests; no docs files in docs/ reference this specific posture toggle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

authorship/co-authored Co-authored by human and AI agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant