fuse tauri cytoscape wasm bridge#100
Open
elasticdotventures wants to merge 2 commits into
Open
Conversation
Member
elasticdotventures
commented
May 17, 2026
- feat: MECE test harness (42 tests) + CDP viz server + viz dashboard
- refactor: extract justfile recipes into module, add viz/test/status recipes
- Comprehensive 42-test integration suite at tests/holon_viz_comprehensive.rs covering ProcessController, ImmutableActionLog, Holon, CytoscapeGraph, HtmlRenderer, emitters, TypeRelationshipGraph, VizObserver, full pipeline - ledgrrr-viz-serve.py: HTTP + CDP-compatible server for viz dashboard (start/stop/status, /json/version + /json/list endpoints for VizObserver) - Fix duplicate [dev-dependencies] in holon-viz/Cargo.toml - Export CytoscapeNodeData and CytoscapeEdgeData from lib.rs - Remove specta dep (nightly-only, not needed for core viz)
…ecipes - Document module pattern header (canonical: when-to-use vs inline) - Add viz, viz-stop, viz-status, viz-build recipes - Add test (42 MECE suite), test-all recipes - Add status recipe (repo/binary/running check) - Fix install target path: ~/.cargo/bin -> ~/.local/bin
Contributor
There was a problem hiding this comment.
Pull request overview
This PR expands the project’s visualization and operational surfaces by adding a lightweight viz dashboard server + a comprehensive holon-viz test harness, while also refactoring/clarifying operational docs and Rotel proxy behavior.
Changes:
- Add a Python HTTP server for serving the holon-viz Cytoscape dashboard plus minimal CDP-compatible JSON endpoints, and wire it into
justrecipes. - Add a large “MECE” integration test suite for
holon-vizand adjustholon-vizexports/serialization types. - Refine Rotel proxying/port configuration behavior and update related docs/config (including env var documentation).
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| skills/ledgerr-devops/SKILL.md | Updates container env var documentation (but currently advertises an env var the server doesn’t read). |
| server.json | Renames advertised workbook env var (but it’s not currently consumed by the server). |
| scripts/ledgrrr-viz-serve.py | Adds a viz dashboard HTTP/CDP server (currently points at the wrong generated HTML path and has a regeneration cwd issue). |
| README.md | Adds a naming/map note pointing to POLYSEME-MAP. |
| ledgrrr.just | Adds viz/test/status recipes and updates install destination. |
| Justfile | Adds env-docs-check and b00t-maintenance-check recipes (currently referencing missing scripts). |
| docs/rotel-otel-journal-surface.md | Updates Rotel surface docs to describe host proxy forwarding to rotel-visual. |
| Dockerfile.ledgerr-mcp | Removes EXPOSE and clarifies stdio transport. |
| Dockerfile | Renames workbook env var (but the server doesn’t currently read it). |
| crates/rotel-visual/tests/health_dashboard_tests.rs | Minor test cleanup / variable naming adjustments. |
| crates/rotel-visual/src/lib.rs | Adds ROTEL_PORT support and a port-collision warning (with a misleading Linux PID claim). |
| crates/ledgerr-mcp/src/mcp_adapter.rs | Removes focus JSONL sidecar persistence from adapter layer. |
| crates/ledgerr-mcp/src/focus_tool.rs | Implements focus record persistence + adds tests (tests currently risk flakiness due to global env var + global store). |
| crates/ledgerr-llm/src/lib.rs | Changes default LLM model to a local-first default. |
| crates/ledgerr-host/src/internal_openai.rs | Switches OTLP handling to forward to rotel-visual and changes export-plan behavior (now ignores bound listener addr). |
| crates/ledger-core/src/ledger_ops.rs | Adds/edits op docs but currently contains unresolved merge conflict markers (compile blocker). |
| crates/holon-viz/tests/holon_viz_comprehensive.rs | Adds a large comprehensive integration test suite. |
| crates/holon-viz/src/type_graph.rs | Removes specta::Type derives (breaks downstream Tauri specta export). |
| crates/holon-viz/src/lib.rs | Expands re-exports (including Cytoscape *Data structs). |
| crates/holon-viz/src/cytoscape.rs | Removes specta::Type derives (breaks downstream Tauri specta export). |
| crates/holon-viz/Cargo.toml | Removes specta dependency (incompatible with downstream specta usage). |
| crates/arc-kit-au/src/graph.rs | Cleans up unused test imports. |
Comments suppressed due to low confidence (4)
crates/ledger-core/src/ledger_ops.rs:1016
- Unresolved Git merge conflict markers in
PdfIngestOp::description()need to be resolved; as-is this will fail to compile.
fn description(&self) -> &str {
<<<<<<< Updated upstream
"Ingest a PDF statement file via the reqif-opa-mcp Python sidecar"
=======
"Ingest a PDF statement file via the reqif-opa-mcp Python sidecar (future/phase-2 — not yet implemented)"
>>>>>>> Stashed changes
crates/ledger-core/src/ledger_ops.rs:1028
- Unresolved merge conflict markers in
PdfIngestOp::execute()(both the full implementation and the NotImplemented stub are present). Resolve the conflict and keep only the intended behavior.
fn execute(&self, _ctx: &OperationContext) -> Result<OperationResult, LedgerOpError> {
<<<<<<< Updated upstream
use crate::classify::ClassificationEngine;
use crate::document::DocType;
use crate::ingest::TransactionInput;
crates/ledger-core/src/ledger_ops.rs:1276
- Unresolved merge conflict markers around the gate op types (
CedarGateOpvsOpaGateOp) will prevent compilation. Please resolve and ensure the correct struct/impl is present under the intended feature flags.
/// Gate classified transactions through AGT compliance before workbook commit.
///
<<<<<<< Updated upstream
/// Replaces OpaGateOp. Uses `LedgrrAgtGateway::compliance_report()` to determine
/// whether transactions should proceed to the workbook or be flagged for review.
#[cfg(feature = "cedar-policy")]
pub struct CedarGateOp;
crates/holon-viz/src/cytoscape.rs:16
holon-viztypes likeCytoscapeGraphare used inledgerr-hostTauri commands annotated with#[specta::specta], which requires these types to implementspecta::Type. Removing thespecta::Typederive here (and dropping the dependency inholon-viz/Cargo.toml) will break the Tauri build/type export. Consider restoringspecta::Typederives (possibly behind an optional feature) so downstream crates can continue using these types with tauri-specta.
/// Data payload for a Cytoscape.js node element.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CytoscapeNodeData {
pub id: String,
pub label: String,
pub kind: String,
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
972
to
976
| /// Ingest a PDF statement file via the external Python sidecar. | ||
| /// | ||
| <<<<<<< Updated upstream | ||
| /// Spawns the sidecar subprocess (`reqif-opa-mcp ingest --file <path> --output ndjson`), | ||
| /// reads NDJSON transaction candidates from stdout, runs the Rhai classification waterfall |
Comment on lines
+670
to
+674
| bash scripts/check-env-docs.sh | ||
|
|
||
| # Timed b00t maintenance probe for version/task/focus/audit surfaces. | ||
| b00t-maintenance-check budget="": | ||
| bash scripts/check-b00t-maintenance.sh {{ if budget == "" { "" } else { "--budget " + budget } }} |
Comment on lines
+30
to
+31
| TARGET_DIR = CRATE_DIR / "target" | ||
| DASHBOARD_HTML = TARGET_DIR / "ledgrrr-viz-dashboard.html" |
Comment on lines
+219
to
+229
| def cmd_regenerate(): | ||
| """Regenerate the dashboard HTML from the holon-viz crate.""" | ||
| vendor_dir = Path(__file__).parent | ||
| print("Rebuilding dashboard...") | ||
| result = subprocess.run( | ||
| ["cargo", "run", "-p", "holon-viz", "--bin", "holon-viz-demo"], | ||
| cwd=vendor_dir, | ||
| capture_output=True, | ||
| text=True, | ||
| timeout=300, | ||
| ) |
|
|
||
|
|
||
| def _run_server(port: int): | ||
| server = http.server.HTTPServer(("0.0.0.0", port), LedgrrrHTTPHandler) |
Comment on lines
513
to
+542
| #[test] | ||
| fn test_query_summary() { | ||
| // Use a temp dir to avoid loading existing records from the default path | ||
| let tmp = tempfile::tempdir().unwrap(); | ||
| let tmp_path = tmp.path().join("focus_records.json"); | ||
| std::env::set_var("FOCUS_SIDECAR_PATH", tmp_path.to_str().unwrap()); | ||
|
|
||
| reset_store_for_test(); | ||
| let input = FocusToolInput { | ||
| action: "query_focus_summary".into(), | ||
| records: vec![], | ||
| experiment_id: None, | ||
| personality: None, | ||
| }; | ||
| let output = handle_focus_tool(input).unwrap(); | ||
| assert!(output.experiment_summary.unwrap().contains("FOCUS")); | ||
| // With no appended records, summary should say "0 records stored" | ||
| let msg = output.experiment_summary.unwrap(); | ||
| assert!(msg.contains("FOCUS")); | ||
| assert!(msg.contains("0 records stored")); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_persistence_round_trip() { | ||
| // Use a temp dir so test data doesn't pollute the real sidecar | ||
| let tmp = tempfile::tempdir().unwrap(); | ||
| let tmp_path = tmp.path().join("focus_records.json"); | ||
| std::env::set_var("FOCUS_SIDECAR_PATH", tmp_path.to_str().unwrap()); | ||
|
|
||
| reset_store_for_test(); | ||
|
|
| The container runs `/usr/local/bin/ledgerr-mcp-server` (stdio MCP transport). | ||
| Mount `-v $PWD/data:/data` for workbook and PDF inbox. | ||
| Env vars: `LEDGER_WORKBOOK_PATH`, `LEDGER_PDF_INBOX`. | ||
| Env vars: `LEDGERR_WORKBOOK_PATH`, `LEDGER_PDF_INBOX`. |
Comment on lines
19
to
23
| "environmentVariables": [ | ||
| { | ||
| "name": "LEDGER_WORKBOOK_PATH", | ||
| "name": "LEDGERR_WORKBOOK_PATH", | ||
| "description": "Path to the Excel workbook (default: tax-ledger.xlsx in CWD)", | ||
| "isRequired": false, |
| COPY --from=builder /app/target/release/ledgerr-mcp-server /usr/local/bin/ledgerr-mcp-server | ||
|
|
||
| ENV LEDGER_WORKBOOK_PATH=/data/tax-ledger.xlsx | ||
| ENV LEDGERR_WORKBOOK_PATH=/data/tax-ledger.xlsx |
Comment on lines
1388
to
+1398
| #[test] | ||
| fn rotel_export_plan_reflects_bound_listener_address() { | ||
| let raw = "GET /rotel/export-plan HTTP/1.1\r\nHost: localhost\r\n\r\n"; | ||
|
|
||
| let response = | ||
| route_http_request_for_addr(raw.as_bytes(), &FixedBackend, None, "127.0.0.1:18081"); | ||
|
|
||
| assert!(response.starts_with("HTTP/1.1 200 OK")); | ||
| assert!(response.contains("\"logs_url\":\"http://127.0.0.1:18081/v1/logs\"")); | ||
| assert!(response.contains("\"metrics_url\":\"http://127.0.0.1:18081/v1/metrics\"")); | ||
| assert!(response.contains("\"traces_url\":\"http://127.0.0.1:18081/v1/traces\"")); | ||
| assert!(response.contains("\"logs_url\":\"http://127.0.0.1:4318/v1/logs\"")); | ||
| assert!(response.contains("\"metrics_url\":\"http://127.0.0.1:4318/v1/metrics\"")); | ||
| assert!(response.contains("\"traces_url\":\"http://127.0.0.1:4318/v1/traces\"")); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.