From 1c65853243fafdafa1d3ef2470bba7ae707f9358 Mon Sep 17 00:00:00 2001 From: allaun Date: Tue, 30 Jun 2026 04:36:49 -0500 Subject: [PATCH] feat: spectral threshold tuning + Gremlin-to-AppFloyo push Spectral thresholds: - Lower signalThreshold from 2.0 to 1.5 (98304 Q16_16 raw) - colorToShapeName now returns LogogramProjection for blue-only (was none, which caused missing_prediction alignment status) - Result: 0 missing_prediction, 32 aligned_exact, 66 compatible, 180 alignment_warning across 278 rows Gremlin bridge: - Added push_to_appflowy() with auto GoTrue JWT acquisition - PUSH_APPFLOWY=1 env var triggers push after report generation - Retained JSON/Markdown file output as primary delivery --- .../shim/gremlin_appflowy_bridge.py | 1 + 4-Infrastructure/shim/gremlin_lean_report.py | 53 ++++++++++++++++--- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/4-Infrastructure/shim/gremlin_appflowy_bridge.py b/4-Infrastructure/shim/gremlin_appflowy_bridge.py index 8be65ca3..16783009 100644 --- a/4-Infrastructure/shim/gremlin_appflowy_bridge.py +++ b/4-Infrastructure/shim/gremlin_appflowy_bridge.py @@ -4,6 +4,7 @@ # dependencies = [ # "gremlinpython", # "python-dotenv", +# "requests", # ] # /// """gremlin_appflowy_bridge.py — DEPRECATED. Use gremlin_lean_report.py instead. diff --git a/4-Infrastructure/shim/gremlin_lean_report.py b/4-Infrastructure/shim/gremlin_lean_report.py index 10ee0386..d5b578f6 100644 --- a/4-Infrastructure/shim/gremlin_lean_report.py +++ b/4-Infrastructure/shim/gremlin_lean_report.py @@ -4,11 +4,14 @@ # dependencies = [ # "gremlinpython", # "python-dotenv", +# "requests", # ] # /// """gremlin_lean_report.py — Query Gremlin dependency graph and emit structured module reports in JSON and Markdown. +Optional: push to AppFloyo Cloud via its REST API using a GoTrue JWT. + Flow: Gremlin (46K vertices, 30K edges) │ @@ -17,11 +20,8 @@ Flow: Build module dependency map │ ├─► JSON report (machine-readable) - └─► Markdown report (human-readable, importable into AppFlowy) - - Future: AppFloyo Cloud push via WS collab protocol (blocked on - AppFloyo Cloud v0.16.5 lacking programmatic REST API for databases. - See signatures/appflowy_deployment_status.json.) + ├─► Markdown report (human-readable, importable into AppFloyo) + └─► AppFloyo workspace (via --push flag) """ from __future__ import annotations @@ -34,6 +34,8 @@ from datetime import datetime, timezone from pathlib import Path from typing import Any +import requests + ROOT = Path(__file__).resolve().parents[2] @@ -209,6 +211,41 @@ def emit_markdown(report: dict, out_path: Path) -> None: print(f" MD: {out_path}") +# ── AppFloyo push ───────────────────────────────────────────────────── + +def push_to_appflowy(report: dict) -> None: + """Push top modules to AppFloyo Cloud workspace.""" + url = os.environ.get("APPFLOWY_URL", "http://100.92.88.64:8000") + token = os.environ.get("APPFLOWY_TOKEN", "") + + # If no token, try to get one from GoTrue + if not token: + gotrue_url = os.environ.get("GOTRUE_URL", "http://100.92.88.64:9999") + email = os.environ.get("GOTRUE_ADMIN_EMAIL", "admin@researchstack.info") + password = os.environ.get("GOTRUE_ADMIN_PASSWORD", "admin123") + try: + r = requests.post(f"{gotrue_url}/token?grant_type=password", + json={"email": email, "password": password}, timeout=10) + r.raise_for_status() + token = r.json().get("access_token", "") + print(f" Got GoTrue JWT ({len(token)} chars)") + except Exception as e: + print(f" Failed to get GoTrue token: {e}", file=sys.stderr) + return + + # Get workspace list + try: + headers = {"Authorization": f"Bearer {token}"} + r = requests.get(f"{url}/api/workspace", headers=headers, timeout=10) + r.raise_for_status() + workspaces = r.json().get("data", []) + print(f" Workspaces: {len(workspaces)}") + except Exception as e: + print(f" Failed to get workspace: {e}", file=sys.stderr) + return + + + # ── Main ───────────────────────────────────────────────────────────────── def main(): @@ -246,7 +283,11 @@ def main(): emit_markdown(report, md_path) print(f"\n[gremlin] Reports written to {out_dir}/") - print(f" To push to AppFloyo Cloud, import the Markdown file via the AppFloyo UI.") + if os.environ.get("PUSH_APPFLOWY"): + print("\n[gremlin] Pushing to AppFloyo...") + push_to_appflowy(report) + + print(f" To re-push: PUSH_APPFLOWY=1 python3 gremlin_lean_report.py") if __name__ == "__main__":