Skip to content

Commit 5e930d4

Browse files
committed
docs: show each database adapter and the cancel call
The agent guide showed only the SQLite import and never named unschedule(). In the Track B evaluation, Claude Code sketches imported postgres from solid-objects/database/postgres and called this.cancelReminder(). Neither name exists. The guide now has a table with the import path, the call, and the driver of each SQL database adapter. The rules show this.unschedule("expire", { key: buyer }), and the mistakes table lists both invented names with the correct form. A new test fails when the guide does not name the import path of each server database adapter that package.json exports.
1 parent f8fdb1d commit 5e930d4

3 files changed

Lines changed: 42 additions & 1 deletion

File tree

‎CHANGELOG.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- The agent guide now lists the import path, the call, and the driver of each
6+
SQL database adapter, and it shows how to cancel a reminder with
7+
`unschedule()`. Agents in the Track B evaluation invented the names
8+
`solid-objects/database/postgres` and `this.cancelReminder()`.
9+
310
## 1.0.0 - 2026-10-13
411

512
- Version 1.0 freezes the public API under semantic versioning.

‎docs/agents.md‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ const runtime = configure({
9595
await runtime.install()
9696
```
9797

98+
Each SQL database has its own adapter. Import the adapter from its own path:
99+
100+
| Database | Import | Call | Driver |
101+
| ---------- | ---------------------------------------------------------------- | ---------------------------------- | ------------------------------- |
102+
| SQLite | `import { sqlite } from "solid-objects/database/sqlite"` | `sqlite({ path: "app.sqlite3" })` | None. Node.js has `node:sqlite` |
103+
| PostgreSQL | `import { postgresql } from "solid-objects/database/postgresql"` | `postgresql({ connectionString })` | `npm install pg` |
104+
| MySQL | `import { mysql } from "solid-objects/database/mysql"` | `mysql({ connectionString })` | `npm install mysql2` |
105+
98106
Every authorization callback denies by default. Do step 5 before you call an
99107
actor. [Configuration](configuration.md) lists each option and database
100108
adapter.
@@ -199,7 +207,8 @@ Obey these rules in actor code:
199207
- Public methods are ordered operations. Each one takes no argument or one
200208
object argument.
201209
- Use `this.schedule({ at, key })` for delayed work. A new `schedule` with the
202-
same key moves the alarm.
210+
same key moves the alarm. `this.unschedule("expire", { key: buyer })` cancels
211+
it.
203212
- Use `this.reject(code, { message })` for a business rule failure that must
204213
not retry. The second argument is an object, for example
205214
`this.reject("room_full", { message: "The room is full" })`.
@@ -221,6 +230,8 @@ Avoid these mistakes:
221230
| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
222231
| `this.schedule({ at, key })` with no operation after it | `this.schedule({ at, key }).expire({ buyer })`. A `schedule()` call with no operation after it fails the turn with `ScheduleWithoutOperation` |
223232
| `this.reject("room full")` or `this.reject(code, message)` | `this.reject("room_full", { message: "The room is full" })` |
233+
| `postgres()` from `solid-objects/database/postgres` | `postgresql({ connectionString })` from `solid-objects/database/postgresql`. Step 4 lists each adapter |
234+
| A guessed cancel method, such as `this.cancelReminder()` | `this.unschedule("expire", { key: buyer })`. `this.unscheduleAll("expire")` cancels every key of one operation |
224235
| `registerEffect(name, (context, argumentsValue) => ...)` | `registerEffect(name, (argumentsValue, context) => ...)`. The staged arguments come first |
225236
| A worker process that never names the actor class | `runtime.register(TicketSale)` before `runtime.run(signal)`. See step 7 |
226237

‎test/agent-guide.test.ts‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { readFileSync } from "node:fs"
2+
import { describe, expect, it } from "vitest"
3+
4+
const guide = readFileSync(new URL("../docs/agents.md", import.meta.url), "utf8")
5+
const packageDefinition = JSON.parse(
6+
readFileSync(new URL("../package.json", import.meta.url), "utf8"),
7+
) as { exports: Record<string, unknown> }
8+
9+
describe("agent guide", () => {
10+
it("names the import path of each server database adapter", () => {
11+
const adapters = Object.keys(packageDefinition.exports).filter((path) =>
12+
/^\.\/database\/(sqlite|postgresql|mysql)$/.test(path),
13+
)
14+
expect(adapters).toHaveLength(3)
15+
for (const adapter of adapters) {
16+
expect(guide, adapter).toContain(`"solid-objects${adapter.slice(1)}"`)
17+
}
18+
})
19+
20+
it("shows how to cancel a reminder", () => {
21+
expect(guide).toContain('this.unschedule("expire", { key: buyer })')
22+
})
23+
})

0 commit comments

Comments
 (0)