Re-commit

This commit is contained in:
2025-11-16 07:27:47 -07:00
parent 3091baecaf
commit 65bee703e9
22 changed files with 240 additions and 3 deletions

2
.github/.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
# These are supported funding model platforms
ko_fi: bunnylab

56
.vscode/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,56 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Borealis - Engine (Production)",
"type": "shell",
"command": "powershell.exe",
"args": [
"-NoLogo",
"-NoProfile",
"-ExecutionPolicy", "Bypass",
"-File", "${workspaceFolder}\\Borealis.ps1",
"-EngineProduction"
],
"presentation": {
"reveal": "always",
"panel": "shared"
},
"problemMatcher": []
},
{
"label": "Borealis - Engine (Dev)",
"type": "shell",
"command": "powershell.exe",
"args": [
"-NoLogo",
"-NoProfile",
"-ExecutionPolicy", "Bypass",
"-File", "${workspaceFolder}\\Borealis.ps1",
"-EngineDev"
],
"presentation": {
"reveal": "always",
"panel": "shared"
},
"problemMatcher": []
},
{
"label": "Borealis - Agent",
"type": "shell",
"command": "powershell.exe",
"args": [
"-NoLogo",
"-NoProfile",
"-ExecutionPolicy", "Bypass",
"-File", "${workspaceFolder}\\Borealis.ps1",
"-Agent"
],
"presentation": {
"reveal": "always",
"panel": "shared"
},
"problemMatcher": []
}
]
}

BIN
Dependencies/Dependencies/7zip/7z.dll vendored Normal file

Binary file not shown.

BIN
Dependencies/Dependencies/7zip/7z.exe vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,35 @@
# Codex Guide: Borealis Agent
Use this doc for agent-only work (Borealis agent runtime under `Data/Agent``/Agent`). For shared guidance, see `Docs/Codex/SHARED.md`.
## Scope & Runtime Paths
- Purpose: outbound-only connectivity, device telemetry, scripting, UI helpers.
- Bootstrap: `Borealis.ps1` preps dependencies, activates the agent venv, and co-launches the Engine.
- Edit in `Data/Agent`, not `/Agent`; runtime copies are ephemeral and wiped regularly.
## Logging
- Primary log: `Agent/Logs/agent.log` with daily rotation to `agent.log.YYYY-MM-DD` (never auto-delete rotated files).
- Subsystems: log to `Agent/Logs/<service>.log` with the same rotation policy.
- Install/diagnostics: `Agent/Logs/install.log`; keep ad-hoc traces (e.g., `system_last.ps1`, ansible) under `Agent/Logs/` to keep runtime state self-contained.
- Troubleshooting: prefix lines with `<timestamp>-<service-name>-<log-data>`; ask operators whether verbose logging should stay after resolution.
## Security
- Generates device-wide Ed25519 keys on first launch (`Certificates/Agent/Identity/`; DPAPI on Windows, `chmod 600` elsewhere).
- Refresh/access tokens are encrypted and pinned to the Engine certificate fingerprint; mismatches force re-enrollment.
- Uses dedicated `ssl.SSLContext` seeded with the Engine TLS bundle for REST + Socket.IO traffic.
- Validates script payloads with backend-issued Ed25519 signatures before execution.
- Outbound-only; API/WebSocket calls flow through `AgentHttpClient.ensure_authenticated` for proactive refresh. Logs bootstrap, enrollment, token refresh, and signature events in `Agent/Logs/`.
## Execution Contexts & Roles
- Auto-discovers roles from `Data/Agent/Roles/`; no loader changes needed.
- Naming: `role_<Purpose>.py` with `ROLE_NAME`, `ROLE_CONTEXTS`, and optional hooks (`register_events`, `on_config`, `stop_all`).
- Standard roles: `role_DeviceInventory.py`, `role_Screenshot.py`, `role_ScriptExec_CURRENTUSER.py`, `role_ScriptExec_SYSTEM.py`, `role_Macro.py`.
- SYSTEM tasks depend on scheduled-task creation rights; failures should surface through Engine logging.
## Platform Parity
- Windows is the reference. Linux (`Borealis.sh`) lags in venv setup, supervision, and role loading; align Linux before macOS work continues.
## Ansible Support (Unfinished)
- Agent + Engine scaffolding exists but is unreliable: expect stalled/silent failures, inconsistent recap, missing collections.
- Windows blockers: `ansible.windows.*` usually needs PSRP/WinRM; SYSTEM context lacks loopback remoting guarantees; interpreter paths vary.
- Treat Ansible features as disabled until packaging/controller story is complete. Future direction: credential mgmt, selectable connections, reliable live output/cancel, packaged collections.

View File

@@ -0,0 +1,35 @@
# Codex Guide: Borealis Engine
Use this doc for Engine work (successor to the legacy server). For shared guidance, see `Docs/Codex/SHARED.md`.
## Scope & Runtime Paths
- Bootstrap: `Borealis.ps1` launches the Engine and/or Agent. The equivalant bootstrap script exists for Linux when running `Borealis.sh`.
- Edit in `Data/Engine`; runtime copies live under `/Engine` and are discarded every time the engine is launched.
## Architecture
- Runtime: `Data/Engine/server.py` with NodeJS + Vite for live dev and Flask for production serving/API endpoints.
## Development Guidelines
- Every Python module under `Data/Engine` or `Engine/Data/Engine` starts with the standard commentary header (purpose + API endpoints). Add the header to any existing module before further edits.
## Logging
- Primary log: `Engine/Logs/engine.log` with daily rotation (`engine.log.YYYY-MM-DD`); do not auto-delete rotated files.
- Subsystems: `Engine/Logs/<service>.log`; install output to `Engine/Logs/install.log`.
- Keep Engine-specific artifacts within `Engine/Logs/` to preserve the runtime boundary.
## Security & API Parity
- Mirrors legacy mutual trust: Ed25519 device identities, EdDSA-signed access tokens, pinned Borealis root CA, TLS 1.3-only serving, Authorization headers + service-context markers on every device API.
- Implements DPoP validation, short-lived access tokens (~15 min), SHA-256hashed refresh tokens (30-day) with explicit reuse errors.
- Enrollment: operator approvals, conflict detection, auditor recording, pruning of expired codes/refresh tokens.
- Background jobs and service adapters maintain compatibility with legacy DB schemas while enabling gradual API takeover.
## WebUI & WebSocket Migration
- Static/template handling: `Data/Engine/services/WebUI`; deployment copy paths are wired through `Borealis.ps1` with TLS-aware URL generation.
- Stage 6 tasks: migration switch in the legacy server for WebUI delegation and porting device/admin API endpoints into Engine services.
- Stage 7 (queued): `register_realtime` hooks, Engine-side Socket.IO handlers, integration checks, legacy delegation updates.
## Platform Parity
- Windows is primary target. Keep Engine tooling aligned with the agent experience; Linux packaging must catch up before macOS work resumes.
## Ansible Support (Shared State)
- Mirrors the agents unfinished story: treat orchestration as experimental until packaging, connection management, and logging mature.

View File

@@ -0,0 +1,6 @@
# Codex Guide: Shared Conventions
Cross-cutting guidance that applies to both Agent and Engine work. Domain-specific rules live in `Docs/Codex/BOREALIS_AGENT.md` and `Docs/Codex/BOREALIS_ENGINE.md`.
- UI & AG Grid: see `Docs/Codex/USER_INTERFACE.md` for MagicUI styling language and AG Grid patterns (with references to live templates).
- Add further shared topics here (e.g., triage process, security posture deltas) instead of growing `AGENTS.md`.

View File

@@ -0,0 +1,35 @@
# Codex Guide: Shared UI (MagicUI + AG Grid)
Applies to all Borealis frontends. Use `Data/Engine/web-interface/src/Admin/Page_Template.jsx` as the canonical visual reference (no API/business logic). Keep this doc as the single source of truth for styling rules and AG Grid behavior.
## Page Template Reference
- Purpose: visual-only baseline for new pages; copy structure but wire your data in real pages.
- Header: small Material icon left of the title, subtitle beneath, utility buttons on the top-right.
- Shell: full-bleed aurora gradient container; avoid gutters on the Paper.
- Selection column (for bulk actions): pinned left, square checkboxes, header checkbox enabled, ~52px fixed width, no menu/sort/resize; rely on AG Grid built-ins.
- Typography/buttons: IBM Plex Sans, gradient primary buttons, rounded corners (~8px), themed Quartz grid wrapper.
## MagicUI Styling Language (Visual System)
- Aurora shells: gradient backgrounds blending deep navy (#040711) with soft cyan/violet blooms, subtle borders (`rgba(148,163,184,0.35)`), and low, velvety shadows.
- Full-bleed canvas: hero shells run edge-to-edge; inset padding lives inside cards so gradients feel immersive.
- Glass panels: glassmorphic layers (`rgba(15,23,42,0.7)`), rounded 1624px corners, blurred backdrops, micro borders, optional radial flares for motion.
- Hero storytelling: start views with stat-forward heroes—gradient StatTiles (min 160px) and uppercase pills (HERO_BADGE_SX) summarizing live signals/filters.
- Summary data grids: use AG Grid inside a glass wrapper (two columns Field/Value), matte navy background, no row striping.
- Tile palettes: online cyan→green; stale orange→red; “needs update” violet→cyan; secondary metrics fade from cyan into desaturated steel for consistent hue families.
- Hardware islands: storage/memory/network blocks reuse Quartz theme in rounded glass shells with flat fills; present numeric columns (Capacity/Used/Free/%) to match Device Inventory.
- Action surfaces: control bars live in translucent glass bands; filled dark inputs with cyan hover borders; primary actions are pill-shaped gradients; secondary controls are soft-outline icon buttons.
- Anchored controls: align selectors/utility buttons with grid edges in a single row; reserve glass backdrops for hero sections so content stays flush.
- Buttons & chips: gradient pills for primary CTAs (`linear-gradient(135deg,#34d399,#22d3ee)` success; `#7dd3fc→#c084fc` creation); neutral actions use rounded outlines with `rgba(148,163,184,0.4)` borders and uppercase microcopy.
- Rainbow accents: for creation CTAs, use dark-fill pills with rainbow border gradients + teal halo (shared with Quick Job).
- AG Grid treatment: Quartz theme with matte navy headers, subtle alternating row opacity, cyan/magenta interaction glows, rounded wrappers, soft borders, inset selection glows.
- Overlays/menus: `rgba(8,12,24,0.96)` canvas, blurred backdrops, thin steel borders; bright typography; deep blue glass inputs; cyan confirm, mauve destructive accents.
## AG Grid Column Behavior (All Tables)
- Auto-size value columns and let the last column absorb remaining width so views span available space.
- Declare `AUTO_SIZE_COLUMNS` near the grid component (exclude the fill column).
- Helper: store the grid API in a ref and call `api.autoSizeColumns(AUTO_SIZE_COLUMNS, true)` inside `requestAnimationFrame` (or `setTimeout(...,0)` fallback); swallow errors because it can run before rows render.
- Hook the helper into both `onGridReady` and a `useEffect` watching the dataset (e.g., `[filteredRows, loading]`); skip while `loading` or when there are zero rows.
- Column defs: apply shared `cellClass: "auto-col-tight"` (or equivalent) to every auto-sized column for consistent padding. Last column keeps the class for styling consistency.
- CSS override: add `& .ag-cell.auto-col-tight { padding-left: 0; padding-right: 0; }` in the theme scope.
- Fill column: last column `{ flex: 1, minWidth: X }` (no width/maxWidth) to stretch when horizontal space remains.
- Example: follow the scaffolding in `Engine/web-interface/src/Scheduling/Scheduled_Jobs_List.jsx` and the structure in `Data/Engine/web-interface/src/Admin/Page_Template.jsx`.

20
Docs/Docs/assemblies.md Normal file
View File

@@ -0,0 +1,20 @@
# Assemblies Runtime Reference
## Database Layout
- Three SQLite databases live under `Data/Engine/Assemblies` (`official.db`, `community.db`, `user_created.db`) and mirror to `Engine/Assemblies` at runtime.
- Automatic JSON → SQLite imports for the official domain have been retired; the staged `official.db` now serves as the authoritative store unless you invoke a manual sync.
- Payload binaries/json store under `Payloads/<payload-guid>` in both staging and runtime directories; the AssemblyCache references payload GUIDs instead of embedding large blobs.
- WAL mode with shared-cache is enabled on every connection; queue flushes copy the refreshed `.db`, `-wal`, and `-shm` files into the runtime mirror.
- `AssemblyCache.describe()` reveals dirty/clean state per assembly, helping operators spot pending writes before shutdown or sync operations.
## Dev Mode Controls
- User-created domain mutations remain open to authenticated operators; community/official writes require an administrator with Dev Mode enabled.
- Toggle Dev Mode via `POST /api/assemblies/dev-mode/switch` or the Assemblies admin controls; state expires automatically based on the server-side TTL.
- Privileged actions (create/update/delete, cross-domain clone, queue flush, official sync, import into protected domains) emit audit entries under `Engine/Logs/assemblies.log`.
- When Dev Mode is disabled, API responses return `dev_mode_required` to prompt admins to enable overrides before retrying protected mutations.
## Backup Guidance
- Regularly snapshot `Data/Engine/Assemblies` and `Data/Engine/Assemblies/Payloads` alongside the mirrored runtime copies to preserve both metadata and payload artifacts.
- Include the queue inspection endpoint (`GET /api/assemblies`) in maintenance scripts to verify no dirty entries remain before capturing backups.
- Maintain the staged databases directly; to publish new official assemblies copy the curated `official.db` into `Data/Engine/Assemblies` before restarting the Engine.
- Future automation will extend to scheduled backups and staged restore helpers; until then, ensure filesystem backups capture both SQLite databases and payload directories atomically.

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

View File

@@ -189,9 +189,41 @@ function Start-AgentScheduledTasks {
function Stop-AgentPythonProcesses {
param(
[string[]]$ProcessNames = @('python', 'pythonw')
[string[]]$ProcessNames = @('python', 'pythonw'),
[string]$ProjectRoot,
[switch]$SkipEngine = $true
)
$enginePids = @()
$engineRoot = ''
$dataEngineRoot = ''
if ($ProjectRoot) {
try { $engineRoot = (Join-Path $ProjectRoot 'Engine') } catch {}
try { $dataEngineRoot = (Join-Path $ProjectRoot 'Data\Engine') } catch {}
}
if ($SkipEngine) {
try {
$cims = Get-CimInstance -ClassName Win32_Process -Filter "Name='python.exe' OR Name='pythonw.exe'" -ErrorAction Stop
foreach ($proc in $cims) {
try {
$pid = [int]$proc.ProcessId
} catch { continue }
$cmd = ($proc.CommandLine -as [string])
$exePath = ($proc.ExecutablePath -as [string])
$isEngine = $false
foreach ($marker in @($engineRoot, $dataEngineRoot, '\Engine\', '\Data\Engine\', 'Engine\server.py', 'Data\Engine\server.py')) {
if (-not $marker) { continue }
try {
if ($cmd -and $cmd.ToLowerInvariant().Contains($marker.ToLowerInvariant())) { $isEngine = $true; break }
if ($exePath -and $exePath.ToLowerInvariant().Contains($marker.ToLowerInvariant())) { $isEngine = $true; break }
} catch {}
}
if ($isEngine -and ($enginePids -notcontains $pid)) { $enginePids += $pid }
}
} catch {}
}
foreach ($name in ($ProcessNames | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Select-Object -Unique)) {
$name = $name.Trim()
if (-not $name) { continue }
@@ -206,13 +238,29 @@ function Stop-AgentPythonProcesses {
foreach ($proc in $processes) {
$procId = $null
$procName = $null
$procPath = $null
try {
$procId = $proc.Id
$procName = $proc.ProcessName
$procPath = $proc.Path
} catch {}
if ($procId -eq $null) { continue }
$isEngineProc = $false
try {
if ($enginePids -and ($enginePids -contains $procId)) { $isEngineProc = $true }
foreach ($marker in @($engineRoot, $dataEngineRoot)) {
if (-not $marker) { continue }
if ($procPath -and $procPath.ToLowerInvariant().StartsWith($marker.ToLowerInvariant())) { $isEngineProc = $true; break }
}
} catch {}
if ($SkipEngine -and $isEngineProc) {
Write-Host "Skipping Engine python process: PID $procId ($procName)" -ForegroundColor Cyan
continue
}
if (-not $procName) { $procName = $name }
$stopped = $false
@@ -1732,7 +1780,7 @@ function Invoke-BorealisAgentUpdate {
} else {
Write-UpdateLog "No managed tasks were running when update started." 'DEBUG'
}
Run-Step "Updating: Terminate Running Python Processes" { Stop-AgentPythonProcesses }
Run-Step "Updating: Terminate Running Python Processes" { Stop-AgentPythonProcesses -ProjectRoot $scriptDir -SkipEngine }
$updateSucceeded = $false
try {
@@ -1797,4 +1845,4 @@ function Invoke-BorealisAgentUpdate {
}
}
Invoke-BorealisAgentUpdate
Invoke-BorealisAgentUpdate