Move scaffold/scaffold/context_loader.py -> scaffold/context_loader.py
Browse files- scaffold/context_loader.py +89 -0
scaffold/context_loader.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Rivet Context Loader — loads architecture + audit into every session.
|
| 2 |
+
|
| 3 |
+
The key innovation: Rivet starts every conversation KNOWING the system.
|
| 4 |
+
Not learning it from the user. Not guessing from file names. KNOWING.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import json
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
from dataclasses import dataclass
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
CONTEXT_DIR = Path("/Users/margaret/project-rivet/context")
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
@dataclass
|
| 16 |
+
class RivetContext:
|
| 17 |
+
architecture: str
|
| 18 |
+
audit_findings: str
|
| 19 |
+
schema_snapshot: str = ""
|
| 20 |
+
recent_git: str = ""
|
| 21 |
+
|
| 22 |
+
def to_system_context(self) -> str:
|
| 23 |
+
"""Format as a system context block for the model."""
|
| 24 |
+
parts = [
|
| 25 |
+
"# SYSTEM CONTEXT — Multiverse Campus Architecture\n",
|
| 26 |
+
"You have the following information loaded. Reference it when answering.\n",
|
| 27 |
+
"## Architecture Map\n",
|
| 28 |
+
self.architecture,
|
| 29 |
+
"\n## Known Issues (Nexus Security Audit, 2026-07-10)\n",
|
| 30 |
+
self.audit_findings,
|
| 31 |
+
]
|
| 32 |
+
if self.schema_snapshot:
|
| 33 |
+
parts.extend(["\n## Database Schema (key tables)\n", self.schema_snapshot])
|
| 34 |
+
if self.recent_git:
|
| 35 |
+
parts.extend(["\n## Recent Changes (last 7 days)\n", self.recent_git])
|
| 36 |
+
return "\n".join(parts)
|
| 37 |
+
|
| 38 |
+
@property
|
| 39 |
+
def token_estimate(self) -> int:
|
| 40 |
+
"""Rough token estimate (4 chars per token)."""
|
| 41 |
+
total = len(self.architecture) + len(self.audit_findings)
|
| 42 |
+
total += len(self.schema_snapshot) + len(self.recent_git)
|
| 43 |
+
return total // 4
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def load_context(context_dir: Path = CONTEXT_DIR) -> RivetContext:
|
| 47 |
+
"""Load all context files from the Rivet context directory."""
|
| 48 |
+
arch_path = context_dir / "architecture_map.md"
|
| 49 |
+
audit_path = context_dir / "audit_findings.md"
|
| 50 |
+
schema_path = context_dir / "schema_snapshot.sql"
|
| 51 |
+
git_path = context_dir / "recent_git.txt"
|
| 52 |
+
|
| 53 |
+
architecture = arch_path.read_text() if arch_path.exists() else "Architecture map not loaded."
|
| 54 |
+
audit = audit_path.read_text() if audit_path.exists() else "Audit findings not loaded."
|
| 55 |
+
schema = schema_path.read_text() if schema_path.exists() else ""
|
| 56 |
+
git_log = git_path.read_text() if git_path.exists() else ""
|
| 57 |
+
|
| 58 |
+
return RivetContext(
|
| 59 |
+
architecture=architecture,
|
| 60 |
+
audit_findings=audit,
|
| 61 |
+
schema_snapshot=schema,
|
| 62 |
+
recent_git=git_log,
|
| 63 |
+
)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def refresh_git_log(repo_path: str, context_dir: Path = CONTEXT_DIR):
|
| 67 |
+
"""Refresh the recent git log from the campus repo."""
|
| 68 |
+
import subprocess
|
| 69 |
+
try:
|
| 70 |
+
result = subprocess.run(
|
| 71 |
+
["git", "log", "--oneline", "--since=7 days ago", "-20"],
|
| 72 |
+
cwd=repo_path, capture_output=True, text=True, timeout=10
|
| 73 |
+
)
|
| 74 |
+
if result.returncode == 0:
|
| 75 |
+
(context_dir / "recent_git.txt").write_text(result.stdout)
|
| 76 |
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
| 77 |
+
pass
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
if __name__ == "__main__":
|
| 81 |
+
ctx = load_context()
|
| 82 |
+
print(f"Context loaded:")
|
| 83 |
+
print(f" Architecture: {len(ctx.architecture)} chars")
|
| 84 |
+
print(f" Audit: {len(ctx.audit_findings)} chars")
|
| 85 |
+
print(f" Schema: {len(ctx.schema_snapshot)} chars")
|
| 86 |
+
print(f" Git: {len(ctx.recent_git)} chars")
|
| 87 |
+
print(f" Estimated tokens: ~{ctx.token_estimate}")
|
| 88 |
+
print(f"\nFirst 200 chars of system context:")
|
| 89 |
+
print(ctx.to_system_context()[:200])
|