Skip to content
Practitioner10 min readUpdated September 2026

Audit Scheduling And The Code Freeze

An external audit is a scarce dependency with a lead time, not a stage gate. How to book it, scope it, prepare for it, survive the freeze, triage findings, and plan the re-review as cost rather than surprise.

Most programmes in this domain manage the external audit badly, and in the same way. The audit is treated as the final phase — something you do when the code is ready, arranged when you get close, completed shortly before you deploy. Under that model it is a gate: work flows towards it, stops, and is released by it.

Two things follow. The booking is made too late, because good review capacity is scarce and committed well in advance, so a team that starts looking when the code is nearly finished finds the earliest slot is later than the plan assumed. And the freeze becomes a fiction, because nobody can stop developing for the duration, so work continues on a branch and findings arrive against code that has already moved.

The better model is dull and effective. The audit is an external dependency with a long lead time, a defined input and a defined output. You schedule it like any other scarce resource, shape the work upstream so the input is ready when the slot arrives, and plan remediation and re-review as scheduled cost rather than overrun.

Book the capacity, not the milestone

Treat review capacity the way a manufacturer treats a long-lead component: commit to the slot before the thing that will occupy it is finished, and shape everything else around it. This inverts the usual sequence, because you are committing to a date for something whose scope is not final. The alternative is worse: waiting until scope is final means joining a queue behind everyone who booked earlier, and the delay lands on your launch date, where you have least flexibility and most committed cost.

Book early and re-scope later. Most firms will hold a slot against an approximate scope and refine it later. Reserving capacity you then reduce is a recoverable error; needing capacity nobody has is not.

Book the re-review at the same time. Remediation review is a separate engagement with its own capacity requirement. Teams that book only the initial audit find, weeks later, that the people who understand their code are committed elsewhere. Book both, with remediation time between them.

Know which reviewers you want and why. Firms and individuals specialise — by execution environment, by protocol category, by technique. A reviewer who has spent years on your class of system produces better findings than a general-purpose engagement, and that specialisation is part of what you are queueing for. For high-value systems, independent reviews by different parties find overlapping but non-identical sets of issues; whether that is proportionate is a judgement about exposure, not a rule.

Build the calendar backwards from the deploy date. Deploy date, minus a deliberate soak period, minus re-review, minus remediation, minus the initial review window, minus freeze preparation. The number you arrive at is your real feature-complete date, and it is almost always earlier than the one in the plan.

What a code freeze actually requires

"Code freeze" is used loosely, and the looseness causes most of the pain. A freeze in this context means one specific thing: the reviewers are given an exact commit, and that commit does not change while they work on it. Every finding, line reference and severity assessment in their report is anchored to that revision.

That is the requirement. Everything else people assume about a freeze is negotiable, and treating the negotiable parts as frozen is what makes freezes unpopular and therefore unenforced.

What must genuinely stop: changes to in-scope contracts at the reviewed revision. Not slowed. Stopped.

What can continue freely: off-chain services, front ends, indexers, infrastructure, documentation, operational tooling, test harnesses, and any contract explicitly out of scope. In a sensibly bounded system this is most of the work, which is one more argument for keeping the on-chain boundary tight.

What continues but must be handled carefully: work on in-scope contracts that cannot wait. It does not stop; it accumulates on a branch. The danger is not the branch but its size, which is the standard batch size problem in a new costume: a freeze running for weeks against an actively developed system produces a merge that is itself an unreviewed change of material size.

The mitigations are simple and routinely skipped. Keep the branch small by deferring anything inessential. Rebase continuously so integration is not a single event. Log every change made during the freeze where reviewers can see it, so a finding you have already fixed closes with evidence rather than argument. And be honest that anything merged after the reviewed commit is unreviewed code going to mainnet — a decision you may take deliberately but should never take accidentally.

Scoping to reduce cost and improve signal

Audit effort scales with the amount of code to be understood, its complexity, and the number of external interactions. All three are things you influence, and doing so does more than reduce cost: reviewer attention is finite, and spending it on peripheral code means not spending it on your core.

Shrink the surface before you book. Delete dead code, remove unused functions, collapse speculative generality. Every construct in scope consumes attention, and a deliberately pruned codebase gets a better review than a larger one for the same effort.

Use established libraries rather than rewriting primitives. Widely deployed implementations of standard behaviour carry accumulated scrutiny. Your own token, access-control system or maths library carries none, and will consume review time proving what the library already established.

Draw the scope boundary explicitly. State which contracts are in scope and which are out. Reviewers will tell you if an exclusion is unsafe, which is itself valuable.

Freeze the interfaces before the code. Much review effort goes into understanding how components interact, and interfaces settled earlier produce fewer clarification round-trips.

Stage the engagement for large systems. An architecture review while the design is malleable, then an implementation review later. The first is cheaper and catches the problems most expensive to fix late.

That last point is worth internalising. If your audit report contains architectural findings, the audit came too late — not in the calendar, in the sequence of decisions. The purpose of upstream verification is that by the time reviewers arrive, the design questions are settled.

Preparing the pack so reviewers spend time on logic

Reviewers spend their engagement doing two things: working out what your system is supposed to do, and working out whether it does it. Only the second is what you are paying for, and everything that shortens the first converts directly into deeper scrutiny of the part that matters.

ArtefactWhat it does for the reviewerCost to you if absent
Written specification of intended behaviourEstablishes what correct means, so deviations are visibleReviewers infer intent from code, so code that consistently does the wrong thing looks right
Stated invariants, as executable assertionsA precise list of your claims to attackReviewers must first guess what you guarantee
Threat model and trust assumptionsNames the actors and what you rely onTrust assumptions discovered late, or missed
Architecture and call-flow diagramsOrientation in hours rather than daysBilled time spent reading for structure
Privileged roles and permission matrixMakes access-control review systematicAccess findings found piecemeal
Deployment and upgrade planSurfaces operational risk, frequently where the real exposure sitsThe most consequential risks out of scope by accident

Two carry disproportionate weight. The specification, because without it a reviewer cannot distinguish a bug from a design choice and will either flag correct behaviour or miss incorrect behaviour. And the invariant list, the most efficient interface between your team and an external one.

Add one more thing that costs nothing: a named point of contact with real availability during the engagement. A question answered in an hour keeps reviewers moving; one answered in three days costs three days of the window you queued months for.

Triaging findings without capitulating

A report arrives with findings classified by severity. The instinct — particularly under time pressure, and particularly if the report will be published — is to fix everything. That is wrong, and acting on it is itself a risk, because every change to reviewed code is a new unreviewed change. Restructuring a function to close a low-severity observation can introduce a defect worse than the one you closed. The correct posture is triage in which fixing is one of several legitimate responses.

Critical and high findings: fix the class, not just the instance. If a rounding error was found in one place, search every analogous calculation. Findings cluster, because they come from a mistaken mental model, and that model produced code in more than one place.

Medium findings: fix unless remediation is riskier than the issue. Make the judgement explicitly and write down the reasoning.

Low and informational findings: decide, do not default. Many are style or gas observations; some are worth taking. Accepting one with a documented rationale beats a rushed change to reviewed code.

Disputed findings: argue them properly, in writing. Reviewers can be wrong, or working from a misunderstanding of intent. Explain why and record the exchange. If you find yourself disagreeing with a great many findings, the likelier explanation is that your specification failed to communicate intent — which is a finding in itself.

Three disciplines make triage work. Record every finding with an owner, a decision, a rationale and a resolution, including the ones you decline. Fix each as a discrete, individually reviewable change rather than one large remediation commit. And resist bundling opportunistic improvements into remediation, which is the most common way unreviewed code reaches production wearing the clothes of an audit fix.

Re-review is a scheduled cost, not a surprise

Remediation changes reviewed code. Reviewed code that has changed is no longer reviewed code. Therefore remediation requires review. This is not a controversial chain of reasoning, and yet re-review is missing from most plans, which is why it appears as a late, unbudgeted delay with the launch date already public. Put it in the plan from the beginning, with time and capacity reserved.

Reserve capacity with the same reviewers. Continuity matters — a reviewer who already understands the system re-reviews a change far faster than a new one.

Leave genuine remediation time between the two. Compressing it is how rushed fixes get made, and a rushed fix to security-critical code is exactly the input you do not want to hand to a re-review.

Scope the re-review to the diff, with judgement about blast radius. Not the whole system again, but not naively the changed lines either — a change to a shared component ripples.

Plan for a second round. Remediation sometimes introduces something, or a reviewer finds an adjacent issue while checking a fix. Treat one extra round as expected and the schedule stops being fragile.

Then leave a soak period before value is at risk. Deploy, verify, let third parties inspect, keep exposure capped, and only then raise limits. This costs calendar and nothing else, and it is the last cheap risk reduction available.

What to do on Monday

Find out the current lead time for the review capacity you actually want, for the kind of system you are building. Not a general figure — a real conversation with the firms or individuals you would engage. If that number is longer than the gap between now and your intended launch, you have found your critical path while there is still time to act.

Then build the calendar backwards through soak, re-review, remediation, review and freeze preparation, and publish the feature-complete date that falls out of it. That date, not the launch date, is the one the delivery plan has to hit.

Finally, start the audit pack now, while the system is still being built: specification, invariant list, threat model, permission matrix, architecture diagram. All of it is work you should be doing anyway for your own verification, and writing it early means reviewers spend their window on your logic rather than your orientation.