Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions plans/research-core-adaptation-v2/milestone-0-execution-dag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Milestone 0 Execution DAG

```yaml
objective: reconcile Research Core Adaptation V2 with the checked-out Nashsu core without changing production behavior
root_owner: current Codex root session
requested_model: GPT-5.6 Sol High
model_verification: unavailable in this task surface

nodes:
- id: package-intake
kind: root
depends_on: []
outcome: verify the complete handoff and extract its constraints and code anchors
status: completed

- id: repository-baseline
kind: root
depends_on: [package-intake]
outcome: acquire the canonical repository, pin the exact version, and create a feature branch
status: completed

- id: scout-frontend-ingest
kind: root
archetype: scout-equivalent
depends_on: [repository-baseline]
outcome: map templates, schema routing, source import, queues, review persistence, page merge, and tests
write_scope: read-only
status: completed

- id: scout-backend-api
kind: root
archetype: scout-equivalent
depends_on: [repository-baseline]
outcome: map Rust persistence, local API routing, graph/search behavior, and project resolution
write_scope: read-only
status: completed

- id: scout-mcp-models
kind: root
archetype: scout-equivalent
depends_on: [repository-baseline]
outcome: map MCP registration and binding, model routing, and integration-test surfaces
write_scope: read-only
status: completed

- id: baseline-validation
kind: root
depends_on: [scout-frontend-ingest, scout-backend-api, scout-mcp-models]
outcome: run existing builds and tests and attempt the canonical desktop launch
status: completed-with-findings

- id: root-reconciliation
kind: root
depends_on: [baseline-validation]
outcome: reconcile reports, identify contradicted assumptions, and choose a proposed PR sequence
status: completed

- id: milestone-0-report
kind: root
depends_on: [root-reconciliation]
outcome: publish the root-owned intake report; make no production change
status: completed
```

Delegation note: the installed Codex CLI reports stable `multi_agent`, but this
task runtime exposes no spawn/subagent tool. Following the handoff fallback, the
three non-overlapping read-only scouting passes were performed sequentially by
the root. No alternate orchestration runtime was installed.

153 changes: 153 additions & 0 deletions plans/research-core-adaptation-v2/milestone-0-fresh-intake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Nashsu Research Core Adaptation V2 — Milestone 0 Fresh Intake

## Status

The implementation map is coherent enough to scope later work, but the baseline
is not fully green. No production code, dependency, lockfile, schema, or runtime
was changed. Milestone 1 was not started.

Nashsu/llm_wiki remains the sole canonical product and knowledge core.
AtomicStrata, AutoSci, OpenKB, Synto, Open Knowledge CLI, llm-wiki-okf, OKF, and
additional orchestration runtimes remain outside the implementation boundary.
OpenDeepWiki remains a future lazy, repository-scoped, non-canonical adjunct.

## Exact baseline

- Repository: `https://github.com/nashsu/llm_wiki.git`
- Baseline branch: `main`
- Intake branch: `codex/research-core-m0-intake`
- Commit: `969e7e8d9e2903af0e3ed0be85c97639511e845c`
- Describe: `v0.6.4-8-g969e7e8`
- Commit: `fix: harden provider and import routing`
- Commit date: `2026-07-16T17:04:21+08:00`
- App/package/Cargo/Tauri version: `0.6.4`
- MCP package version: `0.4.25`
- Handoff: all 25 manifest entries matched their declared SHA-256 and byte size.

The workspace initially contained no Nashsu checkout, so the current upstream
repository was cloned before inspection.

## Orchestration and capability check

- Codex CLI: `0.142.5`
- CLI feature state: `multi_agent = stable/true`;
`multi_agent_v2 = under-development/false`;
`enable_fanout = under-development/false`.
- Official Codex documentation describes direct subagents, a default nesting
depth of one, and built-in `worker` and `explorer` roles.
- This task runtime exposed no spawn/subagent tool, so no worker was delegated.
The root performed three sequential, isolated, read-only scout-equivalent
passes: frontend/ingest, Rust/API, and MCP/model routing.
- The requested GPT-5.6 Sol High identity/reasoning setting is not inspectable
or configurable from this task surface, so it cannot be independently
verified.

The compact DAG is in `milestone-0-execution-dag.md`.

## Root implementation map

| Capability | Current authority and behavior | Adaptation consequence |
| --- | --- | --- |
| Template materialization | `src/lib/templates.ts` defines schema, purpose, and extra directories. `src-tauri/src/commands/project.rs` creates the base project; `src/components/project/create-project-dialog.tsx` then writes the selected template files/directories. | Research Profile v2 must update the existing two-stage path, not add a creator. |
| Schema routing | `src/lib/wiki-schema.ts` parses the `## Page Types` table dynamically and maps type to directory. In ingest, generated blocks are checked against this routing before write. Other schema prose mostly guides prompts. | Add `repository` to the Research table; do not build a generic schema engine. |
| Fixed page-type surfaces | `src/lib/wiki-page-types.ts`, knowledge-tree and activity icon maps, `src/lib/wiki-type-style.ts`, and i18n labels contain known-type lists. Graph affinity and review-page creation also have fixed maps but safe fallbacks. | Milestone 1 must update user-visible/generation lists and test dynamic fallback surfaces. |
| Source import | `src/lib/source-lifecycle.ts` copies files into `raw/sources`, preprocesses them, and immediately calls `enqueueSourceIngest` when an ingest model is usable. | Candidate registration must be inserted before enqueue for Research projects only; reuse import/copy logic. |
| Ingest queue | `src/lib/ingest-queue.ts::enqueueBatch`; state is project-scoped in `.llm-wiki/ingest-queue.json`. It supports pause, restart recovery, retry, cancellation, stable project identity, and serial processing. | Candidate batch include/watch/exclude should feed this queue; no second queue. |
| Ingest and merge | `src/lib/ingest.ts` performs analysis/generation, validates schema routing, creates review items, and writes through `mergePageContent`. `src/lib/page-merge.ts` unions `sources`, `tags`, and `related`, locks `type`, `title`, and `created`, and writes history backups. | Corpus bootstrap and Research writes must use normal ingest/merge/review behavior. |
| Review persistence | `src/stores/review-store.ts`; `.llm-wiki/review.json` through `src/lib/persist.ts` and autosave. The Rust API reads and patches the same file. | Extend existing review/activity patterns; do not add a review store. |
| Search/index | Rust search in `src-tauri/src/commands/search.rs` backs desktop invoke and API search. Index rebuild groups pages dynamically from frontmatter. Embeddings are optional. | `repository` should become searchable without a new index; add acceptance coverage. |
| Graph | Desktop uses the TypeScript wiki graph path. API/MCP use a separate Rust `build_graph` in `api_server.rs`; the API currently excludes `query` nodes. Both derive types dynamically. | Repository visibility should work, but graph parity is an existing architectural discrepancy to resolve or document. |
| Model routing | Desktop chat and ingest use `src/lib/llm-task-routing.ts` with separate `chat` and `ingest` presets. Image captioning is passed the ingest-side configuration. Embedding has separate embedding settings. Rust API/MCP chat uses `project_llm_config`, global config, and project overrides but does not apply `taskModelRouting.chatPresetId`. | Preserve current desktop routing; add parity tests before relying on MCP chat for acceptance. |
| Local API | `src-tauri/src/api_server.rs`, port `19828`, prefix `/api/v1`; exposes health, projects, files, reviews, search, graph, source rescan, chat, and cancellation with auth, bind, rate, size, and path controls. | Extend the API only when a required Research operation cannot use an existing endpoint. |
| MCP | `mcp-server` is a thin HTTP client over the desktop API. It registers 10 tools: status, projects, set-project, files, read-file, reviews, search, chat, graph, and rescan-sources. | Keep MCP thin; no filesystem scan or independent retrieval implementation. |
| Project selection | Stable UUID in `.llm-wiki/project.json`; global `app-state.json` registry; API accepts stable ID, exact path, or `current`; MCP can pin a process to a project and rejects conflicting overrides. | Candidate and corpus state must key by stable project identity and remain project-scoped. |

Representative `.llm-wiki/` state includes `project.json`,
`ingest-queue.json`, `ingest-cache.json`, `ingest-progress/`,
`ingest-warnings.log`, `review.json`, `lint.json`, `file-snapshot.json`,
`file-change-queue.json`, `dedup-queue.json`, `dedup-not-duplicates.json`,
`scheduled-import-db.json`, `image-caption-cache.json`, `conversations.json`,
`chats/`, `chat-preferences.json`, `history/`, `page-history/`, `lancedb/`, and
project `skills/`. Candidate screening needs one new small project-scoped file,
not a replacement for any of these.

## Handoff anchor reconciliation

All named high-value anchors still exist. The paths are useful, but three
assumptions require correction:

1. Schema routing is already substantially dynamic. Adding a page type does not
require Rust index/search/graph type registration, although fixed generation
and UI presentation lists still need updates.
2. Desktop and API/MCP graph generation are not one shared backend. The API has
its own Rust graph builder and intentionally drops `query` nodes.
3. Desktop task-model routing and API/MCP chat routing are not equivalent. The
Rust API does not currently consume the chat task preset.

Additional baseline findings:

- The Research template's shared frontmatter example lists only base types even
though the same schema defines `thesis`, `methodology`, and `finding`.
- Import currently means copy plus immediate enqueue; there is no candidate
registration/screening state.
- `npm ci` at the root is not reproducible from the checked-in lockfile:
`@emnapi/core@1.11.2` and `@emnapi/runtime@1.11.2` are missing and
`@emnapi/wasi-threads` resolves at an invalid locked version. Dependencies
were materialized with `npm install --package-lock=false`; the lockfile was
preserved.
- Existing tests strongly cover page merge preservation and TypeScript task
routing. Research template form state is tested, but full Research project
materialization is not. MCP client tests prove HTTP calls, but there is no
explicit architectural regression test forbidding direct filesystem scans.

## Validation evidence

| Command | Result |
| --- | --- |
| `npm run test:mocks -- --reporter=dot` | PASS: 117 files, 1,707 tests. |
| `npm run build` | PASS: TypeScript and Vite production build; existing chunk/dynamic-import warnings only. |
| `npm run mcp:test` | PASS: 20 tests. |
| `npm run test:llm` | FAIL: 6 failed, 3 passed, 70 skipped. Three fake embedding-server tests receive `undefined`; three Origin tests send `http://localhost` instead of the endpoint origin. External provider suites were skipped because credentials/endpoints were unavailable. |
| `cargo test -q` | PASS: 338 passed, 1 ignored; existing compiler warnings only. |
| `npm run tauri dev` | PASS: desktop binary launched; Vite served `http://localhost:1420/`; Clip Server listened on `127.0.0.1:19827`; API listened on `127.0.0.1:19828/api/v1`. |
| Local API smoke | PASS: health 200 (`version: 0.6.4`), CORS preflight 204. Projects returned the expected 401 because the fresh state requires auth but has no token configured; MCP is disabled. |

The first Rust/launch attempts failed when the data volume had about 118 MiB
free. After space was restored, both completed. The build consumed most of the
new headroom and left about 1 GiB free.

The computer-use skill is installed, but this task surface does not expose its
required action tool. The app and services were launched and probed, but
click-driven creation/import/review/search/graph flows were therefore not
manually exercised.

## Proposed PR sequence

1. **M0 baseline stabilization:** add the canonical-core ADR, repair root
lockfile reproducibility, document the full local stack, add missing Research
materialization/MCP-boundary regressions, and decide whether the six
real-contract failures are code or stale test expectations. Add an
authenticated full-stack fixture for API/MCP acceptance.
2. **M1 Research Profile v2:** add only `repository` and
`wiki/repositories/`; keep flat frontmatter; update the fixed surfaces above;
add creation, routing, rendering, search/graph visibility, and safe-merge
tests.
3. **M2 candidate intake:** add a small Research-only project store and
include/watch/exclude UI; register without ingest; batch-enqueue through the
existing queue.
4. **M3 screening and progress:** structured screening output, migration and
restart tests, and existing activity/review integration.
5. **M4 bounded corpus bootstrap:** inventory, group, cluster synthesis, and
global synthesis through normal compiled pages and merge/review.
6. **M5 MCP/API parity:** expose only missing Research operations, resolve
graph/model-routing parity, and keep MCP as an API client.
7. **M6 OpenDeepWiki adjunct:** lazy repository registration and
commit-pinned evidence only; never canonical.

## Root decision and remaining uncertainty

The extension seams are clear and no new core runtime or generic abstraction is
justified. Before Milestone 1, disposition the six real-contract failures and
perform one authenticated, click-driven baseline pass through current
Research creation, import, review, search, graph, API, and MCP behavior. The
remaining evidence gaps are not permission to broaden Milestone 1.
62 changes: 62 additions & 0 deletions plans/research-core-adaptation-v2/milestone-1-execution-dag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Milestone 1 Execution DAG

```yaml
objective: extend the existing Research template with the repository page type and directory while preserving all existing projects and templates
root_owner: current Codex root session

nodes:
- id: root-scope
kind: root
depends_on: []
outcome: pin accepted seams and exact fixed page-type surfaces from Milestone 0
status: completed

- id: tests-red
kind: root
archetype: verifier
depends_on: [root-scope]
outcome: add failing behavior tests for creation, routing, rendering, search/graph visibility, and safe merge
write_scope: test files only
status: completed

- id: profile-builder
kind: root
archetype: builder
depends_on: [tests-red]
outcome: add only the Research repository type/directory and update required fixed surfaces
write_scope: accepted template and page-type presentation files
status: completed

- id: focused-verification
kind: root
archetype: verifier
depends_on: [profile-builder]
outcome: pass focused tests and typechecking
write_scope: read-only except generated test/build artifacts
status: completed

- id: independent-review
kind: root
archetype: reviewer
depends_on: [focused-verification]
outcome: review the complete diff independently against repository standards and the handoff
write_scope: read-only
status: completed

- id: root-integration
kind: root
depends_on: [independent-review]
outcome: resolve findings and run the full verification matrix
status: completed

- id: commit
kind: root
depends_on: [root-integration]
outcome: commit the accepted Milestone 0 evidence and Milestone 1 implementation
status: completed
```

Delegation note: this task runtime exposes no subagent/spawn tool. The root
therefore collapses builder, verifier, and reviewer roles into explicit
sequential passes with non-overlapping phases. Architecture and integration
remain root-owned.
33 changes: 33 additions & 0 deletions src-tauri/src/api_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2184,6 +2184,39 @@ mod tests {
assert!(!is_public_project_rel("wiki/.draft.md"));
}

#[test]
fn api_graph_includes_repository_pages_with_their_declared_type() {
let root = test_project_dir();
let repository_dir = root.join("wiki/repositories");
let concept_dir = root.join("wiki/concepts");
fs::create_dir_all(&repository_dir).unwrap();
fs::create_dir_all(&concept_dir).unwrap();
fs::write(
repository_dir.join("nashsu-llm-wiki.md"),
"---\ntype: repository\ntitle: Nashsu / llm_wiki\n---\n\n[[knowledge-core]]",
)
.unwrap();
fs::write(
concept_dir.join("knowledge-core.md"),
"---\ntype: concept\ntitle: Knowledge Core\n---\n\n[[nashsu-llm-wiki]]",
)
.unwrap();

let (nodes, edges) = build_graph(root.to_str().unwrap()).unwrap();
let repository = nodes
.iter()
.find(|node| node.id == "nashsu-llm-wiki")
.unwrap();

assert_eq!(repository.node_type, "repository");
assert_eq!(
repository.path,
"wiki/repositories/nashsu-llm-wiki.md"
);
assert_eq!(edges.len(), 1);
let _ = fs::remove_dir_all(root);
}

#[test]
fn review_query_defaults_to_unresolved_items() {
let root = test_project_dir();
Expand Down
28 changes: 28 additions & 0 deletions src-tauri/src/commands/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2038,6 +2038,34 @@ mod tests {
let _ = fs::remove_dir_all(root);
}

#[tokio::test]
async fn keyword_search_includes_repository_pages_in_custom_wiki_directories() {
let root = tmp_project();
write_page(
&root,
"wiki/repositories/nashsu-llm-wiki.md",
"---\ntype: repository\ntitle: Nashsu / llm_wiki\n---\n\nCanonical research knowledge core implementation.",
);

let out = search_project_inner(
root.to_string_lossy().to_string(),
"canonical research knowledge core".into(),
20,
false,
None,
)
.await
.unwrap();

assert_eq!(out.results.len(), 1);
assert_eq!(
out.results[0].path,
"wiki/repositories/nashsu-llm-wiki.md"
);
assert_eq!(out.results[0].title, "Nashsu / llm_wiki");
let _ = fs::remove_dir_all(root);
}

#[tokio::test]
async fn keyword_search_always_blends_available_graph_neighbors() {
let root = tmp_project();
Expand Down
3 changes: 2 additions & 1 deletion src/components/chat/chat-message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import "katex/dist/katex.min.css"
import {
Bot, User, FileText, BookmarkPlus, ChevronDown, ChevronRight, RefreshCw, Copy, Check,
Users, Lightbulb, BookOpen, HelpCircle, GitMerge, BarChart3, Layout, Globe,
TrendingUp, Target, Sparkles, Image as ImageIcon, FileSearch, Terminal,
TrendingUp, Target, GitBranch, Sparkles, Image as ImageIcon, FileSearch, Terminal,
} from "lucide-react"
import { openUrl } from "@tauri-apps/plugin-opener"
import { useWikiStore } from "@/stores/wiki-store"
Expand Down Expand Up @@ -655,6 +655,7 @@ const REF_TYPE_CONFIG: Record<string, { icon: typeof FileText; color: string }>
finding: { icon: TrendingUp, color: "text-purple-500" },
thesis: { icon: Target, color: "text-rose-500" },
methodology: { icon: BookOpen, color: "text-teal-500" },
repository: { icon: GitBranch, color: "text-sky-500" },
overview: { icon: Layout, color: "text-yellow-500" },
clip: { icon: Globe, color: "text-blue-400" },
external: { icon: Globe, color: "text-sky-500" },
Expand Down
2 changes: 2 additions & 0 deletions src/components/graph/graph-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const NODE_TYPE_COLORS: Record<string, string> = {
finding: "#a855f7", // purple-500
thesis: "#f43f5e", // rose-500
methodology: "#14b8a6", // teal-500
repository: "#38bdf8", // sky-400
other: "#94a3b8", // slate-400
}

Expand Down Expand Up @@ -728,6 +729,7 @@ export function GraphView() {
finding: t("graph.nodeTypeLabels.finding"),
thesis: t("graph.nodeTypeLabels.thesis"),
methodology: t("graph.nodeTypeLabels.methodology"),
repository: t("graph.nodeTypeLabels.repository"),
other: t("graph.nodeTypeLabels.other"),
})
}, [t])
Expand Down
Loading