Skip to content

feat(candidate): compile full improvement bundles#514

Merged
drewstone merged 3 commits into
mainfrom
feat/candidate-bundle-builder
Jul 11, 2026
Merged

feat(candidate): compile full improvement bundles#514
drewstone merged 3 commits into
mainfrom
feat/candidate-bundle-builder

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

Summary:

  • add the canonical public builder from typed profiles or profile diffs, verified CodeSurface bytes, knowledge snapshots, and isolated memory policy into AgentCandidateBundle
  • export the existing canonical sealer and require agent-eval 0.113.0, the first release with byte-verified CodeSurface identity
  • fail closed on unsupported profile fields, caller-supplied diff lineage, raw Git patches, and code/profile identity drift
  • cover the installed candidate-execution package path and update the generated API map

Validation:

  • pnpm test: 149 files, 1,484 passed, 2 skipped
  • pnpm run lint
  • pnpm run typecheck
  • pnpm run build
  • pnpm run docs:check
  • pnpm run verify:package
  • git merge-tree --write-tree origin/main HEAD

tangletools
tangletools previously approved these changes Jul 11, 2026

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Auto-approved drewstone PR — bbbddddb

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-07-11T17:39:55Z

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Value Audit — sound-with-nits

Verdict sound-with-nits
Concerns 2 (2 weak-concern)
Heuristic 0.0s
Duplication 0.0s
Interrogation 150.9s (2 bridge agents)
Total 150.9s

💰 Value — sound

Adds the canonical buildAgentCandidateBundle so products no longer hand-roll profile-freezing + CodeSurface-byte-verification + diff-id derivation to produce a sealed candidate bundle; fills a real gap in the existing sealer/verifier pair, no existing equivalent found.

  • What it does: Introduces buildAgentCandidateBundle(input) in src/candidate-execution/builder.ts — the one public constructor that takes high-level inputs (a typed profile source = full profile | profile-diffs | pre-closed candidate profile; a code source = CodeSurface | disabled | no-op; execution policy; optional knowledge; memory policy; lineage) and compiles them into a schema-validated, canonically-dige
  • Goals it achieves: Before this PR the runtime exposed only sealAgentCandidateBundle (digest+schema validation on an already-assembled wire shape, bundle.ts:10) and verifyAgentCandidateBundle (execution-boundary re-verification, verify.ts:37). Every product had to hand-assemble AgentCandidateBundleInput themselves — reproducing the profile-freezing rules, Git-diff byte hashing, and diff-id derivation, each with
  • Assessment: Sound and in the grain of the codebase. It composes with the existing primitives rather than reinventing them: uses sealAgentCandidateBundle (bundle.ts), canonicalCandidateDigest/embeddedCandidateArtifact/canonicalCandidateBytes (digest.ts), verifyCodeSurface from agent-eval, and the agentProfileSchema/agentCandidateProfileSchema/applyAgentProfileDiff from agent-interface. The thre
  • Better / existing approach: Searched src/ for any existing profile→candidate-profile mapping, CodeSurface-to-bundle assembly, or AgentCandidateBundleInput constructor. Found only the inverse: candidateProfileAsAgentProfile in improvement-cycle.ts:324 (candidate→generic, used for round-trip binding verification). lifecycle/tool-build.ts:verifiedBuild builds a different shape (BuiltCandidate for tool generation, not `A
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 2
  • Bridge warning: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content

🎯 Usefulness — sound-with-nits

Adds the canonical high-level builder that compiles typed profiles/diffs + verified CodeSurface bytes + knowledge + memory into a sealed AgentCandidateBundle, composing (not competing with) the existing low-level sealAgentCandidateBundle and filling the gap that the intelligence improvement-cycle's

  • Integration: Reachable and wired. Exported from src/candidate-execution/index.ts:1-11 on the ./candidate-execution package subpath (package.json:67-70), and exercised end-to-end by scripts/verify-package-exports.mjs which imports, calls buildAgentCandidateBundle, and verifies the result. It wraps sealAgentCandidateBundle (bundle.ts:10), which is already consumed by the live intelligence path at src/intelligenc
  • Fit with existing patterns: Fits the codebase's grain precisely. It composes established primitives rather than inventing new ones: sealAgentCandidateBundle + embeddedCandidateArtifact + canonicalCandidateDigest from digest.ts, verifyCodeSurface from @tangle-network/agent-eval/campaign, and agentProfileSchema/agentProfileDiffSchema/agentCandidateProfileSchema/applyAgentProfileDiff from agent-interface. It does not compete wi
  • Real-world viability: Holds up past the happy path. It is synchronous and deterministic; CodeSurface bytes are re-read and verified via verifyCodeSurface before embedding, with an explicit drift check (builder.ts:149-156). assertCanonicalParse (builder.ts:304-308) round-trips every parsed object against its canonical bytes so no unsupported field is silently dropped. The test file covers the realistic failure modes: di
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 1

🎯 Usefulness Audit

🟡 Builder returns sealed bundle but the buildCandidate seam expects unsealed input [ergonomics] ``

buildAgentCandidateBundle returns AgentCandidateBundle (digest included, deeply frozen), but src/intelligence/improvement-cycle.ts:115-118's buildCandidate callback signature is () => AgentCandidateBundleInput | Promise (digest omitted). A caller who wants to use the new canonical builder inside the improvement cycle must wrap it: omitTopLevelDigest(buildAgentCandidateBundle(...)). The cycle re-seals the result anyway (improvement-cycle.ts:173), so it is functionally f

💰 Value Audit

🟡 Forward and inverse profile mappings now live in different modules with parallel field lists [maintenance] ``

freezeGenericProfile (builder.ts:167-217, generic→candidate) and candidateProfileAsAgentProfile (improvement-cycle.ts:324-406, candidate→generic) are inverse mappings that each hardcode the same top-level field list (name/description/version/tags/prompt/harness/permissions/tools/confidential) and parallel MCP/resource handling. They are not duplicates — the freeze is stricter (rejects hooks-with-commands, github resources, non-stdio MCP) while the unfreeze shell-quotes hooks — so both are ge


What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260711T174416Z

tangletools
tangletools previously approved these changes Jul 11, 2026

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Auto-approved drewstone PR — 12346649

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-07-11T17:53:40Z

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Value Audit — sound

Verdict sound
Concerns 1 (1 weak-concern)
Heuristic 0.0s
Duplication 0.0s
Interrogation 106.2s (2 bridge agents)
Total 106.2s

💰 Value — sound

Adds a canonical, fail-closed public builder for sealed agent candidate bundles, extracting profile-freezing logic from improvement-cycle.ts into the candidate-execution package where it belongs — coherent and in-grain.

  • What it does: Introduces buildAgentCandidateBundle (src/candidate-execution/builder.ts:80), the single public entry point that compiles typed profile sources (profile / profile-diffs / candidate-profile), code sources (disabled / no-op / code-surface with byte-verified CodeSurface), execution policy, optional knowledge, and memory into an immutable, schema-validated, canonically-digested AgentCandidateBundle.
  • Goals it achieves: 1) Make bundle construction safe-by-construction: the only path from an agent-eval CodeSurface to embedded patch bytes goes through verifyCodeSurface (builder.ts:146), eliminating the possibility of sealing unverified or drifted code. 2) Centralize profile freezing so both the improvement cycle and external consumers share one implementation rather than each adapter reimplementing the AgentProfi
  • Assessment: Good change, built in the grain of the codebase. The profile-freezing logic was already in the repo (inlined in improvement-cycle.ts at main, 506 lines) and is moved — not copied — to candidate-execution/profile.ts, which is the correct layer (the improvement cycle is a consumer of candidate-execution, not its owner). The builder fills a genuine gap: before this, the only public constructor was `s
  • Better / existing approach: none — this is the right approach. Searched for existing equivalents: (1) sealAgentCandidateBundle in bundle.ts is the low-level sealer this builder wraps — correct to keep, not duplicate. (2) lifecycle/tool-build.ts consumes CodeSurface but for a different purpose (building tools/MCP servers in worktrees via worktreeBuildCandidate, not sealing execution bundles) — not the same concern. (3
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 2
  • Bridge warning: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content

🎯 Usefulness — sound

Promotes the profile-freezing and bundle-building logic from a private inline helper inside the intelligence module into a canonical, exported public builder in candidate-execution — the logic was already live, this just surfaces it as the blessed product entry point and removes the duplication.

  • Integration: Fully reachable. buildAgentCandidateBundle is consumed by the buildCandidate callback in proposeAgentImprovement (src/intelligence/improvement-cycle.ts:174-177), which also widens its callback type to accept the sealed AgentCandidateBundle return. The profile helpers (assertCandidateProfileBinding, parseExactAgentProfile) are imported and called by the live improvement-cycle at improve
  • Fit with existing patterns: Fits the codebase grain precisely. This is a de-duplication, not a competing pattern: the diff vs origin/main shows src/intelligence/improvement-cycle.ts loses ~175 lines of inline freezeGenericAgentCandidateProfile/freezeResources/freezeMcpServers/shellQuote/candidateProfileAsAgentProfile helpers that now live in src/candidate-execution/profile.ts. The builder reuses the pre-existing ca
  • Real-world viability: Holds up off the happy path. The builder is deliberately fail-closed: it rejects caller-supplied profileDiffIds (builder.ts:83), empty diff lists (builder.ts:125), non-canonical schema parses (builder.ts:170), CodeSurface byte drift between verified bytes and the surface's content identity (builder.ts:148-153), and every generic-profile field that cannot be safely tokenized — connections/metadat
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 1

💰 Value Audit

🟡 omitUndefinedObjectFields (builder.ts:176) and canonicalJsonValue (improvement-cycle.ts:362) overlap in purpose [maintenance] ``

Both recursively strip undefined fields from objects/arrays. builder.ts:176 omitUndefinedObjectFields cleans applyAgentProfileDiff output; improvement-cycle.ts:362 canonicalJsonValue does the same plus type validation for proposal serialization. Neither calls the other. If a third consumer appears, these should fold into one shared helper in digest.ts or a canonical-serialize utility. Not blocking — they serve slightly different contracts (one throws on undefined array entries, the other i


What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260711T175713Z

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Auto-approved drewstone PR — 2e6eb28b

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-07-11T17:58:20Z

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Value Audit — sound-with-nits

Verdict sound-with-nits
Concerns 1 (1 weak-concern)
Heuristic 0.0s
Duplication 0.0s
Interrogation 168.4s (2 bridge agents)
Total 168.4s

💰 Value — sound-with-nits

Adds a canonical fail-closed builder that compiles profiles, verified code bytes, and execution policy into sealed candidate bundles — a good extraction + elevation of logic previously trapped inside improvement-cycle.ts, with one minor internal duplication.

  • What it does: Introduces buildAgentCandidateBundle (src/candidate-execution/builder.ts:80), a public high-level API that accepts typed profile sources (full profile, profile-diffs, or pre-frozen candidate-profile), a code source (CodeSurface whose bytes are re-verified via agent-eval's verifyCodeSurface, or explicit disabled/no-op), execution policy, knowledge, and memory — and compiles them into a schema-valid
  • Goals it achieves: 1) Give callers ONE safe path to construct candidate bundles instead of hand-assembling the low-level AgentCandidateBundleInput (where they could embed unverified code bytes, supply contradictory lineage, or drop profile fields silently). 2) Make the profile-freezing/binding logic reusable — it was private inside improvement-cycle.ts and is now a shared module both the improvement cycle and direct
  • Assessment: Sound change in the grain of the codebase. The layering is correct: sealAgentCandidateBundle (bundle.ts) remains the low-level sealer; buildAgentCandidateBundle sits above it as the compiler that assembles inputs safely. The fail-closed design is thorough — it rejects unsupported profile fields (connections, metadata, extensions), derives profileDiffIds from the profile source (callers cannot cont
  • Better / existing approach: none — this is the right approach. The builder correctly delegates code verification to agent-eval's verifyCodeSurface (the substrate), reuses sealAgentCandidateBundle for the actual sealing, and extracts profile logic that was previously trapped in improvement-cycle.ts. No existing equivalent in the codebase does what buildAgentCandidateBundle does.
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 2
  • Bridge warning: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content

🎯 Usefulness — sound

Canonical builder + extracted profile-freezing module that deduplicates inline logic from the intelligence layer and exposes one public entry point for compiling measured candidates into sealed, byte-verified execution bundles.

  • Integration: Fully wired and reachable. buildAgentCandidateBundle (builder.ts:80) is exported from the public ./candidate-execution package path (index.ts:6) and verified by scripts/verify-package-exports.mjs:81-122. It feeds the intelligence lifecycle: proposeAgentImprovement (improvement-cycle.ts:159) accepts a buildCandidate callback whose JSDoc (improvement-cycle.ts:113) names `buildAgentCandidateB
  • Fit with existing patterns: Fits the codebase grain and removes duplication. Before this PR, parseExactAgentProfile, assertCandidateProfileBinding, and candidateProfileAsAgentProfile were inlined in improvement-cycle.ts; the PR extracts them into candidate-execution/profile.ts and re-imports them (improvement-cycle.ts:30-32). The new builder wraps — does not compete with — the pre-existing low-level `sealAgentCandidate
  • Real-world viability: Defensive on the paths that matter. Fails closed on unsupported profile fields (connections/metadata/extensions/model.metadata), caller-supplied profileDiffIds, raw Git patches (must go through agent-eval verifyCodeSurface), and code/profile identity drift (builder.ts:83, 146-153, profile.ts:32-35, 224-227). CodeSurface bytes are re-read and hash-checked before embedding (builder.ts:146-153).
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 1

💰 Value Audit

🟡 assertCanonicalParse duplicated identically in builder.ts and profile.ts [duplication] ``

assertCanonicalParse is defined byte-for-byte identically in builder.ts:170 and profile.ts:246 (same Buffer.from(canonicalCandidateBytes(...)).equals(...) check, same error message template). Both files are in the same candidate-execution/ directory and both already import from digest.ts. Extract this helper into digest.ts (or a shared internal util) and import it from both, the same way canonicalCandidateDigest and canonicalCandidateBytes are already shared. Does not gate shipping — purely a lo


What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260711T180256Z

@drewstone drewstone merged commit 1315217 into main Jul 11, 2026
2 checks passed
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