M5c-2 plan: task 02, brokerd knows ask_memory; the outline split to nine tasks
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,462 @@
|
||||
# M5c-2 task 02: `brokerd` knows `ask_memory`, a built-in memory tool
|
||||
|
||||
**Branch:** `m5c2`. Check it: `git branch --show-current` prints `m5c2` and `git status --short`
|
||||
is empty; otherwise stop. Never switch branch.
|
||||
**Commit subject:** `brokerd: ask_memory, a built-in memory tool that memoryd runs`
|
||||
**Log row:** the Task cell is `M5c2/02-brokerd-ask-memory`.
|
||||
|
||||
## Goal
|
||||
|
||||
Task 01 gave `bxcore` the arguments of a new tool, `ask_memory` (`bxcore::AskMemoryArgs`, with
|
||||
`check()`). This task makes `brokerd` accept it exactly as it accepts `recall` (M5c spec,
|
||||
section 9):
|
||||
|
||||
- **Its name.** `ToolName::AskMemory`, written `ask_memory`. It is a memory tool:
|
||||
`is_memory()` is true, so `memoryd` runs it, never a container.
|
||||
- **Its arguments.** `parse` decodes them into `ToolArgs::AskMemory(AskMemoryArgs)` and runs
|
||||
`check()`; a refusal is `ArgsError::Shape` with `check`'s sentence, as for `recall`. The
|
||||
canonical form is `serde_json::to_string` of the value, as for `recall`.
|
||||
- **Its policy is built in.** A third built-in grant, `builtin-ask-memory`, allows it in every
|
||||
session, `secret` and untrusted ones too: `mode = "auto"`, `max_taint = "secret"`,
|
||||
`result_class = "private"`, `untrusted = false`. A question is not written to Honcho (spec,
|
||||
section 8), and the answer's own labels, which `memoryd` gives, raise the session, as `recall`'s
|
||||
do. An owner's grant file naming `ask_memory` is refused with the `BUILT_IN` sentence, which now
|
||||
names the three tools.
|
||||
|
||||
`brokerd`'s wait for `memoryd` stays 30 s for every memory tool in this task; task 03 gives
|
||||
`ask_memory` its own. Nothing yet asks `brokerd` for `ask_memory`: `loopd` declares it in task 04
|
||||
and `memoryd` answers it from task 09. Until then, a call reaching `memoryd` is answered
|
||||
`memoryd runs only recall and memory`, a failed result.
|
||||
|
||||
## Every place that changes
|
||||
|
||||
This is the complete list.
|
||||
|
||||
| Place | What happens there |
|
||||
|---|---|
|
||||
| `crates/brokerd/src/args.rs` | `ToolName::AskMemory`, `ToolArgs::AskMemory`, and their arms in `parse`, `as_str`, `is_memory`, `tool`, `canonical_json` and `parse` (edits A1 to A9) |
|
||||
| `crates/brokerd/src/builtin.rs` | the grant `ASK_MEMORY`, its id in `sources`, `BUILT_IN`'s sentence, two comments (edits B1, B2) |
|
||||
| `crates/brokerd/src/config.rs`, `Runner::time_limit` | `AskMemory` beside `Recall` and `Memory` (edit C1) |
|
||||
| `crates/brokerd/src/policy/matching.rs` | `ToolArgs::AskMemory` takes no constraints, as `Recall` (edit P1) |
|
||||
| `crates/brokerd/src/runner.rs` | `ToolArgs::AskMemory` has no mounts and no egress, as `Recall` (edit R1) |
|
||||
| `crates/brokerd/src/grants.rs` (rule 3), `container.rs` (`Podman::run`), `memory_port.rs` (`Routed`) | **no change**: each asks `tool.is_memory()`, which edit A5 makes true for `AskMemory` |
|
||||
| `crates/brokerd/tests/ask_memory_tool.rs` | new, given |
|
||||
| `crates/brokerd/tests/grants.rs`, `memory_tools.rs` | new versions, given: three built-in grants, not two |
|
||||
| everything else | **no change**: not `bxcore`, not `loopd`, not `memoryd`, no `Cargo.toml` |
|
||||
|
||||
## Files
|
||||
|
||||
- Copy, from `docs/plans/M5c2/files/` (the same path under it): the new test
|
||||
`crates/brokerd/tests/ask_memory_tool.rs`, and **new versions** of (they replace the files in
|
||||
the tree) `crates/brokerd/tests/grants.rs` and `crates/brokerd/tests/memory_tools.rs`.
|
||||
- Modify: `crates/brokerd/src/args.rs`, `crates/brokerd/src/builtin.rs`,
|
||||
`crates/brokerd/src/config.rs`, `crates/brokerd/src/policy/matching.rs`,
|
||||
`crates/brokerd/src/runner.rs`, `docs/implementer-log.md`.
|
||||
- Do not touch: any other file. The test support files under `crates/brokerd/tests/support/` are
|
||||
used as they are.
|
||||
|
||||
## Facts you need
|
||||
|
||||
- **`AskMemoryArgs`** (task 01, in `bxcore::memory`, exported as `bxcore::AskMemoryArgs`):
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct AskMemoryArgs {
|
||||
pub question: String,
|
||||
#[serde(default)]
|
||||
pub workspaces: Vec<String>,
|
||||
}
|
||||
impl AskMemoryArgs {
|
||||
pub fn check(&self) -> Result<(), String>;
|
||||
pub fn asked(&self) -> Vec<&str>;
|
||||
}
|
||||
```
|
||||
|
||||
It is used here exactly as `RecallArgs` is: `serde_json::from_str`, then `check()`, each error
|
||||
as `ArgsError::Shape`; `serde_json::to_string` for the canonical form. Its canonical form
|
||||
writes every field: `{"question":"q","workspaces":[]}`.
|
||||
- **The order of the built-in grants** is the order of `sources` in `builtin.rs`: `memory`,
|
||||
`recall`, then the new `ask-memory` last. The given `grants.rs` lists them in that order.
|
||||
- **Why the grant is `secret` and trusted.** `max_taint = "secret"` lets a `secret` session ask
|
||||
(spec, section 8: a query is not stored by Honcho). `result_class = "private"` and `untrusted =
|
||||
false` are the floor of the answer's label; `memoryd` labels each answer by the workspaces
|
||||
asked, and `brokerd` keeps the stricter of the two (`runner::run`, unchanged). The given tests
|
||||
send an `ask_memory` call through `broker::handle` to a fake `memoryd` that answers `untrusted`
|
||||
or `secret`, and read the session's state afterwards.
|
||||
- **The long lines.** The three grant constants are string literals longer than 100 characters;
|
||||
`rustfmt` leaves them as they are, and the gate accepts them, as it does `RECALL` and `MEMORY`
|
||||
today. Do not split them.
|
||||
- The given tests:
|
||||
- `ask_memory_tool.rs` (9 tests): the name, `is_memory`, parsing and the canonical form; each
|
||||
refusal with `bxcore`'s sentence and its `detail()`; the built-in grant, its exact text and
|
||||
its hash, allowing the call in a `private`, a `secret` and an untrusted session; an owner's
|
||||
grant file refused with the new `BUILT_IN`; the call routed to `memoryd` with the session's
|
||||
state and canonical arguments; a container runtime refusing it; and, through
|
||||
`broker::handle`, an answer labelled untrusted making the session untrusted, one labelled
|
||||
`secret` raising it to `secret`, and one labelled `public` leaving it `private`.
|
||||
- `grants.rs`: one line changes, the list of built-in ids. `memory_tools.rs`: one line
|
||||
changes, the number of grants `matchable` gives beside one owner grant (4, not 3).
|
||||
- The items the edits use. This table is complete; nothing from a crate's source (the Cargo
|
||||
registry, `~/.cargo/registry`) is needed or allowed.
|
||||
|
||||
| Item | Where |
|
||||
|---|---|
|
||||
| `bxcore::AskMemoryArgs`, `AskMemoryArgs::check(&self) -> Result<(), String>` | A1, A9 |
|
||||
| `serde_json::from_str`, `serde_json::to_string` | A8, A9, as the `Recall` arms beside them |
|
||||
| `ArgsError::Shape(String)` | A9 |
|
||||
|
||||
## The edits, exactly
|
||||
|
||||
Nothing else in these files changes. Each quoted "before" block occurs exactly once in its file
|
||||
when its turn comes (make them in order). Keep the variants in the order shown.
|
||||
|
||||
### `crates/brokerd/src/args.rs`
|
||||
|
||||
**A1.** Add one line. The line
|
||||
|
||||
```rust
|
||||
use bxcore::tools::{HttpFetchArgs, ReadFileArgs, ShellArgs, WriteFileArgs};
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```rust
|
||||
use bxcore::AskMemoryArgs;
|
||||
use bxcore::tools::{HttpFetchArgs, ReadFileArgs, ShellArgs, WriteFileArgs};
|
||||
```
|
||||
|
||||
**A2.** The lines
|
||||
|
||||
```rust
|
||||
/// The tools the broker can dispatch to: four that run in a container, and the two memory
|
||||
/// tools that `memoryd` runs (M5a spec, section 8).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ToolName {
|
||||
ReadFile,
|
||||
WriteFile,
|
||||
Shell,
|
||||
HttpFetch,
|
||||
Recall,
|
||||
Memory,
|
||||
}
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
/// The tools the broker can dispatch to: four that run in a container, and the three memory
|
||||
/// tools that `memoryd` runs (M5a spec, section 8; M5c spec, section 9).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ToolName {
|
||||
ReadFile,
|
||||
WriteFile,
|
||||
Shell,
|
||||
HttpFetch,
|
||||
Recall,
|
||||
Memory,
|
||||
AskMemory,
|
||||
}
|
||||
```
|
||||
|
||||
**A3.** In `ToolName::parse`, the lines (its spaces are checked: the name is `ask_memory`, with an
|
||||
underscore)
|
||||
|
||||
```rust
|
||||
"memory" => Some(ToolName::Memory),
|
||||
_ => None,
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
"memory" => Some(ToolName::Memory),
|
||||
"ask_memory" => Some(ToolName::AskMemory),
|
||||
_ => None,
|
||||
```
|
||||
|
||||
**A4.** In `ToolName::as_str`, the lines (its spaces are checked)
|
||||
|
||||
```rust
|
||||
ToolName::Memory => "memory",
|
||||
}
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
ToolName::Memory => "memory",
|
||||
ToolName::AskMemory => "ask_memory",
|
||||
}
|
||||
```
|
||||
|
||||
**A5.** In `ToolName::is_memory`, the line
|
||||
|
||||
```rust
|
||||
matches!(self, ToolName::Recall | ToolName::Memory)
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```rust
|
||||
matches!(
|
||||
self,
|
||||
ToolName::Recall | ToolName::Memory | ToolName::AskMemory
|
||||
)
|
||||
```
|
||||
|
||||
**A6.** At the end of `enum ToolArgs`, the lines
|
||||
|
||||
```rust
|
||||
Recall(RecallArgs),
|
||||
Memory(MemoryArgs),
|
||||
}
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
Recall(RecallArgs),
|
||||
Memory(MemoryArgs),
|
||||
AskMemory(AskMemoryArgs),
|
||||
}
|
||||
```
|
||||
|
||||
**A7.** In `ToolArgs::tool`, the line
|
||||
|
||||
```rust
|
||||
ToolArgs::Memory(_) => ToolName::Memory,
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```rust
|
||||
ToolArgs::Memory(_) => ToolName::Memory,
|
||||
ToolArgs::AskMemory(_) => ToolName::AskMemory,
|
||||
```
|
||||
|
||||
**A8.** At the end of `ToolArgs::canonical_json`, the lines
|
||||
|
||||
```rust
|
||||
ToolArgs::Memory(value) => {
|
||||
serde_json::to_string(value).unwrap_or_else(|_| "{}".to_string())
|
||||
}
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
ToolArgs::Memory(value) => {
|
||||
serde_json::to_string(value).unwrap_or_else(|_| "{}".to_string())
|
||||
}
|
||||
ToolArgs::AskMemory(value) => {
|
||||
serde_json::to_string(value).unwrap_or_else(|_| "{}".to_string())
|
||||
}
|
||||
```
|
||||
|
||||
**A9.** At the end of `parse`, the lines
|
||||
|
||||
```rust
|
||||
Ok(ToolArgs::Memory(value))
|
||||
}
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
Ok(ToolArgs::Memory(value))
|
||||
}
|
||||
ToolName::AskMemory => {
|
||||
let value: AskMemoryArgs = serde_json::from_str(arguments)
|
||||
.map_err(|error| ArgsError::Shape(error.to_string()))?;
|
||||
value.check().map_err(ArgsError::Shape)?;
|
||||
Ok(ToolArgs::AskMemory(value))
|
||||
}
|
||||
```
|
||||
|
||||
### `crates/brokerd/src/builtin.rs`
|
||||
|
||||
**B1.** The module's doc comment, the lines
|
||||
|
||||
```rust
|
||||
//! The built-in grants of `recall` and `memory` (M5a spec, section 8). Reading and writing memory
|
||||
//! is what an agent is, so no grant file can turn it off or put questions in front of it; the
|
||||
//! prompt is protected by `memoryd`, which lets only clean sessions edit identity.
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
//! The built-in grants of `recall`, `memory` and `ask_memory` (M5a spec, section 8; M5c spec,
|
||||
//! section 9). Reading and writing memory is what an agent is, so no grant file can turn it off or
|
||||
//! put questions in front of it; the prompt is protected by `memoryd`, which lets only clean
|
||||
//! sessions edit identity.
|
||||
```
|
||||
|
||||
**B2.** The lines (its spaces are checked: the grant's text is hashed into the audit log, and the
|
||||
given test compares it and the sentence letter for letter; every `\n` and `\"` is as shown)
|
||||
|
||||
```rust
|
||||
pub const MEMORY: &str = "tool = \"memory\"\nmode = \"auto\"\nmax_taint = \"secret\"\nresult_class = \"private\"\nuntrusted = false\n";
|
||||
|
||||
/// The sentence for an owner's grant naming a memory tool.
|
||||
pub const BUILT_IN: &str = "the policy of recall and memory is built in; remove this grant";
|
||||
|
||||
/// The two built-in grants, `builtin-memory` and `builtin-recall`.
|
||||
pub fn grants() -> Result<Vec<LoadedGrant>, GrantProblem> {
|
||||
// For each (id, text) of [("builtin-memory", MEMORY), ("builtin-recall", RECALL)]:
|
||||
// `toml::from_str::<Grant>(text)` and `sha256(text.as_bytes())`, each error as a GrantProblem {
|
||||
// file: id, line: None, problem: e.to_string() }; build LoadedGrant { id, grant, sha256 }.
|
||||
// Collect into Result<Vec<LoadedGrant>, GrantProblem> (the first error wins).
|
||||
let sources: &[(&str, &str)] = &[("builtin-memory", MEMORY), ("builtin-recall", RECALL)];
|
||||
```
|
||||
|
||||
become
|
||||
|
||||
```rust
|
||||
pub const MEMORY: &str = "tool = \"memory\"\nmode = \"auto\"\nmax_taint = \"secret\"\nresult_class = \"private\"\nuntrusted = false\n";
|
||||
pub const ASK_MEMORY: &str = "tool = \"ask_memory\"\nmode = \"auto\"\nmax_taint = \"secret\"\nresult_class = \"private\"\nuntrusted = false\n";
|
||||
|
||||
/// The sentence for an owner's grant naming a memory tool.
|
||||
pub const BUILT_IN: &str =
|
||||
"the policy of recall, memory and ask_memory is built in; remove this grant";
|
||||
|
||||
/// The three built-in grants, `builtin-memory`, `builtin-recall` and `builtin-ask-memory`.
|
||||
pub fn grants() -> Result<Vec<LoadedGrant>, GrantProblem> {
|
||||
// For each (id, text) of `sources`:
|
||||
// `toml::from_str::<Grant>(text)` and `sha256(text.as_bytes())`, each error as a GrantProblem {
|
||||
// file: id, line: None, problem: e.to_string() }; build LoadedGrant { id, grant, sha256 }.
|
||||
// Collect into Result<Vec<LoadedGrant>, GrantProblem> (the first error wins).
|
||||
let sources: &[(&str, &str)] = &[
|
||||
("builtin-memory", MEMORY),
|
||||
("builtin-recall", RECALL),
|
||||
("builtin-ask-memory", ASK_MEMORY),
|
||||
];
|
||||
```
|
||||
|
||||
The id is `builtin-ask-memory`, with a hyphen; the tool in the grant's text is `ask_memory`, with
|
||||
an underscore.
|
||||
|
||||
### `crates/brokerd/src/config.rs`
|
||||
|
||||
**C1.** In `Runner::time_limit`, the line
|
||||
|
||||
```rust
|
||||
crate::args::ToolName::Recall | crate::args::ToolName::Memory => self.read_file_ms,
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```rust
|
||||
crate::args::ToolName::Recall
|
||||
| crate::args::ToolName::Memory
|
||||
| crate::args::ToolName::AskMemory => self.read_file_ms,
|
||||
```
|
||||
|
||||
### `crates/brokerd/src/policy/matching.rs`
|
||||
|
||||
**P1.** The line
|
||||
|
||||
```rust
|
||||
ToolArgs::Recall(_) | ToolArgs::Memory(_) => Some(None),
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```rust
|
||||
ToolArgs::Recall(_) | ToolArgs::Memory(_) | ToolArgs::AskMemory(_) => Some(None),
|
||||
```
|
||||
|
||||
### `crates/brokerd/src/runner.rs`
|
||||
|
||||
**R1.** The line
|
||||
|
||||
```rust
|
||||
ToolArgs::Recall(_) | ToolArgs::Memory(_) => (Vec::new(), None),
|
||||
```
|
||||
|
||||
becomes
|
||||
|
||||
```rust
|
||||
ToolArgs::Recall(_) | ToolArgs::Memory(_) | ToolArgs::AskMemory(_) => (Vec::new(), None),
|
||||
```
|
||||
|
||||
## Steps
|
||||
|
||||
- [ ] **1. Copy the given tests.** From the repository root, three commands:
|
||||
|
||||
```sh
|
||||
cp docs/plans/M5c2/files/crates/brokerd/tests/ask_memory_tool.rs crates/brokerd/tests/
|
||||
cp docs/plans/M5c2/files/crates/brokerd/tests/grants.rs crates/brokerd/tests/
|
||||
cp docs/plans/M5c2/files/crates/brokerd/tests/memory_tools.rs crates/brokerd/tests/
|
||||
```
|
||||
|
||||
Then `git status --short` lists `grants.rs` and `memory_tools.rs` as modified and
|
||||
`ask_memory_tool.rs` as new, all under `crates/brokerd/tests/`.
|
||||
- [ ] **2. See them fail.** Two commands, each with a shell timeout of 600000 ms:
|
||||
- `cargo build --tests --keep-going -p brokerd`: one test target, `ask_memory_tool`, does not
|
||||
compile, with 11 errors: one `E0432` (``unresolved import `brokerd::builtin::ASK_MEMORY` ``),
|
||||
one `E0599` (``no variant, associated function, or constant named `AskMemory` found for enum
|
||||
`ToolArgs` ``) and nine `E0599` (the same for enum `ToolName`). Every other target compiles.
|
||||
- `cargo test --no-fail-fast -p brokerd --test grants --test memory_tools`: two tests fail,
|
||||
each on its changed line: `an_empty_directory_is_a_valid_empty_set` in `grants` and
|
||||
`grant_files_cannot_name_the_memory_tools_or_take_a_built_in_id` in `memory_tools`.
|
||||
- [ ] **3. The edits.** Make edits A1 to A9, B1, B2, C1, P1 and R1, in order. `cargo check -p
|
||||
brokerd` prints no error and no warning.
|
||||
- [ ] **4. The tests.** With a shell timeout of 600000 ms, every test passes: 9 in
|
||||
`ask_memory_tool`, 17 in `grants`, 4 in `memory_tools`, 5 in `memory_port`, 8 in `runner`:
|
||||
|
||||
```sh
|
||||
cargo test -p brokerd --test ask_memory_tool --test grants --test memory_tools \
|
||||
--test memory_port --test runner
|
||||
```
|
||||
- [ ] **5. Check.** Two commands:
|
||||
- `git diff --stat -- crates/brokerd/src` lists exactly the five files of "Modify" under
|
||||
`crates/brokerd/src`: not `grants.rs`, `container.rs` or `memory_port.rs`.
|
||||
- `git diff --stat -- crates/bxcore crates/loopd crates/memoryd Cargo.toml Cargo.lock` prints
|
||||
nothing.
|
||||
- [ ] **6. Run the gate.** `cargo fmt --all`, then `make gate`, with a shell timeout of 600000 ms.
|
||||
Expected last line: `gate: ok`. The test count is the passed total of `cargo test --workspace`
|
||||
plus one, for the ignored `end_to_end` test that the gate runs on its own: **1381** after this
|
||||
task, 1372 before it; the 9 new ones are the tests of `ask_memory_tool.rs` (the new versions of
|
||||
`grants.rs` and `memory_tools.rs` keep their counts). To count, add up the `N passed` of every
|
||||
`test result:` line the gate's `cargo test --workspace` printed, and add 1. Never run the gate
|
||||
again only to count.
|
||||
- [ ] **7. Log and commit.** Add your row to `docs/implementer-log.md`; its Task cell is
|
||||
`M5c2/02-brokerd-ask-memory`. `git status --short` lists the five source files, the two
|
||||
replaced tests and your log as modified, and `ask_memory_tool.rs` as new. Stage with
|
||||
`git add crates/brokerd 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 1381 tests.
|
||||
- `git diff HEAD~1 --stat` lists only the five source files, the three test files of step 1 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 when its turn comes, or is there more
|
||||
than once.
|
||||
- Step 2 shows a different result: other targets not compiling, other errors, or other tests
|
||||
failing.
|
||||
- `cargo check` in step 3 prints an error or a warning. Quote it, and stop.
|
||||
- A test fails in step 4. Do not change a test: stop, and give the failing tests' names and
|
||||
their messages.
|
||||
- The fix seems to need a change anywhere else: `grants.rs`, `container.rs`, `memory_port.rs`,
|
||||
`bxcore`, a test support file, a per-tool wait. It does not; stop and say why you think so.
|
||||
- A test outside the three given files 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.
|
||||
- The gate passes with a count other than 1381.
|
||||
- A comment in an edit does not fit the code under it. Quote it and stop.
|
||||
|
||||
## What the given tests pin
|
||||
|
||||
Each of these changes to the finished code makes at least one given test fail (17 tried, all
|
||||
caught): `ask_memory` not parsed as a name, or written another way; `AskMemory` not a memory
|
||||
tool; `check` skipped; `tool()` giving another tool; the canonical form lost; the built-in grant
|
||||
missing, under another id, asking instead of allowing, capped at `private`, or labelling its
|
||||
results untrusted; `BUILT_IN`'s old sentence; `AskMemory` matching no grant; an owner's grant
|
||||
naming it accepted; a container running it; `Routed` sending it to the container runtime;
|
||||
`memoryd`'s label dropped, so its answer no longer raises the session.
|
||||
Reference in New Issue
Block a user