Skip to content

fix(parser): bind a copy-retarget grant printed under an "if you do" gate (CR 707.10c)#5716

Merged
matthewevans merged 1 commit into
mainfrom
ship/spiderverse-retarget
Jul 13, 2026
Merged

fix(parser): bind a copy-retarget grant printed under an "if you do" gate (CR 707.10c)#5716
matthewevans merged 1 commit into
mainfrom
ship/spiderverse-retarget

Conversation

@matthewevans

Copy link
Copy Markdown
Member

Spider-Verse prints its retarget grant as the CONSEQUENT of a reflexive gate —
"you may copy it. IF YOU DO, you may choose new targets for the copy." — rather
than as its own sentence. The copy was modeled, but its controller could never
retarget it: CR 707.10c silently unhonored.

The asymmetry that caused it: the followup-continuation recognizer sees the chunk
BEFORE the condition machinery runs, so it was handed "if you do, you may choose
new targets for the copy" and recognize_copy_retarget_clause (an
all_consuming grammar with no gate axis) rejected it. The clause then fell
through to the normal path, where strip_if_you_do_conditional DID peel the
prefix — so by the time it reached the effect parser the text was bare, the same
recognizer now matched, and it lowered to an honest orphaned_copy_retarget
residual. One recognizer, two different inputs, depending on which side of the
condition strip it ran on.

Give parse_copy_retarget_clause an optional leading affirmative-reflexive-gate
axis. Compare Spinerock Tyrant, which prints the identical grant as a standalone
sentence and always bound correctly — the two are the same clause wearing
different grammar, so this is one more axis on an existing combinator, not a new
parser.

Folding the gate away is sound BECAUSE it is affirmative and the copy it rides is
itself optional: "if you do" means "if you made the copy", and a retarget
permission on a copy that was never made is unreachable. The gate carries no
information the CopySpell's own optionality does not already carry.

That reasoning does NOT extend to the negated connectors ("if they don't, …"
gates a branch that runs precisely when the antecedent did NOT happen), so
matching the whole connector set and discarding the condition would silently
invert those clauses. parse_reflexive_conditional_connector is therefore split
into its affirmative and negated halves, and the retarget clause consumes only
the affirmative one. The two halves are disjoint by construction, not by luck —
every negated tag ends in n't, and every affirmative tag requires ,
immediately after the verb — so splitting the original single alt preserves its
behavior exactly.

Measured full-pool, dual export (35,396 faces). Because this change touches a
combinator shared with strip_if_you_do_conditional and the chunk-splitter, the
copy-retarget ledger alone would be blind to collateral on other channels, so the
invariant is checked by diffing every face's ENTIRE tree:

faces with ANY structural change, on ANY channel: 1
spider-verse retargets=[Keep] orphans=1 -> retargets=[May] orphans=0

Zero regressions. Zero faces outside the set touched. The connector split is
behavior-preserving for all 35,395 other faces.

…gate (CR 707.10c)

Spider-Verse prints its retarget grant as the CONSEQUENT of a reflexive gate —
"you may copy it. IF YOU DO, you may choose new targets for the copy." — rather
than as its own sentence. The copy was modeled, but its controller could never
retarget it: CR 707.10c silently unhonored.

The asymmetry that caused it: the followup-continuation recognizer sees the chunk
BEFORE the condition machinery runs, so it was handed "if you do, you may choose
new targets for the copy" and `recognize_copy_retarget_clause` (an
`all_consuming` grammar with no gate axis) rejected it. The clause then fell
through to the normal path, where `strip_if_you_do_conditional` DID peel the
prefix — so by the time it reached the effect parser the text was bare, the same
recognizer now matched, and it lowered to an honest `orphaned_copy_retarget`
residual. One recognizer, two different inputs, depending on which side of the
condition strip it ran on.

Give `parse_copy_retarget_clause` an optional leading affirmative-reflexive-gate
axis. Compare Spinerock Tyrant, which prints the identical grant as a standalone
sentence and always bound correctly — the two are the same clause wearing
different grammar, so this is one more axis on an existing combinator, not a new
parser.

Folding the gate away is sound BECAUSE it is affirmative and the copy it rides is
itself optional: "if you do" means "if you made the copy", and a retarget
permission on a copy that was never made is unreachable. The gate carries no
information the `CopySpell`'s own optionality does not already carry.

That reasoning does NOT extend to the negated connectors ("if they don't, …"
gates a branch that runs precisely when the antecedent did NOT happen), so
matching the whole connector set and discarding the condition would silently
invert those clauses. `parse_reflexive_conditional_connector` is therefore split
into its affirmative and negated halves, and the retarget clause consumes only
the affirmative one. The two halves are disjoint by construction, not by luck —
every negated tag ends in `n't, ` and every affirmative tag requires `, `
immediately after the verb — so splitting the original single `alt` preserves its
behavior exactly.

Measured full-pool, dual export (35,396 faces). Because this change touches a
combinator shared with `strip_if_you_do_conditional` and the chunk-splitter, the
copy-retarget ledger alone would be blind to collateral on other channels, so the
invariant is checked by diffing every face's ENTIRE tree:

  faces with ANY structural change, on ANY channel: 1
    spider-verse  retargets=[Keep] orphans=1  ->  retargets=[May] orphans=0

Zero regressions. Zero faces outside the set touched. The connector split is
behavior-preserving for all 35,395 other faces.
@matthewevans
matthewevans enabled auto-merge July 13, 2026 03:25
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@matthewevans
matthewevans added this pull request to the merge queue Jul 13, 2026
@github-actions

Copy link
Copy Markdown

Parse changes introduced by this PR

Baseline pending for 37b77b42e7a5ca265be7796b01165878e8c1d73c — this populates once main publishes its coverage snapshot (a few minutes after that commit landed).

Merged via the queue into main with commit 9aad1a5 Jul 13, 2026
13 checks passed
@matthewevans
matthewevans deleted the ship/spiderverse-retarget branch July 13, 2026 03:51
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