Skip to content
Merged
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ Public 1.0.1 client reliability release.

- Cloud Sync now defaults to `https://relay.engraphis.com` and safely migrates the former
dashboard host and retired Railway relay URL without changing customer-provided relay URLs.
- Default Pro and Team upgrade links now target the live authenticated account portal rather
than the retired Team dashboard host.
- Hosted endpoint validation now fails closed when DNS resolution cannot establish that a
configured destination is public, preventing unresolved hosts from bypassing the SSRF guard.
- Hosted Automation and maintenance requests now use the selected workspace end to end rather
than silently falling back to the first workspace.
- The Automation tab has one proposal action, clear managed-upload disclosure, and automatic
Expand All @@ -73,6 +77,7 @@ Public 1.0.1 client reliability release.
- Entity extraction and dashboard asset migration avoid adversarial regular-expression
backtracking. CodeQL now disables pull-request diff-informed analysis and CI fails on every
raw SARIF result, including pre-existing and source-suppressed results.
- The documented grounded-recall evaluation prints with the default Windows console encoding.

## [1.0.0] - 2026-07-23

Expand Down
9 changes: 7 additions & 2 deletions engraphis/hosted_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
TRIAL_SECONDS = 3 * 24 * 60 * 60
MAX_LOCAL_WRITE_GRACE_SECONDS = 24 * 60 * 60

DEFAULT_CLOUD_URL = "https://team.engraphis.com"
# The hosted dashboard and the commercial account portal are separate surfaces.
# Upgrade/connect actions must land on the authenticated control-plane portal; the
# dashboard host does not serve its own ``/account`` route.
DEFAULT_CLOUD_URL = "https://api.engraphis.com/account"

_REQUIRED_PLAN = {
"analytics": "pro",
Expand Down Expand Up @@ -115,5 +118,7 @@ def validate_cloud_base_url(value: str) -> str:
"cloud service URL must not target private/reserved IP ranges"
)
except (socket.gaierror, OSError):
pass
raise ValueError(
"cloud service URL could not be resolved"
) from None
Comment on lines 120 to +123

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the cloud-session error contract on DNS failure

When a configured control or compute hostname has a transient DNS failure, this newly raised ValueError escapes callers that deliberately handle only CloudSessionError: for example, scripts/sync.py catches CloudSessionError around access_for_workspace() and will now emit a traceback instead of its documented connection error and exit code 2. Wrap this validation failure as CloudSessionError in the cloud-session boundary (or update those callers) so fail-closed validation remains a graceful operational failure.

Useful? React with 👍 / 👎.

return urlunsplit((scheme, parts.netloc, parts.path.rstrip("/"), "", ""))
6 changes: 4 additions & 2 deletions eval/grounded.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ def run() -> dict:
def main() -> None:
r = run()
print("\nEngraphis grounded-recall eval (deterministic embedder)")
print(f" answerable → grounded : {r['answer_rate']:.3f} "
# Keep the documented offline gate usable from the Windows console's default
# cp1252 encoding, which cannot emit a Unicode arrow.
print(f" answerable -> grounded : {r['answer_rate']:.3f} "
f"({r['grounded_hits']}/{r['n_answerable']})")
print(f" off-topic abstained : {r['abstain_rate']:.3f} "
print(f" off-topic -> abstained : {r['abstain_rate']:.3f} "
f"({r['abstain_hits']}/{r['n_unanswerable']})")
print(f" decision accuracy : {r['accuracy']:.3f} "
f"({r['grounded_hits'] + r['abstain_hits']}/{r['n_answerable'] + r['n_unanswerable']})\n")
Expand Down
9 changes: 9 additions & 0 deletions tests/test_eval_grounded.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Regression coverage for the documented offline grounded-recall gate."""

from eval import grounded


def test_grounded_eval_report_is_windows_console_safe(capsys):
"""The release command must work with Windows' default cp1252 stdout."""
grounded.main()
capsys.readouterr().out.encode("cp1252")
21 changes: 18 additions & 3 deletions tests/test_hosted_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ def test_upgrade_urls_are_hosted_metadata_only(monkeypatch):
monkeypatch.delenv("ENGRAPHIS_TEAM_UPGRADE_URL", raising=False)
monkeypatch.delenv("ENGRAPHIS_CLOUD_URL", raising=False)

assert hosted_client.upgrade_url("pro") == "https://team.engraphis.com"
assert hosted_client.upgrade_url("team") == "https://team.engraphis.com"
assert hosted_client.upgrade_url("pro") == "https://api.engraphis.com/account"
assert hosted_client.upgrade_url("team") == "https://api.engraphis.com/account"
assert hosted_client.required_plan("sync") == "pro"
assert hosted_client.required_plan("team") == "team"


def test_cloud_url_validation_requires_safe_remote_https():
def test_cloud_url_validation_requires_safe_remote_https(monkeypatch):
monkeypatch.setattr(
hosted_client.socket,
"getaddrinfo",
lambda *a, **k: [(2, 1, 6, "", ("1.2.3.4", 0))],
)
assert hosted_client.validate_cloud_base_url("http://127.0.0.1:8700/") == (
"http://127.0.0.1:8700"
)
Expand All @@ -40,6 +45,16 @@ def test_cloud_url_validation_requires_safe_remote_https():
hosted_client.validate_cloud_base_url(invalid)


def test_cloud_url_validation_rejects_unresolvable_hosts(monkeypatch):
monkeypatch.setattr(
hosted_client.socket,
"getaddrinfo",
lambda *a, **k: (_ for _ in ()).throw(hosted_client.socket.gaierror),
)
with pytest.raises(ValueError, match="could not be resolved"):
hosted_client.validate_cloud_base_url("https://unresolvable.example/")


def test_licensing_facade_exposes_no_local_entitlement_engine():
assert licensing.TRIAL_DAYS == 3
assert licensing.production_warnings() == []
Expand Down
Loading