Skip to content

Commit c1f56fb

Browse files
ZhiXiao-Linclaude
andauthored
docs: document filesystem-first agents + neutralize product-name wording (#75)
- README: new "Filesystem-First Agents" section (agent-dir convention, serve daemon, tools mcp/script, rehydrate-on-boot) + docs link. - Node + Python SDK READMEs: add a Filesystem-First Agents section (serveAgentDir / serve_agent_dir). - Neutralize internal product-name references to role-based wording in agent_dir.rs, AGENT_DIR_TOOLS_DESIGN.md, and CHANGELOG; rename the integration test to test_agent_dir_convention.rs. Co-authored-by: Claude <claude@anthropic.com>
1 parent 03c0882 commit c1f56fb

7 files changed

Lines changed: 101 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [4.0.0] - 2026-06-21
99

10-
Milestone release: **filesystem-first agents** ("eve parity"). A single directory
10+
Milestone release: **filesystem-first agents**. A single directory
1111
now defines a durable agent by convention — `instructions.md` (role slot),
1212
`agent.acl` (config), `skills/`, `schedules/` (cron), and `tools/` — served by a
1313
`serve` daemon that runs each schedule as a full harness turn. No breaking changes

README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,59 @@ await session.addMcp({
15931593

15941594
---
15951595

1596+
## Filesystem-First Agents
1597+
1598+
A durable agent can be defined entirely by a **directory** — no code — and run by
1599+
the built-in `serve` daemon. One folder holds the agent's role, config, skills,
1600+
cron schedules, and tools:
1601+
1602+
```text
1603+
my-agent/
1604+
├── instructions.md (required) Role/guidelines — injected as a prompt SLOT.
1605+
├── agent.acl (optional) Model, providers, queue.
1606+
├── skills/ (optional) *.md skills.
1607+
├── schedules/ (optional) *.md cron jobs (frontmatter `cron:` + body prompt).
1608+
└── tools/ (optional) *.md tools: `kind: mcp` (MCP server) or
1609+
`kind: script` (sandboxed QuickJS over `program`).
1610+
```
1611+
1612+
`AgentDir::load` synthesizes the existing config objects from that folder — it adds
1613+
no new runtime or prompt system. `serve_agent_dir` then runs each enabled schedule
1614+
on its own durable session, and every fire is a FULL harness turn (context, tool
1615+
visibility, safety gate, verification), never a raw model call. `instructions.md`
1616+
is a prompt *slot*, so the harness keeps `BOUNDARIES`, the response contract, and
1617+
verification authoritative.
1618+
1619+
```rust
1620+
use a3s_code_core::{Agent, config::AgentDir, serve::serve_agent_dir};
1621+
use tokio_util::sync::CancellationToken;
1622+
1623+
let agent_dir = AgentDir::load("./my-agent")?;
1624+
let agent = Agent::from_config(agent_dir.config.clone()).await?;
1625+
serve_agent_dir(&agent, &agent_dir, "./workspace", None, CancellationToken::new()).await?;
1626+
```
1627+
1628+
From the SDKs:
1629+
1630+
```js
1631+
const handle = await agent.serveAgentDir('./my-agent', './workspace')
1632+
// ... runs in the background until:
1633+
await handle.stop()
1634+
```
1635+
1636+
- **`tools/`**`kind: mcp` registers an MCP server (namespaced
1637+
`mcp__<server>__<tool>`); `kind: script` exposes a sandboxed QuickJS tool over the
1638+
`program` path, with a fail-closed `allowed_tools` allow-list (an omitted list
1639+
grants no tools).
1640+
- **Rehydrate-on-boot** — pass a `SessionStore` and each schedule session resumes
1641+
its accumulated context across daemon restarts (history is restored; the current
1642+
`instructions.md` / `skills/` / `tools/` are re-applied each boot).
1643+
- Gated behind the `serve` Cargo feature; library-only embedders pay nothing.
1644+
1645+
See [Filesystem-First Agents](https://a3s-lab.github.io/a3s/docs/code/agent-dir) for the full guide.
1646+
1647+
---
1648+
15961649
## Slash Commands
15971650

15981651
Sessions support slash commands:
@@ -1683,6 +1736,7 @@ Full reference and guides: [a3s-lab.github.io/a3s/docs/code](https://a3s-lab.git
16831736
- [Tools & Structured Output](https://a3s-lab.github.io/a3s/docs/code/tools)
16841737
- [AHP Protocol](https://a3s-lab.github.io/a3s/docs/code/ahp-integration)
16851738
- [Skills](https://a3s-lab.github.io/a3s/docs/code/skills)
1739+
- [Filesystem-First Agents](https://a3s-lab.github.io/a3s/docs/code/agent-dir)
16861740
- [Memory](https://a3s-lab.github.io/a3s/docs/code/memory)
16871741
- [Security](https://a3s-lab.github.io/a3s/docs/code/security)
16881742
- [Hooks](https://a3s-lab.github.io/a3s/docs/code/hooks)

core/src/config/agent_dir.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Filesystem-first agent directory convention (eve-style, harness-respecting).
1+
//! Filesystem-first agent directory convention (harness-respecting).
22
//!
33
//! A single directory defines a durable agent by convention:
44
//!
@@ -19,7 +19,7 @@
1919
//! [`AgentDir::load`] SYNTHESIZES existing config objects rather than adding a new
2020
//! runtime: `instructions.md` → [`SystemPromptSlots`], `agent.acl` → [`CodeConfig`],
2121
//! `skills/` → `skill_dirs`. Tool definition, visibility, and safety stay
22-
//! harness-owned (the deliberate divergence from eve's user-defined-tools model).
22+
//! harness-owned (the deliberate divergence from user-defined-tools models).
2323
2424
use std::path::{Path, PathBuf};
2525

@@ -44,7 +44,7 @@ pub struct ScheduleSpec {
4444
/// A tool definition parsed from `tools/<name>.md`, dispatched by `kind`.
4545
///
4646
/// Tool *definition* may come from the directory, but visibility and safety stay
47-
/// harness-owned (the deliberate divergence from eve): an `mcp` spec is registered
47+
/// harness-owned (a deliberate divergence from user-defined-tools models): an `mcp` spec is registered
4848
/// through the normal [`add_mcp_server`](crate::AgentSession) path, so its tools
4949
/// are namespaced `mcp__<server>__<tool>` and gated by the session's permission
5050
/// policy like any other tool.
@@ -121,7 +121,7 @@ pub struct ScriptToolLimits {
121121
///
122122
/// Distinct from [`CodeConfig::agent_dirs`](crate::config::CodeConfig) /
123123
/// `register_agent_dir`, which scan a directory for **worker/subagent**
124-
/// definitions. An `AgentDir` is the eve-style *primary* agent — the directory
124+
/// definitions. An `AgentDir` is the filesystem-first *primary* agent — the directory
125125
/// that defines this agent's prompt, skills, schedules, and tools.
126126
#[derive(Debug, Clone)]
127127
pub struct AgentDir {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! End-to-end integration test for the eve-style filesystem-first agent directory
1+
//! End-to-end integration test for the filesystem-first agent directory
22
//! convention: a single on-disk directory with EVERY supported sub-convention
33
//! (instructions, agent.acl, skills/, schedules/, tools/) loads into a
44
//! fully-populated [`AgentDir`]. Hermetic — no provider, no network.

manual/AGENT_DIR_TOOLS_DESIGN.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The loader (`load_tools` in `core/src/config/agent_dir.rs`) parses both into
66
session build — MCP via `add_mcp_server`, script via the new
77
`AgentDirScriptTool` (`core/src/tools/agent_dir_script_tool.rs`), a thin facade
88
over the existing `program` QuickJS path. Scope: how the optional `tools/`
9-
subdirectory of an eve-style agent directory becomes *executable* tools in
9+
subdirectory of a filesystem-first agent directory becomes *executable* tools in
1010
A3S Code without ever running arbitrary host JavaScript or arbitrary host
1111
processes.
1212

@@ -15,7 +15,7 @@ processes.
1515
> NEVER turned into a free-running host JS/native process, and it NEVER gets to
1616
> define its own tool-visibility or safety policy. Tool *definition* is allowed
1717
> from the directory; tool *visibility* and *safety* remain harness-owned. This
18-
> is the deliberate divergence from eve's user-defined-tools model, documented in
18+
> is the deliberate divergence from user-defined-tools models, documented in
1919
> the `core/src/config/agent_dir.rs` module header, and is why the directory
2020
> selects between two harness-owned backends rather than running arbitrary code.
2121

sdk/node/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,25 @@ console.log(await session.mcps())
320320
The positional `addMcpServer(...)` overload and longer
321321
`addMcpServerConfig(...)` alias remain for compatibility.
322322
323+
## Filesystem-First Agents
324+
325+
Define a durable agent as a **directory** — `instructions.md` (required) plus
326+
optional `agent.acl`, `skills/`, `schedules/` (cron), and `tools/` (`kind: mcp` or
327+
`kind: script` sandboxed QuickJS) — and serve its schedules. Each fire is a full
328+
harness turn (context, tool visibility, safety gate, verification). Returns a
329+
handle you must keep and stop explicitly.
330+
331+
```js
332+
const handle = await agent.serveAgentDir('./my-agent', './workspace', {
333+
// Optional: pass a sessionStore so each schedule resumes its accumulated
334+
// context across daemon restarts.
335+
sessionStore: new FileSessionStore('./sessions'),
336+
})
337+
// ... runs in the background until:
338+
await handle.stop()
339+
console.log(handle.isStopped()) // true
340+
```
341+
323342
## HITL Confirmations
324343
325344
Use `permissionPolicy` to decide which tools ask, then `confirmationPolicy` to

sdk/python/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,26 @@ or `session.tool("task", {...})` when you need raw access.
311311
The old standalone lifecycle control-plane API is intentionally removed from
312312
the 2.0 SDK surface.
313313

314+
## Filesystem-First Agents
315+
316+
Define a durable agent as a **directory**`instructions.md` (required) plus
317+
optional `agent.acl`, `skills/`, `schedules/` (cron), and `tools/` (`kind: mcp` or
318+
`kind: script` sandboxed QuickJS) — and serve its schedules. Each fire is a full
319+
harness turn (context, tool visibility, safety gate, verification). Returns a
320+
handle you keep and stop explicitly.
321+
322+
```python
323+
opts = SessionOptions()
324+
# Optional: pass a session_store so each schedule resumes its accumulated
325+
# context across daemon restarts.
326+
opts.session_store = FileSessionStore("./sessions")
327+
328+
handle = agent.serve_agent_dir("./my-agent", "./workspace", opts)
329+
# ... runs in the background until:
330+
handle.stop()
331+
print(handle.is_stopped()) # True
332+
```
333+
314334
## License
315335

316336
MIT

0 commit comments

Comments
 (0)