Inspiration

Two changes can each be locally valid and still be jointly invalid.

That becomes a serious coordination problem when multiple agents work independently against the same shared environment. Each agent can inspect its own task, pass its own checks, and still participate in a combined mutation that violates a constraint neither agent owns.

Interlock is a pre-mutation coordination layer for that gap. It checks revision-bound environment evidence before shared state changes, then makes a deterministic coordination decision that can be traced back to the evidence that produced it.

What Interlock does

Interlock:

  • reads revision-bound environment evidence before mutation;
  • evaluates independently valid intents against their shared constraints;
  • deterministically chooses whether work can proceed in parallel or must serialize;
  • produces an authorization receipt on the protected path;
  • requires that receipt at the target, so the coordination step is load-bearing rather than decorative;
  • separates a mutation's EXECUTED report from an independently authenticated OBSERVED read-back;
  • publishes frozen judge views and commit-pinned evidence so the proof can be inspected without trusting the UI.

The product is not another agent that recommends caution in prose. The decision boundary is deterministic, and the protected target can refuse a mutation that bypasses it.

The shipped causal proof

HAC-330 is a controlled local experiment.

Two locally valid intents share one environment bounded by:

sum(services[].reserved) <= 130

Interlock disabled Interlock enabled
Decision no decision WITHHOLD_SERIALIZE
Joint outcome 140 > 130, invalid joint state 120 <= 130, bounded constraint satisfied

Checks: 24/24.

Then I changed the environment evidence while holding the task structure fixed. The deterministic decision changed to ALLOW_PARALLEL, and the joint outcome returned to 140 > 130.

That perturbation is important. It shows that the evidence is load-bearing in the decision rather than merely displayed beside a predetermined result.

This experiment ran locally. It did not run on Google Cloud.

Google Cloud participation

The cloud proof is a separate recorded run with separate evidence.

HAC-340 records this traversal:

gemini-3.5-flash -> Google ADK 1.35.1 / Vertex AI -> Cloud Run-hosted agent in us-central1 -> Interlock MCP proxy -> ALLOW + authorization receipt -> protected target mutation EXECUTED -> independently authenticated read-back OBSERVED alpha=45 -> Cloud Logging correlated by run id.

EXECUTED and OBSERVED remain separate facts. One is what the mutation reported. The other is what a separately authenticated principal read afterwards.

Three fail-closed controls were recorded on the cloud path:

  • forged identity header -> 403
  • invalid bearer token -> 401
  • direct target bypass without receipt -> 403

Those are three recorded controls, not comprehensive attack coverage.

Why this matters

Multi-agent systems introduce composition failures that single-agent validation can miss. Two agents do not need to edit the same line, call the same tool, or share the same prompt to affect the same operational constraint.

Interlock moves that coordination question to the point before mutation. Instead of asking an agent to infer global coordination from prompt text, it gives the system a deterministic evidence boundary that can allow parallel work when the evidence supports it and serialize work when the observed coupling requires it.

The goal is not to make agents less autonomous. It is to make autonomous action legible before it changes shared state.

How I built it

The Interlock composition engine is a deterministic TypeScript core. It accepts revision-bound environment evidence plus a set of intents and returns a coordination decision with attribution.

The core carries no presentation dependency. Judge-facing surfaces read frozen, generated view models, so values such as 140, 120, 130, 24/24, and alpha=45 come from the evidence package rather than being hand-authored into screenshots.

On Google Cloud:

  • Gemini 3.5 Flash drives the recorded agent run;
  • Google ADK 1.35.1 provides the agent framework;
  • Vertex AI provides the model access path;
  • Cloud Run hosts the agent, Interlock MCP proxy, and protected target;
  • Cloud Run IAM establishes transport identity;
  • Cloud Logging provides a run-correlated record of the traversal.

The architecture keeps two provenance layers distinct:

  • Transport provenance: Cloud Run IAM establishes who called.
  • Application provenance: Interlock establishes the decision and receipt digest.

Those are deliberately not collapsed into the same claim.

Agent Runtime, Agent Gateway, and CONTENT_AUTHZ are not on the recorded deployment path.

Verify it yourself

Live project: https://interlock-sandy.vercel.app

Public repository: https://github.com/Marcelle-Labs/interlock

The public cloud evidence is pinned to a commit rather than a moving branch and includes an independent verifier plus a redaction manifest.

Core reproduction commands:

pnpm install
pnpm run check
pnpm run typecheck
pnpm run build
pnpm test

The repository also contains dedicated gates for provenance, the controlled experiment packet, the public cloud packet, the cockpit, visuals, storyboard, identity system, and final judge-facing package.

The HAC-335 judge-package gate includes 33 negative cases that prove the package fails when key claim boundaries, evidence bindings, capture freshness, or proof-class rules are violated.

Built during the hackathon

I built Interlock alone during this contest period.

I am also the creator and maintainer of the pre-existing open-source workspace.json specification and toolchain that Interlock consumes. That prior work is not presented as new contest work. Interlock itself is new, and the repository carries a machine-readable provenance boundary with CI enforcement so the distinction is inspectable rather than implied.

Challenges I ran into

Proving the evidence actually changes the decision

A visual can make evidence look important without proving that it affected anything. The perturbation arm exists specifically to test that. When the environment evidence changes, the deterministic decision changes with it.

Keeping two proof classes from turning into one stronger story

The local counterfactual and the Google Cloud traversal prove different things. It would be easy to show them consecutively and let a judge infer that the 140/120 experiment ran in the cloud. It did not. The README, cockpit, asset registry, claim ledger, and package gates all enforce the reset between those proof classes.

Making a receipt load-bearing

Generating a receipt is not enough. The protected target must care. The direct-bypass control returns 403, which proves the target refuses the demonstrated mutation path when the required receipt is absent.

Separating a self-report from an observation

A mutation returning success is not the same as independently observing the resulting state. The cloud run uses a different authenticated principal for read-back so EXECUTED and OBSERVED cannot silently collapse into one claim.

Making the proof surface as disciplined as the runtime

A technically correct system can still overclaim through captions, diagrams, stale screenshots, or UI labels. Interlock treats those surfaces as evidence consumers with their own deterministic gates.

Accomplishments

  • Built a new evidence-bound coordination engine during the hackathon period.
  • Demonstrated a controlled local counterfactual with 24/24 checks.
  • Demonstrated that changing the environment evidence changes the coordination decision.
  • Ran a real Gemini 3.5 Flash + Google ADK + Vertex AI + Cloud Run traversal through Interlock.
  • Made the authorization receipt load-bearing at the protected target.
  • Captured three fail-closed cloud controls: 403, 401, 403.
  • Separated mutation execution from independently authenticated read-back.
  • Published a commit-pinned cloud evidence packet with an independent verifier and redaction manifest.
  • Built a frozen judge cockpit, causal visual suite, architecture/trust-boundary diagrams, claim ledger, and deterministic asset registry.
  • Added negative package tests so judge-facing claims fail closed when the evidence or presentation drifts.

What I learned

The hard part of multi-agent coordination is not detecting that two agents exist. It is proving when their actions interact through shared state, making the resulting decision attributable to current evidence, and preventing the proof surface from claiming more than the runtime established.

I also learned that observability and provenance cannot be bolted on after the demo. If a judge cannot tell which system asserted a fact, which run produced it, and whether an outcome was reported or independently observed, the architecture is not yet legible enough.

Limits

The claims are intentionally bounded:

  • HAC-330 did not run on Google Cloud.
  • HAC-340 does not reproduce the 140/120 counterfactual in the cloud.
  • ALLOW is not VERIFIED.
  • OBSERVED is not SAFE.
  • WITHHOLD_SERIALIZE is not human approval, joint authorization, or an AUTHORIZED lifecycle state.
  • Agent Runtime and Agent Gateway did not participate in the recorded path.
  • No exactly-once, restart-safety, recovery, universal collision-prevention, fleet-scale, safety, security, verification, or production-readiness guarantee is claimed.
  • Evaluation metrics such as SPR, precision, recall, false-block rate, and useful concurrency are not yet bound to this package and are not shown.

What's next

The next step is to bind the reserved evaluation surface to measured coordination quality and useful-concurrency results, then expand from the controlled shared-state case to a broader set of multi-agent operational constraints without weakening the evidence boundary that makes the current claim inspectable.

Built With

  • cloud-run-iam
  • gemini-3.5-flash
  • google-adk-1.35.1
  • google-cloud-logging
  • google-cloud-run
  • model-context-protocol-(mcp)
  • node.js
  • typescript
  • vertex-ai
  • workspace.json
Share this project:

Updates