Documentation

Workspace rules and policies

A workspace rule is something every member's agent reads before it starts work. Some rules say how the work should be done. Others say what must never happen. This page explains the difference, how rules from the workspace, a repository and a person combine, which products load them, and how to write one that holds.

Basics

What a rule is

A rule is a short piece of plain language that Unlok puts in front of the model before every task in your workspace. It has a title, a body, a kind (instruction or policy), an enforced switch, and a list of the products it applies to. Rules live on the dashboard under Governance, then Rules and policies, and every member's agent picks them up within a minute of a change. Nothing to install, nothing to commit.

Rules and policies are workspace owned and part of the Team plan. A team has one set that applies to all of its members. The person who writes a rule is recorded, but the rule belongs to the workspace, so it stays when they leave and it applies to people who join later. A personal workspace has no rule list; the repository and personal files described below still work for everyone in Unlok Code.

Rules are read by the model, not executed by a program, with one exception described under typed policies. A well written rule is followed reliably; a vague or contradictory one is not. The guidance under writing a good rule is what makes the difference.

The distinction

Instructions and policies

Every rule is one of two kinds. The kind says what the rule governs and how much weight the agent gives it.

InstructionPolicy
How the work should be done.What must never happen, or must always hold.
Style, habits, preferences. The way your team likes things.Boundaries the workspace sets for everyone. Safety, data, money, scope.
Followed as guidance. A repository or a person can refine or override it.Followed as a limit. Usually enforced, so nothing below the workspace can loosen it.
Explain before you change. Tests before done. Plain language, outcome first.No secrets in code or chat. No destructive actions without approval. No purchases or sign ups.
Read after the policies, in the order you listed them.Read first. Enforced policies come before everything else.
Never enforced by code. There is no program that checks whether an answer was plain enough.Can carry a type that a product enforces in code, regardless of what the model decides.

A quick test when you are not sure which to pick: if breaking the rule would be a mistake to fix, it is an instruction. If breaking it would be an incident to report, it is a policy.

An instruction
Title: Explain before you change
Kind: instruction
Before editing files, say in two lines what you will change and why. If the change
touches more than three files, list them first and wait for a go ahead.
A policy
Title: No secrets in code or chat
Kind: policy, enforced
Never paste, commit, log or print API keys, tokens, passwords, private keys or
customer data. Read secrets from environment variables and say when one is needed.
The switch

What enforced means

Enforced is a separate switch from kind, on purpose. It answers one question: can anything below the workspace override this rule?

An enforced rule sits above every other tier. A repository's own rules cannot relax it, a person's own rules cannot relax it, and the model reads it before anything else in the prompt. Most policies are enforced, because a boundary that a repository can switch off is not a boundary.

You can also leave a policy unenforced, as a strong default that a repository may relax with a rule of the same title, or enforce an instruction you never want overridden, like “always run the tests”. The two switches together give four combinations:

CombinationUse it for
Instruction, not enforcedTeam style that a repository or a person may adapt. The common case.
Instruction, enforcedA working habit the workspace requires everywhere, such as running tests before reporting done.
Policy, not enforcedA strong default boundary that a specific repository may relax with a good reason.
Policy, enforcedA boundary nothing below the workspace may loosen. Secrets, destructive actions, data handling.
Layers

Tiers and precedence

Rules come from three places, and the extension reads all three. From lowest to highest precedence:

TierWhere it lives
WorkspaceThe dashboard, Governance then Rules and policies. Applies to every member.
RepositoryUNLOK.md at the root: the text above the first heading describes the repository, and every ## section is one rule named by its heading. A git ignored UNLOK.local.md beside it holds rules for this machine only.
Personal~/.unlok/UNLOK.md on each machine. Yours alone, in every repository you open.
Workspace, enforcedAbove all three. Nothing below can override it.

When two rules share a title, the higher tier wins and the lower one is dropped. The extension reports every such override under Settings, then Rules, so you can see that your repository's “Commit style” replaced the workspace's, or that the workspace's enforced “No prod keys” replaced a repository's attempt to relax it.

Rules with different titles do not conflict; they all apply. Keep titles specific so two rules about the same subject share one, and two rules about different subjects do not.

Products

Where a rule applies

Each rule lists the products it applies to. A rule about browsing does not belong in a coding task's prompt, and a rule about commit messages means nothing to the Browser Agent. Untick the products a rule is not for, and only the ones you leave ticked load it.

ProductHow it loads rules
Unlok CodeEvery task in the VS Code extension. Merges workspace rules with the repository's and your personal ones, enforced first.
Browser AgentUnlok adds the rules marked for the Browser Agent to every task it runs on a team account, at the task's first request.
OptimusRead once when Optimus builds its digest of the team's memory, and reused for every question until the digest refreshes, in every product that asks Optimus.
ChatUnlok adds the rules marked for Chat to every conversation on the dashboard, at its first message.
APIRequests made straight to the API with a team key get the rules marked for API added by Unlok, unless the caller loaded rules itself and said so.

A rule that applies to nothing is not allowed; the tab keeps at least one product ticked. See how rules reach the model for when each product reads them.

Starting points

Templates

The tab ships with sixteen templates, filterable by product. Open one to read the full rule and a plain account of what it does on each product, then add it. A template becomes the workspace's own rule the moment it is added: rename it, change the wording, change where it applies, or remove it later. Nothing from a template loads until someone adds it and saves.

TemplateKind
Explain before you changeInstruction, Unlok Code
Tests before doneInstruction, Unlok Code
Match the codebaseInstruction, Unlok Code and Optimus
Small commits, plain messagesInstruction, Unlok Code
Plain language, outcome firstInstruction, every product
Ask when a request can be read two waysInstruction, every product
Say where an answer comes fromInstruction, Optimus
Report what was done on each siteInstruction, Browser Agent
No secrets in code or chatPolicy, enforced, every product
No destructive actions without approvalPolicy, enforced, Unlok Code
Stay inside the open folderPolicy, enforced, Unlok Code
Customer data goes only to configured providersPolicy, enforced, every product
Prefer the cheaper model for routine workPolicy, Unlok Code and Optimus
No purchases, payments or sign upsPolicy, enforced, Browser Agent
Only the sites named in the taskPolicy, enforced, Browser Agent
Team facts are not guessedPolicy, enforced, Optimus
Craft

Writing a good rule

The model follows what it can act on. These habits make the difference between a rule that holds and one that gets ignored halfway through a long task.

DoBecause
One behaviour per rule.A rule that says three things gets two of them followed. Split it and each one holds.
Say the why in one clause."Never force push, because other people's branches build on main" is followed in cases the rule did not list. "Never force push" is followed only in the cases it did.
Name the action, not the attitude."Run the test suite before reporting done" can be checked. "Be careful with tests" cannot.
Say what to do instead.A policy that only forbids leaves the agent stuck. "Stop at the review step and ask" gives it the next move.
Keep it under six lines.Every rule rides along on every task. Long rules cost tokens on every step and get skimmed.
Use the same title for the same subject everywhere.That is how a repository refines a workspace rule instead of contradicting it.
Pick policy for boundaries, instruction for preferences.The agent reads policies first and treats them as limits. Putting a boundary in an instruction makes it negotiable.
Tick only the products the rule is for.A browsing rule in a coding prompt is noise, and noise dilutes the rules that matter there.

Avoid rules that contradict each other or the product's own behaviour. “Never ask questions” next to “Ask when a request can be read two ways” leaves the model guessing which one you meant, and it will pick differently on different days.

Beyond the workspace

Repository and personal rules

A repository carries its own rules in one file, UNLOK.md at the root, committed with the code so every clone gets them. Unlok Code offers to create it the first time you start a task in a folder without one, or type /init yourself. The agent then reads the repository and drafts the file, through the usual file approval.

UNLOK.md
---
workspace: 3f2a…            # the team this repository belongs to; the switch card uses it
workspace_name: Acme
---
# Unlok Backend

A FastAPI proxy in front of several model providers, billed per workspace.

## Tests before done

Run the test suite before reporting a task complete. Show failures, don't describe them.

## Commit style

One change per commit, message says what and why.

The text above the first ## heading describes the repository. Every ## section is one rule, named by its heading; that name is what a workspace rule of the same title refines or, if enforced, replaces. The front matter is optional: without it the file simply has no workspace binding.

UNLOK.local.md next to it is git ignored and holds rules for this machine only, in the same shape. Personal rules go in ~/.unlok/UNLOK.md and apply in every repository you open on that machine. Both rank above the repository and the workspace, but never above an enforced workspace rule.

This one file is the whole repository tier. If a repository still has the older .unlok folder, /init folds it into UNLOK.md and removes it. Workflows, hooks and skills live under .unlokrules, unchanged.

Permissions

Who can change them

Reading is for every member of the workspace. Writing needs the Edit workspace rules grant, which owners and admins have by default and which an owner can give to other roles on the Members page. Everyone else sees the same tab read only.

Every save is one change to the whole set and is recorded in the workspace's audit log with who saved it, how many rules there were, and how many were enforced.

On a personal workspace the Rules and policies tab explains that the feature belongs to the Team plan and offers the upgrade. Your personal rules remain the file described above, which the extension reads on every machine it is on.

Under the hood

How rules reach the model

Rules are text the model reads, placed in the system prompt before the conversation. Three things decide when that happens, who does it, and how it is recorded.

QuestionAnswer
When are they read?Once, at the start: the first turn of a task in Unlok Code, the first request of a Browser Agent task, the first message of a chat conversation, the build of an Optimus digest. Not on every message. A running task keeps the rules it started with; the next one picks up any change.
Who puts them in front of the model?Unlok Code does it itself, because it also merges the repository's and the person's files. Every other product gets them from the gateway: when a request arrives with a team key and no rules version, Unlok reads the workspace's rules for that product, renders them, and prepends them as a system message. The dashboard chat, the Browser Agent and scripts against the API need no code for this to hold.
Which rules?Only the ones ticked for that product, in this order: enforced policies, then other policies, then instructions, each with its source. Unlok Code layers the repository's UNLOK.md and the person's files on top, resolving same-titled rules by tier.
How is it recorded?Every rendered set has a version, a short hash of the rules in it. A product that loaded rules itself sends that version on each request; the gateway stamps the version it applied. The Requests page shows the version on every expanded request, and whether the caller or the gateway applied it, so a report that the agent ignored a policy can be checked against what was actually loaded.
What does it cost?One read per session, then nothing. Products that poll for changes ask with the version they have and get a short not modified answer when nothing changed.
Under the hood

What the agent sees

Rules are rendered into one block near the end of the system prompt. Enforced rules first, then the rest, each with the tier it came from so the model can weigh them. This is what a task in Unlok Code reads when the workspace has one enforced policy and a repository has one instruction:

Rendered block
# Unlok Rules

Rules from the workspace, this repository and the person, highest precedence first.
An enforced workspace rule may not be overridden by anything below it.

## No secrets in code or chat (workspace rule, enforced)

Never paste, commit, log or print API keys, tokens, passwords, private keys or customer data.
Read secrets from environment variables and say when one is needed.

## Testing (repository rule)

Run bun test before reporting a task done.

A change on the dashboard reaches the next task, conversation or Optimus digest, not the ones already running. Every request records which version of the rules it ran under, so a “the agent ignored the policy” report can be checked against what was actually loaded.

Developers

Rules from the API

A script or a service that calls Unlok with a team key follows the workspace's rules too. Two headers and one endpoint cover every case, and the default needs no code at all.

You want toDo this
Let Unlok apply the rulesNothing. A completion from a team key that carries no rules version gets the rules marked for API prepended as a system message. Send a session id with your requests and the read happens once, at the first message, instead of once a minute.
Say which product you areSend X-Unlok-Surface with chat, browser, optimus, extension or api. Unlok applies that product's rules. A missing or unknown value counts as API.
Load the rules yourselfGET /v1/rules?surface=api with your key returns the rules that apply, a rendered block ready for a system prompt, and a version. Put the block in your own prompt, then send X-Unlok-Rules-Version with that version on each completion. The gateway leaves your prompt alone and the Requests page records the version you loaded.
Poll cheaplyThe version travels as an ETag. Send it back in If-None-Match and unchanged rules answer 304 with no body.
List the productsGET /v1/rules/surfaces returns the registry the dashboard's product chips come from, so a new product never needs a hard coded list.
Use a personal keyGET /v1/rules answers available: false with the reason team_plan, and nothing is prepended to completions.
Load once, then say so on every completion
# The rules marked for API, with their version as an ETagcurl -i "https://unlok-backend-xpts.onrender.com/v1/rules?surface=api" \
  -H "Authorization: Bearer $UNLOK_API_KEY"

# Ask again later with the version you have; 304 means nothing changedcurl -i "https://unlok-backend-xpts.onrender.com/v1/rules?surface=api" \
  -H "Authorization: Bearer $UNLOK_API_KEY" \
  -H 'If-None-Match: "a1b2c3d4e5f6"'

# Your completion carries the block in its own prompt, so the gateway adds nothingcurl https://unlok-backend-xpts.onrender.com/v1/chat/completions \
  -H "Authorization: Bearer $UNLOK_API_KEY" \
  -H "X-Unlok-Rules-Version: a1b2c3d4e5f6" \
  -H "Content-Type: application/json" \
  -d '{"model": "auto", "messages": [...]}'

The response body has version, workspace (type, id and name), surface, rules (id, kind, title, body, enforced, applies to) and rendered, the same block the gateway would have prepended. Rules for other products are one query away: surface=browser for an automation that drives a browser, surface=chat for a chat front end.

Enforced in code

Typed policies

Text tells the model. Code stops the action. A typed policy is a policy with a small configuration that a product enforces itself, whatever the model decides. The text still reaches the model, with one sentence added saying what is enforced, so a product that cannot enforce the type at least tells the model. Pick the type under Enforced in code in a policy's editor, or start from a template that has one.

Policy typeWhat happens
Allowed domainsOnly the sites you list may be opened, each with its subdomains. The Browser Agent blocks any other address before it loads and names the policy; an enforced policy replaces the local firewall list, a plain one adds to it. Unlok Code's web fetch tool refuses the address, and the model is told why.
Blocked actionsA click that would buy or check out, pay, sign up or create an account, send or submit, or delete is refused by the Browser Agent instead of being sent for approval. The task reports what remains for the person.
Spend cap per taskUnlok adds up what a conversation costs, vendor price, routing and fee, and refuses its next request once it has reached the cap, with an error that names the policy. Every product at once, since the gateway does it. A request Unlok cannot tie to a conversation is not capped.
Model allowlistUnlok routes only to the models you list, as provider/model. A request that pins any other model is refused, auto routing skips models outside the list, and a tier with nothing allowed is refused up front. Every product at once.

What the person sees: the policy's row carries the type, the Browser Agent's Options page lists what it enforces, and a refusal reads like “Blocked by the workspace policy ‘No purchases’: this Browser Agent may not buy or check out.” Two policies of the same type combine: their lists are joined and the lower cap wins.

Reference

Reference

TermMeaning
RuleAny entry on the Rules and policies tab. An instruction or a policy.
InstructionHow the work should be done. Guidance a lower tier may refine.
PolicyWhat must never happen, or must always hold. A limit, read first.
EnforcedCannot be overridden by a repository or a person. Sits above every tier.
Applies toThe products that load the rule: Unlok Code, Browser Agent, Optimus, Chat, API.
TierWhere a rule came from: workspace, repository, personal, or workspace enforced.
OverrideA higher tier rule with the same title replacing a lower one. Reported in Settings, then Rules.
TemplateA starting point on the tab. Becomes your own rule once added.
/initCreates UNLOK.md at the repository root, bound to the active team, then drafts it.
VersionA short hash of a rendered set of rules. Recorded on every request, shown on the Requests page.
GatewayUnlok adding the workspace's rules to a request whose caller did not load them itself.
Typed policyA policy with a configuration a product enforces in code: allowed domains, blocked actions, spend cap per task, model allowlist.
X-Unlok-SurfaceHeader naming the product a request is for, so the gateway applies that product's rules.
X-Unlok-Rules-VersionHeader a caller sends when it loaded the rules itself. The gateway then adds nothing.
© 2026 HEX INNOVATION LIMITED. ALL RIGHTS RESERVED