Skip to content

feat(handoff): brief, repo evidence, --verify, redaction, c0mpute target - #602

Merged
ralyodio merged 1 commit into
mainfrom
feat/handoff-brief
Nov 9, 2026
Merged

ralyodio merged 1 commit into
mainfrom
feat/handoff-brief

Conversation

@ralyodio

@ralyodio ralyodio commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

Brings the useful parts of Relayvora (agent-to-agent work handoff) into moshcode handoff, which already had the reading and launching half.

What changes

  • Brief first. The next engine now reads ~/.moshcode/handoffs/<id>.md, a short brief built without a model inside --budget tokens (default 4000), instead of opening with up to 200 raw messages. Every fact is tagged: [user] (goal and recent requests, quoted), [agent-reported] (the previous engine's last report), [observed] (repo state, check exit codes), [inferred] (e.g. "failing checks come first"). The full transcript stays alongside it as the record.
  • Repo evidence: branch, uncommitted changes, diffstat, and commits since the session started.
  • --verify: runs the project's own typecheck/lint/test (package.json scripts by lockfile's package manager, Cargo, Go, or make test) with no shell and records the real exit codes. --verify="<cmd>" runs a specific command. Failure lines (not ok, FAIL, Error: and similar) are captured as the output streams, so they survive a suite whose output overflows the 256 KB tail.
  • Redaction, always on: private keys, JWTs, URL credentials, bearer tokens, common provider key shapes, and *_SECRET= / *_TOKEN= style assignments are replaced with [redacted:<kind>] in every message and every check output.
  • moshcode handoff <engine> c0mpute: hands off to the c0mpute agent in process, with the brief as its first turn (no argv limit, so no extra read-tool round trip on a CPU node). It prints a warning that c0mpute peers read prompts. The c0agent REPL now actually submits a command-line [prompt] as its first turn, as its usage already said, and -- ends flags.
  • Portable transcript 0.2: optional redactions, evidence and checks fields (documented). MCP moshcode_handoff takes budget and verify.

Briefs are deliberately not written by c0mpute: job prompts are gossiped to peers, and a transcript is private code conversation.

Tested

  • test/handoff-brief.test.mjs (new): redaction shapes and prose left alone, check detection, real exit codes, early failures surviving output overflow, evidence on a real temp repo, brief tags and budget clamp, the 0600 brief, the c0mpute in-process launch.
  • handoff, c0agent, work and help suites: 128/128 pass.
  • Full suite: 3108 pass. apps/pwa coinpay-checkout and ring-footer also fail on a clean origin/main. dns start closes the parking server is flaky alone (1 of 3 runs) and does not touch this code.
  • Real dry run on this box: moshcode handoff claude codex --verify read a live Claude session and wrote a ~585-token brief. It named the two real failing tests, listed the 10 uncommitted files, and pointed the codex seed at the brief.

🤖 Generated with Claude Code

`moshcode handoff` used to hand the next engine a pointer to up to 200 raw
messages. It now writes a brief first (~/.moshcode/handoffs/<id>.md), built
without a model inside --budget tokens (4000), with every fact tagged by
where it came from: [user], [agent-reported], [observed], [inferred].

- git evidence: branch, uncommitted changes, diffstat, commits since the
  session started
- --verify [auto|none] / --verify="<cmd>": runs the project's own
  typecheck/lint/test with no shell and records the real exit codes; failure
  lines are kept even when a suite's output overflows the capture
- secrets are redacted from every carried message and check output, always
- `moshcode handoff <engine> c0mpute` hands off to the c0mpute agent in
  process, with the brief as its first turn (warns that peers read prompts)
- c0agent REPL submits a command-line prompt as its first turn; `--` ends flags
- portable transcript 0.2: optional redactions, evidence, checks
- MCP moshcode_handoff takes budget and verify

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

test("redaction removes the common secret shapes and says which", () => {
const secrets = [
"sk-ant-api03-abcdefghijklmnopqrstuvwxyz0123",

test("redaction removes the common secret shapes and says which", () => {
const secrets = [
"sk-ant-api03-abcdefghijklmnopqrstuvwxyz0123",
test("redaction removes the common secret shapes and says which", () => {
const secrets = [
"sk-ant-api03-abcdefghijklmnopqrstuvwxyz0123",
"sk-proj-abcdefghijklmnopqrstuvwxyz012345",
const secrets = [
"sk-ant-api03-abcdefghijklmnopqrstuvwxyz0123",
"sk-proj-abcdefghijklmnopqrstuvwxyz012345",
"ghp_abcdefghijklmnopqrstuvwxyz0123456789",
"sk-ant-api03-abcdefghijklmnopqrstuvwxyz0123",
"sk-proj-abcdefghijklmnopqrstuvwxyz012345",
"ghp_abcdefghijklmnopqrstuvwxyz0123456789",
"AKIAIOSFODNN7EXAMPLE",
const text = [
...secrets.map((s) => `token ${s} here`),
"curl -H 'Authorization: Bearer abcdefghijklmnopqrstuvwxyz012345' https://api",
"DATABASE_URL=postgres://app:hunter2hunter2@db:5432/app",
"curl -H 'Authorization: Bearer abcdefghijklmnopqrstuvwxyz012345' https://api",
"DATABASE_URL=postgres://app:hunter2hunter2@db:5432/app",
"OPENAI_API_KEY=notarealkeybutlongenough",
"-----BEGIN OPENSSH PRIVATE KEY-----\nb3BlbnNzaC1rZXktdjEAAAA\n-----END OPENSSH PRIVATE KEY-----",
test("the transcript is redacted and counts what it removed", () => {
const doc = buildTranscript({
engine: "claude", id: "x", cwd: CWD, start: 0, end: 1, changes: [],
messages: [{ role: "user", text: "use GITHUB_TOKEN=ghp_abcdefghijklmnopqrstuvwxyz0123456789", at: 0 }],
try {
const results = await runChecks([
{ label: "ok", bin: process.execPath, args: ["-e", "process.exit(0)"] },
{ label: "bad", bin: process.execPath, args: ["-e", "console.log('leaked sk-ant-api03-abcdefghijklmnopqrstuvwxyz0123'); process.exit(3)"] },
try {
const results = await runChecks([
{ label: "ok", bin: process.execPath, args: ["-e", "process.exit(0)"] },
{ label: "bad", bin: process.execPath, args: ["-e", "console.log('leaked sk-ant-api03-abcdefghijklmnopqrstuvwxyz0123'); process.exit(3)"] },
@github-actions

github-actions Bot commented Nov 9, 2026

Copy link
Copy Markdown

ThreatCrush Security Scan

20 finding(s) in the 11 file(s) this pull request changes.

MEDIUM: 9 | LOW: 11

Severity Rule Location
MEDIUM sql-string-concatenation src/cli-schema.mjs:271
MEDIUM sql-string-concatenation src/cli-schema.mjs:394
MEDIUM sql-string-concatenation src/cli-schema.mjs:843
MEDIUM sql-string-concatenation src/cli-schema.mjs:876
MEDIUM sql-string-concatenation src/cli-schema.mjs:983
MEDIUM sql-string-concatenation src/cli-schema.mjs:1346
MEDIUM sql-string-concatenation src/cli-schema.mjs:1883
MEDIUM sql-string-concatenation src/cli-schema.mjs:1901
MEDIUM insecure-temp-file test/handoff.test.mjs:297
LOW secret-openai-key test/handoff-brief.test.mjs:53
LOW secret-anthropic-key test/handoff-brief.test.mjs:53
LOW secret-openai-key test/handoff-brief.test.mjs:54
LOW secret-github-token test/handoff-brief.test.mjs:55
LOW secret-aws-access-key test/handoff-brief.test.mjs:56
LOW secret-jwt test/handoff-brief.test.mjs:58
LOW secret-database-url test/handoff-brief.test.mjs:63
LOW secret-private-key test/handoff-brief.test.mjs:65
LOW secret-github-token test/handoff-brief.test.mjs:86
LOW secret-openai-key test/handoff-brief.test.mjs:127
LOW secret-anthropic-key test/handoff-brief.test.mjs:127
105 pre-existing finding(s) elsewhere in the repository — **HIGH/CRITICAL**: 8 | **MEDIUM**: 78 | **LOW**: 19

Not introduced by this pull request. The full set is in the Security tab.

Severity Rule Location
HIGH js-ssrf-outbound-request apps/pwa/public/sw.js:76
HIGH tls-verification-disabled apps/pwa/src/lib/moshpit-gateway.mjs:299
HIGH sh-remote-script-execution install.sh:87
HIGH sh-remote-script-execution install.sh:91
HIGH sh-remote-script-execution install.sh:259
HIGH sh-remote-script-execution install.sh:270
HIGH sh-remote-script-execution install.sh:276
HIGH tls-verification-disabled src/dns.mjs:823
MEDIUM js-unescaped-html-sink apps/pwa/public/herd/herd.js:117
MEDIUM sql-template-interpolation apps/pwa/src/lib/moshpit-certs.mjs:56
MEDIUM sql-template-interpolation apps/pwa/src/lib/moshpit-certs.mjs:117
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:140
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:154
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:180
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:374
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:378
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:423
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:707
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:909
MEDIUM sql-template-interpolation apps/pwa/src/moshpit.mjs:911

…and 85 more. Full results in the Security tab.

Snippets are redacted; ThreatCrush never prints matched credential material.

@ralyodio
ralyodio merged commit b4e92b4 into main Nov 9, 2026
6 checks passed
@ralyodio ralyodio mentioned this pull request Nov 9, 2026
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.

2 participants