Skip to content

feat(repipe): standing brief — be an interface, not an oracle - #366

Merged
mahaloz merged 1 commit into
mainfrom
feat/repipe-agent-interfaces
Sep 3, 2026
Merged

feat(repipe): standing brief — be an interface, not an oracle#366
mahaloz merged 1 commit into
mainfrom
feat/repipe-agent-interfaces

Conversation

@mahaloz

@mahaloz mahaloz commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

The corpus is deliberately hostile — 171 of its 250 challenges carry at least one obfuscation class, 57 are code-virtualised. Hostile binaries are exactly where a decompiler's automatic answer is wrong, so the interesting question this loop asks is not "why did kuna guess wrong" but "why could the agent not tell it the right answer?"

That is now a standing instruction to both halves of the loop.

Testers file a missing interface whenever they catch themselves thinking "kuna should have known this" — because the useful form of that complaint is almost always "kuna should have let me say so". Define a function boundary, override a jump table, declare a blob as data with a type, steer structuring, fix a prototype, make a rename persist. They check kuna catalog --json first: an option that already exists is a discoverability problem, not a missing interface, and that is worth reporting too. The prompt now names the challenge's own obfuscation classes, because "this one is virtualised and string-encrypted" changes which interface is worth asking for.

Builders expose before they invent. kuna-console registers ~37 intervention-shaped commands — map function, override jumptable, force goto, force datatype, parse line, retype, structure blocks … — and none is reachable from the kuna binary. Three very different jobs hide behind "add an interface":

  1. it already works in the console and is merely unexposed → wiring, the common case, verifiable in one decomp_dbg invocation before any code is written;
  2. it answers engine integration not yet ported (global add, dump, callgraph build confirmed) → real engine work, [PROPOSAL] route, not a half-port;
  3. there is no decision point at all → that is a phases.toml option, not a subcommand, because a new judgement call ships behind a named flag.

Two rules keep the result usable by the thing it is for:

  • A durable assertion beats a one-shot flag. The model is assert(phase, anchor, type, value, strength), consulted on every re-run. An agent that renames forty functions and loses them on the next invocation has gained nothing.
  • Machine-readable in, machine-readable out. Assertions as a file or repeatable flags; JSON beside the human form.

smoke.sh 71/71, make check-spec OK. No Rust touched.

🤖 Generated with Claude Code

171 of the corpus's 250 challenges carry at least one obfuscation class and 57
are code-virtualised. Hostile binaries are exactly where a decompiler's
automatic answer is wrong, so the interesting question this loop asks is not
"why did kuna guess wrong" but "why could the agent not TELL it the right
answer". That is now a standing instruction to both halves of the loop.

Testers are told to file a missing INTERFACE whenever they catch themselves
thinking "kuna should have known this" -- because the useful form of that
complaint is almost always "kuna should have let me say so": define a function
boundary, override a jump table, declare a blob as data with a type, steer
structuring, fix a prototype, make a rename persist. They are told to check
`kuna catalog --json` first, since an option that already exists is a
discoverability problem rather than a missing interface -- and worth reporting
as such. The prompt now also names the challenge's own obfuscation classes,
because "this one is virtualised and string-encrypted" changes which interface
is worth asking for.

Builders are told to EXPOSE before they invent. kuna-console registers ~37
intervention-shaped commands -- map function, map address, map param/return,
override prototype/flow/jumptable, force goto/datatype/varnode, name varnode,
rename, retype, parse line/file, comment instruction, structure blocks,
analyze range -- and NONE is reachable from the `kuna` binary; `kuna decompile`
only ever emits `option` and `kassert` lines. Three very different jobs hide
behind "add an interface" and they cost wildly different amounts:

1. it already works in the console and is merely unexposed -- wiring, the
   common case, and verifiable in one decomp_dbg invocation before any code;
2. it answers `engine integration not yet ported` -- `global add`, `dump` and
   `callgraph build` are confirmed examples -- which is real engine work and
   takes the [PROPOSAL] route rather than a half-port;
3. there is no decision point at all -- then it is a phases.toml option, not a
   subcommand, because a new judgement call ships behind a named flag.

Two rules keep the result usable by the thing it is for. A durable assertion
beats a one-shot flag: the model is assert(phase, anchor, type, value,
strength) consulted on every re-run, and an agent that renames forty functions
and loses them on the next invocation has gained nothing. And machine-readable
in, machine-readable out -- assertions as a file or repeatable flags, JSON
beside the human form.

smoke.sh 71/71, make check-spec OK.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mahaloz mahaloz added the full-ci Run the full cargo workspace suite on this PR before merge (internal PRs skip it by default) label Sep 3, 2026
@mahaloz
mahaloz merged commit fca7a97 into main Sep 3, 2026
10 of 11 checks passed
@mahaloz
mahaloz deleted the feat/repipe-agent-interfaces branch September 3, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-ci Run the full cargo workspace suite on this PR before merge (internal PRs skip it by default)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant