memoryが.insomnia配下ではなくworkspace root直下を想定していた問題の修正
This commit is contained in:
parent
dfa6213c18
commit
8cf1d6c9cf
|
|
@ -322,7 +322,7 @@ mod tests {
|
|||
#[test]
|
||||
fn workflow_write_rejected() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("memory/workflow/wf.md");
|
||||
let path = dir.path().join(".insomnia/memory/workflow/wf.md");
|
||||
let content = format!(
|
||||
"---\nupdated_at: {now}\ndescription: x\nauto_invoke: false\nuser_invocable: true\n---\nbody",
|
||||
now = iso_now()
|
||||
|
|
@ -352,7 +352,7 @@ mod tests {
|
|||
#[test]
|
||||
fn decision_with_unknown_replaced_by_errors() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
let content = format!(
|
||||
"---\ncreated_at: {now}\nupdated_at: {now}\nsources: []\nstatus: replaced\nreplaced_by: ghost\n---\nbody\n",
|
||||
now = iso_now()
|
||||
|
|
@ -369,7 +369,7 @@ mod tests {
|
|||
#[test]
|
||||
fn decision_replaced_by_self_errors() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
let content = format!(
|
||||
"---\ncreated_at: {now}\nupdated_at: {now}\nsources: []\nstatus: replaced\nreplaced_by: foo\n---\nbody\n",
|
||||
now = iso_now()
|
||||
|
|
@ -387,7 +387,7 @@ mod tests {
|
|||
fn decision_replaced_by_existing_ok() {
|
||||
let (dir, linter) = workspace();
|
||||
// Pre-create the target.
|
||||
let target = dir.path().join("memory/decisions/bar.md");
|
||||
let target = dir.path().join(".insomnia/memory/decisions/bar.md");
|
||||
write(
|
||||
&target,
|
||||
&format!(
|
||||
|
|
@ -395,7 +395,7 @@ mod tests {
|
|||
now = iso_now()
|
||||
),
|
||||
);
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
let content = format!(
|
||||
"---\ncreated_at: {now}\nupdated_at: {now}\nsources: []\nstatus: replaced\nreplaced_by: bar\n---\nbody\n",
|
||||
now = iso_now()
|
||||
|
|
@ -407,7 +407,7 @@ mod tests {
|
|||
#[test]
|
||||
fn missing_required_field_errors() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
// Missing `status`.
|
||||
let content = format!(
|
||||
"---\ncreated_at: {now}\nupdated_at: {now}\nsources: []\n---\nbody\n",
|
||||
|
|
@ -423,7 +423,7 @@ mod tests {
|
|||
#[test]
|
||||
fn knowledge_long_description_with_model_invokation_errors() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("knowledge/foo.md");
|
||||
let path = dir.path().join(".insomnia/knowledge/foo.md");
|
||||
let big_desc = "x".repeat(2000);
|
||||
let content = format!(
|
||||
"---\ncreated_at: {now}\nupdated_at: {now}\nkind: rule\ndescription: {big_desc}\nmodel_invokation: true\nuser_invocable: true\nlast_sources: []\n---\nbody\n",
|
||||
|
|
@ -441,7 +441,7 @@ mod tests {
|
|||
#[test]
|
||||
fn knowledge_long_description_without_model_invokation_ok() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("knowledge/foo.md");
|
||||
let path = dir.path().join(".insomnia/knowledge/foo.md");
|
||||
let big_desc = "x".repeat(2000);
|
||||
let content = format!(
|
||||
"---\ncreated_at: {now}\nupdated_at: {now}\nkind: rule\ndescription: {big_desc}\nmodel_invokation: false\nuser_invocable: true\nlast_sources: []\n---\nbody\n",
|
||||
|
|
@ -454,7 +454,7 @@ mod tests {
|
|||
#[test]
|
||||
fn summary_path_accepted() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("memory/summary.md");
|
||||
let path = dir.path().join(".insomnia/memory/summary.md");
|
||||
let content = format!(
|
||||
"---\nupdated_at: {now}\n---\nsummary body\n",
|
||||
now = iso_now()
|
||||
|
|
@ -466,7 +466,7 @@ mod tests {
|
|||
#[test]
|
||||
fn create_when_existing_errors() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
write(
|
||||
&path,
|
||||
&format!(
|
||||
|
|
@ -491,7 +491,7 @@ mod tests {
|
|||
fn workflow_lint_accepts_valid_record() {
|
||||
let (dir, linter) = workspace();
|
||||
// Place a Knowledge record that the workflow will reference.
|
||||
let kn = dir.path().join("knowledge/foo.md");
|
||||
let kn = dir.path().join(".insomnia/knowledge/foo.md");
|
||||
write(
|
||||
&kn,
|
||||
&format!(
|
||||
|
|
@ -548,14 +548,14 @@ mod tests {
|
|||
// `db-pol` (1 deletion), `db-pools` (1 insertion).
|
||||
for slug in ["db-pol", "db-pools"] {
|
||||
write(
|
||||
&dir.path().join(format!("memory/decisions/{slug}.md")),
|
||||
&dir.path().join(format!(".insomnia/memory/decisions/{slug}.md")),
|
||||
&format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nsources: []\nstatus: open\n---\n",
|
||||
n = iso_now()
|
||||
),
|
||||
);
|
||||
}
|
||||
let path = dir.path().join("memory/decisions/db-pool.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/db-pool.md");
|
||||
let content = format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nsources: []\nstatus: open\n---\nbody\n",
|
||||
n = iso_now()
|
||||
|
|
@ -577,14 +577,14 @@ mod tests {
|
|||
let (dir, linter) = workspace();
|
||||
for slug in ["alpha", "bravo"] {
|
||||
write(
|
||||
&dir.path().join(format!("memory/decisions/{slug}.md")),
|
||||
&dir.path().join(format!(".insomnia/memory/decisions/{slug}.md")),
|
||||
&format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nsources: []\nstatus: open\n---\n",
|
||||
n = iso_now()
|
||||
),
|
||||
);
|
||||
}
|
||||
let path = dir.path().join("memory/decisions/charlie.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/charlie.md");
|
||||
let content = format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nsources: []\nstatus: open\n---\n",
|
||||
n = iso_now()
|
||||
|
|
@ -603,7 +603,7 @@ mod tests {
|
|||
#[test]
|
||||
fn body_size_limit_errors() {
|
||||
let (dir, linter) = workspace();
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
let big_body = "x".repeat(8001);
|
||||
let content = format!(
|
||||
"---\ncreated_at: {now}\nupdated_at: {now}\nsources: []\nstatus: open\n---\n{body}",
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ mod tests {
|
|||
model_invokation: bool,
|
||||
body: &str,
|
||||
) {
|
||||
let path = dir.join("knowledge").join(format!("{slug}.md"));
|
||||
let path = dir.join(".insomnia/knowledge").join(format!("{slug}.md"));
|
||||
let content = format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nkind: policy\ndescription: \"{description}\"\nmodel_invokation: {flag}\nuser_invocable: true\nlast_sources: []\n---\n{body}",
|
||||
n = now(),
|
||||
|
|
@ -95,7 +95,7 @@ mod tests {
|
|||
|
||||
fn setup() -> (TempDir, WorkspaceLayout) {
|
||||
let dir = TempDir::new().unwrap();
|
||||
std::fs::create_dir_all(dir.path().join("knowledge")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".insomnia/knowledge")).unwrap();
|
||||
let layout = WorkspaceLayout::new(dir.path().to_path_buf());
|
||||
(dir, layout)
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ mod tests {
|
|||
write_knowledge(dir.path(), "good", "ok", true, "");
|
||||
// Garbage in frontmatter — must be skipped, not panic.
|
||||
std::fs::write(
|
||||
dir.path().join("knowledge/bad.md"),
|
||||
dir.path().join(".insomnia/knowledge/bad.md"),
|
||||
"---\nthis is not yaml: : :\n---\nbody\n",
|
||||
)
|
||||
.unwrap();
|
||||
|
|
@ -155,7 +155,7 @@ mod tests {
|
|||
fn non_md_files_ignored() {
|
||||
let (dir, layout) = setup();
|
||||
write_knowledge(dir.path(), "good", "ok", true, "");
|
||||
std::fs::write(dir.path().join("knowledge/note.txt"), "not markdown\n").unwrap();
|
||||
std::fs::write(dir.path().join(".insomnia/knowledge/note.txt"), "not markdown\n").unwrap();
|
||||
|
||||
let got = collect_resident_knowledge(&layout);
|
||||
assert_eq!(got.len(), 1);
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ mod tests {
|
|||
let layout = WorkspaceLayout::new(PathBuf::from("/ws"));
|
||||
let rules = deny_write_rules(&layout);
|
||||
assert_eq!(rules.len(), 2);
|
||||
assert_eq!(rules[0].target, PathBuf::from("/ws/memory"));
|
||||
assert_eq!(rules[0].target, PathBuf::from("/ws/.insomnia/memory"));
|
||||
assert_eq!(rules[0].permission, Permission::Write);
|
||||
assert!(rules[0].recursive);
|
||||
assert_eq!(rules[1].target, PathBuf::from("/ws/knowledge"));
|
||||
assert_eq!(rules[1].target, PathBuf::from("/ws/.insomnia/knowledge"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ mod tests {
|
|||
fn setup() -> (TempDir, WorkspaceLayout, PathBuf) {
|
||||
let dir = TempDir::new().unwrap();
|
||||
let layout = WorkspaceLayout::new(dir.path().to_path_buf());
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
let initial = format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nsources: []\nstatus: open\n---\nbody body\n",
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
//! omitted, returns one entry per file (no excerpt) so the agent can
|
||||
//! enumerate what records exist without knowing what's inside them.
|
||||
//!
|
||||
//! - `MemoryQuery` walks `memory/summary.md`, `memory/decisions/`,
|
||||
//! `memory/requests/`. `memory/workflow/` and `memory/_staging/`
|
||||
//! are excluded by construction.
|
||||
//! - `KnowledgeQuery` walks `knowledge/*.md` and supports a `kind`
|
||||
//! filter against the Knowledge frontmatter's `kind` field.
|
||||
//! - `MemoryQuery` walks `.insomnia/memory/{summary.md,decisions/,
|
||||
//! requests/}`. `.insomnia/memory/workflow/` and
|
||||
//! `.insomnia/memory/_staging/` are excluded by construction.
|
||||
//! - `KnowledgeQuery` walks `.insomnia/knowledge/*.md` and supports a
|
||||
//! `kind` filter against the Knowledge frontmatter's `kind` field.
|
||||
//!
|
||||
//! No derived index — the file tree is the source of truth and is
|
||||
//! re-scanned per call. 出現順: within a file by line order, across
|
||||
|
|
@ -441,16 +441,16 @@ mod tests {
|
|||
fn setup() -> (TempDir, WorkspaceLayout) {
|
||||
let dir = TempDir::new().unwrap();
|
||||
let layout = WorkspaceLayout::new(dir.path().to_path_buf());
|
||||
std::fs::create_dir_all(dir.path().join("memory/decisions")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join("memory/requests")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join("memory/workflow")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join("memory/_staging")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join("knowledge")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".insomnia/memory/decisions")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".insomnia/memory/requests")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".insomnia/memory/workflow")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".insomnia/memory/_staging")).unwrap();
|
||||
std::fs::create_dir_all(dir.path().join(".insomnia/knowledge")).unwrap();
|
||||
(dir, layout)
|
||||
}
|
||||
|
||||
fn write_decision(dir: &Path, slug: &str, body: &str) {
|
||||
let path = dir.join("memory/decisions").join(format!("{slug}.md"));
|
||||
let path = dir.join(".insomnia/memory/decisions").join(format!("{slug}.md"));
|
||||
let content = format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nsources: []\nstatus: open\n---\n{body}",
|
||||
n = now()
|
||||
|
|
@ -459,7 +459,7 @@ mod tests {
|
|||
}
|
||||
|
||||
fn write_knowledge(dir: &Path, slug: &str, kind: &str, description: &str, body: &str) {
|
||||
let path = dir.join("knowledge").join(format!("{slug}.md"));
|
||||
let path = dir.join(".insomnia/knowledge").join(format!("{slug}.md"));
|
||||
let content = format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nkind: {kind}\ndescription: \"{description}\"\nmodel_invokation: false\nuser_invocable: true\nlast_sources: []\n---\n{body}",
|
||||
n = now()
|
||||
|
|
@ -514,7 +514,7 @@ mod tests {
|
|||
let (dir, layout) = setup();
|
||||
write_decision(dir.path(), "alpha", "body\n");
|
||||
write_decision(dir.path(), "beta", "body\n");
|
||||
let summary_path = dir.path().join("memory/summary.md");
|
||||
let summary_path = dir.path().join(".insomnia/memory/summary.md");
|
||||
std::fs::write(
|
||||
&summary_path,
|
||||
format!("---\nupdated_at: {n}\n---\nhello\n", n = now()),
|
||||
|
|
@ -534,7 +534,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn memory_query_finds_summary() {
|
||||
let (dir, layout) = setup();
|
||||
let summary_path = dir.path().join("memory/summary.md");
|
||||
let summary_path = dir.path().join(".insomnia/memory/summary.md");
|
||||
std::fs::write(
|
||||
&summary_path,
|
||||
format!("---\nupdated_at: {n}\n---\nthe needle is here\n", n = now()),
|
||||
|
|
@ -552,9 +552,9 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn memory_query_excludes_workflow_and_staging() {
|
||||
let (dir, layout) = setup();
|
||||
let wf = dir.path().join("memory/workflow/wf.md");
|
||||
let wf = dir.path().join(".insomnia/memory/workflow/wf.md");
|
||||
std::fs::write(&wf, "needle in workflow\n").unwrap();
|
||||
let stg = dir.path().join("memory/_staging/abc.json");
|
||||
let stg = dir.path().join(".insomnia/memory/_staging/abc.json");
|
||||
std::fs::write(&stg, "needle in staging\n").unwrap();
|
||||
|
||||
let (_, tool) = memory_query_tool(layout, QueryConfig::default())();
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn read_decision_by_slug() {
|
||||
let (dir, layout) = setup();
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
std::fs::write(&path, "alpha\nbeta\n").unwrap();
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn read_summary_without_slug() {
|
||||
let (dir, layout) = setup();
|
||||
let path = dir.path().join("memory/summary.md");
|
||||
let path = dir.path().join(".insomnia/memory/summary.md");
|
||||
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
std::fs::write(&path, "summary body\n").unwrap();
|
||||
|
||||
|
|
@ -199,7 +199,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn knowledge_path_resolution() {
|
||||
let (dir, layout) = setup();
|
||||
let path = dir.path().join("knowledge/policy.md");
|
||||
let path = dir.path().join(".insomnia/knowledge/policy.md");
|
||||
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
std::fs::write(&path, "k\n").unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn write_creates_summary() {
|
||||
let (dir, layout) = setup();
|
||||
let path = dir.path().join("memory/summary.md");
|
||||
let path = dir.path().join(".insomnia/memory/summary.md");
|
||||
let content = format!("---\nupdated_at: {n}\n---\nbody\n", n = now());
|
||||
|
||||
let (meta, tool) = write_tool(layout)();
|
||||
|
|
@ -187,7 +187,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn write_update_existing() {
|
||||
let (dir, layout) = setup();
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
std::fs::create_dir_all(path.parent().unwrap()).unwrap();
|
||||
let initial = format!(
|
||||
"---\ncreated_at: {n}\nupdated_at: {n}\nsources: []\nstatus: open\n---\nold\n",
|
||||
|
|
@ -220,7 +220,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn write_does_not_persist_on_lint_failure() {
|
||||
let (dir, layout) = setup();
|
||||
let path = dir.path().join("memory/decisions/foo.md");
|
||||
let path = dir.path().join(".insomnia/memory/decisions/foo.md");
|
||||
let bad = "no frontmatter at all";
|
||||
let (_, tool) = write_tool(layout)();
|
||||
let inp = serde_json::json!({
|
||||
|
|
|
|||
|
|
@ -1,20 +1,28 @@
|
|||
//! Workspace-level path layout for the memory subsystem.
|
||||
//!
|
||||
//! Resolves a workspace root into the concrete directories the linter
|
||||
//! and tools operate on:
|
||||
//! `WorkspaceLayout` carries the workspace root (typically the Pod's
|
||||
//! pwd). All insomnia-managed content lives under the conventional
|
||||
//! `<root>/.insomnia/` subdirectory — the same place that holds
|
||||
//! `manifest.toml` and `prompts/`. The memory subsystem nests its
|
||||
//! trees inside it:
|
||||
//!
|
||||
//! - `<root>/memory/summary.md`
|
||||
//! - `<root>/memory/decisions/<slug>.md`
|
||||
//! - `<root>/memory/requests/<slug>.md`
|
||||
//! - `<root>/memory/workflow/<slug>.md`
|
||||
//! - `<root>/memory/_staging/<id>.json`
|
||||
//! - `<root>/knowledge/<slug>.md`
|
||||
//! - `<root>/.insomnia/memory/summary.md`
|
||||
//! - `<root>/.insomnia/memory/decisions/<slug>.md`
|
||||
//! - `<root>/.insomnia/memory/requests/<slug>.md`
|
||||
//! - `<root>/.insomnia/memory/workflow/<slug>.md`
|
||||
//! - `<root>/.insomnia/memory/_staging/<id>.json`
|
||||
//! - `<root>/.insomnia/knowledge/<slug>.md`
|
||||
//!
|
||||
//! Configuring `[memory]` with an empty body is therefore sufficient
|
||||
//! for any workspace that already uses the `.insomnia/` convention; no
|
||||
//! `workspace_root` override is needed.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::error::LintError;
|
||||
use crate::slug::Slug;
|
||||
|
||||
const INSOMNIA_DIR: &str = ".insomnia";
|
||||
const MEMORY_DIR: &str = "memory";
|
||||
const KNOWLEDGE_DIR: &str = "knowledge";
|
||||
const SUMMARY_FILE: &str = "summary.md";
|
||||
|
|
@ -81,12 +89,17 @@ impl WorkspaceLayout {
|
|||
&self.root
|
||||
}
|
||||
|
||||
/// `<root>/.insomnia/`. The base of every other memory path.
|
||||
pub fn insomnia_dir(&self) -> PathBuf {
|
||||
self.root.join(INSOMNIA_DIR)
|
||||
}
|
||||
|
||||
pub fn memory_dir(&self) -> PathBuf {
|
||||
self.root.join(MEMORY_DIR)
|
||||
self.insomnia_dir().join(MEMORY_DIR)
|
||||
}
|
||||
|
||||
pub fn knowledge_dir(&self) -> PathBuf {
|
||||
self.root.join(KNOWLEDGE_DIR)
|
||||
self.insomnia_dir().join(KNOWLEDGE_DIR)
|
||||
}
|
||||
|
||||
pub fn summary_path(&self) -> PathBuf {
|
||||
|
|
@ -126,13 +139,14 @@ impl WorkspaceLayout {
|
|||
}
|
||||
|
||||
/// Classify a path under the memory tree. Returns `None` if the
|
||||
/// path is not under `memory/` or `knowledge/` of this workspace,
|
||||
/// or if it lives in `_staging/` (which is opaque to the linter).
|
||||
/// path is not under `.insomnia/memory/` or `.insomnia/knowledge/`
|
||||
/// of this workspace, or if it lives in `_staging/` (which is
|
||||
/// opaque to the linter).
|
||||
///
|
||||
/// On a conventional path that's *almost* a record but malformed
|
||||
/// (e.g. `decisions/Foo.md` with an invalid slug), returns
|
||||
/// `Err(LintError::InvalidSlug | InvalidPath)` so the caller can
|
||||
/// surface it as a write violation.
|
||||
/// (e.g. `.insomnia/memory/decisions/Foo.md` with an invalid slug),
|
||||
/// returns `Err(LintError::InvalidSlug | InvalidPath)` so the caller
|
||||
/// can surface it as a write violation.
|
||||
pub fn classify(&self, path: &Path) -> Result<Option<ClassifiedPath>, LintError> {
|
||||
let memory = self.memory_dir();
|
||||
let knowledge = self.knowledge_dir();
|
||||
|
|
@ -221,7 +235,7 @@ mod tests {
|
|||
#[test]
|
||||
fn classifies_summary() {
|
||||
let cp = layout()
|
||||
.classify(&PathBuf::from("/ws/memory/summary.md"))
|
||||
.classify(&PathBuf::from("/ws/.insomnia/memory/summary.md"))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(cp.kind, RecordKind::Summary);
|
||||
|
|
@ -231,7 +245,7 @@ mod tests {
|
|||
#[test]
|
||||
fn classifies_decision_with_slug() {
|
||||
let cp = layout()
|
||||
.classify(&PathBuf::from("/ws/memory/decisions/foo-bar.md"))
|
||||
.classify(&PathBuf::from("/ws/.insomnia/memory/decisions/foo-bar.md"))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(cp.kind, RecordKind::Decision);
|
||||
|
|
@ -241,7 +255,7 @@ mod tests {
|
|||
#[test]
|
||||
fn classifies_knowledge() {
|
||||
let cp = layout()
|
||||
.classify(&PathBuf::from("/ws/knowledge/x.md"))
|
||||
.classify(&PathBuf::from("/ws/.insomnia/knowledge/x.md"))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(cp.kind, RecordKind::Knowledge);
|
||||
|
|
@ -250,7 +264,7 @@ mod tests {
|
|||
#[test]
|
||||
fn classifies_workflow() {
|
||||
let cp = layout()
|
||||
.classify(&PathBuf::from("/ws/memory/workflow/wf.md"))
|
||||
.classify(&PathBuf::from("/ws/.insomnia/memory/workflow/wf.md"))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(cp.kind, RecordKind::Workflow);
|
||||
|
|
@ -260,7 +274,7 @@ mod tests {
|
|||
fn staging_returns_none() {
|
||||
assert!(
|
||||
layout()
|
||||
.classify(&PathBuf::from("/ws/memory/_staging/abc.json"))
|
||||
.classify(&PathBuf::from("/ws/.insomnia/memory/_staging/abc.json"))
|
||||
.unwrap()
|
||||
.is_none()
|
||||
);
|
||||
|
|
@ -285,7 +299,7 @@ mod tests {
|
|||
#[test]
|
||||
fn invalid_slug_rejected() {
|
||||
let err = layout()
|
||||
.classify(&PathBuf::from("/ws/memory/decisions/Foo.md"))
|
||||
.classify(&PathBuf::from("/ws/.insomnia/memory/decisions/Foo.md"))
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, LintError::InvalidSlug(_)));
|
||||
}
|
||||
|
|
@ -293,7 +307,7 @@ mod tests {
|
|||
#[test]
|
||||
fn nested_under_record_dir_rejected() {
|
||||
let err = layout()
|
||||
.classify(&PathBuf::from("/ws/memory/decisions/sub/foo.md"))
|
||||
.classify(&PathBuf::from("/ws/.insomnia/memory/decisions/sub/foo.md"))
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, LintError::InvalidPath(_)));
|
||||
}
|
||||
|
|
@ -301,7 +315,7 @@ mod tests {
|
|||
#[test]
|
||||
fn unknown_top_level_dir_rejected() {
|
||||
let err = layout()
|
||||
.classify(&PathBuf::from("/ws/memory/something/foo.md"))
|
||||
.classify(&PathBuf::from("/ws/.insomnia/memory/something/foo.md"))
|
||||
.unwrap_err();
|
||||
assert!(matches!(err, LintError::InvalidPath(_)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ Workflow(`/<slug>` で呼び出される制約付き作業フロー)は別 p
|
|||
|
||||
### 記録対象の 4 種
|
||||
|
||||
本ドキュメント以下のパスはすべて **`<workspace_root>/.insomnia/`** からの相対表記。`.insomnia/` は manifest / prompts と同じく workspace に紐付く insomnia コンテンツのルートで、memory もこの規約に従う。`workspace_root` 既定は Pod の pwd。
|
||||
|
||||
| 種別 | パス | 備考 |
|
||||
| ---------------- | ---------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| Always-on サマリ | `memory/summary.md` | 1-5k tokens 目安 |
|
||||
|
|
|
|||
|
|
@ -2,3 +2,6 @@
|
|||
|
||||
Prefer the most specific tool for the job. When reading files you already know the path of, use the file-read tool directly instead of searching.
|
||||
When searching, use grep/glob primitives rather than shell pipelines.
|
||||
|
||||
You can run multiple tools simultaneously by calling them within a single response.
|
||||
It is recommended to run tools that handle asynchronous processing, such as queries and readings, in batches.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
You are here as an agent of the "insomnia system".
|
||||
|
||||
Stay precise, edit code directly when asked, and avoid speculative refactoring. Explain what you changed in one short paragraph at the end of each turn.
|
||||
|
||||
{% include "common/workspace" %}
|
||||
|
||||
{% include "common/tool-usage" %}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user