Skip to content

fix(core-engine): assembly + agc_assembly branch counts decisions, not unconditional transfers (#2764) - #2779

Merged
squid-protocol merged 2 commits into
mainfrom
fix/2764-assembly-branch-unconditional
Sep 5, 2026
Merged

squid-protocol merged 2 commits into
mainfrom
fix/2764-assembly-branch-unconditional

Conversation

@squid-protocol

@squid-protocol squid-protocol commented Sep 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

Both assembly dialects counted every control transfer as a branch. The
generic-assembly rule carried jmp|call|ret|b|bl|bx|blr next to the conditional
jumps; agc_assembly's carried TC|TCF|TCR|CALL|GOTO (unconditional — TC is the
AGC's subroutine call) plus RESUME|RETURN (returns). Measured against the
keyword-rosetta control corpus, 23 of assembly's 25 branch hits and 4 of agc's 5
were not decisions
— 13 returns, 7 calls, 3 unconditional jumps.

Why this is a defect and not ISA morphology

branch feeds avg_func_complexity, max_func_complexity,
func_internal_density, cog_raw, control_flow_ratio and risk_cognitive_load
— every one a decision-density measure — plus #2546's ×3 cascading-flux
amplifier. Counting call/ret made cognitive load track how many subroutines a
file has
, which functions_found already measures:

metric assembly median deviation
avg_func_complexity 1.708 0.1875 +811%
func_internal_density 0.1424 0.01562 +811%
cog_raw 0.18 0.0205 +778%
control_flow_ratio 0.5853 0.09375 +524%
risk_cognitive_load 9.389 2.795 (irc4) +236%

assembly was also the only language in the corpus where the flux amplifier fired at
all — the "branch context" within 150 characters of the mutation was a ret.

#2545 settled the identical question for high-level languages when it took bare
return out of branch in kotlin/apex/objective-c/powershell/solidity/zig. ret
IS return, call is a call, and no other language's branch counts its call
syntax.

Fix — relocate, not delete (#2545's own branch)

# assembly
"branch":                 je|jne|jz|jnz|ja|jb|jl|jg|jge|jle|jae|jbe|cbz|cbnz|tbz|tbnz|beq|bne|loop
"structural_boundaries":  ...existing... + jmp|call|ret|blr|bl|bx|b

# agc_assembly
"branch":                 BZF|BZMF|BZE|BMN|BPL|BMI|CCS|OVSK|BVBZ
"structural_boundaries":  ...existing... − CCS + TCF|TCR|TC|CALL|GOTO|RESUME|RETURN

Both structural_boundaries rules already held the mnemonic families these belong
with (push/pop/mov/lea; CA/TS/XCH), so the tokens stay measured, in the
rule that means structure rather than decision — and control_flow_ratio = branch / (branch + linear) keeps the same denominator. One deliberate
de-duplication: agc's CCS (Count, Compare and Skip, its one real multi-way test)
was counted by both rules and is now claimed by branch alone.

Side effect: ARM's single-letter b stops inflating branch from prose and paths
(the filename inside %include "b.asm" matched \bb\b — rosetta ledger
asm-single-letter-mnemonic-in-path). The false positive moves with the token to
the bulk structural signal, where it is not a decision claim.

Verification

  • Golden masters re-blessed both modes. Every non-coordinate diff is inside an
    assembly or agc_assembly directory group, verified programmatically across all
    2817 files: 189 files moved, none outside those languages' own extensions. The
    issue's polyglot warning does not bite here — all 244 .asm/.s/.S/.inc/.agc files
    in the crucible live under those two categories, checked rather than assumed.
  • Function name/line sets are byte-identical corpus-wide. The
    5. Function Analysis[N] churn is impact-order reshuffling of the same functions,
    not re-extraction.
  • branch+linear is conserved per file — except on the nine apollo-11 files
    carrying CCS, where the total drops by exactly that file's CCS count (15/4/26/1/…
    cross-checked against a raw \bCCS\b count per file). That is the intended
    de-duplication and nothing else.
  • Nine global aggregates move (three corpus-wide health averages; the top-3
    state_flux leaderboard reshuffles as agc's amplified flux drops) plus the usual
    global 3D topology reflow.
  • Strict tests: the branch/structural_boundaries parametrized cases are
    re-partitioned in both languages (\tjmp foo was a structural_boundaries
    negative and is now a positive), plus 5 new regression tests — decision-vs-transfer
    sweeps in each dialect, the %include "b.asm" false positive, and RESUME still
    reading as cleanup — and 2 ReDoS detonations for the widened alternations.
  • Full suite 7716 passed; crucible_check.py PASS both venvs; audit_check.py
    all clear (ruff/mypy/dead-key/ast-accuracy).

Cross-repo

🤖 Generated with Claude Code

https://claude.ai/code/session_01JrpVFZDVVWo19LP3nYoQfP

…t unconditional transfers (#2764)

Both assembly dialects counted every control transfer as a `branch`: the
generic-assembly rule matched `jmp|call|ret|b|bl|bx|blr` alongside the
conditional jumps, and agc_assembly's matched `TC|TCF|TCR|CALL|GOTO`
(unconditional -- `TC` is the AGC's subroutine call) plus `RESUME|RETURN`
(returns). Measured against the keyword-rosetta control corpus, 23 of
assembly's 25 branch hits and 4 of agc's 5 were not decisions.

`branch` feeds avg_func_complexity, max_func_complexity,
func_internal_density, cog_raw, control_flow_ratio and
risk_cognitive_load -- all decision-DENSITY measures -- plus #2546's x3
cascading-flux amplifier. Counting calls and returns made cognitive load
track how many subroutines a file has, the thing `functions_found`
already measures: assembly ran +811% over the corpus median on
avg_func_complexity and func_internal_density, +778% on cog_raw, +524%
on control_flow_ratio, and was the only language in the corpus where the
flux amplifier fired at all (its "branch context" was a `ret`).

#2545 settled the identical question for high-level languages when it
took bare `return` out of `branch` in six of them; `ret` IS `return`, and
no other language's `branch` counts its call syntax. Per that precedent
the tokens are RELOCATED to `structural_boundaries`, not deleted --
`control_flow_ratio = branch / (branch + linear)` keeps the same
denominator and no signal is lost. One deliberate de-duplication: agc's
`CCS` (Count, Compare and Skip) was counted by BOTH rules and is now
claimed by `branch` alone.

Side effect: ARM's single-letter `b` stops inflating `branch` from prose
and paths (the filename inside `%include "b.asm"` matched `\bb\b`); the
false positive moves with the token to the bulk structural signal, where
it is not a decision claim.

Verification:
- Golden masters re-blessed both modes. Every non-coordinate diff is
  inside an `assembly` or `agc_assembly` directory group -- verified
  programmatically over all 2817 files; 189 files moved, none of them
  outside the language's own extensions (this corpus has no polyglot
  assembly: all 244 `.asm/.s/.S/.inc/.agc` files live under those two
  categories). Function name/line sets are byte-identical corpus-wide;
  the `5. Function Analysis[N]` churn is impact-order reshuffling, not
  re-extraction. branch+linear is conserved per file except on the nine
  apollo-11 files carrying `CCS`, where the total drops by exactly that
  file's CCS count -- the intended de-duplication. Nine global
  aggregates move (three corpus-wide health averages, the top-3
  state_flux leaderboard) plus the global 3D topology reflow.
- Strict tests: the branch/structural_boundaries parametrized cases are
  re-partitioned in both languages, plus 5 new regression tests
  (decision vs transfer in each dialect, the `b.asm` path FP, RESUME
  still reading as cleanup) and 2 ReDoS detonations for the widened
  alternations. Full suite 7716 passed. audit_check all clear.
- rosetta_audit against this build moves exactly two languages,
  assembly and agc_assembly (44 others PASS unchanged), including the
  predicted b.asm state_mutation 6 -> 2 flux ripple.

The changed Absolute Project Path / Remote Origin URL / timestamp /
duration fields are the usual machine-to-machine churn (golden_diff
sanitizes them).

Closes #2764

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrpVFZDVVWo19LP3nYoQfP
@squid-protocol squid-protocol added the rosetta:rebless-owed Intentionally moves keyword-rosetta counts; audit warns, corpus re-blesses after merge label Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

Conflict was the two golden masters only (#2778 re-blessed them for the
orphan-census fixes; `assembly.py` auto-merged cleanly -- its
`_visibility_export` addition sits well below this branch's `branch` /
`structural_boundaries` edits).

Resolved per the ledger-sweep playbook: took main's fixtures wholesale
(`--theirs`) rather than hand-merging 680k lines of JSON, then re-blessed
both modes from scratch on the merged tree.

Re-verified every invariant against the NEW baseline -- identical scope to
the pre-merge run: all 11784 non-coordinate leaf diffs sit in `assembly`
(6240) or `agc_assembly` (5535); 189 files touched, none outside those
languages' own extensions; function name/line sets byte-identical across
all 2817 files; branch+linear conserved everywhere except the nine
apollo-11 files carrying `CCS`, by exactly that file's CCS count. Nine
global aggregates and the 3D topology reflow, as before.

Full suite 7725 passed; audit_check all clear.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrpVFZDVVWo19LP3nYoQfP
@squid-protocol
squid-protocol merged commit 3b0b004 into main Sep 5, 2026
31 checks passed
@squid-protocol
squid-protocol deleted the fix/2764-assembly-branch-unconditional branch September 5, 2026 22:58
squid-protocol added a commit to squid-protocol/keyword-rosetta that referenced this pull request Sep 6, 2026
…less against gitgalaxy#2764 (#65)

gitgalaxy#2764 (engine PR squid-protocol/gitgalaxy#2779) takes the
unconditional control transfers out of both assembly dialects' `branch`
rule and relocates them to `structural_boundaries`: assembly loses
`jmp|call|ret|b|bl|bx|blr`, agc_assembly loses `TC|TCF|TCR|CALL|GOTO`
(unconditional -- TC is the AGC's subroutine call) and `RESUME|RETURN`
(returns), and agc's `CCS` is de-duplicated out of
`structural_boundaries` so only `branch` claims it.

Authoring (NOT a pure re-bless -- the issue's "Corpus pairing" section
said no authoring change, but both shells planted unconditional
mnemonics as branch keywords):

- `main.asm` probe_branch planted `jmp` / `je` / `jne`. `jmp` is an
  unconditional transfer, so leaving it would drop probe_branch to two
  conditionals against SPEC's `branch x 3`. Re-authored to `jz`.
- `main.agc` PROBEBR planted `TCF` + `BZF` and leaned on DISPATCH's `TC`
  to reach three, which no longer holds once only conditionals count. It
  now plants three real conditionals: `BZF` on the label line (still a
  func_start opcode), then `BZMF` and `BMN`. main.agc branch stays 3.

Manifests (both PASS: assembly 76 assertions, agc_assembly 80):

- assembly branch main 10->3, a 4->0, b 5->0, c 5->0 (25 hits corpus-wide
  of which 23 were transfers -> 3, all decisions).
- assembly b.asm `state_mutation` 6->2, the predicted flux ripple: the
  branch context inside probe_state's 150-character radius was the
  function's own `ret`, so with call/ret out of `branch` the file records
  its raw inc+dec. Same de-amplification gitgalaxy#2634 produced for apex.
- agc_assembly c.agc branch 1->0 (RESUME is an interrupt return; it keeps
  its `cleanup` reading). main.agc branch 3->3, now three conditionals.

Ledger:

- `asm-call-ret-in-branch` -> `still_reproduces: false`, upstream_issue
  gitgalaxy#2764, languages_seen gains agc_assembly (same shape, same fix).
- `asm-single-letter-mnemonic-in-path` -> `signal` repointed from `branch`
  to `structural_boundaries`. The collision still reproduces (a bare `b`
  in a path is still matched) but no longer claims a decision; the
  underlying literal-counting cause (#2535) is unchanged, so the entry is
  repointed rather than retired.
- `state-flux-branch-weighting` -> assembly drops out of languages_seen.

Menus regenerated for the two languages (`tools/keyword_menu.py assembly
agc_assembly`). Both files also pick up a stale-since-gitgalaxy#2730 `api`
refresh (EXTERN/IMPORT, SUBROUTINE/BEXT/EXTEND) that predates this change.

Effect (bias_report.py against the #2779 build, not committed --
bias-history.yml owns those artifacts): assembly 10 out-of-band cells ->
1, agc_assembly 8 -> 3. avg_func_complexity, max_func_complexity,
func_internal_density, cog_raw, func_complexity_gini, risk_cognitive_load,
risk_state_flux, control_flow_ratio, structural_mass and
dependency_density all come back into band. Corpus-wide: 36 -> 37 metrics
at >=80% green-band share, avg_func_complexity 67% -> 72%, and
func_internal_density leaves the five weakest metrics. `na_check --ci`
clean.

Cross-repo: squid-protocol/gitgalaxy#2779 merges FIRST (docs/GATING.md
"Cross-repo flow (no pins)"); `verify.yml` here is red against engine main
until it lands.


Claude-Session: https://claude.ai/code/session_01JrpVFZDVVWo19LP3nYoQfP

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rosetta:rebless-owed Intentionally moves keyword-rosetta counts; audit warns, corpus re-blesses after merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

assembly/agc_assembly: branch counts unconditional transfers — 23 of 25 hits are call/ret/jmp, not decisions (#2545's shape)

1 participant