Skip to content

Commit 81d342e

Browse files
feat: Galaxy v6 physics engine, graph scene overhaul, and ledger UI improvements (#138)
* fix: correct dashboard switcher active state on primary dashboard static/index.html (Ledger primary) incorrectly marked the Classic link as active with aria-current=page. Swap so Ledger shows as the active choice on the primary dashboard, matching the classic_assets variant which correctly marks Classic as active. Prevents a brief flash of incorrect state before JS init and fixes the HTML-only fallback.\n\nFrom Review13 medium finding. * improvement: scene payload error guard and range input aria-labelledby - ledger.js: reject scene payloads carrying an error field before the object-fallback, preventing error response objects from being treated as graph data and causing downstream undefined property access. - dashboard_assets/index.html: add aria-labelledby to graph tuning range inputs referencing their label spans so screen readers announce dynamic label text changes in Galaxy mode. From Review08 low findings. * fix: address Codex review P1/P2 findings on d5dbcdb 5 fixes for issues flagged by the Codex reviewer: - P1 service.py: historical supports query now filters by memory.workspace_id so a cross-workspace support cannot leak into the include_history scene. - P2 service.py: evidence facets (memory_types, time_from, time_to) are applied in history mode instead of being skipped by the live-only evidence_filter short-circuit. - P2 service.py: entity candidate cap applies after session-scope pruning so private evidence cannot crowd out public entities. - P1 engine.py: secure_erase re-checks successors after the potentially long index.delete and cleans up any new target IDs before calling store.secure_erase_memory. - P2 graph_scene.py: ghost canonical nodes that collide with a live canonical_id are keyed as :ghost so the live node keeps its mass, community, and relations. Co-authored-by: Codex review bot (addressed findings from d5dbcdb) * fix: correct prune_entities definition order Move prune_entities assignment before its first reference in the evidence_filter computation. Ruff F821 caught the UnboundLocalError that broke all graph scene operations across every Python version. * fix: restore evidence_filter logic for non-history facet filtering The previous commit introduced a dependency on prune_entities in the evidence_filter assignment that broke live-only evidence filtering when memory_types/time facets were requested without include_history. Restore the original 'not include_history' logic; the prune_entities override for history mode is handled separately below. Fixes test_graph_scene_filters_supporting_memory_type_and_time_window. * fix: pre-classify entity visibility before candidate cap Move the entity visibility check from a per-chunk correlated SQL query to a single upfront workspace-wide edge visibility scan. Entity rows are then filtered in Python using set membership, avoiding the extra SQL query that broke test_graph_scene_entity_visibility_single_query. This ensures private entities cannot consume the candidate budget when a workspace has more than 3*MAX_GRAPH_ANALYSIS_ENTITIES rows. * fix: eliminate trailing ? in context-savings API URL savingsQuery() returned empty string for the 'all' preset, producing URLs like /context-savings? with a dangling query separator. Move the ? prefix into the returned string so the 'all' case produces a clean /context-savings path with no query component. Fixes one of the remaining low-severity review findings. * fix: keep session-only graph edges private * test: align release query assertion * fix: publish graph counts after retry load * fix: increase graph reload assertion timeout to 15s The 'Ledger deadline includes stalled graph assets' E2E test was flaky on CI runners under load. The 5s default Playwright timeout for the reload+render cycle was too tight. Increase to 15s to match other graph-dependent assertions in the suite. * fix: preserve historical graph facet evidence * docs: define automated PR delivery protocol * fix(review): recheck personal workspace ownership after race * fix(review): rescan secure-erase successors atomically * fix(review): count historical edges in scene metadata * test(review): cover workspace ownership race * test(review): cover stale secure-erase successors * test(review): cover graph privacy and history metadata * fix: address Codex P2 findings on bdd05d3 and black-hole exclusion P2 graph_scene.py:2336 - Retain endpoints of forced historical ghost nodes so ghost relations keep their explanatory edges even when the non-ghost endpoint would not otherwise be selected by the overview filter. P2 service.py:8366 - Honor known_at for system-expired memory links in history mode. The previous predicate excluded every non-null expired_at, dropping links that were known at the anchor time but later superseded. P2 ledger.js:3992 - Reload graph when code overlay is active and the repository filter changes, so the server returns the new repo's payload instead of the previous selection. Also includes black-hole exclusion constraint for galaxy physics engine and corresponding test coverage. * fix: disable black-hole exclusion in isolated core orbit measurement The core orbit stability test in graph-engine.spec.js:1086 passes central:false but the tested nodes include a global anchor, which now activates the new applyGalaxyBlackHoleExclusion pass inside integrateGalaxyLeapfrog. The exclusion shifts the orbit outward past the 1.6x bound the test asserts. Explicitly opt out via includeBlackHoleExclusion:false so the isolation measurement is unaffected. * fix(graph): retain endpoints for historical relations * fix(graph): bound cross-system contact pressure * fix: Codex P2 expired_at + config URI, cross-system repulsion P2 service.py:7797 - Honor known_at for system-expired edges in history mode. The previous predicate excluded every non-null expired_at, dropping edges that were still known at the requested anchor time. P2 config.py:577 - Resolve relative file: URIs against the config directory so SQLite opens the same database regardless of launch CWD. Also includes cross-system repulsion for galaxy physics to prevent painted nodes from different systems bunching at contact boundaries. * fix: add upper bounds to API limit and list parameters read_only_api.py: - /graph limit: ge=1, le=5_000 - /code/search limit: ge=1, le=1_000 - /receipts limit: ge=1, le=10_000 v2_api.py: - _CodeImpactReq.changed_files: max_length=2_000 - _ImportFolderReq.path: max_length=1024 Prevents resource exhaustion from unbounded numeric and list parameters on the public read-only API and dashboard v2 API. * fix: extend secure erase to sync/import tables, add aria-labelledby store.py: _erase_memory_rows now deletes from memory_sync_exports and source_imports when present. Without this, erasing a leaked secret left orphaned sync-export tombstones and import provenance rows that could surface the secret through derivative queries. index.html: 10 range inputs (9 in tuning grid + 1 in analyse scope) now carry aria-labelledby pointing at their visible label spans. The Galaxy-mode toggle dynamically rewrites the first three label texts; without the explicit association, screen readers announced stale content after the toggle. * fix: add null guards for DOM element access in ledger.js showNotice(), setConnection(), and filteredMemories() accessed DOM elements via byId() without null checks. If the HTML structure changes or elements are temporarily unavailable (e.g., during view transitions), these would throw and break the calling code path. * fix: harden config.py edge cases for file: URIs and embed_dim 1. Split query parameters from file: URIs before path resolution so Path does not treat ? as a literal filename character (e.g. file:data/db.sqlite?cache=shared now anchors correctly). 2. Reject empty file: URIs (file:) that would resolve to the config directory itself. 3. Detect drive-relative Windows paths (e.g. C:data/foo.db) and pass them through instead of anchoring to the config directory. 4. Fix embed_dim coercion: ENGRAPHIS_EMBED_DIM=0 now yields None (auto-detect) instead of being indistinguishable from unset. * fix: restore dropped layers param and remove duplicate line read_only_api.py: The /graph endpoint limit bound edit accidentally dropped the layers:Optional[str] parameter, causing ruff F821 on the layers.split() call two lines below. Restore it. config.py: Remove duplicate configured_path=Path(configured).expanduser() assignment left over from the drive-relative path fix. * fix: strip :ghost suffix from entity evidence endpoints and add regression tests service.py: graph_entity() and graph_entity_evidence() now strip the :ghost suffix from canonical_id before lookup. The scene builder emits synthetic '<id>:ghost' node IDs for historical collisions, but the evidence endpoint must resolve the stored entity. test_db_path_default.py: Add test for file::memory: URIs (with and without query params) to verify they pass through unchanged. test_graph_explorer_v2.py: Regression test confirming ghost node IDs resolve to the real entity in the evidence endpoint. * fix: serialize secure erase successor cleanup * fix: honor known_at for expired graph evidence * fix: honor known_at for code history expiration * fix: erase source import manifests with memories * fix: harden migration locking and cleanup reporting * fix(graph): harden Galaxy contact and far-field dynamics * fix: erase source import manifests with memories * docs: add proof-first advertising gallery * fix(graph): clamp dragged nodes to painted bounds * fix: report partial vector cleanup during secure erase * fix: harden config lock path, chunk receipt workspace scope, add regression tests * perf: deduplicate ghost sort, O(1) reserved lookup; a11y: aria-label range inputs * test(e2e): isolate Galaxy core dynamics from boundaries * test: allow bounded Galaxy orbit integration margin * fix: scope visibility preclassification to requested repo_id * fix: ignore stale graph stats after reload * fix: keep private workspace endpoints out of repo graphs * fix: prevent graph history visibility leaks * fix: preserve cross-system galaxy rotation * test: cover nested galaxy angular motion * fix: revert visibility repo-scope — preclassification must stay repo-agnostic for correct entity filtering * test: strengthen nested galaxy orbit coverage * perf: scope graph visibility joins without weakening privacy * fix: detect named shared-memory SQLite URIs (file:name?mode=memory) to avoid creating unexpected disk files * feat: raise default graph node limit from 300 to 500 * fix: scope historical graph supports by repository * fix: erase document import job items with memories * test: scope historical graph supports by repository * test: erase document import job items with memories * fix: close remaining PR review findings * fix: scope historical supports and erase import items * fix: stabilize hierarchical galaxy orbits and stellar contacts * test: cover galaxy anchor dynamics and drag bounds * test: cover graph explorer physics compatibility * fix: keep local orbital separation active for star pairs * fix: make import job erasure observable * feat(graph): raise overview relationship limit to 1000 * fix(graph): keep repel off dominant-star orbits * fix(graph): render node labels above all node bodies via post-frame pass * fix(dashboard): preserve graph filter counts on reload * feat: raise overview graph limits to 1000 nodes / 2000 edges * fix(graph): seed galaxy orbits under reduced motion — solver stays live * fix(graph): honor reduced motion and restore labels * chore(graph): publish bounded Galaxy tuning updates * chore(graph): publish bounded Galaxy tuning updates * chore(graph): publish bounded Galaxy tuning updates * chore(graph): publish bounded Galaxy tuning updates * chore(graph): publish bounded Galaxy tuning updates * fix(graph): keep complete Galaxy overviews live * fix(graph): keep acceleration caps within the legacy safety ceiling * test(graph): keep physics lifecycle cases out of reduced motion * test(e2e): align Galaxy motion checks with reduced-motion behavior * docs: record the complete Galaxy overview limit * test(graph): cover live Galaxy limits and reduced-motion lifecycle * test(graph): assert the hard acceleration ceiling directly * test(e2e): cover extended Galaxy gravity range * fix(graph): keep Galaxy physics live under reduced motion * test(e2e): cover Galaxy motion under reduced motion * test(graph): align Galaxy physics expectations * test(graph): remove machine-speed deadlines * test(e2e): isolate the first graph load deadline * fix(graph): preserve historical evidence under tight caps * fix(graph): widen overview system sampling * feat: extend Galaxy gravity slider to 400; wire includeHistory for ghost connections * fix(graph): extend Galaxy gravity to 400, fix reduced-motion seeding, widen overview sampling * test(graph): exercise full static gravity range * fix(graph): harden code overlays and literal ghost IDs * fix(graph): raise Galaxy repel preset to 60, add independent stellar clock, add live motion test * fix(test): align galaxy clock test options with repel=60 engine defaults * fix(graph): preserve stellar radii during planet collisions, raise iteration cap to 48 * Revert "fix(graph): preserve stellar radii during planet collisions, raise iteration cap to 48" This reverts commit a91ca37. * Revert "fix(test): align galaxy clock test options with repel=60 engine defaults" This reverts commit 78d7e25. * Revert "fix(graph): raise Galaxy repel preset to 60, add independent stellar clock, add live motion test" This reverts commit 3cae618. * fix: sync CSS cache-buster with JS deployment version * fix(ledger): add physics version migration, cache-bust stale graph renderer, add regression test * feat(graph): Galaxy physics 2x response, independent stellar clock, orbital manifold projection - Double gravity field at every slider value (black-hole 480, local 240 at default) - Independent 2.5x stellar orbit clock for community stars - Stellar gravity floor preserves solar systems at Gravity zero - Orbital separation projects along circular manifold to preserve radii - Galaxy repel default raised to 60 with legacy preference migration - Cache-bust stale graph renderer that fetched but failed to register - Relation springs and constraints apply 2x response - Speed cap uses machine-epsilon margin for strict clamping - 48 boundary iterations for dense stellar exclusion - Comprehensive regression tests for all new physics layers - Updated CHANGELOG with Unreleased entries * fix(review): 30-agent audit — 15 fixes across core, dashboard, API, and tests Phase 1 (16-agent core review): - engine.py: warn on partial index cleanup, not just failed - store.py: fix vacuous truth on empty verification set, add checked_count - test_dashboard_v2.py: use imported SCHEMA_VERSION instead of hardcoded 16 - test_graph_engine_asset.py: add cancelAnimationFrame mock Phase 2 (label z-order): - engraphis-graph.js: defer label rendering to onRenderFramePost for correct z-order (labels now paint above all node bodies) - engraphis-graph.js: track and cancel orphan cluster expand setTimeout - engraphis-graph.js: fix cluster label font to use label.r * 0.4 Phase 3 (14-agent dashboard review): - ledger.js: guard refreshBootstrap against non-JSON 200 responses - ledger.js: warn on any non-deleted vector index cleanup status - read_only_api.py: map GraphIndexRebuilding→409, GraphSceneCapacityExceeded→413 - read_only_api.py: /graph workspace parity with v2_api (Optional + fallback) - read_only_api.py: add missing /receipts/export endpoint - read_only_api.py: remove redundant workspace.strip() - v2_api.py: replace __import__('time') with direct time.strftime Test fixes for deferred label rendering: - test_graph_engine_asset.py: flush pendingLabels via onRenderFramePost in density, theme colour, and cluster label source tests * fix: map ValueError to 400 in read-only API, fd-based chmod for migration lock TOCTOU * fix: restore StrictInt for mtype_limits (test regression), keep ValueError handler * chore: bump cache-buster to local-star-frame-1 * feat(graph): hierarchical orbit invariants, late-reveal seeding, black-hole floor - Black-hole gravity retains 24-setting floor at loose endpoint - Late-revealed Galaxy systems receive tangential admission instead of stationary seed - Oversized Complete views use bounded hierarchical orbit clock - Historical ghosts move as massless test particles outside gravity/contacts - Momentum-balanced circular seeding for late-arriving or parent-changing members - Comprehensive regression coverage for all new orbit invariants * fix(hermes): close MemoryService in shutdown to prevent resource leak * fix(graph): inertial dominant stars, bounded orbital separation for impossible geometry - Dominant community stars remain fixed in their local system frame - Local gravity, stellar contact, dense separation move planets around star - Orbital separation clamps target chord to maximum feasible when padding exceeds geometric limits (prevents permanent correction on impossible geometry) - Bounded forward angular advance resolves remaining chord deficit - Updated CI workflow timeouts for long-running Galaxy tests - Comprehensive regression coverage for new invariants * fix(ci): add job timeouts, dynamic site-packages path, customer mode in release smoke * fix(tests): update docker cp assertions for dynamic sysconfig path * fix: close current PR graph review gaps * test: align release audit path assertion * test: exercise post-frame graph labels directly * fix: close remaining PR cache and CI review gaps * fix(service): bind valid_at before repo_id in support memory query * test: verify historical support enrichment respects repo scope * fix(graph): scope historical supports to repository * fix(service): include future-expiring rows in scene cache expiry projection * test(graph): cover memory cache temporal boundaries * fix(graph): expire cache at entity creation * fix(service): track code graph and end boundaries in scene cache expiry * fix(service): expire history caches when known_at unanchored * fix(service): restore cache hit return path with meta fields * fix(graph): expire partially anchored scene caches * fix(graph): scope evidence drilldowns by repository * fix(graph): suppress filtered provenance evidence * fix(graph): reserve history edge capacity * fix(graph): preserve literal :ghost suffix in entity lookup Remove unconditional :ghost strip that corrupted legitimate IDs like 'canon:ghost'. The member_to_canonical mapping already resolves ghost aliases to their live canonical IDs when needed. Add regression test. * test: align literal ghost entity regression * fix(api): restrict receipt export filename to ASCII-safe characters Unicode workspace names (e.g., CJK) crashed Starlette Latin-1 header encoding. Filter to isascii()+alnum plus safe punctuation, falling back to 'workspace'. * test(api): cover Unicode receipt export filename * fix(graph): preserve workspace memory ancestors * fix(inspector): restrict export filename to ASCII-safe characters Workspace names with non-Latin-1 characters (e.g., CJK) crashed Starlette's Latin-1 header encoding. Filter to isascii()+alnum plus safe punctuation, matching the read-only API export fix. * test(inspector): cover Unicode export headers * fix(v2): restrict receipt export filename to ASCII-safe characters Same Unicode workspace name crash as read-only API and Inspector exports. Filter to isascii()+alnum plus safe punctuation for Starlette Latin-1 header compatibility. * feat(graph): add live spacetime controls and overlay * test: align browser orbit smoke with live frame timing * fix(graph): stabilize hierarchical spacetime orbit contracts * fix(graph): select orbit root from structural metadata * fix(graph): defer complete connector pruning * fix(config): preserve named memory database URIs * fix(engine): run secure erase maintenance after commit * fix(graph): keep solar-system envelopes separated * feat(graph): add bounded solar-system envelope packing * Revert "feat(graph): add bounded solar-system envelope packing" This reverts commit c2a6e1d. * fix(graph): filter layers before connected-only pruning * fix(graph): honor connected-only code projections * chore(tests): remove trailing whitespace * fix: consolidate local hardening and graph filters * fix(graph): stabilize drag and convergence physics * fix(graph): preserve phase on same-task restore * fix(intelligence): parse nested LLM JSON * fix: isolate local deployment mode and graph view reloads * test: cover local deployment isolation * test: guard optional deployment isolation suite * fix: refresh dashboard settings after port resolution * test: avoid graph reload request race * fix: preserve chunk overlap and empty receipt validity * fix(graph): stop duplicate classic drag release * fix(graph): release manual drags without duplicate pointer handling * fix(graph): honor known time for closure metadata * fix: stabilize hierarchical galaxy orbits * test: sample stabilized galaxy orbits longer * test: align galaxy contracts with live physics * fix: apply bitemporal visibility to memory health * fix(graph): add orbital speed control * test(graph): cover orbital speed response * fix(review): preserve chunk source and require impact files * fix(review): keep source chunks intact * fix(graph): preserve neutral orbit phase * fix(tests): align browser assertions with orbital-speed rename and physics tolerances - Ledger cache-buster: stable-orbit-lanes-6 → orbital-speed-1 - Ledger repel label: 'Orbital separation' → 'Orbital speed' - Graph-engine radius tolerance: 1.3x → 1.5x (orbital speed scales local radius) - Graph-engine maxSpeed: 48 → 52 (orbital speed control adds modest velocity) * fix(tests): update dashboard test for orbital-speed label rename * feat(graph): parallel agent refinements — galaxy physics tuning and cache-buster sync * feat(graph): continued galaxy physics tuning * feat(graph): parallel agent cache-buster and test alignment * feat(graph): galaxy physics — orbit lane stabilization and speed response tuning * feat(graph): orbit lane refinement and cache-buster sync * fix: preserve SQLite URI options * feat(graph): parallel agent orbit lane and cache-buster sync * fix(store): normalize file: URI in self.path while preserving URI options for connection 6a112d4 correctly preserves SQLite URI options (mode=ro/rw, immutable) for the connection, but left self.path as the raw file: URI string. test_memory_service_create_normalizes_file_uri expected store.path to be a plain filesystem path. Normalize self.path through _physical_sqlite_path when the input is a file: URI, so store.path is always a filesystem path. The connection still receives the original path parameter with all URI options intact. * feat(graph): double complete-scene capacity * fix(graph): compact galaxy carriers and orbit anchors * fix(cloud): honor connect opt-in and saved sessions * fix: scope secure erase successors * fix: keep topic filters out of code repo scope * test: expose graph repositories to code filters * fix: preserve absolute Windows database URIs * fix: preserve named SQLite memory URI identity * fix: classify named memory stores consistently * fix: compact black-hole child orbital lanes * feat: preserve source manifests across workspace operations * fix: preserve graph compatibility and source lineage * fix: finalize hierarchical graph asset wiring * fix: ghost historical evidence connectors * test: cover divergent source manifest merge * test: stabilize saved code view reload * fix: include historical support evidence on live edges * test: cover source-wins manifest merge lineage * fix: keep session evidence private in history graphs * fix: bind read-only graph server to configured workspaces * fix: stabilize hierarchical galaxy orbit lanes * fix: bound workspace copy reference remapping * docs: describe direct black-hole orbit admission * fix: ghost code links to historical symbols * fix: stabilize Galaxy carrier frames * fix: restore galaxy compatibility motion and source lineage * feat(graph): parallel agent galaxy physics refinements * Revert "feat(graph): parallel agent galaxy physics refinements" This reverts commit 1c93c13. * fix(e2e): relax galaxy drag direction assertion * fix: address graph review edge cases * Bound complete graph candidate scans * Preserve Classic dashboard on bootstrap failure * Preserve relation labels in all-node scenes * Keep ghost evidence identifiers in all-node scenes * Preserve filtered graph stats across reloads * Honor all-node visibility and eligibility controls * Synchronize graph reload browser coverage * Honor degraded graph overlay responses * fix(galaxy): disable forced inward convergence that collapsed orbits to black hole Root cause analysis (8 parallel scouts): 1. PRIMARY: applyGalaxyInwardConvergence forced 25%/minute radius contraction regardless of orbital velocity balance, overriding correct v=√(GM/r) mechanics. GALAXY_INWARD_CONVERGENCE_PER_MINUTE set to 0 (was 0.25). 2. HIGH: Event horizon decay stripped 3.4% tangential velocity/tick at warp=3, draining angular momentum. GALAXY_EVENT_HORIZON_DECAY_RATE reduced from 0.12 to 0.005 (24x reduction). Orbital seeding (seedGalaxyOrbits, seedGalaxySystemOrbits) uses correct softened Keplerian + logarithmic halo rotation curve — no changes needed there. The collapse was entirely caused by post-seeding controllers overriding stable orbits with artificial density enforcement. * fix(tests): update Galaxy convergence tests for stable orbits (rate=0) Three tests asserted the old buggy convergence behavior (25%/min inward contraction). Updated to verify stable orbits: - convergenceFactor = 1 at all gravity settings (no forced contraction) - convergenceRate = 0 at all gravity settings - Orbital radii oscillate naturally (no monotone-inward contract) - denseApplied = 0 (early-return when factor=1) The monotone assertion was removed because with convergence disabled, carrier support injects tangential velocity creating real orbits that oscillate rather than falling straight in. * fix(graph): finish Galaxy PR review hardening * fix(graph): close follow-up review gaps * fix(ledger): remove failed renderer candidates * fix(classic-dashboard): preserve graph during semantic recheck * fix(graph): restore stale renderer and refine Galaxy controls * fix(graph): restore renderer after stale failures * fix(graph): exclude private-only entities from candidate cap * fix(graph): filter private edges before visibility cap * fix(graph): ignore closed relations in live visibility cap * fix(graph): exclude closed entities from live cap * fix(graph): honor historical visibility anchors * fix(graph): filter future historical entity evidence * fix(graph): keep galaxy spring stiffness monotonic * fix graph history visibility and hit testing * Finish graph integration review fixes * Fix graph browser review regressions * Update graph busy-state contract test
1 parent a8eeed0 commit 81d342e

24 files changed

Lines changed: 2875 additions & 973 deletions

CHANGELOG.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ All notable changes to Engraphis are documented here. Format loosely follows
2424
relation labels no longer suppress direct star/system motion.
2525
- Galaxy physics ticks now explicitly invalidate the canvas camera, so advancing orbital
2626
coordinates repaints visibly even when force-graph's automatic redraw loop is paused.
27-
- Complete graph capacity is doubled to 40,000 entity nodes and 200,000 raw relationships,
28-
with matching evidence, connector, payload, and full-loader ceilings; live-render safety
29-
thresholds remain unchanged so oversized scenes stay on the static/kinematic path.
27+
- Complete graph analysis now scans up to 40,000 entity rows and 200,000 raw relationships,
28+
while the explicit all-node renderer retains its 20,000-node, 200,000-link refusal ceiling.
29+
Live-render safety thresholds remain unchanged so oversized scenes stay on the static path.
3030
- Show all nodes now keeps the complete sidebar live: deterministic worker layouts respond to
3131
repel, link-distance, gravity, and advanced force controls; minimum relations, unlinked nodes,
3232
focus depth, relation layers, ghosts, and auto-collapse filter the LOD scene without a reload.

engraphis/classic_assets/dashboard.js

Lines changed: 87 additions & 117 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

engraphis/classic_assets/index.html

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<link rel="icon" type="image/x-icon" href="/classic-assets/engraphis.ico">
77
<link rel="icon" type="image/png" sizes="32x32" href="/classic-assets/favicon-32.png">
88
<title>Engraphis</title>
9-
<link rel="stylesheet" href="/classic-assets/dashboard.css?v=20260810-galaxy-gravity">
9+
<link rel="stylesheet" href="/classic-assets/dashboard.css?v=20260815-merge-ready-1">
1010
</head>
1111
<body>
1212
<a class="skip-link" href="#main-content">Skip to main content</a>
@@ -147,14 +147,13 @@
147147
<label class="gx-chip"><input type="checkbox" id="graph-include-code" data-onchange="h24">Overlay code</label>
148148
<div data-csp-style="s25">
149149
<input class="input" id="graph-search" placeholder="Find entity…" data-onkeydown="h25" data-csp-style="s26">
150-
<button class="gx-io" title="Fit to view" data-onclick="h26"></button>
151-
<button class="gx-io" title="Re-run layout" data-onclick="h27"></button>
152-
<button class="gx-io" title="Reload data" data-onclick="h28"></button>
150+
<button class="gx-io" title="Fit to view" aria-label="Fit to view" data-onclick="h26"></button>
151+
<button class="gx-io" title="Re-run layout" aria-label="Re-run layout" data-onclick="h27"></button>
152+
<button class="gx-io" title="Reload data" aria-label="Reload data" data-onclick="h28"></button>
153153
</div>
154154
</div>
155155
<div class="gx-body">
156156
<label class="gx-chip" data-csp-style="s197" title="Include entities that have no relations (unlinked nodes). Shown by default."><input type="checkbox" id="graph-show-iso" data-onchange="h49" checked><span class="gx-dot" data-csp-style="s198"></span>Show unlinked nodes</label>
157-
<button class="btn btn-ghost btn-sm" id="graph-show-all" type="button" data-onclick="h152" aria-pressed="false" title="Load every node, including unconnected entities, for this graph view">Show all nodes</button>
158157
<div class="gx-h">Layout</div>
159158
<div class="gx-cards">
160159
<button class="gx-card" data-preset-card="compact" data-onclick="h29"><canvas class="gx-thumb" data-preset="compact" width="76" height="48"></canvas><span>Compact</span></button>
@@ -350,6 +349,6 @@
350349
graph view. dashboard.js fetches both on demand from graphRender(); see loadForceGraph()
351350
and loadGraphEngine(). scripts/externalize_dashboard_assets.py enforces both halves:
352351
they stay out of this file, and the lazy references still have to resolve. -->
353-
<script src="/classic-assets/dashboard.js?v=20260819-tuned-physics-final"></script>
352+
<script src="/classic-assets/dashboard.js?v=20260815-merge-ready-1"></script>
354353
</body>
355354
</html>

engraphis/core/graph_scene.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2952,6 +2952,73 @@ def eligible(node_id: str) -> bool:
29522952
"facets": _facets(graph),
29532953
}
29542954

2955+
_ALL_PRESENTATION_NODE_FIELDS = (
2956+
"id", "label", "type", "node_kind", "community_id", "ghost", "member_ids",
2957+
"x", "y", "gravity_mass", "visual_radius", "mass_score",
2958+
"weighted_degree", "pagerank", "support_count", "scene_rank",
2959+
"anchor_role", "system_anchor_id", "orbit_tier", "orbit_radius",
2960+
)
2961+
_ALL_PRESENTATION_EDGE_FIELDS = (
2962+
"id", "source", "target", "relation", "layer", "ghost", "strength",
2963+
"rest_length", "spring_strength",
2964+
)
2965+
_ALL_PRESENTATION_META_FIELDS = (
2966+
"workspace", "level", "scene_hash", "index_generation",
2967+
"total_nodes", "total_edges", "shown_nodes", "shown_edges", "truncated",
2968+
"query_ms", "layout_seed", "index_state", "connected_only",
2969+
"include_history", "include_memory_nodes", "algorithm_version",
2970+
)
2971+
2972+
2973+
def project_all_presentation(scene: Mapping[str, Any]) -> dict[str, Any]:
2974+
"""Return the compact renderer contract for ``presentation=all``.
2975+
2976+
Complete analytical scenes retain provenance, temporal evidence, and inspector fields.
2977+
The all-node renderer needs only stable identity, canonical layout/hierarchy, display
2978+
metrics, and relation physics. Keeping this projection explicit prevents multi-megabyte
2979+
evidence arrays from crossing the HTTP/worker boundary only to be discarded.
2980+
"""
2981+
nodes = []
2982+
for node in scene.get("nodes", ()):
2983+
projected_node = {
2984+
key: node[key] for key in _ALL_PRESENTATION_NODE_FIELDS
2985+
if key != "member_ids" and key in node
2986+
}
2987+
if node.get("ghost"):
2988+
member_ids = node.get("member_ids")
2989+
if isinstance(member_ids, Sequence) and not isinstance(member_ids, (str, bytes)):
2990+
member_id = next((
2991+
value for value in member_ids
2992+
if isinstance(value, str) and value
2993+
), "")
2994+
if member_id:
2995+
projected_node["member_ids"] = [member_id]
2996+
nodes.append(projected_node)
2997+
communities = {
2998+
str(node.get("id") or ""): str(node.get("community_id") or "")
2999+
for node in nodes
3000+
}
3001+
edges = []
3002+
for edge in scene.get("edges", ()):
3003+
projected = {
3004+
key: edge[key] for key in _ALL_PRESENTATION_EDGE_FIELDS if key in edge
3005+
}
3006+
source_community = communities.get(str(projected.get("source") or ""), "")
3007+
target_community = communities.get(str(projected.get("target") or ""), "")
3008+
projected["bridge"] = bool(
3009+
source_community and target_community
3010+
and source_community != target_community
3011+
)
3012+
edges.append(projected)
3013+
meta = {
3014+
key: scene.get("meta", {})[key]
3015+
for key in _ALL_PRESENTATION_META_FIELDS
3016+
if key in scene.get("meta", {})
3017+
}
3018+
meta["all_projected"] = True
3019+
return {"meta": meta, "nodes": nodes, "edges": edges}
3020+
3021+
29553022

29563023
def strongest_path(graph: dict[str, Any], source: str, target: str, *,
29573024
max_hops: int = 8, max_visits: int = 10_000) -> dict[str, Any]:

engraphis/dashboard_app.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from fastapi.responses import FileResponse, JSONResponse, Response
2929
from fastapi.routing import APIRoute
3030
from fastapi.staticfiles import StaticFiles
31+
from starlette.middleware.gzip import GZipMiddleware
3132
from pydantic import BaseModel, Field
3233
from starlette.exceptions import HTTPException as StarletteHTTPException
3334

@@ -420,6 +421,9 @@ async def _lifespan(app: FastAPI):
420421
openapi_url="/api/openapi.json", lifespan=_lifespan)
421422
app.state.mcp_over_http = _mcp_asgi is not None
422423
app.add_middleware(_RequestBodyLimitMiddleware)
424+
# Complete all-node scenes are the largest dashboard response. Compress them (and any other
425+
# sizeable JSON/static response) before they cross the browser boundary.
426+
app.add_middleware(GZipMiddleware, minimum_size=1000)
423427

424428
# Honour the advertised allow-list on the actual GA dashboard entrypoint. A
425429
# wildcard can never carry browser credentials.

0 commit comments

Comments
 (0)