docs: M6a implementation plan
This commit is contained in:
@@ -0,0 +1,184 @@
|
||||
# M6a task 01: `subagent` in the M5c registry, not core
|
||||
|
||||
**Branch:** `m6a`. Check it: `git branch --show-current` prints `m6a` and `git status --short`
|
||||
is empty; otherwise stop. Never switch branch.
|
||||
**Commit subject:** `loopd: subagent in the M5c registry, not core`
|
||||
**Log row:** the Task cell is `M6a/01-loopd-subagent-registry`.
|
||||
|
||||
**First action.** Run this before any Read of crate source. Do not `ls` `crates/loopd/tests/`.
|
||||
Do not Read `tests/support/`, `turn.rs`, `session.rs`, `docs/implementer-log.md` (except the
|
||||
first 12 lines at the log step). The signatures below are complete.
|
||||
|
||||
```sh
|
||||
cp docs/plans/M6a/files/crates/loopd/tests/subagent_registry.rs crates/loopd/tests/
|
||||
```
|
||||
|
||||
## Goal
|
||||
|
||||
`subagent` is in `Registry::m5c()`, not core. `find_tool` finds it. A new session's epoch
|
||||
`tools` array stays `clock`, `recall`, `memory`, `ask_memory`, `find_tool`, `call_tool`
|
||||
(spec 3.2). `loopd` does not answer the call yet (task 02).
|
||||
|
||||
## Every place that changes
|
||||
|
||||
| Place | What happens there |
|
||||
|---|---|
|
||||
| `crates/loopd/src/subagent.rs` | new: `SUBAGENT`, `schema()` |
|
||||
| `crates/loopd/src/lib.rs` | `pub mod subagent;` |
|
||||
| `crates/loopd/src/tools.rs` | `m5c()` pushes the non-core entry |
|
||||
| `crates/loopd/tests/subagent_registry.rs` | new, given |
|
||||
| everything else | **no change**: not `dispatch`, not `turn.rs` |
|
||||
|
||||
## Files
|
||||
|
||||
- Copy, from `docs/plans/M6a/files/` (the same path under it): the new test
|
||||
`crates/loopd/tests/subagent_registry.rs`.
|
||||
- Create: `crates/loopd/src/subagent.rs` (the module below).
|
||||
- Modify: `crates/loopd/src/lib.rs`, `crates/loopd/src/tools.rs`,
|
||||
`docs/implementer-log.md`.
|
||||
- Do not touch: any other file.
|
||||
|
||||
At the log-and-commit step, read only the first 12 lines of `docs/implementer-log.md`.
|
||||
|
||||
## Facts you need
|
||||
|
||||
- **Not core.** `core_schemas()` already filters `e.core`. A non-core `Entry` is found by
|
||||
`find` and by `get`, and is absent from `Baseline.tools`.
|
||||
- **`m5c()` only.** Do not add the entry to `m2b`, `m3a`, or `m5a`. `loopd serve` uses `m5c`.
|
||||
- **`push`, not `insert`.** `ask_memory` stays at index 3. `subagent` is last among the
|
||||
non-core names, after `http_fetch`.
|
||||
- rustfmt `mod` order: `subagent` after `sse` / before `summarise` as rustfmt decides.
|
||||
- Same-crate modules may import each other. This task's module imports nothing from
|
||||
`turn` or `tools`.
|
||||
- The items the edits use. This table is complete.
|
||||
|
||||
| Item | Signature |
|
||||
|---|---|
|
||||
| `ToolSchema` | `{ name: String, description: String, parameters: serde_json::Value }` in `crate::llama` |
|
||||
| `Entry` | `{ schema: ToolSchema, core: bool }` |
|
||||
| `Registry::m5c` | `m5c() -> Registry` |
|
||||
| `Registry::get` | `get(&self, name: &str) -> Option<&Entry>` |
|
||||
| `Registry::find` | `find(&self, query: &str) -> Vec<&ToolSchema>` |
|
||||
| `Registry::core_schemas` | `core_schemas(&self) -> Vec<ToolSchema>` |
|
||||
|
||||
## The edits, exactly
|
||||
|
||||
### `crates/loopd/src/subagent.rs`
|
||||
|
||||
Write this module. Do not add `parse_task`, `dispatch_args`, or `run` (task 02 / 03).
|
||||
|
||||
```rust
|
||||
//! The `subagent` tool: loopd answers it itself (M6 spec, section 3).
|
||||
//! It is not core; the parent finds it with `find_tool` and calls it through `call_tool`.
|
||||
|
||||
pub const SUBAGENT: &str = "subagent";
|
||||
|
||||
pub fn schema() -> crate::llama::ToolSchema {
|
||||
crate::llama::ToolSchema {
|
||||
name: SUBAGENT.to_string(),
|
||||
description: "Run a short task in an isolated child session on the background slot."
|
||||
.to_string(),
|
||||
parameters: serde_json::json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task": {
|
||||
"type": "string",
|
||||
"description": "What the child should do."
|
||||
}
|
||||
},
|
||||
"required": ["task"]
|
||||
}),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `crates/loopd/src/lib.rs`
|
||||
|
||||
**L1.** After `pub mod sse;` add `pub mod subagent;`. rustfmt decides the final order.
|
||||
|
||||
### `crates/loopd/src/tools.rs`
|
||||
|
||||
**R1.** The lines (exactly once, inside `m5c`)
|
||||
|
||||
```rust
|
||||
entries.insert(
|
||||
3,
|
||||
Entry {
|
||||
schema: crate::memory::ask_memory_schema(),
|
||||
core: true,
|
||||
},
|
||||
);
|
||||
Registry::new(entries)
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
entries.insert(
|
||||
3,
|
||||
Entry {
|
||||
schema: crate::memory::ask_memory_schema(),
|
||||
core: true,
|
||||
},
|
||||
);
|
||||
entries.push(Entry {
|
||||
schema: crate::subagent::schema(),
|
||||
core: false,
|
||||
});
|
||||
Registry::new(entries)
|
||||
```
|
||||
|
||||
## Steps
|
||||
|
||||
- [ ] **1. Copy the given test.**
|
||||
|
||||
```sh
|
||||
cp docs/plans/M6a/files/crates/loopd/tests/subagent_registry.rs crates/loopd/tests/
|
||||
```
|
||||
|
||||
- [ ] **2. See it fail.** `cargo build --tests --keep-going -p loopd`, with a shell timeout of
|
||||
600000 ms: test target `subagent_registry` does not compile (`E0432` unresolved
|
||||
`loopd::subagent`). Every other target compiles.
|
||||
- [ ] **3. The edits.** Write `subagent.rs`, L1, R1. `cargo check -p loopd` prints no error
|
||||
and no warning. `wc -l crates/loopd/src/subagent.rs` and `wc -l crates/loopd/src/tools.rs`
|
||||
each ≤ 500.
|
||||
- [ ] **4. The tests.** `cargo test -p loopd --test subagent_registry --test ask_memory_tool
|
||||
--test tools --test baseline`: every test passes, 2 in `subagent_registry`.
|
||||
- [ ] **5. Check.** `git diff --stat` lists exactly `crates/loopd/src/subagent.rs`,
|
||||
`crates/loopd/src/lib.rs`, `crates/loopd/src/tools.rs`. `git status --short` also shows
|
||||
the new test as untracked.
|
||||
- [ ] **6. Run the gate.** `cargo fmt --all`, then `make gate`, with a shell timeout of
|
||||
600000 ms. Expected last line: `gate: ok`. That is done counting: **1577** (1575 before,
|
||||
plus the 2 of `subagent_registry.rs`). After `gate: ok`, do not add up `test result:`
|
||||
lines and do not run `cargo test --workspace`.
|
||||
- [ ] **7. Log and commit.** Add your row to `docs/implementer-log.md`; its Task cell is
|
||||
`M6a/01-loopd-subagent-registry`. Read only the first 12 lines of that file; insert the
|
||||
row under the header. Stage with
|
||||
`git add crates/loopd docs/implementer-log.md Cargo.lock`, then commit as `AGENTS.md`
|
||||
says. `Cargo.lock` does not change in this task; the `git add` is harmless.
|
||||
|
||||
## Done when
|
||||
|
||||
- `make gate` prints `gate: ok` with 1577 tests.
|
||||
- `git diff HEAD~1 --stat` lists only `crates/loopd/src/subagent.rs`,
|
||||
`crates/loopd/src/lib.rs`, `crates/loopd/src/tools.rs`,
|
||||
`crates/loopd/tests/subagent_registry.rs` and `docs/implementer-log.md`.
|
||||
|
||||
## Stop and report if
|
||||
|
||||
- The branch check at the top fails.
|
||||
- A "before" block is not in its file exactly as shown, or is there more than once.
|
||||
- Step 2 shows a different result: the tests compile, or a different crate fails.
|
||||
- `cargo check` in step 3 prints an error or a warning. Quote it, and stop.
|
||||
- A test fails in step 4. Do not change the test: stop, and give the failing tests' names
|
||||
and their messages.
|
||||
- The fix seems to need a change anywhere else. It does not; stop and say why you think so.
|
||||
- A test outside `subagent_registry.rs` fails in the gate: check once whether it fails
|
||||
without your change (`git stash -u`, run it, `git stash pop`), then stop and report both
|
||||
results.
|
||||
|
||||
## What the given tests pin
|
||||
|
||||
`subagent` is in `m5c()`, `core` is false, `schema()` matches the entry, `find("subagent")`
|
||||
and `find("isolated")` both hit it, and a baseline assembled from `m5c()` still lists only
|
||||
the six core names in `tools`.
|
||||
Reference in New Issue
Block a user