← Back to BlogEngineering

Your AI Coding Policy Template Enforces Nothing

Oracle banned AI code in OpenJDK, then allowed it in GraalVM two weeks later. A rule with no mechanism and no owner is not a policy.

Someone in security asks who approved a specific AI-assisted push, and by what mechanism. If the answer is a paragraph in a wiki, that is not a policy. It is a position statement, and most published AI coding policy templates are the same thing: rules with no trigger, no action and nobody who owns them. A policy is only real when something checks it at the moment code is written or committed.

Published templates cluster at two extremes, ban everything or trust everyone, and both fail for the same reason: neither names a mechanism. Oracle proved the point against itself in about two weeks. In early April 2026 the OpenJDK Governing Board approved an interim policy stating that contributions must not include content generated, in part or in full, by large language models, diffusion models or similar deep-learning systems. The scope is wide. It covers source code, text and images across OpenJDK Git repositories, GitHub pull requests, email messages, wiki pages and JBS issues. The board cited reviewer burden from plausible-looking but flawed code, safety in mission-critical systems, and the fact that ownership of intellectual property in AI-generated output is the subject of active litigation, which collides with a contributor agreement that requires you to own what you sign over. In mid-April, Oracle's own GraalVM project, an Oracle Labs effort outside the Governing Board's remit, permitted AI coding assistants on a contributor-accountability basis: if a contributor cannot explain, defend or maintain an AI-assisted change, maintainers may reject it.

Sources: InfoQ: Oracle's OpenJDK Bans Generative AI Contributions While Oracle's GraalVM Allows Them

Neither position is wrong for its context, and that is the uncomfortable part. One company reached both conclusions inside a fortnight. Which means the ban-versus-allow argument that consumes most policy drafting is the least consequential decision on the table. Copying a stance is not the work. A stance you inherit from someone else tells you nothing about what runs in your pipeline.

The Godot Foundation is a useful third data point because its policy names an automated action rather than only a position. It requires all code to be human authored, limits AI assistance to menial things such as code completion, regex, and find and replace, and requires anyone who used AI to author code to disclose it in the pull request discussion. Autonomous AI agent use and vibe coding already trigger an automatic ban from its GitHub repository. Disclosure is a social mechanism and a weak one. The auto-ban is a real action attached to a real trigger. The harder question is what any mechanism buys once engineers learn its shape: a required trailer becomes a field people paste without reading, and an engineer satisfies a diff-size check by splitting one agent change across four pull requests. A mechanism someone can game still beats a preference, because the evasion leaves a trace in the history that an auditor can find later.

Sources: Godot Engine: Changes to our Contribution Policies

Insight

If a rule has no trigger and no action, it is not a policy row. It is a preference, and it should carry that label so nobody mistakes it for coverage.

Three audiences judge the finished policy. A security reviewer wants to know what fires and when. Engineers route around anything that costs them more than it protects. An auditor checks whether the document's claims match the systems behind them. One structure survives all three: a table where every rule carries its mechanism and its owner, and where the rules with no mechanism say so out loud.

Every policy rule needs a mechanism and an owner

Write the policy as a table with four columns and refuse to leave any cell blank. When the honest answer is that nothing enforces a rule, write None available in the mechanism column. A cell that admits it is empty stays visible in a way a missing row never does.

Each column has a test. A mechanism is a trigger plus an action, so a pre-commit hook, a required check or an organization setting qualifies and an expectation does not. An owner is a named team that can change the mechanism, not a role in the abstract, because a row owned by everybody goes stale without anyone noticing. Status takes two values. Enforced means something fires whether or not a human chooses to care that day. Advisory means a person has to notice, which is a legitimate answer for judgment calls and a dishonest one for anything a setting could cover. Resist a third value such as partly enforced. A hedge in the status column is where a reader stops believing the rest of the table. A row is finished when a stranger can read it and predict what happens when someone breaks it.

Policy ruleMechanismOwnerStatus
Only approved agent tools may access the repoManaged settings allowlistPlatform teamEnforced
Permission bypass mode is disableddisableBypassPermissionsMode in managed settingsPlatform teamEnforced
No secrets in agent-authored commitsPre-commit scanner plus push protectionSecurityEnforced
A commit trailer records agent involvementCI check on the trailer fieldEng leadsEnforced
The disclosure is accurateNone availableReviewerAdvisory
No change may weaken CIBranch protection and required checksPlatform teamEnforced
Agent PRs stay under a size limitCI check on diff statEng leadsEnforced
A spec exists before implementationGate in the dev workflowEng leadsEnforced
The submitter understood the changeNone availableReviewerAdvisory
The abstraction fits the codebaseNone availableReviewerAdvisory

What GitHub and Claude Code already enforce for you

Several rows above are enforceable today without building anything. Claude Code reads two keys from managed settings that a developer cannot override locally: permissions.disableAutoMode strips auto mode out of the session, and permissions.disableBypassPermissionsMode blocks the mode that skips permission checks entirely. The same documentation lists what the auto-mode classifier blocks by default, including git remotes added or repointed mid-session, which it treats as untrusted; pushes of secrets or confidential material to a repository known to be public; and rm or rmdir removals aimed at a critical path. Those are policy rows with mechanisms already attached. Find out whether yours are switched on before you write another sentence of policy.

Sources: Claude Code docs: Choose a permission mode, Claude Code docs: Configure permissions

Governance is arriving on the other side of the market too. On 18 August 2026 GitHub shipped enterprise managed settings for Copilot in JetBrains IDEs, covering plugin and marketplace governance, allowlists and denylists for MCP servers, central OpenTelemetry configuration, and a control that stops the Copilot agent from using bypass features. Administrators own all four. That ownership is the property that matters for a policy row, because the setting does not depend on the person under deadline agreeing with it. Those controls landed in August 2026, which is the point: the gap worth measuring first is the one between what your policy claims and what your platform can already enforce.

Sources: GitHub Changelog: Enterprise managed settings in GitHub Copilot for JetBrains

GitHub's own guidance on reviewing agent pull requests, written by Andrea Griffiths in May 2026, states that any change that weakens CI is a blocker, full stop. That is close to the correct shape for a policy row: an unambiguous trigger and a binary default. It is also the row where policies go soft. The same guidance treats CI gaming as a red flag category and asks for an explicit justification before the reviewer continues, which is a reasonable compromise and also the seam where a row like this turns advisory without anyone deciding to. If your CI rule has a justification path, log who invokes it and how often.

Sources: GitHub: Agent pull requests are everywhere. Here's how to review them.

Why good-faith engineers bypass the policy

People rarely violate a policy on purpose. They bypass it in good faith, mid-incident, when it sits between them and a fix. An engineer debugging production at midnight turns off a permission restriction, ships the fix, and the setting stays off. A team adopts an agent that is not on the approved list because the approved one cannot do the thing they need, and nobody re-runs the approval afterward. That is shadow AI, and it starts with a capability gap rather than a disagreement. Neither person decided to ignore the policy. The policy was not in the room when they made the call.

A setting an individual cannot change locally survives the midnight incident. A rule written in a wiki does not, and the leader who wrote it will not learn it failed until an audit or an incident review months later. That is the argument for enforcing at the organization level rather than in a document. When you choose where to put a rule, prefer the layer furthest from the person under time pressure. The obvious cost is that the same lock stands between an on-call engineer and a production fix. Treat that as a design problem rather than a reason to move the rule back into a wiki: give the row a break-glass path with a named approver and an expiry, so a bypass becomes an event someone sees rather than a setting that silently stays off.

Mark the unenforced rows as unenforced

Many of the rules leaders actually care about have no mechanism. Label those Advisory and assign them to review anyway, because almost every template omits that split, and omitting it is exactly what makes policies untrustworthy. Whether the abstraction fits, whether the change belongs in this service, whether the submitter understood what they submitted: no hook, scanner or CI job can check any of them. Writing them in the same visual register as enforced rules produces a document that reads as comprehensive and behaves as partial.

An auditor who sees an honest split between enforced and advisory rows will trust the enforced ones. An auditor who finds a rule presented as policy with nothing behind it will reasonably question every other row in the table. Auditors are not asking you to enforce everything. They are asking which half is which.

Pro Tip

A row nobody has tested is Advisory wearing a better label. For every Enforced row, write down the last date someone deliberately violated it and watched the mechanism fire. Most tables cannot fill that column at all.

What to put in an AI coding policy template

These eight rows cover most teams, and each one names a mechanism rather than an expectation.

  • Org settings pin approved tools and versions. The wiki list is not the control.
  • A default permission mode, with bypass disabled at the organization level so no individual can opt out locally.
  • Sandbox and network requirements for autonomous runs, written as configuration values rather than advice.
  • Provenance: a commit trailer recording that a change was agent-assisted, for example a single Agent-Assisted line, checked in CI so it is present rather than remembered.
  • Size limits on agent-authored pull requests. Whatever you believe about review quality at scale, a diff-stat threshold is one of the cheapest CI checks you will ever write.
  • A required spec or intent statement before implementation, so review compares the change to something written down.
  • Secret handling: scanning plus push protection, never a sentence asking people to be careful.
  • An explicit Advisory section for judgment-dependent rules, owned by review and labeled honestly.

Where a gate fits

The two Advisory rows are the ones teams most want mechanized and least often can: whether the submitter understood the change, and whether the abstraction fits the codebase. No off-the-shelf setting produces either. That is the row TLM Forge occupies: a spec audit before code exists, independent multi-agent review of the plan and the diff, phase-gated TDD, and a red-team pass that holds the commit until critical findings reach zero. It is one row in your policy with a mechanism attached, not a replacement for the rest of the table, and the platform settings above will do more for you on day one than any tool purchase.

Write the table first. Fill in the mechanisms you already own, turn on the platform controls you are paying for and not using, mark the judgment rows Advisory, and only then look at what is left. That exercise usually shows which half was available all along.

How often to revise an AI coding policy

A policy written today will understate what you can enforce next quarter. So put a recurring review on the calendar whose only job is to move rows from Advisory to Enforced as mechanisms appear. Give it a fixed agenda so it takes an hour rather than a workshop. Read the vendor changelogs for settings that did not exist last quarter. Re-test one Enforced row by deliberately breaking it. Confirm each owner still owns their rows after the last reorganization. Then check whether any Advisory row now has a mechanism worth turning on. Put a date next to anything you promote, so the table carries its own history and the next reviewer can see which rows have never moved. A policy that gets more enforceable over time is a sign the process is working. One that stays static is a document nobody owns.

How to test whether a policy row is real

The test for whether you are done is not length. Hand the table to someone in security. Let them pick any Enforced row and say what happens when an engineer violates it. If you can answer with a specific mechanism and the name of the team that owns it, the row is real. If the answer starts with an expectation about how engineers behave, move the row to Advisory and be honest that it is a preference you have not yet mechanized.

Frequently asked questions

01Should we ban AI-generated code outright?

Only if your context resembles OpenJDK, which banned generated contributions in April 2026 citing reviewer burden, safety in mission-critical systems and unsettled IP ownership. Oracle's own GraalVM project permitted AI assistants weeks later on a contributor-accountability basis. The stance matters less than whether anything checks it.

02What should an AI coding policy template include?

Approved tools and versions pinned in org settings, a default permission mode with bypass disabled organization-wide, sandbox and network rules for autonomous runs, a commit trailer recording agent involvement, size limits on agent pull requests, a required spec before implementation, secret scanning with push protection, and an explicit advisory section for judgment calls.

03What makes an AI coding policy enforceable?

Every rule needs a trigger, an action and an owner. If you cannot name what fires and what it blocks, the rule belongs in an advisory section rather than in the enforced part of the policy.

04How do we track which code was AI-assisted?

Use a commit trailer recording agent involvement, checked in CI so the field is required rather than requested. Disclosure that relies on people remembering to mention it in a pull request description degrades quickly, as Godot found when it made disclosure mandatory and still auto-bans agent contributions.

05What can we enforce without buying anything?

Default permission modes and organization-level bypass restrictions, approved tool lists, secret scanning with push protection, required CI checks, branch protection and diff-size limits. GitHub and Claude Code both ship admin-controlled settings for most of this in plans teams already pay for.

Ship AI-written code you can trust

TLM Forge is the missing process layer for Claude Code: a spec audit, independent multi-agent review, enforced TDD, and an adversarial red-team gate.

Get TLM Forge