rule_unread
The rules table binds a name nothing reads: a key that names no Service file, or a row no step performs that is neither an advice class nor refused.
| Fix | Fails in | Exit |
|---|---|---|
| Rename it to what it means, or take it out. | rules.ts:8 · rules.services['translation'].notarize | 1 |
Owned by Build it: the page that explains what this gate holds.
✗ The rules table binds a name nothing reads: a key that names no Service file, or a row no step performs that is neither an advice class nor refused. Rename it to what it means, or take it out. rules.services['translation'].notarize is a row no step of translation performs. A row binds nothing until a step does its act.
at rules.ts:8 · rules.services['translation'].notarize
✗ 1 to fiximport { Rules } from 'services.dev'
export default Rules({
version: '2026-10',
services: {
translation: {
sign: { reserved: 'sworn translator', where: '*', position: 'A sworn translator signs a translation filed with a registry.' },
notarize: { reserved: 'sworn translator', where: '*', position: 'A notary seals a translation for a registry.' },
},
},
})diff --git a/rules.ts b/rules.ts
index ab66914..ea708e3 100644
--- a/rules.ts
+++ b/rules.ts
@@ -5,7 +5,6 @@ export default Rules({
services: {
translation: {
sign: { reserved: 'sworn translator', where: '*', position: 'A sworn translator signs a translation filed with a registry.' },
- notarize: { reserved: 'sworn translator', where: '*', position: 'A notary seals a translation for a registry.' },
},
},
})✓ ready to sell · 1 Service · it keeps at least 80% of every jobimport { Service } from 'services.dev'
import rules from '../rules.ts'
export default Service({
name: 'Translation',
input: { document: 'file', to: 'language: a BCP 47 tag, such as fr-CA' },
output: { document: 'file' },
rules,
roles: { translator: { credential: 'sworn translator' } },
deliver: {
translate: 'ai',
harden: { review: 'adversarial', lenses: ['meaning', 'terms'] },
sign: { by: 'translator', stamp: true },
},
price: 89,
})How the legal example passes this gate, in lines read from its files.
'trademark-response': {
// …
fee: { open: true, position: 'Paying the office its fee is a delivery act.' },
// …
shared: { litigate: { refused: true, route: 'https://referrals.example.test/litigation', position: 'Litigation is retained directly, never ordered here.' } },deliver: {
// …
fee: { routed: true, submit: 'https://filings.example.test/fees', to: 'USPTO', receipt: 'receipt', next: () => 'file' },Read them in context: The rules table, Trademark response.
{
"code": "rule_unread",
"reason": "The rules table binds a name nothing reads: a key that names no Service file, or a row no step performs that is neither an advice class nor refused.",
"next": "Rename it to what it means, or take it out. rules.services['translation'].notarize is a row no step of translation performs. A row binds nothing until a step does its act.",
"doc_url": "https://services.dev/docs/reference/check/rule_unread",
"file": "rules.ts",
"line": 8,
"path": "rules.services['translation'].notarize"
}The whole document check --json prints
{
"ai": {
"cents_per_call": 42,
"simulated": true
},
"mcp": {
"tools": 13,
"tokens": 4490,
"sandbox": 9,
"budget": 8000
},
"files": [
{
"path": "rules.ts",
"lines": 7,
"kind": "rules",
"says": "rules 2026-10 · 1 Service · 2 rows"
}
],
"services": [