-
Notifications
You must be signed in to change notification settings - Fork 0
feat(core): nanograph v1 integration with per-feature port traits #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
368d69f
0900e29
452ffc1
29a283e
56a74a6
0f199c9
f8099d9
fd61a76
68f6436
a71d02e
573c514
d5edeb6
c875d40
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # Architecture Rules | ||
|
|
||
| ## Port Traits | ||
|
|
||
| 1. **Per-feature port traits** — each feature/use-case defines its own port trait. Never create a single god trait for all graph operations. | ||
| 2. **Port trait methods must use domain types only** — if a method signature contains query text, query names, or generic parameter maps, the abstraction is wrong. | ||
| 3. **Port traits must have ≤5 methods** — if more are needed, split into separate per-consumer traits. | ||
|
|
||
| ## Layer Boundaries | ||
|
|
||
| 4. **No `include_str!` across module boundaries** — query files, schema files, and templates must only be referenced by the infrastructure module that owns them. Features must never use `include_str!("../../infrastructure/...")`. | ||
| 5. **Features must not import from infrastructure** — except in `#[cfg(test)]` blocks for integration tests using `open_in_memory()`. | ||
| 6. **Infrastructure owns all engine-specific details** — query syntax, query file paths, engine configuration. Features see only domain-typed trait methods. | ||
|
|
||
| ## Error Handling | ||
|
|
||
| 7. **Port traits return `Result<T, TankyuError>`** — never `anyhow::Result` in port trait signatures. | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,6 +24,11 @@ jobs: | |||||||||||||
| steps: | ||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||
|
|
||||||||||||||
| - name: Install protoc | ||||||||||||||
| uses: arduino/setup-protoc@v3 | ||||||||||||||
|
Comment on lines
+27
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Verify arduino/setup-protoc action and latest protoc version
# Check the action's README for version parameter support
curl -s https://raw.githubusercontent.com/arduino/setup-protoc/v3/README.md | grep -A5 "version"
# Get latest protoc release
curl -s https://api.github.com/repos/protocolbuffers/protobuf/releases/latest | jq -r '.tag_name'Repository: cmbays/tankyu-rs Length of output: 862 Good addition; consider pinning the protoc version for reproducibility. Adding protoc installation consistently across all test jobs is correct for supporting nanograph's transitive dependencies. However, the action is called without specifying a protoc version, which means it will use the action's default (typically the latest). This could lead to non-deterministic builds if protoc behavior changes between versions. The 📌 Suggested enhancement to pin protoc version - name: Install protoc
uses: arduino/setup-protoc@v3
+ with:
+ version: "34.x"Apply the same change to all four jobs' protoc installation steps (lines 27-28, 78-79, 131-132, and 229-230). 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| with: | ||||||||||||||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||
|
|
||||||||||||||
| - name: Install Rust stable | ||||||||||||||
| uses: dtolnay/rust-toolchain@1.91.0 | ||||||||||||||
| with: | ||||||||||||||
|
|
@@ -72,6 +77,11 @@ jobs: | |||||||||||||
| steps: | ||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||
|
|
||||||||||||||
| - name: Install protoc | ||||||||||||||
| uses: arduino/setup-protoc@v3 | ||||||||||||||
| with: | ||||||||||||||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||
|
|
||||||||||||||
| - name: Install Rust stable | ||||||||||||||
| uses: dtolnay/rust-toolchain@1.91.0 | ||||||||||||||
| with: | ||||||||||||||
|
|
@@ -122,6 +132,11 @@ jobs: | |||||||||||||
| with: | ||||||||||||||
| fetch-depth: 0 | ||||||||||||||
|
|
||||||||||||||
| - name: Install protoc | ||||||||||||||
| uses: arduino/setup-protoc@v3 | ||||||||||||||
| with: | ||||||||||||||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||
|
|
||||||||||||||
| - name: Install Rust stable | ||||||||||||||
| uses: dtolnay/rust-toolchain@1.91.0 | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -217,6 +232,11 @@ jobs: | |||||||||||||
| steps: | ||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||
|
|
||||||||||||||
| - name: Install protoc | ||||||||||||||
| uses: arduino/setup-protoc@v3 | ||||||||||||||
| with: | ||||||||||||||
| repo-token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||
|
|
||||||||||||||
| - name: Install Rust stable | ||||||||||||||
| uses: dtolnay/rust-toolchain@1.91.0 | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| mutants.out/ | ||
| mutants.out.old/ | ||
| docs/private/ | ||
| .firecrawl/ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Minor: Unrelated change bundled in PR. The 🤖 Prompt for AI Agents |
||
|
|
||
| # Claude Code — track rules, ignore everything else | ||
| .claude/* | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| {"type":"decision","phase":"discover","step":"framing","text":"Option B selected: collapse 6 store traits into single IResearchGraph backed by nanograph. Eliminates glue code, leverages open_in_memory() for tests.","date":"2026-03-19"} | ||
| {"type":"decision","phase":"discover","step":"framing","text":"Clean start for v1 — no JSON data migration required. Migration is mechanical (JSON→JSONL) and can be done later.","date":"2026-03-19"} | ||
| {"type":"decision","phase":"discover","step":"framing","text":"Architecture uplift: introduce application/use-case layer, enforce domain/infra boundary via module visibility + CI lint.","date":"2026-03-19"} | ||
| {"type":"assumption","phase":"discover","step":"framing","text":"nanograph enum() syntax supports kebab-case values — needs verification against schema parser.","date":"2026-03-19","resolved":"2026-03-19","resolution":"CONFIRMED — kebab-case enums work, auto-sorted alphabetically."} | ||
| {"type":"assumption","phase":"discover","step":"framing","text":"UUID strings as @key will work for nanograph node identity — needs verification (nanograph examples use slugs).","date":"2026-03-19","resolved":"2026-03-19","resolution":"CONFIRMED — UUID strings as String @key work for nodes and edge resolution."} | ||
| {"type":"gap","phase":"discover","step":"framing","text":"No automated Rust tool for detecting domain/infra layer violations. Will build lightweight CI lint (grep-based).","date":"2026-03-19"} | ||
| {"type":"decision","phase":"discover","step":"research","text":"Feature-gate nanograph behind cargo feature flag. Binary goes from 1.4MB to 58MB (+341 deps). Default build stays lean; graph backend is opt-in.","date":"2026-03-19"} | ||
| {"type":"gap","phase":"discover","step":"research","text":"protoc (protobuf compiler) required at build time when nanograph feature is enabled — needs CI setup.","date":"2026-03-19"} | ||
| {"type":"outcome","session":"S1.1b","gate":"atdd","timestamp":"2026-03-21","result":"ALL_PASS","details":{"bdd":"PASS — doctor 3/3, status 2/3 (1 pre-existing skip)","tdd":"PASS — 165 tests, clippy clean","crap":"SKIPPED — Rust project","mutation":"PASS — 14 caught, 7 unviable, 0 survivors","arch_auto":"PASS — no boundary violations","arch_review":"PASS — 0 HIGH, 0 MEDIUM (fixed DoctorReport placement)"},"gaps":["CRAP analysis skipped — crap4ts not available for Rust"]} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| { | ||
| "phase": "build", | ||
| "status": "running", | ||
| "steps": [ | ||
| { | ||
| "name": "S1.1", | ||
| "description": "Schema + IResearchGraph + NanographStore", | ||
| "status": "completed", | ||
| "startedAt": "2026-03-19T00:00:00Z", | ||
| "completedAt": "2026-03-21T00:00:00Z", | ||
| "branch": "feat/nanograph-v1-schema", | ||
| "notes": "Schema (.pg), IResearchGraph port, NanographStore impl, StatusUseCase, DoctorUseCase, slug_from_name, topic queries. 6+8 unit tests green." | ||
| }, | ||
| { | ||
| "name": "S1.2", | ||
| "description": "Wire Status + Doctor BDD scenarios", | ||
| "status": "completed", | ||
| "startedAt": "2026-03-19T00:00:00Z", | ||
| "completedAt": "2026-03-21T00:00:00Z", | ||
| "branch": "feat/nanograph-v1-schema", | ||
| "notes": "Doctor 3/3 green, Status 2/3 green + 1 skipped (depends on source-topic link from S2.2). All wiring done in S1.1 commit — no separate branch needed.", | ||
| "bddScenarios": "5/6 passing (1 blocked on S2.2 prerequisite)" | ||
| }, | ||
| { | ||
| "name": "S2.1", | ||
| "description": "Topic CRUD via nanograph", | ||
| "status": "pending", | ||
| "branch": "feat/nanograph-v2-topics", | ||
| "bddScenarios": 7 | ||
| } | ||
| ], | ||
| "startedAt": "2026-03-21T00:00:00Z", | ||
| "completedAt": null | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "phase": "closeout", | ||
| "status": "pending", | ||
| "steps": [], | ||
| "startedAt": null, | ||
| "completedAt": null | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| { | ||
| "phase": "discover", | ||
| "status": "completed", | ||
| "steps": [ | ||
| { | ||
| "name": "existing-decisions", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z" | ||
| }, | ||
| { | ||
| "name": "framing", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z", | ||
| "artifact": "~/Github/ops/workspace/tankyu-rs/tankyu-rs/20260319-nanograph-integration/frame.md" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded home directory paths are non-portable. The artifact paths at lines 14, 21, and 27 use 🤖 Prompt for AI Agents |
||
| }, | ||
| { | ||
| "name": "research", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z", | ||
| "notes": "Spikes: kebab-case enums + UUID @key confirmed. Binary 1.4→58MB. Nullability/concurrency/negation/mutations/migration all tested. `id` field naming bug found and worked around (use `slug`).", | ||
| "artifact": "~/Github/ops/research/tankyu-rs/nanograph-v1.0.0-capabilities.md" | ||
| }, | ||
| { | ||
| "name": "interrogation", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z", | ||
| "artifact": "~/Github/ops/workspace/tankyu-rs/tankyu-rs/20260319-nanograph-integration/requirements.md" | ||
| } | ||
| ], | ||
| "startedAt": "2026-03-19T00:00:00Z", | ||
| "completedAt": "2026-03-19T00:00:00Z" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| { | ||
| "phase": "plan", | ||
| "status": "completed", | ||
| "steps": [ | ||
| { | ||
| "name": "design-doc", | ||
| "status": "completed", | ||
| "startedAt": "2026-03-19T00:00:00Z", | ||
| "completedAt": "2026-03-20T00:00:00Z", | ||
| "artifact": "~/Github/ops/workspace/tankyu-rs/tankyu-rs/20260319-nanograph-integration/impl-plan.md" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded home directory path is non-portable. The artifact path uses 🤖 Prompt for AI Agents |
||
| } | ||
| ], | ||
| "startedAt": "2026-03-19T00:00:00Z", | ||
| "completedAt": "2026-03-20T00:00:00Z" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "phase": "review", | ||
| "status": "pending", | ||
| "steps": [], | ||
| "startedAt": null, | ||
| "completedAt": null | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| { | ||
| "phase": "shape", | ||
| "status": "completed", | ||
| "steps": [ | ||
| { | ||
| "name": "existing-decisions", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z", | ||
| "notes": "7 ADRs from write-side-mutations pipeline. No product decisions yet." | ||
| }, | ||
| { | ||
| "name": "shaping", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z", | ||
| "notes": "Shape A selected: Thin Port, Fat Use Cases. 8 parts defined.", | ||
| "artifact": "~/Github/ops/workspace/tankyu-rs/tankyu-rs/20260319-nanograph-integration/shaping.md" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hardcoded home directory paths are non-portable. The artifact paths at lines 16 and 23 use 🤖 Prompt for AI Agents |
||
| }, | ||
| { | ||
| "name": "breadboarding", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z", | ||
| "notes": "14 CLI commands mapped, 6 vertical slices defined. AddSource is most complex flow.", | ||
| "artifact": "~/Github/ops/workspace/tankyu-rs/tankyu-rs/20260319-nanograph-integration/breadboard.md" | ||
| }, | ||
| { | ||
| "name": "breadboard-reflection", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z", | ||
| "notes": "7 smells fixed + 8 nanograph cross-reference findings. All resolved including F2 edge endpoints." | ||
| }, | ||
| { | ||
| "name": "bdd-formulation", | ||
| "status": "completed", | ||
| "completedAt": "2026-03-19T00:00:00Z", | ||
| "notes": "6 .feature files: status, topic, source, entry, health, doctor. 42 scenarios total. Slug-based identity, graph traversal, auto-init, idempotent source add, cascade delete." | ||
| } | ||
| ], | ||
| "startedAt": "2026-03-19T00:00:00Z", | ||
| "completedAt": "2026-03-19T00:00:00Z" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "id": "tankyu-rs/20260319-nanograph-integration", | ||
| "description": "Discover and shape nanograph v1.0.0 integration as tankyu's graph backend, replacing JsonGraphStore", | ||
| "template": "vertical", | ||
| "phaseSequence": ["discover", "shape", "plan", "build", "review", "closeout"], | ||
| "currentPhase": "build", | ||
| "status": "running", | ||
| "startedAt": "2026-03-19T00:00:00Z", | ||
| "completedAt": null | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,14 @@ Cargo workspace with two crates: | |
| Reads `~/.tankyu/` data directory produced by the TypeScript CLI. | ||
| Set `TANKYU_DIR` env var to override the data directory (used in tests). | ||
|
|
||
| ## Language Context | ||
|
|
||
| Language: Rust | ||
| Framework: clap (CLI) | ||
| Idiom reference: `~/.claude/knowledge/languages/rust/` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use a portable idiom-reference location instead of a home-directory path.
Suggested doc tweak-Idiom reference: `~/.claude/knowledge/languages/rust/`
+Idiom reference: `.claude/knowledge/languages/rust/` (repo-relative) or the team-approved Rust style guide URL🤖 Prompt for AI Agents |
||
|
|
||
| Consult the idiom reference before making architectural decisions (trait design, module boundaries, port abstractions). | ||
|
|
||
| ## Key Conventions | ||
|
|
||
| - `#![forbid(unsafe_code)]` in every crate root | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scope these constraints to new per-feature graph ports (or add explicit legacy exceptions).
Rules
#3and#7are currently written as universal, but existing retained legacy ports incrates/tankyu-core/src/domain/ports.rsstill exceed 5 methods and useanyhow::Result. As-is, the rule set is self-contradictory and not enforceable.Suggested wording adjustment
Also applies to: 17-17
🤖 Prompt for AI Agents