Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
544aaa6
fix(dashboard): refine galaxy layout and physics response
Coding-Dev-Tools Sep 6, 2026
6c23174
fix(dashboard): address Galaxy review findings
Coding-Dev-Tools Sep 6, 2026
3cfeda4
fix(dashboard): address follow-up review findings
Coding-Dev-Tools Sep 6, 2026
dfef126
fix(dashboard): stabilize authored Galaxy orbit lanes
Coding-Dev-Tools Sep 7, 2026
9cfd3b3
fix(dashboard): preserve Galaxy lane and orbit invariants
Coding-Dev-Tools Sep 7, 2026
fc9155a
fix(release): prepare Engraphis 1.7.3
Coding-Dev-Tools Sep 7, 2026
1d29a7b
fix(graph): cap nested kinematic orbit speeds
Coding-Dev-Tools Sep 7, 2026
3a30df2
test(browser): normalize orbit movement by fixed steps
Coding-Dev-Tools Sep 7, 2026
3076de0
fix(graph): honor local gravity speed increases
Coding-Dev-Tools Sep 7, 2026
176448c
fix(graph): preserve stable initial orbit phase
Coding-Dev-Tools Sep 7, 2026
a37b882
fix(graph): budget nested orbit headroom dynamically
Coding-Dev-Tools Sep 7, 2026
dc1e517
fix(graph): bound central endpoint and diagnostics
Coding-Dev-Tools Sep 7, 2026
c2f0acb
fix(graph): keep live lane physics and cap diagnostics aligned
Coding-Dev-Tools Sep 7, 2026
0f875d0
fix(graph): invalidate physics snapshot after drag release
Coding-Dev-Tools Sep 8, 2026
6faf747
Merge origin/main into codex/local-unmerged-20260906
Coding-Dev-Tools Sep 8, 2026
b0654bc
fix(graph): address follow-up review findings
Coding-Dev-Tools Sep 8, 2026
09d59b5
fix(graph): enforce painted fallback horizon
Coding-Dev-Tools Sep 8, 2026
3ff56c4
fix(dashboard): align pending Galaxy motion controls
Coding-Dev-Tools Sep 8, 2026
cfd5935
test: stabilize promoted history timestamps
Coding-Dev-Tools Sep 8, 2026
08452fb
fix(dashboard): preserve orbit budgets and colour controls
Coding-Dev-Tools Sep 8, 2026
76ddda3
fix(dashboard): cap kinematic phase before advancing
Coding-Dev-Tools Sep 8, 2026
eed3e29
fix(graph): space homogeneous galaxy tiers by local slots
Coding-Dev-Tools Sep 8, 2026
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
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"name": "engraphis-memory",
"source": "./",
"description": "Discipline for giving agents durable, scoped, explainable memory across sessions and repos with the Engraphis MCP tools.",
"version": "1.7.2"
"version": "1.7.3"
}
]
}
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "engraphis-memory",
"version": "1.7.2",
"version": "1.7.3",
"description": "Give agents durable, scoped, explainable memory across sessions and repos via the Engraphis MCP tools. Use when you learn something worth keeping, need prior context before acting, or ask why/how a fact changed. Covers remember/recall, why/timeline, forget/pin/correct, sessions, and code search.",
"author": {
"name": "The Engraphis Authors",
Expand Down
4 changes: 2 additions & 2 deletions .claude-plugin/skill-assets.sha256
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
595a395f048219beb8dd741443b17d889e725effa91bf3f20578bbe497f5d55e .claude-plugin/marketplace.json
8294e6c2de066bd7dee01251cea42d301904cbf94a17cf8f884b26f0a67f7dc0 .claude-plugin/plugin.json
1731b35c796e5ac26d7e4c7c9b77b2640d6e7478006d2c67a155f66df70bb50a .claude-plugin/marketplace.json
4b2453788ff35f0c46eb8d0cd4c2491ca9352fc4bae96ee81a4c330f2709ac77 .claude-plugin/plugin.json
4bc8979b9ffeb97190960e551dbf4ddc6f7aeeb7b86894fd2298a59ff0001efa skills/engraphis-memory/SKILL.md
055655db84af07561d002f0c69744313d8413c39f3e873f941f0fa0b1e76dc66 skills/engraphis-memory/references/CONVENTIONS.md
62019760766ff472a76a0f81437898f39e3c1fe2631732b7b7733e50c1ad837f skills/engraphis-memory/references/SCOPING.md
Expand Down
46 changes: 33 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Changelog

All notable changes to Engraphis are documented here. Format loosely follows
[Keep a Changelog](https://keepachangelog.com/); versions use SemVer.
## [Unreleased]
- Added schema 18 content-free command receipts and cross-process source revalidation for
corrections, approvals, promotions and merges. Combined memory revisions have expected
versions, operation IDs, atomic metadata/history, and typed conflicts.
- Sync publication uses current canonical state and generation-aware repair; delayed work
cannot restore erased vectors. Native-index failures roll back canonical changes.
- Context retains distinct scoped evidence; synthesis falls back when complete source
units, titles, values or conditions are lost. Answer coverage defaults to unknown.
[Keep a Changelog](https://keepachangelog.com/); versions use SemVer.

## [Unreleased]

- Added schema 18 content-free command receipts and cross-process source revalidation for
corrections, approvals, promotions and merges. Combined memory revisions have expected
versions, operation IDs, atomic metadata/history, and typed conflicts.
- Sync publication uses current canonical state and generation-aware repair; delayed work
cannot restore erased vectors. Native-index failures roll back canonical changes.
- Context retains distinct scoped evidence; synthesis falls back when complete source
units, titles, values or conditions are lost. Answer coverage defaults to unknown.
- Added project-aware memory workflows and paginated record history.
- Library cursors survive unrelated activity and work across processes. File-backed
browsing uses bounded live read snapshots; completed graph migrations are not
Expand All @@ -21,8 +21,28 @@ All notable changes to Engraphis are documented here. Format loosely follows
- Added content-free diagnostics and build/capability information, strict coding
acceptance validation and a file-backed independent-process capacity harness.
These provide measurement infrastructure, not verified 100k capacity claims.

## [1.7.2] - 2026-09-05

## [1.7.3] - 2026-09-07

### Fixed

- Preserved Galaxy carrier lane and kinematic orbit invariants through central-field slider
changes, including the global and core cached radii used by the next fixed slice.
- Refreshed the retained local orbital speed budget when the effective local-gravity control
changes, preventing a stale phase cache from masking the slider.
- Kept high-density Galaxy layouts inside the strict speed cap while maintaining authored
carrier and nested local orbit phase.
- Bounded the zero central-gravity radius response so finite far-field envelopes cannot leave
oversized kinematic carrier caches behind, and counted fallback speed-cap activations.
- Bumped the deterministic Galaxy scene algorithm identity to `galaxy-v13-responsive-compact-orbits`
so cached layouts cannot be confused with the revised placement contract.

### Tests

- Added deterministic regressions for central-field cache scaling and local-gravity phase
invalidation, alongside the existing 500-body and browser accessibility coverage.

## [1.7.2] - 2026-09-05

### Added

Expand Down
4 changes: 2 additions & 2 deletions engraphis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from importlib.metadata import PackageNotFoundError, version as _dist_version

_SOURCE_VERSION = "1.7.2"
_SOURCE_VERSION = "1.7.3"

try:
__version__ = _dist_version("engraphis")
Expand All @@ -14,7 +14,7 @@
except PackageNotFoundError: # source tree without an installed distribution
# Keep in step with [project] version in pyproject.toml — tests/test_packaging.py
# pins the two together so a release cannot ship them out of sync.
__version__ = "1.7.2"
__version__ = "1.7.3"


def _default_memory_engine_factory(**kwargs):
Expand Down
2 changes: 1 addition & 1 deletion engraphis/commercial_manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema": "engraphis-commercial/v2",
"version": "1.7.2",
"version": "1.7.3",
"control_plane": "https://api.engraphis.com",
"account_portal": "https://api.engraphis.com/account",
"billing": {
Expand Down
192 changes: 150 additions & 42 deletions engraphis/core/graph_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from typing import Any, Iterable, Mapping, Optional, Sequence


ALGORITHM_VERSION = "galaxy-v12-responsive-compact-orbits"
ALGORITHM_VERSION = "galaxy-v13-responsive-compact-orbits"
PUBLIC_REFERENCE_ID_LIMIT = 200
PUBLIC_FACET_LIMIT = 100
PUBLIC_REPO_NAME_LIMIT = 100
Expand Down Expand Up @@ -707,47 +707,155 @@ def _community_positions(
# survive the overview cap. Rank-based assignment (rank/N) fails when only the top-K
# by mass are shown — they occupy a tight arc instead of spreading evenly.
GOLDEN_ANGLE_RAD = math.pi * (3.0 - math.sqrt(5.0))
orbital_rank = 0
for community in ordered:
community_id = str(community["id"])
system_radius = _clamp(
_finite_float(community.get("radius"), 36.0), 36.0, 10_000.0
)
if community_id == global_community_id:
non_global = [c for c in ordered if str(c["id"]) != global_community_id]
non_global_count = len(non_global)
Comment thread
Coding-Dev-Tools marked this conversation as resolved.

if non_global_count <= 1:
orbital_rank = 0
for community in ordered:
community_id = str(community["id"])
system_radius = _clamp(
_finite_float(community.get("radius"), 36.0), 36.0, 10_000.0
)
if community_id == global_community_id:
specs.append({
"id": community_id, "system_radius": system_radius,
"arm": -1, "nominal_x": 0.0, "nominal_y": 0.0,
})
continue
arm = orbital_rank % arm_count if arm_count > 0 else 0
digest = hashlib.sha256(
f"{ALGORITHM_VERSION}:{layout_seed}:system:{community_id}".encode("utf-8")
).digest()
# Small angular jitter for visual variety; kept tight so even spacing dominates.
angular_jitter = (
int.from_bytes(digest[:4], "big") / float(1 << 32) - 0.5
) * 0.06
radial_jitter = 0.95 + (
int.from_bytes(digest[4:8], "big") / float(1 << 32)
) * 0.10
# Golden-angle based placement: each successive system advances by ≈137.5°.
# This guarantees that any contiguous or sampled subset fills the circle evenly.
golden_angle = base_phase + orbital_rank * GOLDEN_ANGLE_RAD
angle = golden_angle + angular_jitter
# Ring radius clears the core envelope. Inter-system clearance is handled
# per-pair in the collision pass using actual radii, not a pessimistic global max.
baseline_radius = max(
core_clearance_radius,
spacing * 0.90 * radial_jitter,
)
specs.append({
"id": community_id, "system_radius": system_radius,
"arm": -1, "nominal_x": 0.0, "nominal_y": 0.0,
"id": community_id,
"system_radius": system_radius,
"arm": arm,
"nominal_x": baseline_radius * math.cos(angle),
"nominal_y": baseline_radius * math.sin(angle),
})
continue
arm = orbital_rank % arm_count if arm_count > 0 else 0
digest = hashlib.sha256(
f"{ALGORITHM_VERSION}:{layout_seed}:system:{community_id}".encode("utf-8")
).digest()
# Small angular jitter for visual variety; kept tight so even spacing dominates.
angular_jitter = (
int.from_bytes(digest[:4], "big") / float(1 << 32) - 0.5
) * 0.06
radial_jitter = 0.95 + (
int.from_bytes(digest[4:8], "big") / float(1 << 32)
) * 0.10
# Golden-angle based placement: each successive system advances by ≈137.5°.
# This guarantees that any contiguous or sampled subset fills the circle evenly.
golden_angle = base_phase + orbital_rank * GOLDEN_ANGLE_RAD
angle = golden_angle + angular_jitter
# Ring radius clears the core envelope. Inter-system clearance is handled
# per-pair in the collision pass using actual radii, not a pessimistic global max.
baseline_radius = max(
core_clearance_radius,
spacing * 1.10 * radial_jitter,
orbital_rank += 1
else:
# Multi-tiered concentric orbital lanes: distribute communities across radial bands
# (inner, mid-inner, mid-outer, outer) filling the 2D disk from the core clearance radius
# outward. Each tier accommodates as many systems as geometrically fit without overlap
# before placing subsequent systems on the next radial tier, interleaved with golden-angle
# angular offsets. This prevents all star systems from colliding onto a single outer hoop.
for community in ordered:
if str(community["id"]) == global_community_id:
system_radius = _clamp(
_finite_float(community.get("radius"), 36.0), 36.0, 10_000.0
)
specs.append({
"id": str(community["id"]), "system_radius": system_radius,
"arm": -1, "nominal_x": 0.0, "nominal_y": 0.0,
})
break

avg_sys_radius = sum(
_clamp(_finite_float(c.get("radius"), 36.0), 36.0, 10_000.0)
for c in non_global
) / non_global_count
tier_step = max(spacing * 0.65, 2.0 * avg_sys_radius + GALAXY_SYSTEM_MIN_GAP * 0.35)

tiers: list[dict[str, float | int]] = []
curr_radius = core_clearance_radius + avg_sys_radius
Comment thread
Coding-Dev-Tools marked this conversation as resolved.
remaining = non_global_count
while remaining > 0:
circ = 2.0 * math.pi * curr_radius
envelope_size = 2.0 * avg_sys_radius + GALAXY_SYSTEM_MIN_GAP * 0.35
capacity = max(2, int(circ / envelope_size))
take = min(capacity, remaining)
tiers.append({
"radius": curr_radius,
"count": take,
})
remaining -= take
curr_radius += tier_step

# Homogeneous systems can share a true tier-local lattice: using the actual slot
# count keeps every lane's angular gaps consistent and avoids radial fallback when
# several similarly sized systems sit close to the core. Heterogeneous envelopes
# retain the scene-wide low-discrepancy carrier so a large system does not create a
# regular angular wall for the smaller systems. A three-or-more-tier scene is also
# compact enough that local lane spacing is the safer choice even with modest size
# variation.
non_global_radii = [
_clamp(_finite_float(c.get("radius"), 36.0), 36.0, 10_000.0)
for c in non_global
]
homogeneous_envelopes = (
max(non_global_radii, default=0.0) - min(non_global_radii, default=0.0)
<= max(2.0, avg_sys_radius * 0.08)
)
specs.append({
"id": community_id,
"system_radius": system_radius,
"arm": arm,
"nominal_x": baseline_radius * math.cos(angle),
"nominal_y": baseline_radius * math.sin(angle),
})
orbital_rank += 1
use_tier_local_slots = len(tiers) >= 3 or homogeneous_envelopes

sys_idx = 0
for tier_index, tier_info in enumerate(tiers):
t_rad = float(tier_info["radius"])
t_count = int(tier_info["count"])
for tier_slot in range(t_count):
community = non_global[sys_idx]
community_id = str(community["id"])
system_radius = _clamp(
_finite_float(community.get("radius"), 36.0), 36.0, 10_000.0
)
arm = sys_idx % arm_count if arm_count > 0 else 0
digest = hashlib.sha256(
f"{ALGORITHM_VERSION}:{layout_seed}:system:{community_id}".encode("utf-8")
).digest()
angular_jitter = (
int.from_bytes(digest[:4], "big") / float(1 << 32) - 0.5
) * 0.06
radial_jitter = 0.96 + (
int.from_bytes(digest[4:8], "big") / float(1 << 32)
) * 0.08
if use_tier_local_slots:
tier_phase = base_phase + tier_index * math.tau / 12.0
# Use the tier's actual slot count rather than continuing the previous
# tier's golden-angle rank; the deterministic phase keeps the lanes
# visually distinct while the exact local lattice prevents radial
# fallback from an ID-dependent jitter collapse.
angle = (
tier_phase
+ tier_slot * math.tau / max(1, t_count)
)
else:
# Mixed-size two-tier scenes keep a scene-wide low-discrepancy carrier so
# the angular distribution remains stable across unequal envelopes.
angle = base_phase + sys_idx * GOLDEN_ANGLE_RAD + angular_jitter

# ``preferred_targets`` applies the user-facing compactness scale below.
# Tier radii are already physical lane coordinates, so compensate here or a
# compactness of 0.192 would shrink every tier back through the core floor and
# make the collision walk, rather than the tier plan, choose the lanes.
physical_tier_radius = max(core_clearance_radius, t_rad * radial_jitter)
nominal_r = physical_tier_radius / max(clean_radius_scale, 1e-9)
specs.append({
"id": community_id,
"system_radius": system_radius,
"arm": arm,
"nominal_x": nominal_r * math.cos(angle),
"nominal_y": nominal_r * math.sin(angle),
})
sys_idx += 1

def pack_with_radial_clearance(
targets: Mapping[str, tuple[float, float]],
Expand Down Expand Up @@ -803,7 +911,7 @@ def collides(x: float, y: float, system_radius: float) -> bool:
# The radius_scale compactness pass may shrink preferred targets inside
# the core; clamp the walk's starting radius to the clearance floor so
# the collision search never considers orbits inside the black hole.
minimum_orbital_radius = core_outer_extent + GALAXY_SYSTEM_MIN_GAP
minimum_orbital_radius = core_outer_extent + system_radius + GALAXY_SYSTEM_MIN_GAP
axis_radius = max(axis_radius, minimum_orbital_radius)
# Radial-only walk preserves the even angular distribution. Moving only
# the system centre outward (not angularly) keeps every local star/planet
Expand Down Expand Up @@ -2341,7 +2449,7 @@ def _build_complete_scene(
str(all_nodes[global_anchor]["community_id"]) if global_anchor else ""
)
positions, community_hints = _community_positions(
communities, global_community_id, layout_seed, spacing=92.0
communities, global_community_id, layout_seed, spacing=74.0
)
for community in communities:
community.update(community_hints[community["id"]])
Expand Down Expand Up @@ -2890,7 +2998,7 @@ def eligible(node_id: str) -> bool:
graph, set(graph["community_members"]), set(graph["nodes"]), _system_radii
)
layout_positions, layout_hints = _community_positions(
layout_communities, global_community_id, layout_seed, spacing=98.0
layout_communities, global_community_id, layout_seed, spacing=78.0
)
seeded_positions = _orbital_layout_positions(
graph["nodes"], graph["community_members"], graph["community_anchors"],
Expand Down
Loading