@oneie/claude 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/w1-recon.md +9 -4
- package/agents/w2-decide.md +51 -28
- package/agents/w3-edit.md +70 -78
- package/agents/w4-verify.md +164 -69
- package/commands/browser.md +98 -35
- package/commands/cc-connect.md +6 -0
- package/commands/chat.md +13 -1
- package/commands/close.md +45 -19
- package/commands/create.md +20 -10
- package/commands/db-sync.md +5 -1
- package/commands/deploy.md +174 -87
- package/commands/do-autonomous.md +31 -20
- package/commands/do-improve.md +4 -4
- package/commands/do-show.md +4 -3
- package/commands/do.md +53 -13
- package/commands/go.md +75 -0
- package/commands/improve.md +4 -2
- package/commands/kill.md +6 -8
- package/commands/notify.md +15 -2
- package/commands/oo-push.md +24 -9
- package/commands/rag.md +6 -0
- package/commands/release.md +46 -25
- package/commands/restart.md +5 -4
- package/commands/see.md +45 -35
- package/commands/skill-create.md +38 -5
- package/commands/sync.md +21 -11
- package/hooks/scripts/auto-continue.sh +70 -0
- package/hooks/scripts/branch-pin.sh +85 -0
- package/hooks/scripts/git-add-guard.sh +16 -5
- package/hooks/scripts/post-edit-check.sh +16 -0
- package/hooks/scripts/session-start.sh +13 -8
- package/hooks/scripts/sync-priority-todo.sh +5 -0
- package/package.json +1 -1
- package/rules/api.md +9 -0
- package/rules/design.md +13 -3
- package/rules/documentation.md +30 -71
- package/rules/engine.md +8 -1
- package/rules/ui.md +5 -1
- package/scripts/__pycache__/do-rank.cpython-313.pyc +0 -0
- package/scripts/browser-check.mjs +44 -103
- package/scripts/cc-events-proof.sh +13 -12
- package/scripts/chrome.mjs +381 -0
- package/scripts/do-analyze.sh +109 -4
- package/scripts/do-auto.sh +350 -43
- package/scripts/do-consumer-sweep.sh +72 -0
- package/scripts/do-derives-check.sh +88 -0
- package/scripts/do-fleet.sh +50 -1
- package/scripts/do-killswitch-audit.py +33 -14
- package/scripts/do-promise-lint.sh +150 -4
- package/scripts/do-promise-settle.sh +131 -9
- package/scripts/do-prove.sh +197 -17
- package/scripts/do-rank.py +606 -20
- package/scripts/do-rubric.py +21 -2
- package/scripts/do-signal.sh +157 -17
- package/scripts/do-smoke.sh +9 -0
- package/scripts/do-substrate-check.sh +49 -0
- package/scripts/do-tasks-wire-check.sh +81 -0
- package/scripts/do-tier.sh +90 -5
- package/scripts/do-ui-gate.sh +332 -0
- package/scripts/do-untracked-gate.sh +231 -0
- package/scripts/do-walk.sh +344 -0
- package/scripts/factory-check.sh +747 -0
- package/scripts/factory-repo.sh +1361 -0
- package/scripts/factory-tasks-check.sh +85 -0
- package/scripts/outcome-pull.ts +279 -0
- package/scripts/promise-manifest.mjs +167 -0
- package/scripts/reconcile-allow.txt +5 -0
- package/scripts/rubric-weights.json +64 -0
- package/scripts/spine-canary.sh +20 -0
- package/scripts/typedb-cluster-status.sh +128 -0
- package/scripts/typedb-env.sh +182 -0
- package/scripts/typedb-flap-recorder.sh +85 -0
- package/scripts/typedb-probes/containment-probe.py +88 -0
- package/scripts/typedb-probes/panic-probe-version.py +92 -0
- package/scripts/typedb-probes/panic-probe.py +77 -0
- package/scripts/typedb-scratch.sh +73 -0
- package/scripts/urls-lint.sh +58 -0
- package/scripts/w4-rubric.ts +96 -12
- package/scripts/wf-check.mjs +75 -0
- package/skills/ai-ui/SKILL.md +1 -1
- package/skills/astro/SKILL.md +177 -132
- package/skills/astro/add-content-collection.md +29 -13
- package/skills/astro/check-build.md +19 -13
- package/skills/astro/create-component.md +36 -9
- package/skills/astro/create-page.md +39 -10
- package/skills/astro/optimize-performance.md +36 -8
- package/skills/cli/SKILL.md +254 -220
- package/skills/dev/SKILL.md +1 -1
- package/skills/directory-autofill/SKILL.md +68 -0
- package/skills/docs/SKILL.md +4 -4
- package/skills/mcp/SKILL.md +186 -156
- package/skills/promise-make/SKILL.md +2 -2
- package/skills/puck/SKILL.md +465 -250
- package/skills/react19/SKILL.md +196 -296
- package/skills/reactflow/SKILL.md +387 -412
- package/skills/sdk/SKILL.md +167 -106
- package/skills/shadcn/SKILL.md +245 -201
- package/skills/signal/SKILL.md +5 -0
- package/skills/sui/SKILL.md +6 -1
- package/skills/tutorial/SKILL.md +15 -0
- package/skills/typedb/SKILL.md +427 -217
- package/skills/typedb/examples/python-patterns.py +11 -4
- package/skills/typedb/examples/query-patterns.tql +8 -3
- package/skills/typedb/examples/schema-patterns.tql +4 -2
- package/skills/typedb/reference/migration-2x-3x.md +19 -1
- package/skills/typedb/reference/python-driver.md +17 -1
- package/skills/voice/SKILL.md +117 -0
- package/skills/writer/SKILL.md +29 -12
- package/templates/template-feature.md +26 -1
- package/templates/template-tests.md +4 -0
- package/templates/template-todo.md +65 -10
package/skills/typedb/SKILL.md
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
name: typedb
|
|
3
|
+
description: Write, debug, and deploy TypeQL against the ONE substrate on TypeDB 3.12.1. Use when editing any `.tql` file under `schema/` (one.tql, roles.tql, do.tql, reason.tql, router.tql, factory.tql, work-contract.tql, migrations/), writing a `fun`, composing a match/insert/update/put pipeline, reading or writing through the `/v1/` HTTP API, or diagnosing a TypeDB error code (TQL0, REP1, REP4, REP44, FIN4, FUN5, SVL2, COW5, WCP4, INF11) or a query that hangs. Triggers — "write a TypeQL query", "add a fun", "change the schema", "deploy the schema", "this TypeDB query times out", "why is this .tql rejected", "match/fetch/reduce syntax", "TypeDB 2.x vs 3.x".
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
6
|
+
# TypeDB 3.x Complete Reference Skill
|
|
7
|
+
|
|
8
|
+
> **Version**: TypeDB **3.12.1** — prod (TypeDB Cloud) AND the local OrbStack
|
|
9
|
+
> container both run 3.12.1 as of 2026-07-29. Profiles: `.claude/typedb/{dev,prod}.env`,
|
|
10
|
+
> switched by `.claude/scripts/typedb-env.sh`. Never assume 3.0 or 3.8.x behaviour.
|
|
11
|
+
> **Last Updated**: 2026-08-02 (syntax claims re-probed read-only against live 3.12.1)
|
|
5
12
|
> **Purpose**: Comprehensive TypeDB/TypeQL knowledge for Claude Code
|
|
6
13
|
> **Primary sources**: TypeQL paper (Dorn & Pribadi, PACMMOD 2024, *Best Newcomer Award* at SIGMOD/PODS 2024) · TypeDB lecture series (Vaticle YouTube, 2023–2024) · "Inside TypeDB: The Next Chapter" (Dec 2025) · TypeDB 3.0 roadmap ([GitHub #6764](https://github.com/typedb/typedb/issues/6764))
|
|
14
|
+
>
|
|
15
|
+
> **In-repo canon is `schema/`, not this file.** `schema/one.tql` (480 lines) is the
|
|
16
|
+
> locked ontology; `schema/CLAUDE.md` says which files load, in what order, and which
|
|
17
|
+
> must never co-load. When this skill and a `.tql` disagree, the `.tql` wins.
|
|
18
|
+
>
|
|
19
|
+
> **How this repo actually talks to TypeDB: the `/v1/` HTTP API.** No driver package
|
|
20
|
+
> is installed anywhere in the monorepo. TypeScript goes through
|
|
21
|
+
> `one.ie/web/src/lib/substrate.ts` → the gateway in `api/src/index.ts` → `POST
|
|
22
|
+
> {TYPEDB_URL}/v1/query`; the Python scripts in `backup/scripts/typedb/` use
|
|
23
|
+
> `urllib` against the same endpoint. The *Python Driver* section below is
|
|
24
|
+
> background for reading upstream docs — it is not the path any code here takes.
|
|
25
|
+
>
|
|
26
|
+
> **Do not mock TypeDB in tests.** Real TypeDB or skip (root `CLAUDE.md`).
|
|
7
27
|
|
|
8
28
|
---
|
|
9
29
|
|
|
@@ -30,7 +50,7 @@
|
|
|
30
50
|
19. [Development Tools & Ecosystem](#development-tools--ecosystem) — Studio, Vibe Querying, Cloud, LSP
|
|
31
51
|
20. [SQL → TypeQL: Concrete Contrasts](#sql--typeql-concrete-contrasts)
|
|
32
52
|
21. [Works With /sui](#works-with-sui--the-same-ontology-two-deterministic-fires)
|
|
33
|
-
22. [Production Patterns: Classifier Functions, Thing Collapse, Symmetric Routing](#production-patterns-classifier-functions-thing-collapse-symmetric-routing) — from `
|
|
53
|
+
22. [Production Patterns: Classifier Functions, Thing Collapse, Symmetric Routing](#production-patterns-classifier-functions-thing-collapse-symmetric-routing) — from `schema/world.tql`
|
|
34
54
|
23. [Project-Specific Patterns](#project-specific-patterns)
|
|
35
55
|
|
|
36
56
|
---
|
|
@@ -79,28 +99,48 @@ This is a generalization of Wadler's *Propositions as Types* into **Queries as T
|
|
|
79
99
|
- **Type Hierarchies**: Single-inheritance subtyping with `sub`. Works on entities, relations, AND attributes.
|
|
80
100
|
- **Type Functions**: `fun` declarations replace 2.x `rule`; dependent-type subtyping generalizes Datalog-like reasoning.
|
|
81
101
|
|
|
82
|
-
### Connection Details (
|
|
102
|
+
### Connection Details (this repo — the `/v1/` HTTP API)
|
|
83
103
|
|
|
84
|
-
|
|
85
|
-
|
|
104
|
+
Two endpoints, both 3.12.1, both database `one`, credentials in
|
|
105
|
+
`.claude/typedb/{dev,prod}.env`:
|
|
86
106
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
107
|
+
```
|
|
108
|
+
prod https://flsiu1-0.cluster.typedb.com:1729 (TypeDB Cloud)
|
|
109
|
+
dev http://127.0.0.1:8000 (local OrbStack container)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`bash .claude/scripts/typedb-env.sh {dev|prod|status|up|down}` rewrites the four
|
|
113
|
+
`TYPEDB_*` lines in `one.ie/web/.env`. Every call is two HTTP requests:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
TOKEN=$(curl -s -X POST "$TYPEDB_URL/v1/signin" \
|
|
117
|
+
-H 'content-type: application/json' \
|
|
118
|
+
-d "{\"username\":\"$TYPEDB_USERNAME\",\"password\":\"$TYPEDB_PASSWORD\"}" \
|
|
119
|
+
| jq -r .token)
|
|
91
120
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
121
|
+
curl -s -X POST "$TYPEDB_URL/v1/query" \
|
|
122
|
+
-H "Authorization: Bearer $TOKEN" -H 'content-type: application/json' \
|
|
123
|
+
-d '{"query":"match $g isa group; reduce $c = count($g);",
|
|
124
|
+
"databaseName":"one","transactionType":"read","commit":false}'
|
|
95
125
|
```
|
|
96
126
|
|
|
127
|
+
`transactionType` is `read` | `write` | `schema`; `commit` must be `true` for
|
|
128
|
+
anything but `read`. `GET /v1/databases/one/schema` dumps the live schema —
|
|
129
|
+
the fastest way to answer "is this fun actually deployed?". `GET /v1/version`
|
|
130
|
+
returns the running build.
|
|
131
|
+
|
|
132
|
+
The Python driver (`TypeDB.driver(...)`, `driver.transaction(...)`) is covered in
|
|
133
|
+
the *Python Driver* section for reading upstream docs. **No code in this repo
|
|
134
|
+
uses it** — there is no `typedb-driver` dependency in any `package.json` or
|
|
135
|
+
`requirements.txt`.
|
|
136
|
+
|
|
97
137
|
---
|
|
98
138
|
|
|
99
139
|
## Critical Syntax Rules
|
|
100
140
|
|
|
101
141
|
### MUST-KNOW RULES
|
|
102
142
|
|
|
103
|
-
| Feature | Correct TypeDB 3.
|
|
143
|
+
| Feature | Correct TypeDB 3.x (verified on 3.12.1) |
|
|
104
144
|
|---------|-------------------|
|
|
105
145
|
| Sessions | **NO SESSIONS** - transactions directly on driver |
|
|
106
146
|
| Concept API | **DROPPED** — all operations go through TypeQL queries |
|
|
@@ -116,6 +156,42 @@ with driver.transaction("database-name", TransactionType.READ) as tx:
|
|
|
116
156
|
| List attributes | `attribute emails, value string[];` — 3.x-only syntax for list-valued attributes |
|
|
117
157
|
| Struct values | `struct address { street: string, city: string };` — 3.x compound values |
|
|
118
158
|
|
|
159
|
+
### VERIFIED against the live cluster (flsiu1-0.cluster.typedb.com)
|
|
160
|
+
|
|
161
|
+
These override anything else in this file — each was probed against the prod
|
|
162
|
+
TypeDB Cloud build (`commit:false` schema txs, or read txs with `with fun`).
|
|
163
|
+
Rows are dated: **2026-07-07** was probed on the pre-bump build; the syntax rows
|
|
164
|
+
marked **re-probed 2026-08-02** were re-run against live **3.12.1** and still
|
|
165
|
+
hold. `with fun … match …` in a `read` transaction is the cheap way to test
|
|
166
|
+
function syntax without touching the schema.
|
|
167
|
+
|
|
168
|
+
| Claim elsewhere in this file | What the live cluster ACTUALLY accepts |
|
|
169
|
+
|---|---|
|
|
170
|
+
| `return first if (...) then X else Y` conditional returns | **REJECTED — re-probed 2026-08-02 on 3.12.1, still rejected.** `match let $x = if (true) then 1 else 2;` → `[TQL0] [TQL03] syntax error: expected PLUS, MINUS, TIMES, DIVIDE, POWER, or MODULO`. There is no conditional *expression* in TypeQL. Encode classifiers as an exhaustive disjunction that binds a `let` per branch, then `return first $var`: `{ $st == "halted"; let $stage = "halted"; } or { … };` — this is exactly what the deployed `do_stage` and `path_status` do. **Beware:** `schema/world.tql`, `schema/sui.tql` and `schema/skins.tql` in this repo are written in the `if/then/else` form and are therefore NOT deployable to the main `one` database — see the note in *Production Patterns* below. `schema/reason.tql` carries the deployable rewrite of `path_status`. |
|
|
171
|
+
| `return $x;` for scalar functions | **REJECTED** — scalar returns require a selector: `return first $x;` (`expected return_single_selector or return_reduce_reduction`) |
|
|
172
|
+
| `fun f() -> { $to: city }` — naming the returned variable in the signature | **REJECTED** (re-probed 2026-08-02) — `[TQL0] syntax error: expected named_type_any`. A stream return type is types only: `-> { city }`, `-> { actor }`, `-> { thing, string }`. Tuple returns without braces (`-> string, integer`) are valid. |
|
|
173
|
+
| stream membership via `contains` — `my_stream_fun($x) contains $y;` | **REJECTED** (re-probed 2026-08-02) — `[REP44] The variable 'y' is required to be bound to a value before it's used`. `contains` is *substring* matching on strings. Iterate a stream with `let $y in my_stream_fun($x);` — the only form the deployed schema uses. |
|
|
174
|
+
| calling a `fun` and then reading attributes off the returned rows | **Works, but it is the wrong tool and it is slow.** Functions are for **COUNTS and scalars** — `return count($x)`, `return first $status`. When you need **rows plus their attributes**, do NOT call the fun and then `has` the results: **inline the fun's body** into your match and select the attributes there. This is the single most common cause of a query that "works locally, hangs in prod". |
|
|
175
|
+
| a `\uXXXX` escape inside a TypeQL string literal | **Killed the server process on 3.8.3** (a PANIC, not an error) — reproducer at `.claude/scripts/typedb-probes/panic-probe.py`, and the reason `backup/scripts/typedb/dump.py` renders every literal with `ensure_ascii=False`. Prod and local moved to **3.12.1 on 2026-07-29 and this has not been re-probed since.** Treat as unresolved: keep emitting raw UTF-8, never `\uXXXX`. The same build also panicked on the same variable used in two roles. |
|
|
176
|
+
| `fun f(threshold: double = 10.0)` default params | **REJECTED** — params need `$` and no defaults: `fun f($threshold: double)` |
|
|
177
|
+
| `define fun` re-applies like types | **REJECTED** (`FUN5 already exists`) — an existing function needs `redefine fun …` (one per tx); `define` is idempotent for types only |
|
|
178
|
+
| `redefine attribute x, value string @values(…)` | Syntax is `redefine x value string @values(…);` — no `attribute` keyword, no comma |
|
|
179
|
+
| value param binding an attribute: `has tag $axis` ($axis: string param) | **REJECTED** (`REP1`) — bind then compare: `has tag $t; $t == $axis;` |
|
|
180
|
+
| role named `as` (e.g. `relates as`) | **REJECTED** — `as` is reserved (role aliasing). A relation using it makes the whole file unparseable |
|
|
181
|
+
| labels are per-kind | Labels are **global across kinds** — `entity channel` cannot coexist with `attribute channel` (`SVL2`) |
|
|
182
|
+
| a fun calling a not-yet-defined fun validates | Cross-fun references only resolve against **committed** functions (`REP4` on commit:false) — commit dependencies first, or define both in one tx. This is why `schema/factory.tql` is one file: a partial multi-file deploy produced prod's `[REP4] Could not resolve function with name 'gaps'` on 2026-07-29. |
|
|
183
|
+
| a fun body that type-checks in isolation deploys | **`FIN4` / `QUA2`** — "The types inferred for the return statement of function 'f' did not match those declared in the signature. Mismatching index: 0". The return type is checked against what the body actually binds, so `-> string` with a body binding an attribute concept fails. Fix the signature or bind a value with `let`. |
|
|
184
|
+
| reading an attribute off a variable the planner infers as a *union* of owner types | **`INF11`** — the union has no member that can own the attribute, and the **whole schema transaction is rejected** at function type-check. This is why the three `*-schema.tql` domain files are absent from prod (`schema/CLAUDE.md`). Constrain the variable's type before reading the attribute. |
|
|
185
|
+
| `return first true` (boolean literal) | **REJECTED — re-probed 2026-08-02 on 3.12.1, still rejected** (`[TQL0] syntax error: expected var`) — bind first: `let $ok = true; return first $ok;`. The live schema contains **zero** `return first <literal>`; every one of its nine distinct return-first forms returns a bound variable (`$ok`, `$stage`, `$status`, `$toxic`, …). The deployed existence-check idiom is `match <the predicate>; let $ok = true; return first $ok;` — see `route_exists`. |
|
|
186
|
+
| `put` with non-key attributes is idempotent | **CRASHES on keyed entities** (`COW5` duplicate-key) when any non-key attribute differs from the existing row — the whole pattern fails to match, put inserts a duplicate @key. Put by key only, then put each invariant attribute as its own stage: `put $m isa actor, has aid "X"; put $m has actor-type "agent";` Never put attributes that vary (e.g. `name`) |
|
|
187
|
+
| `delete $attr of $e;` removes an ownership | **REJECTED** (`REP1 Object vs ThingType`) — and `delete has $attr of $e;` parses but can't feed a computed re-insert. There is NO in-database increment on this build |
|
|
188
|
+
| computed values in writes: `insert $e has strength ($s + 1)` or `has strength $ns` (value var) | **REJECTED** (`REP1 Attribute vs Value`) — writes take LITERALS only. The increment pattern is read-then-write: read current values, compute in the caller, write back with `update $e has strength 7.0;` (update = replace-or-add on card 0..1, no delete needed). See substrate.ts readPathWeights/updatePathWeights |
|
|
189
|
+
| relation insert/match+update: `insert $r (role: $x) isa rel-type, has attr val;` (role-list before `isa`) | **INSERT: REJECTED** (`WCP4 Could not determine the type of the insert variable '_anonymous'`). **MATCH-then-UPDATE: REJECTED** (`REP1 variable cannot be declared as both Object/Thing and ThingType`) the moment that same match feeds an `update`/`delete` stage — a plain match+select with this shape is fine. Verified 2026-07-12 while shipping `path-context` writes (`substrate.ts` `upsertPathContext`, `fade()`, `follow()`). Fix: declare `isa` first, `links` second — `insert $r isa rel-type, links (role: $x), has attr val;` and `match $r isa rel-type, links (role: $x), has attr val; update $r has attr val2;` both work for insert, match, AND update. Only pure match+select tolerates the role-first shorthand; treat isa-first as the universal safe form. |
|
|
190
|
+
| re-asserting `isa <type>` on a variable whose type is already implied by a role constraint elsewhere in the same match (e.g. `$e isa path, links(...)` after `$pc isa path-context, links(followed: $e)` already implies `$e` is a `path` via the schema's `path plays path-context:followed`) | **NOT rejected, but silently forces a full unbound scan** of the re-asserted type before the join — on a relation with real production volume (e.g. `path`, thousands of rows) this reliably **times out** (`"The operation was aborted due to timeout"`) even though the equivalent query with the redundant `isa` dropped returns instantly. Verified 2026-07-12: `match $e isa path, links(source:$a,target:$b); $pc isa path-context, links(followed:$e), has context-tag $ct, has context-strength $cs; ...` timed out; `match $pc isa path-context, has context-tag $ct, has context-strength $cs, links(followed:$e); $e links(source:$a,target:$b); ...` (path-context first, no re-`isa` on `$e`) returned instantly with identical results. Rule: **start the match from the smallest/most-selective relation, and never re-declare a type TypeDB can already infer from a role constraint.** |
|
|
191
|
+
| joining `has <attr> $x` on BOTH role players of the same two-role relation in one match (e.g. `(container: $p, contained: $c) isa containment; $c has tid $id; $p has tid $parent;`) | **NOT rejected, but reliably TIMES OUT** (10s, `"The operation was aborted due to timeout"`) — even on relation types with single-digit row counts platform-wide (`containment`: 9 rows, `blocks`: 2 rows). Reproduced consistently regardless of `limit`, statement order, or dropping a redundant `isa thing` on the role players — this is a distinct defect from the row above (that one is about a *redundant* `isa`; this one triggers even with the minimal, non-redundant `has` shape). Verified 2026-07-16 in `one.ie/web/src/pages/api/things/index.ts` (task board's subtask-parent + blocked-by lookups) — the query had been silently swallowing this 10s hang via `.catch(() => [])` on every single page load. **Each half in isolation is fast** (`$c has tid $id;` alone: ~0.7s; `$p has tid $parent;` alone: ~1s) — it's specifically resolving an attribute on **both** sides in the same query that's poisonous. Fix: split into two queries — (1) `match (container: $p, contained: $c) isa containment; limit N; select $p, $c;` with NO attribute join at all (returns raw entity `iid`s, sub-second), then (2) batch-resolve every involved `iid` to its attribute in ONE disjunction query: `match { $x iid 0x1e...; } or { $x iid 0x1e...; }; $x has tid $id; select $x, $id;` (also sub-second, confirmed via `flattenAnswers` — an entity concept with no `value`/`label` flattens to its bare `iid` string, so `row['p']`/`row['c']` from step 1 are directly usable as iid literals in step 2, no re-quoting). |
|
|
192
|
+
|
|
193
|
+
Deploy path: `POST {TYPEDB_URL}/v1/signin` → `POST /v1/query` with `transactionType:"schema"`, validate `commit:false` first. Working deployer pattern: `one.ie/web/scripts/deploy-chat-schema.ts`.
|
|
194
|
+
|
|
119
195
|
### Transaction Pattern (No Sessions!)
|
|
120
196
|
|
|
121
197
|
```python
|
|
@@ -635,13 +711,14 @@ fun friend_count($user: user) -> integer:
|
|
|
635
711
|
match ($user, $friend) isa friendship;
|
|
636
712
|
return count($friend);
|
|
637
713
|
|
|
638
|
-
# Recursive function (transitive closure)
|
|
639
|
-
|
|
714
|
+
# Recursive function (transitive closure).
|
|
715
|
+
# `node` is a DEAD NAME in this repo — use the real domain type.
|
|
716
|
+
fun reachable($from: city) -> { city }:
|
|
640
717
|
match
|
|
641
|
-
{ $_ isa
|
|
718
|
+
{ $_ isa flight, links (from: $from, to: $to); }
|
|
642
719
|
or {
|
|
643
720
|
let $mid in reachable($from);
|
|
644
|
-
$_ isa
|
|
721
|
+
$_ isa flight, links (from: $mid, to: $to);
|
|
645
722
|
};
|
|
646
723
|
return { $to };
|
|
647
724
|
```
|
|
@@ -675,7 +752,8 @@ select $name, $age;
|
|
|
675
752
|
with
|
|
676
753
|
fun is_adult($u: user) -> boolean:
|
|
677
754
|
match $u has age $a; $a >= 18;
|
|
678
|
-
return first true
|
|
755
|
+
let $ok = true; # bind — `return first true` is a TQL0 syntax error
|
|
756
|
+
return first $ok;
|
|
679
757
|
match
|
|
680
758
|
$u isa user;
|
|
681
759
|
let $adult = is_adult($u);
|
|
@@ -683,128 +761,137 @@ match
|
|
|
683
761
|
select $u;
|
|
684
762
|
```
|
|
685
763
|
|
|
764
|
+
A `with fun` block runs inside a plain **read** transaction, which makes it the
|
|
765
|
+
cheapest way to test function syntax against a live server without opening a
|
|
766
|
+
schema transaction. Every re-probe in the VERIFIED table above was done this way.
|
|
767
|
+
|
|
768
|
+
Each ad-hoc function needs **its own `with`** — `with fun a(…): …; fun b(…): …;`
|
|
769
|
+
is a parse error (`expected query_pipeline or WITH`). Write
|
|
770
|
+
`with fun a(…): …; with fun b(…): …; match …` and `b` may call `a`.
|
|
771
|
+
|
|
686
772
|
---
|
|
687
773
|
|
|
688
774
|
## Inference Rules (Emergence Patterns)
|
|
689
775
|
|
|
690
|
-
|
|
776
|
+
**There are no rules in TypeDB 3.x.** The `rule <name>: when { … } then { … };`
|
|
777
|
+
construct was removed with the 2.x line, and the live 3.12.1 schema dump contains
|
|
778
|
+
zero of them. Everything this section used to show as a rule is written as a
|
|
779
|
+
`fun` today. The translation is mechanical and lossy in exactly one place:
|
|
691
780
|
|
|
692
|
-
|
|
781
|
+
| 2.x rule | 3.x function |
|
|
782
|
+
|---|---|
|
|
783
|
+
| `when { … }` | the `match` body |
|
|
784
|
+
| `then { $e has tier "elite"; }` | a `let $tier = "elite";` binding + `return first $tier` |
|
|
785
|
+
| fires automatically, writes derived facts into the graph | evaluated **on call**; derives nothing until something calls it |
|
|
786
|
+
| chained rules (rule B reads rule A's output) | function composition — B calls A, or (faster) B inlines A's body |
|
|
787
|
+
| rule firing order / priority | the top-down order of the disjunction branches, visible in the source |
|
|
788
|
+
| `?val = $a / $b` value variables | `let $val = $a / $b;` — all variables use `$` |
|
|
693
789
|
|
|
694
|
-
|
|
695
|
-
|
|
790
|
+
The loss is the automatic part: a rule *materialised* derived facts, a function
|
|
791
|
+
*computes* them per query. Nothing in the graph changes until a caller asks.
|
|
696
792
|
|
|
697
|
-
|
|
698
|
-
when {
|
|
699
|
-
$e isa signal-edge,
|
|
700
|
-
has win-rate $wr,
|
|
701
|
-
has trail-pheromone $tp,
|
|
702
|
-
has traversal-count $tc;
|
|
703
|
-
$wr >= 0.75;
|
|
704
|
-
$tp >= 70.0;
|
|
705
|
-
$tc >= 50;
|
|
706
|
-
} then {
|
|
707
|
-
$e has tier "elite";
|
|
708
|
-
};
|
|
709
|
-
```
|
|
793
|
+
### Basic classification
|
|
710
794
|
|
|
711
|
-
|
|
795
|
+
The 2.x "elite pattern" rule becomes a classifier that returns the tier. Note the
|
|
796
|
+
shape: **an exhaustive disjunction, each branch binding the same `let`, closed by
|
|
797
|
+
`return first $var`.** There is no `if/then/else` expression in TypeQL — see the
|
|
798
|
+
VERIFIED table.
|
|
712
799
|
|
|
713
800
|
```typeql
|
|
714
801
|
define
|
|
715
802
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
$e
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
$
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
803
|
+
fun edge_tier($e: path) -> string:
|
|
804
|
+
match
|
|
805
|
+
$e has strength $s, has resistance $r, has traversals $t;
|
|
806
|
+
{ $s >= 70.0; $t >= 50;
|
|
807
|
+
let $tier = "elite"; }
|
|
808
|
+
or { $r >= 25.0; not { $s >= 70.0; $t >= 50; };
|
|
809
|
+
let $tier = "danger"; }
|
|
810
|
+
or { not { $s >= 70.0; $t >= 50; };
|
|
811
|
+
not { $r >= 25.0; };
|
|
812
|
+
let $tier = "active"; };
|
|
813
|
+
return first $tier;
|
|
726
814
|
```
|
|
727
815
|
|
|
728
|
-
|
|
816
|
+
Every branch after the first must **negate the earlier branches' conditions**.
|
|
817
|
+
A disjunction is not a cascade: without the `not { … }` guards, a path matching
|
|
818
|
+
two branches yields two rows and `return first` picks an arbitrary one. This is
|
|
819
|
+
the single most common bug when porting a chained rule set. `path_status` in
|
|
820
|
+
`schema/reason.tql:63` is the deployed five-branch example — read it before
|
|
821
|
+
writing your own.
|
|
729
822
|
|
|
730
|
-
|
|
731
|
-
define
|
|
823
|
+
### Chained rules become composition
|
|
732
824
|
|
|
733
|
-
|
|
734
|
-
rule hardening-candidate:
|
|
735
|
-
when {
|
|
736
|
-
$e isa signal-edge,
|
|
737
|
-
has tier "elite", # DERIVED from elite-pattern rule
|
|
738
|
-
has traversal-count $tc,
|
|
739
|
-
has trail-pheromone $tp;
|
|
740
|
-
$tc >= 100;
|
|
741
|
-
$tp >= 80.0;
|
|
742
|
-
} then {
|
|
743
|
-
$e has hardening-ready true;
|
|
744
|
-
};
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
### Rule with Disjunction (OR)
|
|
825
|
+
A rule that read another rule's derived fact becomes a function that calls it:
|
|
748
826
|
|
|
749
827
|
```typeql
|
|
750
828
|
define
|
|
751
829
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
$
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
$
|
|
758
|
-
|
|
830
|
+
fun hardening_ready($e: path) -> boolean:
|
|
831
|
+
match
|
|
832
|
+
$e has traversals $t, has strength $s;
|
|
833
|
+
$t >= 100; $s >= 80.0;
|
|
834
|
+
let $tier = edge_tier($e);
|
|
835
|
+
$tier == "elite";
|
|
836
|
+
let $ok = true;
|
|
837
|
+
return first $ok;
|
|
759
838
|
```
|
|
760
839
|
|
|
761
|
-
|
|
840
|
+
For anything hot, **inline the body instead of calling** — a call is an
|
|
841
|
+
optimisation barrier, and the deployed `preflight` inlines its three pre-checks
|
|
842
|
+
rather than calling `can_receive`/`is_safe`/`within_budget` for exactly this
|
|
843
|
+
reason.
|
|
844
|
+
|
|
845
|
+
### Disjunction over a single value
|
|
762
846
|
|
|
763
847
|
```typeql
|
|
764
848
|
define
|
|
765
849
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
$
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
?acc = $cp / $tp;
|
|
773
|
-
?acc >= 0.60;
|
|
774
|
-
} then {
|
|
775
|
-
$d has pheromone-level ?acc;
|
|
776
|
-
};
|
|
850
|
+
fun path_pressure($p: path) -> string:
|
|
851
|
+
match
|
|
852
|
+
$p has resistance $r;
|
|
853
|
+
{ $r > 25.0; let $sev = "high"; }
|
|
854
|
+
or { $r <= 25.0; let $sev = "normal"; };
|
|
855
|
+
return first $sev;
|
|
777
856
|
```
|
|
778
857
|
|
|
779
|
-
###
|
|
858
|
+
### Computed values
|
|
859
|
+
|
|
860
|
+
`?acc = $cp / $tp` becomes `let $acc = $cp / $tp;`. The result is returned, not
|
|
861
|
+
written back to the instance — **a function cannot write.**
|
|
780
862
|
|
|
781
863
|
```typeql
|
|
782
864
|
define
|
|
783
865
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
$
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
$tc >= 100;
|
|
791
|
-
} then {
|
|
792
|
-
$e has is-superhighway true;
|
|
793
|
-
};
|
|
866
|
+
fun delivery_rate($p: path) -> double:
|
|
867
|
+
match
|
|
868
|
+
$p has attempts $a, has deliveries $d;
|
|
869
|
+
$a >= 20;
|
|
870
|
+
let $rate = $d / $a;
|
|
871
|
+
return first $rate;
|
|
794
872
|
```
|
|
795
873
|
|
|
796
|
-
### Querying
|
|
874
|
+
### Querying derived values
|
|
797
875
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
match $e isa signal-edge, has tier "elite";
|
|
801
|
-
select $e;
|
|
876
|
+
In 2.x you matched the materialised fact. In 3.x you call the function and
|
|
877
|
+
compare its result:
|
|
802
878
|
|
|
803
|
-
|
|
804
|
-
match $e isa signal-edge, has
|
|
879
|
+
```typeql
|
|
880
|
+
# 2.x: match $e isa signal-edge, has tier "elite"; <- the fact was written
|
|
881
|
+
# 3.x: the tier is computed at query time
|
|
882
|
+
match
|
|
883
|
+
$e isa path;
|
|
884
|
+
let $tier = edge_tier($e);
|
|
885
|
+
$tier == "elite";
|
|
805
886
|
select $e;
|
|
806
887
|
```
|
|
807
888
|
|
|
889
|
+
**If you need the derived value to persist** — because you want to index it,
|
|
890
|
+
sort a large set by it, or hand it to a non-TypeQL consumer — compute it in the
|
|
891
|
+
caller and write it back with `update`. The substrate does this for path weights
|
|
892
|
+
(`readPathWeights` / `updatePathWeights` in `one.ie/web/src/lib/substrate.ts`),
|
|
893
|
+
because there is no in-database increment on this build (VERIFIED table).
|
|
894
|
+
|
|
808
895
|
---
|
|
809
896
|
|
|
810
897
|
## Patterns
|
|
@@ -1659,6 +1746,15 @@ The `[...]` brackets around `$resource.event-timestamp` tell `fetch` this is a m
|
|
|
1659
1746
|
|
|
1660
1747
|
These are 3.0+ features that change how you model data. Previously unavailable in 2.x.
|
|
1661
1748
|
|
|
1749
|
+
> **Three of these are UNVERIFIED here.** `struct`, list value types
|
|
1750
|
+
> (`value string[]`) and `@index` have **zero occurrences** in `schema/*.tql`
|
|
1751
|
+
> and **zero** in the live `GET /v1/databases/one/schema` dump, and confirming
|
|
1752
|
+
> them needs a schema transaction, which is a write. Treat the `struct`, *List
|
|
1753
|
+
> Attributes* and *Relation Indexing* subsections below as upstream-documentation
|
|
1754
|
+
> summaries, not as things known to work on 3.12.1. Probe with a `commit:false`
|
|
1755
|
+
> schema tx before relying on any of them. `@cascade` and `@subkey` are in the
|
|
1756
|
+
> same position.
|
|
1757
|
+
|
|
1662
1758
|
### Cascading Delete
|
|
1663
1759
|
|
|
1664
1760
|
Delete semantics are explicit via `@cascade` on relation roles. When the annotated role player is deleted, the relation itself is also deleted.
|
|
@@ -1749,28 +1845,46 @@ select $other;
|
|
|
1749
1845
|
### Functions (replace 2.x `rule`)
|
|
1750
1846
|
|
|
1751
1847
|
Rules are gone. Functions are the only way to express derivation logic in 3.x.
|
|
1848
|
+
See *Inference Rules (Emergence Patterns)* above for the full rule→fun
|
|
1849
|
+
translation table.
|
|
1752
1850
|
|
|
1753
1851
|
```typeql
|
|
1754
1852
|
define
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1853
|
+
# Return type names TYPES ONLY. `-> { $to: city }` is a TQL0 syntax error
|
|
1854
|
+
# ("expected named_type_any").
|
|
1855
|
+
fun reachable-cities($from: city) -> { city }:
|
|
1856
|
+
match ($from, $to) isa flight;
|
|
1758
1857
|
return { $to };
|
|
1759
1858
|
|
|
1760
|
-
# Transitively: fun with recursive call (bounded by type system)
|
|
1761
|
-
|
|
1859
|
+
# Transitively: fun with recursive call (bounded by the type system).
|
|
1860
|
+
# Iterate a stream with `let $x in f(...)` — NOT `f(...) contains $x`,
|
|
1861
|
+
# which is substring matching and fails with REP44.
|
|
1862
|
+
fun reachable-transitively($from: city) -> { city }:
|
|
1762
1863
|
match
|
|
1763
1864
|
{ ($from, $direct) isa flight; }
|
|
1764
1865
|
or
|
|
1765
|
-
{ reachable-cities($from)
|
|
1766
|
-
reachable-transitively($mid)
|
|
1866
|
+
{ let $mid in reachable-cities($from);
|
|
1867
|
+
let $direct in reachable-transitively($mid); };
|
|
1767
1868
|
return { $direct };
|
|
1768
1869
|
|
|
1769
|
-
# Use in a query
|
|
1870
|
+
# Use in a query — `in`, not `=`, for a stream
|
|
1770
1871
|
match
|
|
1771
1872
|
$nyc isa city, has name "New York";
|
|
1772
|
-
let $
|
|
1773
|
-
select $
|
|
1873
|
+
let $dest in reachable-transitively($nyc);
|
|
1874
|
+
select $dest;
|
|
1875
|
+
```
|
|
1876
|
+
|
|
1877
|
+
This is exactly the shape of the deployed `descendants-of` and `reachable`
|
|
1878
|
+
functions — see `schema/reason.tql` and `schema/roles.tql`:
|
|
1879
|
+
|
|
1880
|
+
```typeql
|
|
1881
|
+
fun descendants-of($g: group) -> { group }:
|
|
1882
|
+
match
|
|
1883
|
+
{ (parent: $g, child: $descendant) isa hierarchy; }
|
|
1884
|
+
or
|
|
1885
|
+
{ (parent: $g, child: $mid) isa hierarchy;
|
|
1886
|
+
let $descendant in descendants-of($mid); };
|
|
1887
|
+
return { $descendant };
|
|
1774
1888
|
```
|
|
1775
1889
|
|
|
1776
1890
|
Functions can return streams (`{ ... }`), single values (`scalar`), or structs. They compose in pipelines and let the planner see through the abstraction.
|
|
@@ -1905,21 +2019,21 @@ RETURN path
|
|
|
1905
2019
|
```typeql
|
|
1906
2020
|
# TypeQL — reachability is a type function, not a path operator
|
|
1907
2021
|
define
|
|
1908
|
-
fun flight-reachable($from: city, $hops: integer) -> {
|
|
2022
|
+
fun flight-reachable($from: city, $hops: integer) -> { city }:
|
|
1909
2023
|
match
|
|
1910
2024
|
{ $hops == 1; ($from, $to) isa flight; }
|
|
1911
2025
|
or
|
|
1912
2026
|
{ $hops > 1;
|
|
1913
2027
|
($from, $mid) isa flight;
|
|
1914
|
-
let $
|
|
1915
|
-
$to
|
|
2028
|
+
let $next = $hops - 1;
|
|
2029
|
+
let $to in flight-reachable($mid, $next); };
|
|
1916
2030
|
return { $to };
|
|
1917
2031
|
|
|
1918
2032
|
match
|
|
1919
2033
|
$nyc isa city, has name "New York";
|
|
1920
|
-
let $
|
|
1921
|
-
$
|
|
1922
|
-
select $
|
|
2034
|
+
let $city in flight-reachable($nyc, 3);
|
|
2035
|
+
$city has name "London";
|
|
2036
|
+
select $city;
|
|
1923
2037
|
```
|
|
1924
2038
|
|
|
1925
2039
|
In Neo4j, variable-length path is a query-language primitive. In TypeQL, it's a **user-definable function** — which means any reachability logic (weighted, filtered by attribute, cross-type) is equally expressible without new syntax.
|
|
@@ -1928,11 +2042,22 @@ In Neo4j, variable-length path is a query-language primitive. In TypeQL, it's a
|
|
|
1928
2042
|
|
|
1929
2043
|
## Works With /sui — The Same Ontology, Two Deterministic Fires
|
|
1930
2044
|
|
|
1931
|
-
|
|
2045
|
+
> **STALE — this section describes a layout the repo no longer has. Verify
|
|
2046
|
+
> before acting on any path or function name in it (checked 2026-08-02).**
|
|
2047
|
+
> `src/engine/bridge.ts`, `src/move/one/sources/one.move` and `src/lib/sui.ts`
|
|
2048
|
+
> **do not exist**, and no file in the monorepo defines `mirrorMark`,
|
|
2049
|
+
> `mirrorHarden` or `absorb`. The Move sources live under `pay/contracts/sui/`
|
|
2050
|
+
> and the Sui runtime under `pay/backend/src/chains/sui.ts` +
|
|
2051
|
+
> `one.ie/web/src/lib/resolvers/sui.ts`. `struct Colony` is **not** in the
|
|
2052
|
+
> current `one.move`. The *conceptual* crosswalk below (Move struct ⇌ TQL
|
|
2053
|
+
> attribute, shared `strength`/`resistance` names) still holds and is why the
|
|
2054
|
+
> section is kept; the file/function inventory does not.
|
|
2055
|
+
|
|
2056
|
+
**"The same ontology. Two deterministic fires."** TypeDB is the learning, classification fire (hypotheses, frontiers, tags — cheap to write, rich to query). Move is the permanent, economic fire (path revenue, escrow, treasury — expensive to write, cheap to trust). The runtime is the fast nervous system between them. Both skills speak the same vocabulary by design — `strength`, `resistance`, `revenue`, `path`, `actor` — so the bridge is a **1:1 rename, not a translation**.
|
|
1932
2057
|
|
|
1933
2058
|
### Canonical crosswalk
|
|
1934
2059
|
|
|
1935
|
-
`
|
|
2060
|
+
`schema/sui.tql` (475 lines) is the Rosetta Stone — every Move struct has a matching TQL entity, every Move function has a matching TQL `fun`. Read it when names or shapes drift. **It is codegen input, not a loadable schema** — `schema/codegen/codegen.ts` parses it standalone to emit Move; it is never loaded into TypeDB, and it is written in the `if/then/else` form the server rejects. The canonical ontology (6 dimensions, stable) is `schema/one.tql` (480 lines).
|
|
1936
2061
|
|
|
1937
2062
|
### Attribute mapping (Move struct ⇌ TypeDB attribute)
|
|
1938
2063
|
|
|
@@ -1949,11 +2074,11 @@ In Neo4j, variable-length path is a query-language primitive. In TypeQL, it's a
|
|
|
1949
2074
|
| `Highway.id` (address) | `path.sui-highway-id` | address | string | Sui → TQL on `mirrorHarden()` |
|
|
1950
2075
|
| `Signal.payload` (vector<u8>) | `signal.data` | bytes | string | one-way, usually TQL-only |
|
|
1951
2076
|
|
|
1952
|
-
**Name drift to know about:** Move
|
|
2077
|
+
**Name drift to know about:** older Move sources carried a `struct Colony`; TypeDB moved to `entity group` per `text/dictionary.md`. `colony` is a **dead name** (root `CLAUDE.md`) and is **no longer present** in `pay/contracts/sui/.../one.move` (checked 2026-08-02). If you meet it in an old artifact, read it as TQL `group`.
|
|
1953
2078
|
|
|
1954
2079
|
**Load-bearing invariant:** `strength` and `resistance` share the same name in both layers. If you rename one, rename both — `bridge.ts` is a pass-through, there's no translation logic. Type-width (`u64` ↔ `double`) is handled by JSON serialization at the bridge; don't write TQL queries that assume sub-integer precision on these columns.
|
|
1955
2080
|
|
|
1956
|
-
### Bridge contract (
|
|
2081
|
+
### Bridge contract (module no longer present — shape reference only)
|
|
1957
2082
|
|
|
1958
2083
|
| Function | Fires when | Maps |
|
|
1959
2084
|
|-----------------------------------|-----------------------------|------------------------------------------------------------------------|
|
|
@@ -1990,84 +2115,116 @@ select $p, $hw;
|
|
|
1990
2115
|
### When to load /sui alongside this skill
|
|
1991
2116
|
|
|
1992
2117
|
- Adding a field to a Move struct that needs off-chain query — the TQL attribute must match
|
|
1993
|
-
- Touching
|
|
1994
|
-
- Debugging why
|
|
1995
|
-
- Writing a TQL `fun` that needs an on-chain twin — see `
|
|
1996
|
-
- Querying `actor.wallet` values — they're derived
|
|
2118
|
+
- Touching Move path/signal logic under `pay/contracts/sui/` — `schema/one.tql` and `text/dictionary.md` are the source of truth for names
|
|
2119
|
+
- Debugging why an on-chain absorb isn't writing to TypeDB — check the loaded schema accepts the attribute type
|
|
2120
|
+
- Writing a TQL `fun` that needs an on-chain twin — see `schema/sui.tql` for parallel function signatures
|
|
2121
|
+
- Querying `actor.wallet` values — they're derived from the Sui resolvers (`one.ie/web/src/lib/resolvers/sui.ts`), not always stored
|
|
1997
2122
|
|
|
1998
2123
|
---
|
|
1999
2124
|
|
|
2000
2125
|
## Production Patterns: Classifier Functions, Thing Collapse, Symmetric Routing
|
|
2001
2126
|
|
|
2002
|
-
These
|
|
2127
|
+
These patterns come from **`schema/world.tql`** and are worth learning because they turn abstract ideas ("Queries as Types", polymorphism, role interfaces) into code that's actually short, composable, and fast to query.
|
|
2128
|
+
|
|
2129
|
+
> **Read the code below for the *shape*, and never paste it.** Two corrections
|
|
2130
|
+
> that this section got wrong for a long time:
|
|
2131
|
+
>
|
|
2132
|
+
> 1. **`world.tql` is not the live runtime schema of the main database.** Per
|
|
2133
|
+
> `schema/CLAUDE.md` it is the **brain schema for the standalone `api/`
|
|
2134
|
+
> BrainDO database only** — it declares `task-value`/`task-effort` as strings
|
|
2135
|
+
> where `one.tql` declares doubles, so co-loading the two fails on a
|
|
2136
|
+
> value-type conflict. The main `one` database's canon is
|
|
2137
|
+
> `one.tql` + `roles.tql` + `do.tql` + `reason.tql` + `router.tql` +
|
|
2138
|
+
> `factory.tql` + `work-contract.tql` + `chat.tql`.
|
|
2139
|
+
> 2. **`world.tql` is written in `return first if … then … else …`, which the
|
|
2140
|
+
> live 3.12.1 server rejects with `TQL0`** (VERIFIED table). It is therefore
|
|
2141
|
+
> not deployable as written. `schema/reason.tql` carries the rewrite that
|
|
2142
|
+
> *is* deployed. Below, every function is shown in the **deployable**
|
|
2143
|
+
> disjunction form, with the `world.tql` original noted where it differs.
|
|
2144
|
+
>
|
|
2145
|
+
> Attribute names differ across the two too: `success-rate`, `sample-count` and
|
|
2146
|
+
> `activity-score` exist in `world.tql` and **not** in the live `one` database.
|
|
2147
|
+
> Check `GET /v1/databases/one/schema` before assuming an attribute is there.
|
|
2003
2148
|
|
|
2004
2149
|
### Pattern 1 — The Deterministic Sandwich as a Function Chain
|
|
2005
2150
|
|
|
2006
|
-
A **deterministic sandwich** wraps a probabilistic operation (usually an LLM call) in a pre-check and a post-check, so the indeterminism is bounded on both sides. In TypeQL 3.x, every slice of the sandwich is a **typed function** returning either
|
|
2151
|
+
A **deterministic sandwich** wraps a probabilistic operation (usually an LLM call) in a pre-check and a post-check, so the indeterminism is bounded on both sides. In TypeQL 3.x, every slice of the sandwich is a **typed function** returning either a bound boolean or a stream.
|
|
2007
2152
|
|
|
2008
2153
|
```typeql
|
|
2009
|
-
#
|
|
2154
|
+
# schema/world.tql:586–614 — shape only; signatures corrected to `actor`
|
|
2155
|
+
# (world.tql says `actor`, an older draft of this skill said `unit`, a dead name)
|
|
2010
2156
|
|
|
2011
2157
|
# PRE: Can this receiver handle this skill? (capability check)
|
|
2012
|
-
fun can_receive($u:
|
|
2158
|
+
fun can_receive($u: actor, $sk: skill) -> boolean:
|
|
2013
2159
|
match (provider: $u, offered: $sk) isa capability;
|
|
2014
|
-
|
|
2160
|
+
let $ok = true;
|
|
2161
|
+
return first $ok;
|
|
2015
2162
|
|
|
2016
2163
|
# PRE: Is the path to this receiver safe? (not toxic)
|
|
2017
|
-
fun is_safe($from:
|
|
2018
|
-
match
|
|
2019
|
-
|
|
2020
|
-
|
|
2164
|
+
fun is_safe($from: actor, $to: actor) -> boolean:
|
|
2165
|
+
match
|
|
2166
|
+
(source: $from, target: $to) isa path,
|
|
2167
|
+
has strength $s, has resistance $r;
|
|
2168
|
+
{ $r > $s; $r >= 10.0; let $ok = false; }
|
|
2169
|
+
or { not { $r > $s; $r >= 10.0; }; let $ok = true; };
|
|
2170
|
+
return first $ok;
|
|
2021
2171
|
|
|
2022
2172
|
# PRE: Is the signal within budget?
|
|
2023
|
-
fun within_budget($u:
|
|
2024
|
-
match
|
|
2025
|
-
|
|
2173
|
+
fun within_budget($u: actor, $sk: skill, $amount: double) -> boolean:
|
|
2174
|
+
match
|
|
2175
|
+
(provider: $u, offered: $sk) isa capability, has price $p;
|
|
2176
|
+
{ $amount >= $p; let $ok = true; }
|
|
2177
|
+
or { $amount < $p; let $ok = false; };
|
|
2178
|
+
return first $ok;
|
|
2026
2179
|
|
|
2027
|
-
# POST: Does the referenced
|
|
2180
|
+
# POST: Does the referenced actor still exist?
|
|
2028
2181
|
fun unit_exists($uid: string) -> boolean:
|
|
2029
2182
|
match $u isa actor, has aid $uid;
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
# POST: Is a unit performing well enough to trust its output?
|
|
2033
|
-
fun is_trustworthy($u: unit) -> boolean:
|
|
2034
|
-
match $u has success-rate $sr, has sample-count $sc;
|
|
2035
|
-
return first if ($sr >= 0.50 or $sc < 10) then true else false;
|
|
2183
|
+
let $ok = true;
|
|
2184
|
+
return first $ok;
|
|
2036
2185
|
|
|
2037
2186
|
# COMPOSED: All the PRE checks as a single type assertion
|
|
2038
|
-
fun preflight($from:
|
|
2039
|
-
match
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2187
|
+
fun preflight($from: actor, $to: actor, $sk: skill) -> boolean:
|
|
2188
|
+
match
|
|
2189
|
+
(provider: $to, offered: $sk) isa capability;
|
|
2190
|
+
(source: $from, target: $to) isa path,
|
|
2191
|
+
has strength $s, has resistance $r;
|
|
2192
|
+
{ $r > $s; $r >= 10.0; let $ok = false; }
|
|
2193
|
+
or { not { $r > $s; $r >= 10.0; }; let $ok = true; };
|
|
2194
|
+
return first $ok;
|
|
2043
2195
|
```
|
|
2044
2196
|
|
|
2045
2197
|
**Why this is elegant:**
|
|
2046
2198
|
|
|
2047
2199
|
1. **Each check is a type, not a subroutine.** `is_safe($from, $to)` declares the type "this path is safe". The planner decides whether to evaluate it by scanning strength/resistance, by checking an index, or by proving it vacuously. You never write "first look up strength, then compare".
|
|
2048
2200
|
|
|
2049
|
-
2.
|
|
2201
|
+
2. **An exhaustive disjunction binding one `let` per branch, closed by `return first $var`,** is the TypeDB 3.x idiom for boolean and string classifiers — there is no conditional expression in the language. Each branch after the first must negate the earlier ones, or a row matching two branches makes `return first` arbitrary.
|
|
2050
2202
|
|
|
2051
|
-
3. **Composition is just another function.** `preflight()` inlines the match patterns of its children rather than calling them — this lets the planner see the whole constraint set and pick the cheapest plan. (Calling three separate functions would force three sequential lookups.)
|
|
2203
|
+
3. **Composition is just another function.** `preflight()` inlines the match patterns of its children rather than calling them — this lets the planner see the whole constraint set and pick the cheapest plan. (Calling three separate functions would force three sequential lookups.) This is the same "inline the body" rule as *functions are for counts*.
|
|
2052
2204
|
|
|
2053
|
-
4. **Negative space stays declarative.**
|
|
2205
|
+
4. **Negative space stays declarative.** A trust check that passes when `success-rate >= 0.50 OR sample-count < 10` trusts new agents by default, because there is no evidence against them. That's a domain rule encoded as a type, not as a runtime `if`. (`is_trustworthy` reads `success-rate`/`sample-count` — BrainDO-only attributes, so it is a `world.tql` function and has no counterpart in the main database.)
|
|
2054
2206
|
|
|
2055
2207
|
### Pattern 2 — The `thing` Collapse (Polymorphism as Entity-Level Union)
|
|
2056
2208
|
|
|
2057
|
-
Instead of modeling plan, cycle, task, and skill as four separate entities, the canonical ontology (`
|
|
2209
|
+
Instead of modeling plan, cycle, task, and skill as four separate entities, the canonical ontology (`schema/one.tql:96+`) **collapses them into one `thing` entity** discriminated by a `thing-type` attribute. Attributes specific to each kind (`task-status`, `cycles-planned`, `goal`) live on the shared entity, unused for non-matching kinds.
|
|
2058
2210
|
|
|
2059
2211
|
```typeql
|
|
2212
|
+
# Abridged — schema/one.tql is the source, and it is much longer than this.
|
|
2060
2213
|
entity thing,
|
|
2061
2214
|
owns tid @key,
|
|
2062
2215
|
owns name,
|
|
2063
|
-
owns thing-type,
|
|
2216
|
+
owns thing-type, # skill|task|token|service|plan|step|corpus|
|
|
2217
|
+
# creative-asset|do-cycle|do-plan — see @values
|
|
2064
2218
|
owns price,
|
|
2065
2219
|
owns tag @card(0..),
|
|
2066
2220
|
# Task-only (meaningful when thing-type='task')
|
|
2067
|
-
owns task-status,
|
|
2221
|
+
owns task-status, # open/blocked/picked/done/verified/failed/dissolved
|
|
2068
2222
|
owns task-effort,
|
|
2069
2223
|
owns task-value,
|
|
2070
2224
|
owns exit-condition,
|
|
2225
|
+
# Workflow steps (meaningful when thing-type='step')
|
|
2226
|
+
owns step-kind, # trigger|tool|skill|agent|condition|human|delay|sell
|
|
2227
|
+
owns step-config,
|
|
2071
2228
|
# Plan-only (meaningful when thing-type='plan')
|
|
2072
2229
|
owns goal,
|
|
2073
2230
|
owns cycles-planned,
|
|
@@ -2092,6 +2249,11 @@ entity thing,
|
|
|
2092
2249
|
plays production:produced;
|
|
2093
2250
|
```
|
|
2094
2251
|
|
|
2252
|
+
**Vocabulary law:** every `@values` enum lives in `one.tql` AND must be mirrored
|
|
2253
|
+
by a migration before prod writes rely on a new value. Adding a convention value
|
|
2254
|
+
in a doc or a `.ts` without widening the deployed `@values` means the write is
|
|
2255
|
+
rejected at the constraint (`schema/CLAUDE.md`).
|
|
2256
|
+
|
|
2095
2257
|
**When to use it:**
|
|
2096
2258
|
|
|
2097
2259
|
- The concepts share >50% of their attributes and all their relations.
|
|
@@ -2112,44 +2274,41 @@ fun open_tasks() -> { thing } :
|
|
|
2112
2274
|
$t isa thing, has thing-type "task", has task-status "open";
|
|
2113
2275
|
return { $t };
|
|
2114
2276
|
|
|
2115
|
-
# Polymorphic priority: works across kinds because all own priority
|
|
2277
|
+
# Polymorphic priority: works across kinds because all own task-priority
|
|
2116
2278
|
fun top_by_priority($kind: string) -> { thing } :
|
|
2117
2279
|
match
|
|
2118
|
-
$t isa thing, has thing-type $kind, has priority
|
|
2280
|
+
$t isa thing, has thing-type $kind, has task-priority $p;
|
|
2119
2281
|
sort $p desc; limit 10;
|
|
2120
2282
|
return { $t };
|
|
2121
2283
|
```
|
|
2122
2284
|
|
|
2123
|
-
Compare this with the maximalist `
|
|
2285
|
+
Compare this with the maximalist `schema/world.tql` (844 lines, separate `task` entity with its own `task-id`, `task-status`, priority formula, etc.). The **skinny ontology** (`one.tql`, 480 lines) uses the collapse for flexibility; the **BrainDO schema** (`world.tql`) uses separate entities for performance and strict typing. Both are valid — the choice depends on how much schema change you expect. They cannot be loaded into the same database.
|
|
2124
2286
|
|
|
2125
2287
|
### Pattern 3 — Symmetric Routing via Shared-Variable Unification
|
|
2126
2288
|
|
|
2127
2289
|
When you have a relation "X matches Y on tag", you usually need both directions — "what Y's match this X" AND "what X's match this Y". In SQL this is two separate queries. In TypeQL, both queries share the same match pattern; only the return changes.
|
|
2128
2290
|
|
|
2129
2291
|
```typeql
|
|
2130
|
-
#
|
|
2292
|
+
# schema/world.tql:805–822 — verbatim symmetric pair.
|
|
2293
|
+
# Note every signature says `actor`, never `unit` (a dead name).
|
|
2131
2294
|
|
|
2132
|
-
# "What tasks can this
|
|
2133
|
-
fun tasks_for_unit($u:
|
|
2134
|
-
match
|
|
2135
|
-
|
|
2136
|
-
$t isa task, has tag $tag,
|
|
2137
|
-
has done false, has task-status "open";
|
|
2295
|
+
# "What tasks can this actor work on?" (actor → tasks)
|
|
2296
|
+
fun tasks_for_unit($u: actor) -> { task }:
|
|
2297
|
+
match $u has tag $tag;
|
|
2298
|
+
$t isa task, has tag $tag, has done false, has task-status "open";
|
|
2138
2299
|
return { $t };
|
|
2139
2300
|
|
|
2140
|
-
# "Which
|
|
2141
|
-
fun actors_for_task($t: task) -> {
|
|
2142
|
-
match
|
|
2143
|
-
|
|
2144
|
-
$u isa actor, has tag $tag, has status "active";
|
|
2301
|
+
# "Which actors can do this task?" (task → actors)
|
|
2302
|
+
fun actors_for_task($t: task) -> { actor }:
|
|
2303
|
+
match $t has tag $tag;
|
|
2304
|
+
$u isa actor, has tag $tag, has status "active";
|
|
2145
2305
|
return { $u };
|
|
2146
2306
|
|
|
2147
|
-
# "Best
|
|
2148
|
-
fun best_unit_for_task($t: task) ->
|
|
2149
|
-
match
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
(source: $any, target: $u) isa path, has strength $s;
|
|
2307
|
+
# "Best actor for this task": tag overlap × path strength
|
|
2308
|
+
fun best_unit_for_task($t: task) -> actor:
|
|
2309
|
+
match $t has tag $tag;
|
|
2310
|
+
$u isa actor, has tag $tag, has status "active";
|
|
2311
|
+
(source: $any, target: $u) isa path, has strength $s;
|
|
2153
2312
|
sort $s desc; limit 1;
|
|
2154
2313
|
return $u;
|
|
2155
2314
|
```
|
|
@@ -2158,7 +2317,7 @@ fun best_unit_for_task($t: task) -> unit :
|
|
|
2158
2317
|
|
|
2159
2318
|
- The `$tag` variable is shared between `$u has tag $tag` and `$t has tag $tag`. TypeQL **unifies** these — there must exist at least one tag value that both sides agree on. No `JOIN ON` clause, no foreign key; the type constraint IS the join.
|
|
2160
2319
|
|
|
2161
|
-
- The pattern is symmetric because the *type* of "
|
|
2320
|
+
- The pattern is symmetric because the *type* of "actor-task matches on tag" doesn't care about direction. Only the *projection* (`return { $t }` vs `return { $u }`) picks a side.
|
|
2162
2321
|
|
|
2163
2322
|
- `best_unit_for_task` composes the matching pattern with a *third* constraint (pheromone strength on an incoming path). Notice `(source: $any, target: $u)` — `$any` is bound but unconstrained; we don't care WHO marked the path, only that SOMEONE marked it. That's a free variable in the type.
|
|
2164
2323
|
|
|
@@ -2166,19 +2325,39 @@ fun best_unit_for_task($t: task) -> unit :
|
|
|
2166
2325
|
|
|
2167
2326
|
One more worth lifting out. The substrate labels every path with one of five statuses using a single function whose body is a nested conditional:
|
|
2168
2327
|
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
match $e has strength $s, has resistance $a, has traversals $t;
|
|
2173
|
-
return first
|
|
2174
|
-
if ($a > $s and $a >= 10.0) then "toxic"
|
|
2175
|
-
else if ($s >= 50.0) then "highway"
|
|
2176
|
-
else if ($s >= 10.0 and $s < 50.0 and $t < 10) then "fresh"
|
|
2177
|
-
else if ($s > 0.0 and $s < 5.0) then "fading"
|
|
2178
|
-
else "active";
|
|
2179
|
-
```
|
|
2328
|
+
`schema/world.tql:570–577` writes it as an `if/then/else` cascade. **That form does
|
|
2329
|
+
not parse on the live server** — this is the deployed rewrite, and it is the
|
|
2330
|
+
single best worked example of translating a cascade into TypeQL:
|
|
2180
2331
|
|
|
2181
|
-
|
|
2332
|
+
```typeql
|
|
2333
|
+
# schema/reason.tql:63–79 — the DEPLOYED five-branch classifier
|
|
2334
|
+
fun path_status($p: path) -> string:
|
|
2335
|
+
match
|
|
2336
|
+
$p has strength $s, has resistance $r, has traversals $t;
|
|
2337
|
+
{ $r > $s; $r >= 10.0;
|
|
2338
|
+
let $status = "toxic"; }
|
|
2339
|
+
or { $s >= 50.0; not { $r > $s; $r >= 10.0; };
|
|
2340
|
+
let $status = "highway"; }
|
|
2341
|
+
or { $s >= 10.0; $s < 50.0; $t < 10;
|
|
2342
|
+
not { $r > $s; $r >= 10.0; };
|
|
2343
|
+
let $status = "fresh"; }
|
|
2344
|
+
or { $s > 0.0; $s < 5.0; not { $r > $s; $r >= 10.0; };
|
|
2345
|
+
let $status = "fading"; }
|
|
2346
|
+
or { not { $r > $s; $r >= 10.0; };
|
|
2347
|
+
not { $s >= 50.0; };
|
|
2348
|
+
not { $s >= 10.0; $s < 50.0; $t < 10; };
|
|
2349
|
+
not { $s > 0.0; $s < 5.0; };
|
|
2350
|
+
let $status = "active"; };
|
|
2351
|
+
return first $status;
|
|
2352
|
+
```
|
|
2353
|
+
|
|
2354
|
+
The precedence that `else if` gave you for free — `toxic` beats `highway`,
|
|
2355
|
+
`highway` beats `fresh` — **you now write by hand** as a `not { … }` guard in
|
|
2356
|
+
every later branch. That verbosity is the whole cost of the missing conditional
|
|
2357
|
+
expression, and skipping a guard is a silent bug: a path matching two branches
|
|
2358
|
+
produces two rows and `return first` picks one arbitrarily. In 2.x this was five
|
|
2359
|
+
chained `rule`s with priority annotations; the cascade order is at least still
|
|
2360
|
+
visible in the source.
|
|
2182
2361
|
|
|
2183
2362
|
**Adjacent pattern — reading the label:**
|
|
2184
2363
|
|
|
@@ -2190,12 +2369,35 @@ match
|
|
|
2190
2369
|
select $p, $s;
|
|
2191
2370
|
```
|
|
2192
2371
|
|
|
2193
|
-
The result reads like English: "paths whose status is highway". The function is a verb (`path_status(p)`) that returns a type-tagged string
|
|
2372
|
+
The result reads like English: "paths whose status is highway". The function is a verb (`path_status(p)`) that returns a type-tagged string — classification without explicit rule firing.
|
|
2373
|
+
|
|
2374
|
+
This is also the boundary where **functions are for counts** bites. `path_status`
|
|
2375
|
+
returns a scalar, so calling it per row is what it is for. If instead you wanted
|
|
2376
|
+
*the paths and their strengths and their tags*, do not call a stream fun and then
|
|
2377
|
+
`has` the results — inline the fun's match body and select the attributes in one
|
|
2378
|
+
pipeline. The call form is what turns a sub-second query into a 10-second timeout.
|
|
2194
2379
|
|
|
2195
2380
|
---
|
|
2196
2381
|
|
|
2197
2382
|
## Project-Specific Patterns
|
|
2198
2383
|
|
|
2384
|
+
> **These examples are from a trading prototype, not from this repo.**
|
|
2385
|
+
> `signal-edge`, `live-prediction`, `edge-trail-level`, `win-count`,
|
|
2386
|
+
> `from-state-id`, `prediction-id` and friends exist in **no** `.tql` file here
|
|
2387
|
+
> and in **no** live database. `trail` is also a dead name (root `CLAUDE.md`).
|
|
2388
|
+
> They are kept as generic modelling shapes; for a real query against the ONE
|
|
2389
|
+
> substrate use `path` / `strength` / `resistance` / `traversals` and the
|
|
2390
|
+
> functions listed in `schema/CLAUDE.md`.
|
|
2391
|
+
>
|
|
2392
|
+
> **The read-modify-write examples below are the rejected pattern.** Writes take
|
|
2393
|
+
> **literals only** — `insert $e has strength ($s + 1)` and `insert $e has
|
|
2394
|
+
> strength $ns` (a value variable) both fail with `REP1 Attribute vs Value`, and
|
|
2395
|
+
> there is no in-database increment on this build. The shape that works is:
|
|
2396
|
+
> read the current value, compute it in the caller, write it back with
|
|
2397
|
+
> `update $e has strength 7.0;` (`update` is replace-or-add on `@card(0..1)` —
|
|
2398
|
+
> no delete needed). See `readPathWeights` / `updatePathWeights` in
|
|
2399
|
+
> `one.ie/web/src/lib/substrate.ts`.
|
|
2400
|
+
|
|
2199
2401
|
### Signal-Edge Operations (Trading)
|
|
2200
2402
|
|
|
2201
2403
|
```typeql
|
|
@@ -2230,12 +2432,9 @@ select $id, $level, $pnl;
|
|
|
2230
2432
|
sort $pnl desc;
|
|
2231
2433
|
limit 20;
|
|
2232
2434
|
|
|
2233
|
-
# Update edge statistics
|
|
2234
|
-
match
|
|
2235
|
-
|
|
2236
|
-
$e has win-count $old_wins;
|
|
2237
|
-
delete $old_wins;
|
|
2238
|
-
insert $e has win-count 15;
|
|
2435
|
+
# Update edge statistics — literal only, and `update` needs no delete
|
|
2436
|
+
match $e isa signal-edge, has edge-id "edge-001";
|
|
2437
|
+
update $e has win-count 15;
|
|
2239
2438
|
```
|
|
2240
2439
|
|
|
2241
2440
|
### Pheromone Trail Patterns
|
|
@@ -2255,12 +2454,15 @@ select $id, $level;
|
|
|
2255
2454
|
sort $level desc;
|
|
2256
2455
|
limit 10;
|
|
2257
2456
|
|
|
2258
|
-
# Decay
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2457
|
+
# Decay by 10% — THERE IS NO IN-DATABASE FORM OF THIS.
|
|
2458
|
+
# `let $new = $old * 0.9; delete $old; insert $e has edge-trail-level $new;`
|
|
2459
|
+
# is REJECTED (REP1 Attribute vs Value): writes take literals only.
|
|
2460
|
+
# Step 1 — read the current values:
|
|
2461
|
+
match $e isa signal-edge, has edge-id $id, has edge-trail-level $old;
|
|
2462
|
+
select $id, $old;
|
|
2463
|
+
|
|
2464
|
+
# Step 2 — multiply in the caller, then write one literal per row:
|
|
2465
|
+
# update $e has edge-trail-level 22.95;
|
|
2264
2466
|
```
|
|
2265
2467
|
|
|
2266
2468
|
### Live Prediction Tracking
|
|
@@ -2307,15 +2509,13 @@ reduce $wins = count groupby $name;
|
|
|
2307
2509
|
|
|
2308
2510
|
```
|
|
2309
2511
|
┌─────────────────────────────────────────────────────────────┐
|
|
2310
|
-
│ TypeDB 3.
|
|
2512
|
+
│ TypeDB 3.12.1 Quick Reference │
|
|
2311
2513
|
├─────────────────────────────────────────────────────────────┤
|
|
2312
|
-
│ CONNECT
|
|
2313
|
-
│
|
|
2314
|
-
│
|
|
2315
|
-
│
|
|
2316
|
-
│
|
|
2317
|
-
│ result = tx.query("...").resolve() │
|
|
2318
|
-
│ tx.commit() # only for WRITE/SCHEMA │
|
|
2514
|
+
│ CONNECT (this repo: HTTP, no driver) │
|
|
2515
|
+
│ POST /v1/signin -> token │
|
|
2516
|
+
│ POST /v1/query {query, databaseName, │
|
|
2517
|
+
│ transactionType, commit} │
|
|
2518
|
+
│ GET /v1/version · GET /v1/databases/one/schema │
|
|
2319
2519
|
│ │
|
|
2320
2520
|
│ TRANSACTION TYPES │
|
|
2321
2521
|
│ READ - read only, concurrent │
|
|
@@ -2331,7 +2531,7 @@ reduce $wins = count groupby $name;
|
|
|
2331
2531
|
│ integer (not long!), double, decimal, boolean │
|
|
2332
2532
|
│ string, date, datetime, datetime-tz, duration │
|
|
2333
2533
|
│ │
|
|
2334
|
-
│ DELETE SYNTAX (3.
|
|
2534
|
+
│ DELETE SYNTAX (3.x) │
|
|
2335
2535
|
│ delete $attr; # delete attribute │
|
|
2336
2536
|
│ delete has $attr of $e; # delete ownership │
|
|
2337
2537
|
│ delete $e; # delete entity/relation │
|
|
@@ -2358,10 +2558,20 @@ reduce $wins = count groupby $name;
|
|
|
2358
2558
|
|
|
2359
2559
|
### In-repo
|
|
2360
2560
|
|
|
2361
|
-
-
|
|
2362
|
-
- `
|
|
2363
|
-
- `
|
|
2364
|
-
- `
|
|
2561
|
+
- **`schema/CLAUDE.md` — read this first.** It is the authority on which `.tql` files load, in what order, which must never co-load, the `@values` vocabulary law, and the codegen pipeline. It outranks this skill on all of that.
|
|
2562
|
+
- `schema/one.tql` (480 lines) — canonical 6-dimension ontology, locked. See *Pattern 2 — The `thing` Collapse*.
|
|
2563
|
+
- `schema/roles.tql` (184) — the authority walk: `self-or-ancestors-of` · `open-ancestors-of` · `controls` · `can` · `funding-of` · `brand-of`. All six are live in prod.
|
|
2564
|
+
- `schema/reason.tql` — inference layer, functions only. **The deployable `path_status`** and the recursive-closure examples (`reachable`, `strong-reach`, `route_exists`).
|
|
2565
|
+
- `schema/do.tql` — build-engine layer, functions only. `do_stage` is the reference disjunction classifier.
|
|
2566
|
+
- `schema/router.tql` (206) — universal signal router; `receivers-reachable-by` is live in prod.
|
|
2567
|
+
- `schema/factory.tql` (993) — the factory ladder. **One file is one schema transaction on purpose:** a fun may only reference *committed* funs (`REP4`), so a partial deploy breaks it. Prod carried 39 of 43 funs as of 2026-07-30; `next` + the cost trio ship in `migrations/0045_factory_next.tql` and are **not yet live** (confirmed absent 2026-08-02).
|
|
2568
|
+
- `schema/world.tql` (844 lines) — **standalone BrainDO schema, not the main database, and not deployable as written** (`if/then/else`). Source for *Production Patterns* above; read for shape only.
|
|
2569
|
+
- `schema/sui.tql` (475 lines) — Move mirror. Codegen input, never loaded.
|
|
2570
|
+
- `schema/migrations/` — 24 entries. Migration numbering is live through `0045`.
|
|
2571
|
+
- `one.ie/web/src/lib/substrate.ts` — how TypeScript actually queries: gateway → `POST /v1/query`. `readPathWeights` / `updatePathWeights` are the read-compute-write increment pattern.
|
|
2572
|
+
- `backup/scripts/typedb/dump.py` · `replay.py` — Python against `/v1/` via `urllib`, no driver. Also the source of the `(?![\w-])` role-matching fix and the `ensure_ascii=False` rule.
|
|
2573
|
+
- `.claude/scripts/typedb-env.sh` · `.claude/typedb/{dev,prod}.env` — the dev/prod switch and the version pin.
|
|
2574
|
+
- `.claude/scripts/typedb-probes/` — the 3.8.3 server-panic reproducers.
|
|
2365
2575
|
- `.claude/skills/typedb/reference/research-notes-2026-04.md` — source notes behind this skill's 2026-04 refinement: PACMMOD paper, 3.0 roadmap, Vaticle lectures, "Inside TypeDB: The Next Chapter".
|
|
2366
2576
|
- `.claude/skills/typedb/reference/migration-2x-3x.md` — mechanical 2.x→3.x translations (sessions, Concept API, rule→fun, long→integer, delete syntax).
|
|
2367
2577
|
- `.claude/skills/typedb/reference/python-driver.md` — deeper Python-driver reference than the summary in this file.
|