Spaces:
Sleeping
Sleeping
Commit ·
a64d9be
1
Parent(s): f51c224
Asterion JNO seed v2 — pre-staged doctrine MD; ONBOARDING reflects pre-staged plugin
Browse filesAdds:
SA-orchestration MD/ doctrine reference (root .md docs from SA-Orch source repo)
plain files; no nested .git or .claude
ONBOARDING.md Step 5 updated to reference the pre-staged plugin tree at
<repo-root>/sa-orchestration/ rather than a GitHub clone. If the directory
is missing, the seed is corrupt — surface to human; do NOT invent a clone URL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This view is limited to 50 files because it contains too many changes. See raw diff
- ONBOARDING.md +7 -9
- SA-orchestration MD/Archvie/MidCoast/CLAUDE.md +267 -0
- SA-orchestration MD/Archvie/MidCoast/DEPLOY.md +128 -0
- SA-orchestration MD/Archvie/MidCoast/INSTALL.md +161 -0
- SA-orchestration MD/Archvie/MidCoast/README.md +1 -0
- SA-orchestration MD/Archvie/sa-core/README.md +185 -0
- SA-orchestration MD/Archvie/sa-core/docs/ARCHITECTURE.md +0 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/01-ontology.md +281 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/02-invariants.md +180 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/03-realm-adapter-contract.md +282 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/04-async-execution.md +678 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/05-zoom-quantum-engine.md +373 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/06-toolbox-action-contract.md +127 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/README.md +70 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/attention-doctrine.md +52 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/cognitive-heatsink.md +164 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/compass-doctrine.md +67 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/concept-vs-label.md +84 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/legacy-prime-prompt.md +123 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/lineage-chain.md +62 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/prime-prompt-conjecture.md +81 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/reference-traversal-continuity.md +131 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/signal-telemetry-doctrine.md +115 -0
- SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/story-seed-pattern.md +81 -0
- SA-orchestration MD/BYPASS_AND_RECOVERY.md +88 -0
- SA-orchestration MD/CORE_MODEL.md +90 -0
- SA-orchestration MD/DEFERRED_SA_CORE_CONCERNS.md +39 -0
- SA-orchestration MD/DEVELOPMENT_MODES.md +84 -0
- SA-orchestration MD/ENERGY_MODEL.md +69 -0
- SA-orchestration MD/ENVIRONMENT.md +181 -0
- SA-orchestration MD/FLUENT_DATA_MAPPING.md +360 -0
- SA-orchestration MD/ONBOARDING.md +239 -0
- SA-orchestration MD/PLUGIN_STATUS.md +331 -0
- SA-orchestration MD/PROJECTION_SURFACES.md +137 -0
- SA-orchestration MD/README.md +25 -0
- SA-orchestration MD/SCATTER_AND_CONVERGENCE.md +73 -0
- SA-orchestration MD/SIGNAL_FLOW.md +115 -0
- SA-orchestration MD/asterion/01-ontology.md +281 -0
- SA-orchestration MD/asterion/02-invariants.md +180 -0
- SA-orchestration MD/asterion/03-realm-adapter-contract.md +282 -0
- SA-orchestration MD/asterion/04-async-execution.md +678 -0
- SA-orchestration MD/asterion/05-zoom-quantum-engine.md +373 -0
- SA-orchestration MD/asterion/06-toolbox-action-contract.md +127 -0
- SA-orchestration MD/asterion/README.md +20 -0
- SA-orchestration MD/asterion/concepts/attention-doctrine.md +52 -0
- SA-orchestration MD/asterion/concepts/cognitive-heatsink.md +164 -0
- SA-orchestration MD/asterion/concepts/compass-doctrine.md +67 -0
- SA-orchestration MD/asterion/concepts/concept-vs-label.md +84 -0
- SA-orchestration MD/asterion/concepts/legacy-prime-prompt.md +123 -0
- SA-orchestration MD/asterion/concepts/lineage-chain.md +62 -0
ONBOARDING.md
CHANGED
|
@@ -145,24 +145,22 @@ After activating each, walk its setup wizard to completion. Skip any optional in
|
|
| 145 |
- FluentCRM: `wp_fc_*` tables exist (subscribers, campaigns, etc.). Admin page renders.
|
| 146 |
- Fluent Support: `wp_fs_tickets` table exists. Admin page at `?page=fluent-support` renders. **Watch for the prefix-orphan trap** — if tables ended up at a non-standard prefix (e.g., from a cloned DB), that's a separate fix not part of fresh JNO.
|
| 147 |
|
| 148 |
-
### Step 5 —
|
| 149 |
|
| 150 |
-
|
| 151 |
|
| 152 |
-
|
| 153 |
-
git clone https://github.com/SleeperAgents/SA-Orchestration.git /tmp/sa-orchestration-src
|
| 154 |
-
```
|
| 155 |
-
|
| 156 |
-
Then copy the plugin tree into the local WP install:
|
| 157 |
|
| 158 |
```
|
| 159 |
-
cp -r
|
| 160 |
```
|
| 161 |
|
| 162 |
-
Adjust path syntax for the
|
| 163 |
|
| 164 |
**Verify**: `<wp-install>/wp-content/plugins/sa-orchestration/sa-orchestration.php` exists.
|
| 165 |
|
|
|
|
|
|
|
| 166 |
### Step 6 — Place the Asterion canonical corpus
|
| 167 |
|
| 168 |
The SA-Orchestration plugin reads its canonical content from a filterable path. For local JNO, point that path at the corpus copy in this repo.
|
|
|
|
| 145 |
- FluentCRM: `wp_fc_*` tables exist (subscribers, campaigns, etc.). Admin page renders.
|
| 146 |
- Fluent Support: `wp_fs_tickets` table exists. Admin page at `?page=fluent-support` renders. **Watch for the prefix-orphan trap** — if tables ended up at a non-standard prefix (e.g., from a cloned DB), that's a separate fix not part of fresh JNO.
|
| 147 |
|
| 148 |
+
### Step 5 — Install SA-Orchestration plugin (pre-staged in this repo)
|
| 149 |
|
| 150 |
+
**The plugin source is already in this repo at `<repo-root>/sa-orchestration/`** — no GitHub clone is needed. Operational doctrine MD files are at `<repo-root>/SA-orchestration MD/` for agent reference.
|
| 151 |
|
| 152 |
+
Copy (or symlink) the pre-staged plugin tree into the local WP install:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
|
| 154 |
```
|
| 155 |
+
cp -r <repo-root>/sa-orchestration <wp-content>/plugins/sa-orchestration
|
| 156 |
```
|
| 157 |
|
| 158 |
+
Adjust path syntax for the developer's OS. On Windows: use the WP install's `wp-content\plugins\` path. The dev's Claude resolves `<repo-root>` and `<wp-content>` from the developer's actual environment.
|
| 159 |
|
| 160 |
**Verify**: `<wp-install>/wp-content/plugins/sa-orchestration/sa-orchestration.php` exists.
|
| 161 |
|
| 162 |
+
If the pre-staged `sa-orchestration/` directory is missing for some reason, **stop and surface to the human**. Do not invent a clone URL. The seed should always include the plugin tree at `<repo-root>/sa-orchestration/`; absence indicates a corrupted seed, not a missing dependency.
|
| 163 |
+
|
| 164 |
### Step 6 — Place the Asterion canonical corpus
|
| 165 |
|
| 166 |
The SA-Orchestration plugin reads its canonical content from a filterable path. For local JNO, point that path at the corpus copy in this repo.
|
SA-orchestration MD/Archvie/MidCoast/CLAUDE.md
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# QB Inventory Bin Audit — Project Context for Claude
|
| 2 |
+
|
| 3 |
+
## What this is
|
| 4 |
+
A WordPress plugin for **MidCoast Engines** that manages a QuickBooks Desktop inventory audit system.
|
| 5 |
+
Two components work together:
|
| 6 |
+
|
| 7 |
+
1. **WordPress plugin** (`midcoast_audit.php` + `lib/` + `views/`) — hosted on WP Engine at `sleeperagents.wpengine.com`. Provides admin UI, database, and REST API.
|
| 8 |
+
2. **C# Windows Service** (`QBSyncService/`) — runs on the on-premises machine that hosts QuickBooks Desktop at MidCoast Engines. Polls WordPress every 60 seconds, executes QBXML commands against QB Desktop via COM, posts results back.
|
| 9 |
+
|
| 10 |
+
## Architecture
|
| 11 |
+
|
| 12 |
+
```
|
| 13 |
+
[MidCoast Engines — on-site QB machine] [WP Engine — internet]
|
| 14 |
+
QB Desktop (running)
|
| 15 |
+
C# Windows Service (QBSyncService.exe) ──HTTPS──▶ WordPress REST API
|
| 16 |
+
- polls /wp-json/qbinv/v1/sync/queue - stores sync queue
|
| 17 |
+
- executes QBXML via COM SDK - admin UI
|
| 18 |
+
- posts results back - heartbeat status
|
| 19 |
+
```
|
| 20 |
+
|
| 21 |
+
The C# service is developed on Thomas's laptop (VS 2026) and deployed to the QB machine on-site via Andrew using FileZilla. Thomas uses **Tailscale + RDP** for remote access to the QB machine without requiring anyone on-site.
|
| 22 |
+
|
| 23 |
+
## WordPress Plugin
|
| 24 |
+
|
| 25 |
+
### Entry point
|
| 26 |
+
`midcoast_audit.php` — registers autoloader, hooks, admin menu, REST API, SOAP endpoint.
|
| 27 |
+
|
| 28 |
+
### Key constant
|
| 29 |
+
`PUBLIC_AUDIT_KEY = 'steelblue123'` — used for the public-facing shortcode `[qbinv_audit_public]`.
|
| 30 |
+
|
| 31 |
+
### lib/ files
|
| 32 |
+
| File | Purpose |
|
| 33 |
+
|---|---|
|
| 34 |
+
| `DB.php` | Table names, `install()` (dbDelta), schema |
|
| 35 |
+
| `QBSync.php` | Queue helpers + QBWC SOAP service class |
|
| 36 |
+
| `REST.php` | REST endpoints consumed by the C# service |
|
| 37 |
+
| `Actions.php` | POST mutation handler; fires `qbinv_entry_changed` action on qty save |
|
| 38 |
+
| `Importer.php` | Legacy CSV import |
|
| 39 |
+
| `Router.php` | URL helpers |
|
| 40 |
+
| `Helpers.php` | Shared utilities |
|
| 41 |
+
| `QueryBuilder.php` | Dynamic query builder for parts/shelves browse |
|
| 42 |
+
| `TableRenderer.php` | HTML table output |
|
| 43 |
+
|
| 44 |
+
### views/ files
|
| 45 |
+
| File | Purpose |
|
| 46 |
+
|---|---|
|
| 47 |
+
| `Upload.php` | Import page — primary: live QB pull; secondary: CSV legacy |
|
| 48 |
+
| `QBSync.php` | Sync queue admin + settings (token, QBWC creds, .qwc download) |
|
| 49 |
+
| `Parts.php` | Browse/edit parts |
|
| 50 |
+
| `Shelves.php` | Browse/edit shelves |
|
| 51 |
+
| `Audit.php` | Official audit view |
|
| 52 |
+
|
| 53 |
+
### Database tables (all prefixed with `{wpdb->prefix}qbinv_`)
|
| 54 |
+
- `parts` — inventory parts (part_number, preferred_description, etc.)
|
| 55 |
+
- `locations` — bin/shelf locations
|
| 56 |
+
- `entries` — qty per part per location
|
| 57 |
+
- `uploads` — import history
|
| 58 |
+
- `sync_queue` — QB sync action queue
|
| 59 |
+
|
| 60 |
+
### REST endpoints (`/wp-json/qbinv/v1/`)
|
| 61 |
+
All require `X-QBSync-Token` header matching WP option `qbinv_sync_token`, **except** `/sync/interrupt` which requires `manage_options` capability.
|
| 62 |
+
|
| 63 |
+
| Method | Path | Purpose |
|
| 64 |
+
|---|---|---|
|
| 65 |
+
| GET | `/sync/queue` | Fetch up to 50 pending actions; auto-rescues stale processing rows |
|
| 66 |
+
| POST | `/sync/{id}/claim` | Mark action as processing (atomic); sets `processed_at` |
|
| 67 |
+
| POST | `/sync/{id}/done` | Save QB response, mark done; fires inventory parser if applicable |
|
| 68 |
+
| POST | `/sync/{id}/fail` | Save error message, mark error, increment retries |
|
| 69 |
+
| POST | `/sync/heartbeat` | C# service posts version+host+phase+stats; WP stores all |
|
| 70 |
+
| GET | `/sync/config` | Remote config (poll interval, mode, interrupt flag, etc.) |
|
| 71 |
+
| POST | `/sync/interrupt` | Admin sets abort flag (one-shot, auto-cleared on next config fetch) |
|
| 72 |
+
| POST | `/sync/update-status` | C# service reports self-update progress |
|
| 73 |
+
|
| 74 |
+
### WP options used
|
| 75 |
+
| Option | Purpose |
|
| 76 |
+
|---|---|
|
| 77 |
+
| `qbinv_sync_token` | API token — must match `appsettings.json ApiToken` |
|
| 78 |
+
| `qbinv_wc_username` | QBWC username (legacy SOAP path) |
|
| 79 |
+
| `qbinv_wc_password` | QBWC password (legacy SOAP path) |
|
| 80 |
+
| `qbinv_adjustment_account` | QB account name for InventoryAdjustmentAdd |
|
| 81 |
+
| `qbinv_auto_sync_qty` | Auto-enqueue QB adjustment when qty saved in WP |
|
| 82 |
+
| `qbinv_service_last_seen` | Last heartbeat timestamp — drives online/offline dot |
|
| 83 |
+
| `qbinv_service_host` | Machine name from last heartbeat |
|
| 84 |
+
| `qbinv_service_version` | Service version from last heartbeat |
|
| 85 |
+
| `qbinv_service_cycles` | Poll cycles completed since last service start |
|
| 86 |
+
| `qbinv_service_items_found` | Pending items found on last poll |
|
| 87 |
+
| `qbinv_service_qb_status` | QB connection status: not_attempted / connected / ok / error / interrupted |
|
| 88 |
+
| `qbinv_service_last_error` | Last error message from service |
|
| 89 |
+
| `qbinv_service_phase` | Current cycle phase string (e.g. "QB: executing 1/1 — ItemInventoryQueryRq") |
|
| 90 |
+
| `qbinv_service_log_tail` | Last 100 log lines (autoload=false — fetched explicitly) |
|
| 91 |
+
| `qbinv_sync_interrupt` | One-shot abort flag; set by admin Abort button; cleared on config read |
|
| 92 |
+
| `qbinv_mode` | `read_only` or `read_write` — gates write actions service-side |
|
| 93 |
+
|
| 94 |
+
## C# Windows Service (`QBSyncService/`)
|
| 95 |
+
|
| 96 |
+
### Files
|
| 97 |
+
| File | Purpose |
|
| 98 |
+
|---|---|
|
| 99 |
+
| `Program.cs` | Host bootstrap, Serilog, typed HttpClient registration |
|
| 100 |
+
| `Worker.cs` | BackgroundService poll loop — heartbeat then RunCycleAsync |
|
| 101 |
+
| `WordPressClient.cs` | Typed HTTP client for all WP REST calls |
|
| 102 |
+
| `QuickBooksSession.cs` | QB COM wrapper — static `RunSession()` pattern |
|
| 103 |
+
| `Models/SyncAction.cs` | Maps to sync_queue row; `BuildFullQbxml()` wraps snippet in envelope |
|
| 104 |
+
| `Models/SyncConfig.cs` | Remote config model deserialized from `/sync/config` |
|
| 105 |
+
| `appsettings.json` | Config — WP URL, API token, poll interval, QB company file |
|
| 106 |
+
|
| 107 |
+
### Key technical details — STA threading (critical)
|
| 108 |
+
|
| 109 |
+
**3-phase cycle design** — HTTP and COM are never interleaved:
|
| 110 |
+
1. **Phase 1 (HTTP)**: `GetPendingAsync` + `ClaimAsync` for all actions
|
| 111 |
+
2. **Phase 2 (COM)**: `QuickBooksSession.RunSession()` — opens QB, executes all actions, closes QB, all on one dedicated STA thread without any awaits or HTTP calls
|
| 112 |
+
3. **Phase 3 (HTTP)**: `CompleteAsync` / `FailAsync` for each result
|
| 113 |
+
|
| 114 |
+
**Why this matters**: QB's COM server invalidates the session if the STA thread is idle between calls. Any `await` inside the old loop (e.g. `await ClaimAsync()` between `Open()` and `Execute()`) would idle the STA thread long enough for QB to invalidate the session → `COM object separated from its underlying RCW`.
|
| 115 |
+
|
| 116 |
+
**`QuickBooksSession.RunSession()`** — static factory. Creates a dedicated STA thread, runs Open → body → Close as one uninterrupted block, joins the thread (10-minute timeout), re-throws any exception via `ExceptionDispatchInfo`. The `Execute()` method is a simple instance method — no marshaling needed because the caller is already on the STA thread.
|
| 117 |
+
|
| 118 |
+
**Session timeout**: `thread.Join(TimeSpan.FromMinutes(10))` — if QB hangs (frozen/crashed), throws `TimeoutException` after 10 minutes rather than blocking the service forever.
|
| 119 |
+
|
| 120 |
+
- **Late-bound COM**: Uses `Type.GetTypeFromProgID("QBXMLRP2.RequestProcessor")` — no compile-time SDK reference. SDK only required at runtime on the QB machine.
|
| 121 |
+
- Logs to `C:\ProgramData\QBSyncService\logs\qbsync-YYYYMMDD.log` and console.
|
| 122 |
+
|
| 123 |
+
### Remote interrupt / abort
|
| 124 |
+
- Admin clicks **Abort** in WP Admin → QB Sync Queue
|
| 125 |
+
- Browser POSTs to `/sync/interrupt` → sets `qbinv_sync_interrupt = true`
|
| 126 |
+
- Service reads `interrupt_requested: true` from next `/sync/config` call (within 60s); WP auto-clears the flag
|
| 127 |
+
- Service fails all claimed actions with "Interrupted by remote admin command." and skips QB session
|
| 128 |
+
- Interrupt only fires between actions — cannot cancel a mid-COM-call. Session timeout handles hung QB.
|
| 129 |
+
|
| 130 |
+
### Phase tracking
|
| 131 |
+
`_currentPhase` string updated throughout each cycle and sent in every heartbeat:
|
| 132 |
+
- `"idle"` — between cycles
|
| 133 |
+
- `"fetching queue"` — calling GetPending
|
| 134 |
+
- `"claiming (N action(s))"` — claiming loop
|
| 135 |
+
- `"opening QB session"` — before RunSession
|
| 136 |
+
- `"QB: executing N/M — ActionType"` — inside RunSession, per action
|
| 137 |
+
- `"reporting N result(s)"` — Phase 3 HTTP
|
| 138 |
+
- `"interrupted"` — after abort
|
| 139 |
+
- `"stopped"` — service shutdown
|
| 140 |
+
|
| 141 |
+
### NuGet packages
|
| 142 |
+
- `Microsoft.Extensions.Hosting.WindowsServices` — Windows Service registration
|
| 143 |
+
- `Serilog.Extensions.Hosting` + `Serilog.Settings.Configuration` + `Serilog.Sinks.Console` + `Serilog.Sinks.File` — structured logging
|
| 144 |
+
- `Microsoft.Extensions.Http` — `AddHttpClient()`
|
| 145 |
+
|
| 146 |
+
### appsettings.json (do not commit real token to public repo)
|
| 147 |
+
```json
|
| 148 |
+
{
|
| 149 |
+
"QBSync": {
|
| 150 |
+
"WordPressUrl": "https://sleeperagents.wpengine.com/",
|
| 151 |
+
"ApiToken": "...",
|
| 152 |
+
"PollIntervalSeconds": 60,
|
| 153 |
+
"QuickBooksCompanyFile": ""
|
| 154 |
+
}
|
| 155 |
+
}
|
| 156 |
+
```
|
| 157 |
+
|
| 158 |
+
## Deployment
|
| 159 |
+
|
| 160 |
+
### WordPress (WP Engine)
|
| 161 |
+
- FTP/SFTP files to live site after changes
|
| 162 |
+
- After deploying: **Settings → Permalinks → Save** to flush rewrite rules
|
| 163 |
+
- Purge WP Engine page cache after major changes
|
| 164 |
+
- **short_open_tag=On** is active on WP Engine — never write `<?` anywhere in PHP source (strings, comments, heredocs). Split as `'<' . '?'` in string literals.
|
| 165 |
+
|
| 166 |
+
### C# Service — publish path (important)
|
| 167 |
+
|
| 168 |
+
**The actual executable is one folder deeper than the publish root:**
|
| 169 |
+
```
|
| 170 |
+
QBSyncService\bin\Release\net8.0-windows\win-x64\publish\win-x64\
|
| 171 |
+
↑ THIS folder contains QBSyncService.exe
|
| 172 |
+
```
|
| 173 |
+
|
| 174 |
+
To publish: right-click `QBSyncService` in VS 2026 → Publish → Folder → self-contained, win-x64
|
| 175 |
+
|
| 176 |
+
### C# Service — deploy via Andrew + FileZilla
|
| 177 |
+
|
| 178 |
+
Andrew is the on-site IT contact. He transfers using FileZilla from the MCESleeperAgents Windows account.
|
| 179 |
+
|
| 180 |
+
**Steps for Andrew:**
|
| 181 |
+
1. `Stop-ScheduledTask -TaskName "QB Sync Service"` (Admin PowerShell)
|
| 182 |
+
2. Log in as Windows user **MCESleeperAgents** (pw: `MCESA26!`)
|
| 183 |
+
3. Open / restore FileZilla
|
| 184 |
+
4. Reconnect (click Reconnect icon or File → Reconnect)
|
| 185 |
+
5. **Right side** (remote/source): `/xfer/win-x64/publish/win-x64` ← one level IN from publish root
|
| 186 |
+
6. **Left side** (local/dest): `C:\QBSyncService`
|
| 187 |
+
7. Select all files on right → drag to left → Overwrite all
|
| 188 |
+
8. Switch back to Administrator account
|
| 189 |
+
9. `Start-ScheduledTask -TaskName "QB Sync Service"` (Admin PowerShell)
|
| 190 |
+
|
| 191 |
+
Confirm: first log line should read `QB Sync Service started. Base poll: 60s.` (not the old `Poll interval:` format).
|
| 192 |
+
|
| 193 |
+
### Remote access to QB machine
|
| 194 |
+
Tailscale + RDP. Tailscale installed on mcvmfarm2 and dev machine.
|
| 195 |
+
- RDP command: `mstsc /v:100.112.16.19`
|
| 196 |
+
- Login as: `mcvmfarm2\Administrator`
|
| 197 |
+
- Note: RDP on Server 2016 opens a **new session** — QB Desktop on the console and your RDP session are separate windows
|
| 198 |
+
|
| 199 |
+
## Current status (2026-04-14)
|
| 200 |
+
|
| 201 |
+
### WordPress ✓
|
| 202 |
+
- Plugin network-activated on `sleeperagents.wpengine.com` / `sleeperagents.org` ✓
|
| 203 |
+
- REST API routes live ✓
|
| 204 |
+
- Token set, heartbeat confirmed working ✓
|
| 205 |
+
- Multisite constants confirmed in LIVE `wp-config.php` ✓
|
| 206 |
+
- Phase tracking, abort button, live elapsed timer, auto-refresh (30s) all deployed ✓
|
| 207 |
+
- `qbinv_service_phase` option added — no dbDelta needed (it's an option, not a column)
|
| 208 |
+
|
| 209 |
+
### C# Service
|
| 210 |
+
- Deployed to `C:\QBSyncService\` on `mcvmfarm2` ✓
|
| 211 |
+
- Running under Task Scheduler as `mcvmfarm2\Administrator` ✓
|
| 212 |
+
- **Latest build in progress** — 3-phase STA fix + phase tracking + abort + session timeout
|
| 213 |
+
- Confirm new binary: first log line must say `Base poll:` not `Poll interval:`
|
| 214 |
+
- If log still shows old format → Andrew transferred from wrong folder (`publish\` root instead of `publish\win-x64\`)
|
| 215 |
+
|
| 216 |
+
### QB Desktop ✓
|
| 217 |
+
- Running on mcvmfarm2 under Administrator account
|
| 218 |
+
- Session 0 isolation resolved by switching to Task Scheduler
|
| 219 |
+
- SDK permission approved (one-time dialog — done)
|
| 220 |
+
|
| 221 |
+
### Task Scheduler
|
| 222 |
+
- Task name: **"QB Sync Service"**
|
| 223 |
+
- Runs as: `mcvmfarm2\Administrator` ("Run only when user is logged on")
|
| 224 |
+
- Trigger: At logon for Administrator
|
| 225 |
+
- Start: `Start-ScheduledTask -TaskName "QB Sync Service"`
|
| 226 |
+
- Stop: `Stop-ScheduledTask -TaskName "QB Sync Service"`
|
| 227 |
+
- **Critical**: task must run under the same Windows user that has QB Desktop open
|
| 228 |
+
|
| 229 |
+
### Known code gap — QB response parser not yet exercised
|
| 230 |
+
- `complete_action` in `REST.php` calls `QBInv_QBSync::parse_inventory_response($response)` for `ItemInventoryQueryRq` actions
|
| 231 |
+
- Parser upserts into `wp_qbinv_parts` and `wp_qbinv_entries`
|
| 232 |
+
- Has not been run against a real QB response yet — first successful sync will validate it
|
| 233 |
+
|
| 234 |
+
### Client machine details
|
| 235 |
+
- Machine: `mcvmfarm2` — Windows Server 2016, Hyper-V host
|
| 236 |
+
- RDP login: `mcvmfarm2\Administrator`
|
| 237 |
+
- Also available: `mcvmfarm2\MCESleeperAgent` (local admin) — FileZilla transfers only
|
| 238 |
+
- Tailscale IP: `100.112.16.19`
|
| 239 |
+
- Service binary: `C:\QBSyncService\QBSyncService.exe`
|
| 240 |
+
- Logs: `C:\ProgramData\QBSyncService\logs\qbsync-YYYYMMDD.log`
|
| 241 |
+
- QB company file dir: `C:\QuickBooks\` — if QB freezes, rename `<company>.TLG` → `.TLG.bak` and reopen
|
| 242 |
+
|
| 243 |
+
### On-site infrastructure (MidCoast Engines location)
|
| 244 |
+
- **Lantronix device server** — on local LAN, exposes AIS box serial port as raw TCP socket on port `10001`
|
| 245 |
+
- Connect via: `nc <lantronix-ip> 10001` — streams NMEA 0183 AIS sentences directly
|
| 246 |
+
- No Lantronix CPR software needed for Linux/TCP
|
| 247 |
+
- **Linux box** — on-site, running a webserver, on same LAN
|
| 248 |
+
- Plan: install Tailscale, use as persistent AIS reader
|
| 249 |
+
- Install Tailscale: `curl -fsSL https://tailscale.com/install.sh | sh && sudo tailscale up`
|
| 250 |
+
- **AIS data format**: NMEA 0183 (`!AIVDM` = other vessels, `!AIVDO` = own vessel) — needs decoder like `gpsd`
|
| 251 |
+
- **IDEC RJ1S-CL-D12 relay** — 12V DC coil, plug-in style. No reset switch — replace if failed (~$10-15)
|
| 252 |
+
|
| 253 |
+
## Diagnosing service issues
|
| 254 |
+
|
| 255 |
+
- Run EXE directly for console output: `C:\QBSyncService\QBSyncService.exe`
|
| 256 |
+
- Check logs: `C:\ProgramData\QBSyncService\logs\qbsync-YYYYMMDD.log`
|
| 257 |
+
- QB frozen: rename `C:\QuickBooks\<company>.TLG` → `.TLG.bak`, reopen QB
|
| 258 |
+
- Task not starting: Task Scheduler → right-click → Run → check Last Run Result
|
| 259 |
+
- Wrong binary deployed: check log first line — must say `Base poll:` not `Poll interval:`
|
| 260 |
+
- Service appears stuck: use **Abort** button in WP Admin → QB Sync Queue; flag picked up within 60s
|
| 261 |
+
|
| 262 |
+
## Pending / future work
|
| 263 |
+
- **First successful sync** — confirm `ItemInventoryQueryRq` goes pending→processing→done and parts table populates
|
| 264 |
+
- **Reset & Re-Import** — after successful sync, flush bad CSV data with "Reset & Re-Import from QB"
|
| 265 |
+
- **QB auto-launch on Administrator login** — Task Scheduler task to open QB Desktop on login so it survives reboots
|
| 266 |
+
- **AIS integration** — Linux box reads Lantronix TCP → gpsd → decoded vessel JSON
|
| 267 |
+
- **Auto-start hardening** — verify QB Desktop, service, and Tailscale all survive cold power cycle
|
SA-orchestration MD/Archvie/MidCoast/DEPLOY.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# QB Sync — Deploy Instructions (for Mark)
|
| 2 |
+
|
| 3 |
+
You publish two things: **C# binaries** to WP Engine's uploads folder, and **PHP files** to the plugin directory. Andrew downloads one file from WP Engine and double-clicks it. That's the whole chain.
|
| 4 |
+
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
## One-time setup (first deploy only)
|
| 8 |
+
|
| 9 |
+
On WP Engine, create this folder so the installer has a download target:
|
| 10 |
+
```
|
| 11 |
+
/wp-content/uploads/qbsync/
|
| 12 |
+
```
|
| 13 |
+
|
| 14 |
+
Via WP Engine's SFTP/SSH, or the WP Engine file manager. Make sure it's web-reachable — test by browsing to:
|
| 15 |
+
```
|
| 16 |
+
https://sleeperagents.org/wp-content/uploads/qbsync/
|
| 17 |
+
```
|
| 18 |
+
You should get a directory listing or a 403 (either is fine; a 404 means the folder isn't there).
|
| 19 |
+
|
| 20 |
+
---
|
| 21 |
+
|
| 22 |
+
## Compile
|
| 23 |
+
|
| 24 |
+
In VS 2026 on the laptop:
|
| 25 |
+
|
| 26 |
+
1. **Publish QBSyncService**
|
| 27 |
+
- Right-click `QBSyncService` project → **Publish** → **Folder**
|
| 28 |
+
- Target: `bin\Release\net8.0-windows\win-x64\publish\win-x64\`
|
| 29 |
+
- Configuration: `Release | win-x64`
|
| 30 |
+
- Deployment mode: **Self-contained**
|
| 31 |
+
- File publish options: **Produce single file** ✓ / **Enable ReadyToRun** (optional, faster startup)
|
| 32 |
+
- Publish
|
| 33 |
+
- Expected output: one file `QBSyncService.exe` (~70 MB)
|
| 34 |
+
|
| 35 |
+
2. **Publish QBSyncUpdater**
|
| 36 |
+
- Right-click `QBSyncUpdater` project → **Publish** → **Folder**
|
| 37 |
+
- Same settings as above
|
| 38 |
+
- Expected output: one file `QBSyncUpdater.exe` (~15 MB)
|
| 39 |
+
|
| 40 |
+
---
|
| 41 |
+
|
| 42 |
+
## Upload to WP Engine
|
| 43 |
+
|
| 44 |
+
Upload **only these two files** to `/wp-content/uploads/qbsync/`:
|
| 45 |
+
|
| 46 |
+
```
|
| 47 |
+
QBSyncService.exe
|
| 48 |
+
QBSyncUpdater.exe
|
| 49 |
+
```
|
| 50 |
+
|
| 51 |
+
You do NOT need to upload `appsettings.json` or `updater.json` — the installer generates them on Andrew's machine from his on-screen answers (baked defaults + any overrides he types).
|
| 52 |
+
|
| 53 |
+
Verify both files are reachable:
|
| 54 |
+
```
|
| 55 |
+
https://sleeperagents.org/wp-content/uploads/qbsync/QBSyncService.exe
|
| 56 |
+
https://sleeperagents.org/wp-content/uploads/qbsync/QBSyncUpdater.exe
|
| 57 |
+
```
|
| 58 |
+
Both should start downloading when clicked in a browser.
|
| 59 |
+
|
| 60 |
+
---
|
| 61 |
+
|
| 62 |
+
## Deploy PHP changes
|
| 63 |
+
|
| 64 |
+
Via SFTP to WP Engine, upload the changed plugin files:
|
| 65 |
+
|
| 66 |
+
```
|
| 67 |
+
lib/REST.php (adds /sync/restart, restart_requested, updater update channel)
|
| 68 |
+
lib/QBSync.php (iterator back, no OwnerID)
|
| 69 |
+
```
|
| 70 |
+
|
| 71 |
+
After upload:
|
| 72 |
+
- WP Admin → Settings → Permalinks → Save (flushes the REST route cache so `/sync/restart` is live)
|
| 73 |
+
- Purge WP Engine page cache
|
| 74 |
+
|
| 75 |
+
Verify the new endpoint exists (should return 401 without a token — that's good, means the route registered):
|
| 76 |
+
```
|
| 77 |
+
curl -X POST https://sleeperagents.org/wp-json/qbinv/v1/sync/restart
|
| 78 |
+
```
|
| 79 |
+
|
| 80 |
+
---
|
| 81 |
+
|
| 82 |
+
## Get the token to Andrew
|
| 83 |
+
|
| 84 |
+
The installer needs the API token (value of the WP option `qbinv_sync_token`). You have two options:
|
| 85 |
+
|
| 86 |
+
- **A. Email/SMS it to Andrew** — he types it in during install (one-time).
|
| 87 |
+
- **B. Pre-bake it** — edit `QBSyncUpdater/InteractiveInstall.cs`, set `DefaultApiToken` to the real token, republish. Andrew just hits Enter through that prompt. Don't commit the token to git.
|
| 88 |
+
|
| 89 |
+
Option B is smoother for Andrew. Option A keeps the token out of any binary that's sitting on WP Engine's public `/uploads/` folder.
|
| 90 |
+
|
| 91 |
+
---
|
| 92 |
+
|
| 93 |
+
## Send Andrew this link
|
| 94 |
+
|
| 95 |
+
> Download and run this file on the QuickBooks machine:
|
| 96 |
+
> https://sleeperagents.org/wp-content/uploads/qbsync/QBSyncUpdater.exe
|
| 97 |
+
>
|
| 98 |
+
> Detailed steps in INSTALL.md (also attached).
|
| 99 |
+
|
| 100 |
+
That's it. Andrew gets ONE link. The installer handles everything else.
|
| 101 |
+
|
| 102 |
+
---
|
| 103 |
+
|
| 104 |
+
## After Andrew's install
|
| 105 |
+
|
| 106 |
+
You should see within 60 seconds:
|
| 107 |
+
|
| 108 |
+
- WP Admin → **QB Inventory → QB Sync** shows a green dot with a recent heartbeat
|
| 109 |
+
- Service version `1.0.0.0`, host `MCVMFARM2`, QB: OK
|
| 110 |
+
- **Two** scheduled tasks on the machine:
|
| 111 |
+
- `QB Sync Service` — the actual worker
|
| 112 |
+
- `QB Sync Updater` — the monitor/patcher
|
| 113 |
+
|
| 114 |
+
From now on:
|
| 115 |
+
- Click **Restart** in WP Admin → updater cycles the service within 30s
|
| 116 |
+
- Push a new `QBSyncService.exe` to `/wp-content/uploads/qbsync/` and set `qbinv_update_available=true` + `qbinv_update_url` → updater downloads it and swaps it in on its next poll. No FileZilla. No Andrew.
|
| 117 |
+
- Same channel works in reverse for the updater itself via `qbinv_updater_update_*` options.
|
| 118 |
+
|
| 119 |
+
---
|
| 120 |
+
|
| 121 |
+
## Rolling back
|
| 122 |
+
|
| 123 |
+
If the new updater misbehaves, SSH to WP Engine and replace `QBSyncUpdater.exe` with the previous known-good copy. On the QB machine, the **running** updater won't notice (it already loaded) — you'd need Andrew to re-run the installer. Keep a backup copy of each published version in a dated subfolder:
|
| 124 |
+
|
| 125 |
+
```
|
| 126 |
+
/wp-content/uploads/qbsync/archive/2026-04-21/QBSyncUpdater.exe
|
| 127 |
+
/wp-content/uploads/qbsync/archive/2026-04-21/QBSyncService.exe
|
| 128 |
+
```
|
SA-orchestration MD/Archvie/MidCoast/INSTALL.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# QB Sync — Installation (for Andrew)
|
| 2 |
+
|
| 3 |
+
**What this is:** A small background service that lets MidCoast Engines' WordPress site read and update QuickBooks inventory automatically. Once installed it starts itself at logon and stays out of the way — you'll see a small icon in the system tray when it's running.
|
| 4 |
+
|
| 5 |
+
**What you'll do:** Download one file. Run it. Click through a short setup window. Check for a tray icon. Done.
|
| 6 |
+
|
| 7 |
+
**Time required:** About 90 seconds.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## 1. Download
|
| 12 |
+
|
| 13 |
+
Open this link in any browser on the QuickBooks machine (`mcvmfarm2`):
|
| 14 |
+
|
| 15 |
+
> https://sleeperagents.org/wp-content/uploads/qbsync/QBSyncUpdater.exe
|
| 16 |
+
|
| 17 |
+
Save the file anywhere — Desktop is fine. It's about 20 MB.
|
| 18 |
+
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
## 2. Run it as administrator
|
| 22 |
+
|
| 23 |
+
Find the downloaded `QBSyncUpdater.exe`.
|
| 24 |
+
|
| 25 |
+
**Right-click → Run as administrator.**
|
| 26 |
+
|
| 27 |
+
Windows will show a UAC prompt ("Do you want to allow this app to make changes?"). Click **Yes**.
|
| 28 |
+
|
| 29 |
+
A window opens titled **"QB Sync — Installer"**. This is the only screen you'll interact with.
|
| 30 |
+
|
| 31 |
+
---
|
| 32 |
+
|
| 33 |
+
## 3. Review the setup window
|
| 34 |
+
|
| 35 |
+
The window has three sections before you click Install:
|
| 36 |
+
|
| 37 |
+
### Environment (top)
|
| 38 |
+
Read-only info the installer detected about your machine. Confirms:
|
| 39 |
+
- **Machine / Windows user** — should say `MCVMFARM2` and `MCVMFARM2\Administrator`.
|
| 40 |
+
- **Admin rights** — should be green ✓.
|
| 41 |
+
- **QuickBooks SDK** — if green ✓, you're ready. If red ✗ with an **Install SDK now** button, click that button *before* clicking Install. It auto-downloads and silently installs the Intuit SDK (takes 1–2 minutes).
|
| 42 |
+
- **QB company file** — shows what it detected in `C:\QuickBooks\`. Informational only.
|
| 43 |
+
|
| 44 |
+
### Configuration (middle)
|
| 45 |
+
Three fields, mostly pre-filled:
|
| 46 |
+
- **WordPress URL** — already set to `https://sleeperagents.org/`. Leave alone.
|
| 47 |
+
- **API token** — either pre-filled or blank. **If blank, Mark will send you the value to paste in.** It's a long random string — paste exactly, no spaces.
|
| 48 |
+
- **QB company file** — leave blank (auto-detects whatever QB has open).
|
| 49 |
+
|
| 50 |
+
There's a **Test Connection** button next to the token field. Click it *before* installing to confirm WordPress accepts your token. You should see a green "Token accepted" line in the log area at the bottom. If you see red, double-check the token with Mark before proceeding.
|
| 51 |
+
|
| 52 |
+
### Install button (bottom)
|
| 53 |
+
Click **Install**. Progress bar and status log fill in:
|
| 54 |
+
|
| 55 |
+
```
|
| 56 |
+
✓ Existing tasks stopped
|
| 57 |
+
✓ Service downloaded (70 MB)
|
| 58 |
+
✓ Updater copied to C:\QBSyncService\QBSyncUpdater.exe
|
| 59 |
+
✓ Wrote appsettings.json
|
| 60 |
+
✓ Wrote updater.json
|
| 61 |
+
✓ Registered "QB Sync Updater"
|
| 62 |
+
✓ Registered "QB Sync Service"
|
| 63 |
+
✓ Started "QB Sync Updater"
|
| 64 |
+
✓ Started "QB Sync Service"
|
| 65 |
+
✓ Reached https://sleeperagents.org/wp-json/qbinv/v1/sync/config — token accepted.
|
| 66 |
+
|
| 67 |
+
════ Installation complete and verified. ════
|
| 68 |
+
```
|
| 69 |
+
|
| 70 |
+
When you see **"Installation complete and verified"**, click **Close**.
|
| 71 |
+
|
| 72 |
+
---
|
| 73 |
+
|
| 74 |
+
## 4. Find the tray icon
|
| 75 |
+
|
| 76 |
+
Within ~30 seconds of install, a small circle icon should appear in your system tray (bottom-right corner, near the clock).
|
| 77 |
+
|
| 78 |
+
- **Green** ✓ — everything healthy.
|
| 79 |
+
- **Amber** — WordPress has work queued; the service is about to act on it.
|
| 80 |
+
- **Red** ✗ — something's wrong. Hover for details.
|
| 81 |
+
- **Grey** — starting up / missing config.
|
| 82 |
+
|
| 83 |
+
### Windows 11: pin the icon so it stays visible
|
| 84 |
+
|
| 85 |
+
On Windows 11, new tray icons hide behind the ⌃ chevron by default. To pin it:
|
| 86 |
+
|
| 87 |
+
1. Click the ⌃ chevron (shows hidden icons).
|
| 88 |
+
2. **Drag the QB Sync circle icon** from the overflow panel down into the visible tray area.
|
| 89 |
+
3. Release. It now stays visible permanently.
|
| 90 |
+
|
| 91 |
+
### Windows 10 / Server 2016
|
| 92 |
+
|
| 93 |
+
Usually visible immediately. If not, right-click the taskbar → Taskbar settings → scroll to *Notification area* → *Select which icons appear on the taskbar* → turn on **QB Sync**.
|
| 94 |
+
|
| 95 |
+
---
|
| 96 |
+
|
| 97 |
+
## 5. Test the tray icon
|
| 98 |
+
|
| 99 |
+
Right-click the tray icon. You should see this menu:
|
| 100 |
+
|
| 101 |
+
```
|
| 102 |
+
QB Sync — Last poll: 12s ago
|
| 103 |
+
────────────────────
|
| 104 |
+
Open Status Window…
|
| 105 |
+
Open Admin in Browser
|
| 106 |
+
Open Log Folder
|
| 107 |
+
────────────────────
|
| 108 |
+
Restart Service
|
| 109 |
+
Force Config Poll Now
|
| 110 |
+
────────────────────
|
| 111 |
+
Exit
|
| 112 |
+
```
|
| 113 |
+
|
| 114 |
+
**Double-click the tray icon** to open the Status Window. Confirm it shows:
|
| 115 |
+
- Green dot + "Service is healthy"
|
| 116 |
+
- "Last WP poll: Ns ago" (updating every second)
|
| 117 |
+
- QB SDK: ✓ COM ProgID present
|
| 118 |
+
- Log tail scrolling at the bottom
|
| 119 |
+
|
| 120 |
+
If all that looks good, close the Status Window (it hides back to the tray — the service keeps running) and you're done.
|
| 121 |
+
|
| 122 |
+
---
|
| 123 |
+
|
| 124 |
+
## That's it
|
| 125 |
+
|
| 126 |
+
Nothing else to do. The service runs automatically from now on, including after reboots (as long as Administrator logs in).
|
| 127 |
+
|
| 128 |
+
You won't need FileZilla for this service again — Mark can push updates from WordPress and the service installs them itself on its next poll.
|
| 129 |
+
|
| 130 |
+
---
|
| 131 |
+
|
| 132 |
+
## If something doesn't look right
|
| 133 |
+
|
| 134 |
+
**No tray icon after install:**
|
| 135 |
+
- Open Task Scheduler (Start → type "Task Scheduler"). Look for two tasks: `QB Sync Service` and `QB Sync Updater`. Both should show "Running" status.
|
| 136 |
+
- If they say "Ready" instead, right-click each one → Run.
|
| 137 |
+
- On Windows 11 check the ⌃ chevron (step 4 above).
|
| 138 |
+
|
| 139 |
+
**Red dot after install:**
|
| 140 |
+
- Right-click tray → **Open Status Window**. Read the "Last WP error" line — that's the specific problem.
|
| 141 |
+
- Most common: token mismatch. Right-click tray → Exit, re-run installer, pay close attention to the token field.
|
| 142 |
+
|
| 143 |
+
**"Installation complete, connection not verified":**
|
| 144 |
+
- The install still worked — just the token was wrong or WP was unreachable.
|
| 145 |
+
- Either re-run the installer with the corrected token, or edit these files directly and restart the tasks:
|
| 146 |
+
- `C:\QBSyncService\appsettings.json`
|
| 147 |
+
- `C:\QBSyncService\updater.json`
|
| 148 |
+
|
| 149 |
+
**Send Mark a screenshot** of the Status Window (or the install log area) if anything looks off — it tells us exactly which step failed.
|
| 150 |
+
|
| 151 |
+
---
|
| 152 |
+
|
| 153 |
+
## If you need to uninstall
|
| 154 |
+
|
| 155 |
+
Right-click the tray icon → Exit. Then from an Administrator Command Prompt:
|
| 156 |
+
|
| 157 |
+
```
|
| 158 |
+
C:\QBSyncService\QBSyncUpdater.exe --uninstall
|
| 159 |
+
```
|
| 160 |
+
|
| 161 |
+
Both scheduled tasks are removed and `C:\QBSyncService\` is deleted. Logs in `C:\ProgramData\QBSyncService\logs\` are left behind for reference.
|
SA-orchestration MD/Archvie/MidCoast/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
# MidCoastEngines
|
SA-orchestration MD/Archvie/sa-core/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Core
|
| 2 |
+
|
| 3 |
+
The required substrate of the SleeperAgent framework.
|
| 4 |
+
|
| 5 |
+
A space is a SleeperAgent space only if Core is online underneath it. Everything above Core is **manufactured processing** — subsystems built on top of Core's primitive set. The primitive set is closed; subsystems extend the framework by composition, not by adding new primitives.
|
| 6 |
+
|
| 7 |
+
Core is a WordPress plugin. It ships as `sa-core` on disk. It is the unified package into which every prior Sleeper Agents subsystem (`sleeperagent/`, `saws_plugin/`, `CMP_JNO/`, `sleeperagents-svg-chat/`, `sleeperagents-svg-workspace/`, `sleeperagents-organizations/`, `sa-jira-bridge/`, `take2/`, `carma-audit/`) absorbs over time.
|
| 8 |
+
|
| 9 |
+
## What Core provides
|
| 10 |
+
|
| 11 |
+
- **Primitive layer** — the closed set of shapes the field is built from: Entity, Edge, InfluenceRing, Membrane, IOPort, ACL, GroupingOverlay.
|
| 12 |
+
- **Orchestration** — SubTokenEvent (every internal step visible to the billing principal), GeodesicMarker + GeodesicSeeder (memory of known-failure paths, pre-prompt seeding around them), StructuralAudit (time-indexed readout of attributed acts).
|
| 13 |
+
- **Billing** — PricingPolicy (decomposed cost calculation), CredentialPool (multi-tenant encrypted credentials), TokenLedger (immutable, settlement-ready).
|
| 14 |
+
- **Packaging** — Capability registry, Package, PackageAssignment (binds package to org/subdomain over time), CapabilityGate (the runtime yes/no with audited denials), SiteProvisioner (in-site activation handler for WPEngine clones).
|
| 15 |
+
- **Operating memory** — `SA_Operating_Memory` ingests filesystem trees (repo → folder → file → class/function/heading → method/paragraph → line) as entities at bands 0–5. `SA_Doc_Lens` parses markdown; `SA_Code_Lens` parses PHP via `token_get_all` (no execution). Self-hosting (Pillar 0.9): our own `.md` and `.php` files are navigable as first-class entities.
|
| 16 |
+
- **Adapter contract** — `SA_Provider_Adapter` interface. `SA_Dummy_Adapter` is the reference implementation and conformance anchor.
|
| 17 |
+
|
| 18 |
+
## Subsystem posture
|
| 19 |
+
|
| 20 |
+
Subsystems sit on a spectrum from *manual mirror* to *discernment*:
|
| 21 |
+
|
| 22 |
+
- **Manual mirror** — records what the user does, reflects it back, lets them manually re-apply. Low ambition, low risk.
|
| 23 |
+
- **Discernment** — infers what the user means, proposes a default path, asks the user to tune small corrections. High ambition, higher value.
|
| 24 |
+
|
| 25 |
+
Core biases every subsystem toward discernment. Given the right contextual knowledge, the human's role is **tuning perception**, not operating tools. The machine simulates perception across the spectrum; the human corrects the simulation through small, audited adjustments.
|
| 26 |
+
|
| 27 |
+
Core itself is neither; Core is the substrate. Discernment is expressed by subsystems built above.
|
| 28 |
+
|
| 29 |
+
## Status
|
| 30 |
+
|
| 31 |
+
Alpha. Phase 2 Step 1 of 10.
|
| 32 |
+
|
| 33 |
+
Delivered: schema + interfaces + primitive/orchestration/billing/packaging classes + reference dummy adapter + structural audit. Activating the plugin creates all `{wp_prefix}sa_*` tables idempotently via `dbDelta`.
|
| 34 |
+
|
| 35 |
+
**Delivered in the second slice (executor + REST + admin UI):**
|
| 36 |
+
|
| 37 |
+
- `SA_Provider_Registry` — adapter lookup with capability-flag selection (replaces the legacy binary routing).
|
| 38 |
+
- `SA_Context_Piper` — LLM-mediated context selection via edge walk. Given a root entity, gathers neighbors, asks the LLM which are relevant (recorded as a `router` sub-token event), folds selected payloads into the prompt. This is the concrete "context piping via tree-grid" mechanism.
|
| 39 |
+
- `SA_Executor` — end-to-end chain: `context piping → geodesic seeding → adapter invocation → sub-token recording → parent + response entities → edges → token ledger → structural audit`.
|
| 40 |
+
- REST routes at `/wp-json/sa-core/v1/`:
|
| 41 |
+
- `POST /prompt` — run a prompt (optional `root_entity_id` enables context piping).
|
| 42 |
+
- `GET /prompt/{id}/trace` — full sub-token graph for a prompt.
|
| 43 |
+
- `POST /subtoken/{id}/verdict` — mark good/bad (bad auto-seeds a geodesic marker).
|
| 44 |
+
- `GET /memory?path=...` — resolve a path expression to an entity.
|
| 45 |
+
- `POST /memory/ingest` — run `ingest_root` (admin only).
|
| 46 |
+
- WP admin page *SA Core → Chat* with textarea, optional root-entity input, sub-token trace, and per-step verdict buttons.
|
| 47 |
+
|
| 48 |
+
**Not yet delivered:**
|
| 49 |
+
|
| 50 |
+
- Presentation layer (zoom-quantum engine, circle primitive, halo renderer, perspective projection). Build order Step 2.
|
| 51 |
+
- Migration from the legacy `saws_prompts` / `saws_sessions` tables into `sa_entity` + `sa_token_ledger`. Build order Step 4, Triage item 1.
|
| 52 |
+
- WPEngine clone-and-route API client. `SA_Site_Provisioner::activate_site()` picks up *after* WPEngine has cloned the template and routed the subdomain.
|
| 53 |
+
- Live provider adapters (OpenAI, Anthropic, Gemini, local) beyond the dummy. Build order Step 8.
|
| 54 |
+
|
| 55 |
+
## Install
|
| 56 |
+
|
| 57 |
+
1. Drop the `sa-core/` directory into `wp-content/plugins/` on the target WordPress site.
|
| 58 |
+
2. Activate *Sleeper Agents Core* in wp-admin.
|
| 59 |
+
3. All tables with prefix `{wp_prefix}sa_*` are created idempotently.
|
| 60 |
+
4. Safe to activate alongside existing Sleeper Agents plugins. No name collisions, no admin menus (yet), no REST routes (yet).
|
| 61 |
+
|
| 62 |
+
Requires PHP 8.1+ and WordPress 6.3+. Production deployments should install libsodium (the CredentialPool falls back to AES-256-CBC via OpenSSL if sodium is absent; the fallback works but is not production-grade).
|
| 63 |
+
|
| 64 |
+
## Database tables
|
| 65 |
+
|
| 66 |
+
All prefixed `{wp_prefix}sa_`:
|
| 67 |
+
|
| 68 |
+
| Table | Role |
|
| 69 |
+
|---|---|
|
| 70 |
+
| `entity` | Universal unit of the field |
|
| 71 |
+
| `edge` | Typed, weighted, band-gated relationships |
|
| 72 |
+
| `influence_ring` | Concentric sphere-of-influence bands |
|
| 73 |
+
| `membrane` | Per-entity veils |
|
| 74 |
+
| `io_port` | Typed anchors on membraned entities |
|
| 75 |
+
| `acl` | Per-entity access control, four axes |
|
| 76 |
+
| `grouping_overlay` | Attributed, non-destructive re-parentings |
|
| 77 |
+
| `subtoken_event` | Every internal orchestration step |
|
| 78 |
+
| `geodesic_marker` | Known-failure memory |
|
| 79 |
+
| `structural_audit` | Time-indexed readout of attributed acts |
|
| 80 |
+
| `pricing_policy` | Per-org/provider/model cost policy |
|
| 81 |
+
| `credential_pool` | Multi-tenant encrypted credentials |
|
| 82 |
+
| `token_ledger` | Immutable, cost-decomposed, settlement-ready |
|
| 83 |
+
| `package` | Purchased SKU with enumerated capabilities |
|
| 84 |
+
| `package_assignment` | Binds a package to an org (subdomain) over time |
|
| 85 |
+
| `capability` | Enumerable, per-subsystem permission strings |
|
| 86 |
+
|
| 87 |
+
## Layout
|
| 88 |
+
|
| 89 |
+
```
|
| 90 |
+
sa-core/
|
| 91 |
+
├── sa-core.php # plugin header + hooks
|
| 92 |
+
├── includes/
|
| 93 |
+
│ ├── class-sa-core.php # autoload + bootstrap
|
| 94 |
+
│ ├── class-sa-migrations.php # schema install for every Core table
|
| 95 |
+
│ ├── interfaces/
|
| 96 |
+
│ │ └── interface-provider-adapter.php
|
| 97 |
+
│ ├── primitives/
|
| 98 |
+
│ ├── orchestration/
|
| 99 |
+
│ ├── billing/
|
| 100 |
+
│ ├── packaging/
|
| 101 |
+
│ ├── memory/
|
| 102 |
+
│ │ ├── class-sa-operating-memory.php
|
| 103 |
+
│ │ ├── class-sa-doc-lens.php
|
| 104 |
+
│ │ └── class-sa-code-lens.php
|
| 105 |
+
│ ├── executor/
|
| 106 |
+
│ │ ├── class-sa-provider-registry.php
|
| 107 |
+
│ │ ├── class-sa-context-piper.php
|
| 108 |
+
│ │ └── class-sa-executor.php
|
| 109 |
+
│ ├── rest/
|
| 110 |
+
│ │ ├── class-sa-rest.php
|
| 111 |
+
│ │ ├── class-sa-rest-prompt.php
|
| 112 |
+
│ │ ├── class-sa-rest-verdict.php
|
| 113 |
+
│ │ └── class-sa-rest-memory.php
|
| 114 |
+
│ ├── admin/
|
| 115 |
+
│ │ └── class-sa-admin.php
|
| 116 |
+
│ └── adapters/
|
| 117 |
+
│ └── class-sa-dummy-adapter.php
|
| 118 |
+
├── templates/
|
| 119 |
+
│ └── admin-chat.php
|
| 120 |
+
├── assets/
|
| 121 |
+
│ ├── admin-chat.css
|
| 122 |
+
│ └── admin-chat.js
|
| 123 |
+
├── docs/
|
| 124 |
+
│ └── ARCHITECTURE.md # the canonical spec
|
| 125 |
+
├── LICENSE
|
| 126 |
+
└── README.md
|
| 127 |
+
```
|
| 128 |
+
|
| 129 |
+
## Operating memory — map any .md or .php location to an entity
|
| 130 |
+
|
| 131 |
+
Register a root once:
|
| 132 |
+
|
| 133 |
+
```php
|
| 134 |
+
SA_Operating_Memory::register_root('sa-core', SA_CORE_DIR);
|
| 135 |
+
```
|
| 136 |
+
|
| 137 |
+
Then resolve any location along the band hierarchy:
|
| 138 |
+
|
| 139 |
+
```php
|
| 140 |
+
// Band 0 — the repo root
|
| 141 |
+
$repo = SA_Operating_Memory::view('sa-core/');
|
| 142 |
+
|
| 143 |
+
// Band 1 — a folder
|
| 144 |
+
$primitives = SA_Operating_Memory::view('sa-core/includes/primitives/');
|
| 145 |
+
|
| 146 |
+
// Band 2 — a file
|
| 147 |
+
$arch = SA_Operating_Memory::view('sa-core/docs/ARCHITECTURE.md');
|
| 148 |
+
$ent = SA_Operating_Memory::view('sa-core/includes/primitives/class-sa-entity.php');
|
| 149 |
+
|
| 150 |
+
// Band 3 — a markdown heading or a PHP class
|
| 151 |
+
$pillar0 = SA_Operating_Memory::view('sa-core/docs/ARCHITECTURE.md:Pillar 0');
|
| 152 |
+
$class = SA_Operating_Memory::view('sa-core/includes/primitives/class-sa-entity.php:SA_Entity');
|
| 153 |
+
|
| 154 |
+
// Band 4 — a sub-heading, a PHP method, or a PHP property
|
| 155 |
+
$create = SA_Operating_Memory::view('sa-core/includes/primitives/class-sa-entity.php:SA_Entity::create');
|
| 156 |
+
$id_prop = SA_Operating_Memory::view('sa-core/includes/primitives/class-sa-entity.php:SA_Entity::$id');
|
| 157 |
+
$subhead = SA_Operating_Memory::view('sa-core/docs/ARCHITECTURE.md:Canonical glossary::Entity');
|
| 158 |
+
|
| 159 |
+
// Band 5 — a specific line
|
| 160 |
+
$line_42 = SA_Operating_Memory::view('sa-core/includes/primitives/class-sa-entity.php#42');
|
| 161 |
+
```
|
| 162 |
+
|
| 163 |
+
Each `view()` call is idempotent and deterministic — the same expression always returns the same entity id (hash of the expression). Entities persist to `sa_entity` once viewed, so they can be annotated (verdict), wrapped (membrane), connected (edges), or re-parented (grouping overlay) like any other entity.
|
| 164 |
+
|
| 165 |
+
For bulk ingestion to band 2 (file-level, one pass across the whole repo):
|
| 166 |
+
|
| 167 |
+
```php
|
| 168 |
+
SA_Operating_Memory::ingest_root('sa-core', [
|
| 169 |
+
'org_id' => $org_id,
|
| 170 |
+
'created_by' => $user_id,
|
| 171 |
+
]);
|
| 172 |
+
```
|
| 173 |
+
|
| 174 |
+
Band 3+ (classes, methods, headings) are materialized lazily on first `view()` to keep the ingestion cheap.
|
| 175 |
+
|
| 176 |
+
## Deployment posture
|
| 177 |
+
|
| 178 |
+
One WordPress site per customer on WPEngine, on its own subdomain. `sa-core` is activated on every provisioned site. `SA_Site_Provisioner::activate_site()` is the in-site activation handler called after WPEngine clones the template and routes the subdomain.
|
| 179 |
+
|
| 180 |
+
Each subdomain maps to one `org_id`; `SA_Site_Provisioner::current_org_id()` resolves it. The active `SA_Package_Assignment` for that org determines which capabilities are enabled. `SA_Capability_Gate::allows()` is the runtime check every subsystem consults.
|
| 181 |
+
|
| 182 |
+
## See also
|
| 183 |
+
|
| 184 |
+
- `docs/ARCHITECTURE.md` — the canonical spec this plugin is built against.
|
| 185 |
+
- The legacy working tree at `../ChatBot/` (private) — contains the pre-absorption subsystems that migrate into Core over Build order steps 4–7.
|
SA-orchestration MD/Archvie/sa-core/docs/ARCHITECTURE.md
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
SA-orchestration MD/Archvie/sa-core/docs/specs/01-ontology.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MissionNet Ontology (v0.1)
|
| 2 |
+
|
| 3 |
+
*Implementation © Sleeper Agents LLC. Conceptual framework authored independently by Mark Holak; see `docs/specs/concepts/`.*
|
| 4 |
+
|
| 5 |
+
This is the vocabulary lock. Every downstream doc, every class, every log message, and every UI surface uses these terms precisely. Drift here = drift everywhere.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Primary nouns
|
| 10 |
+
|
| 11 |
+
### Core
|
| 12 |
+
|
| 13 |
+
The required substrate. One WordPress plugin (`sa-core`). A space is a SleeperAgent space only when Core is online underneath it.
|
| 14 |
+
|
| 15 |
+
### Realm
|
| 16 |
+
|
| 17 |
+
An externally sovereign system of record or operation. FluentCRM is a realm. Jira is a realm. QuickBase is a realm. QuickBooks is a realm. PortTracker's Node backend is a realm. An arbitrary REST API is a realm. A client's database is a realm. A realm is sovereign because its integrity does not depend on Core.
|
| 18 |
+
|
| 19 |
+
### Subsystem
|
| 20 |
+
|
| 21 |
+
A coherent slice of Core itself. SAWS-executor is a subsystem. CARMA (the absorbed WP maintenance toolset) is a subsystem. MissionNet (the presentation layer) is a subsystem. A customer-facing brand may wrap a subsystem; the brand is cosmetic, the subsystem is structural.
|
| 22 |
+
|
| 23 |
+
### Adapter
|
| 24 |
+
|
| 25 |
+
A bidirectional conduit between Core and a realm. See the **Realm Adapter Contract** (`03-realm-adapter-contract.md`). Adapters do not own realm data; they mediate flow. A provider adapter (`SA_Provider_Adapter`) is a specialized adapter for LLM and tool providers; a realm adapter (`SA_Realm_Adapter`) is the general-case conduit.
|
| 26 |
+
|
| 27 |
+
### Entity
|
| 28 |
+
|
| 29 |
+
The universal unit of the field inside Core. Rendered as circle (compressed atom) or rounded-rect (expanded container). Carries band hints, ratio, position, payload, ACL, provenance, and truth class.
|
| 30 |
+
|
| 31 |
+
### Record
|
| 32 |
+
|
| 33 |
+
A specific row in a realm's native schema. A record's canonical home is the realm. A record's Core-side reflection is a **Projection**.
|
| 34 |
+
|
| 35 |
+
### Projection
|
| 36 |
+
|
| 37 |
+
Core's non-canonical mirror of a realm record. Stored as an entity with `truth_class = projected`, `origin_realm` + `origin_id` populated, and TTL-bounded when cached.
|
| 38 |
+
|
| 39 |
+
### Canonical Source
|
| 40 |
+
|
| 41 |
+
The realm in which a record is authoritative. Only the canonical source may author canonical state for its own records. Core cannot author canonical on a realm's behalf.
|
| 42 |
+
|
| 43 |
+
### Event
|
| 44 |
+
|
| 45 |
+
Something that happened. Immutable, time-indexed. Recorded to `sa_structural_audit` with actor, target, before/after, correlation_id, causation_id, policy_basis.
|
| 46 |
+
|
| 47 |
+
### Command
|
| 48 |
+
|
| 49 |
+
An instruction or intent. Typically initiated by an actor or a scheduled policy. A command may yield one or more events when executed.
|
| 50 |
+
|
| 51 |
+
### Actor
|
| 52 |
+
|
| 53 |
+
The who of an action. One of: a WordPress user id (human), a service principal id (non-human authenticated identity), or the string `system` (Core's own internal automation under an audited policy).
|
| 54 |
+
|
| 55 |
+
### Authority
|
| 56 |
+
|
| 57 |
+
The scope of what an actor may do. Held by role, package capabilities, ACL entries, and adapter capability matrices.
|
| 58 |
+
|
| 59 |
+
### Session
|
| 60 |
+
|
| 61 |
+
A grouping of related commands and events initiated by a single actor or chain. Correlated by a shared `correlation_id`.
|
| 62 |
+
|
| 63 |
+
### Mission
|
| 64 |
+
|
| 65 |
+
A composite objective that spans one or more sessions. (Future spec — see `10-mission-orchestration.md` when written.)
|
| 66 |
+
|
| 67 |
+
### Quest
|
| 68 |
+
|
| 69 |
+
A unit of narrative direction. Defines target, not-target, and admissible uncertainty for a body of work. Quests are authored, not executed: their canonical home is the planning surface (Boards in MissionNet's instance).
|
| 70 |
+
|
| 71 |
+
Quests describe what the work is *about*. Resolution of a Quest is a narrative judgment — was the direction met, was it abandoned, was it superseded — made by a human.
|
| 72 |
+
|
| 73 |
+
Distinct from a Job. See Job below; see also Distinguishing pairs.
|
| 74 |
+
|
| 75 |
+
### Task / Job
|
| 76 |
+
|
| 77 |
+
A unit of executable work within a Quest. May be scheduled, assigned, retried, or delegated. Jobs describe what is *done*. Resolution of a Job is a real-world consequence — the work either happened or did not — measured against reality, not against the system.
|
| 78 |
+
|
| 79 |
+
A Quest may produce one or more Jobs. A Job belongs to one Quest. Conversion between Quest and Job is not automatic; see I10.
|
| 80 |
+
|
| 81 |
+
### Attention
|
| 82 |
+
|
| 83 |
+
A routing signal — never an instruction, never a state mutation. Attention asks for arbitration; it does not perform it. NPCs (agents, automated processes) may emit Attention. Only humans may resolve it.
|
| 84 |
+
|
| 85 |
+
The infrastructure: the attention log records signals with actor, target, correlation_id, causation_id. Read-only by construction; resolving Attention requires the human to take a separate, explicit act.
|
| 86 |
+
|
| 87 |
+
Sub-doctrine: see `concepts/attention-doctrine.md` and `concepts/compass-doctrine.md`.
|
| 88 |
+
|
| 89 |
+
### Realm Signal
|
| 90 |
+
|
| 91 |
+
A low-cost notification from a realm ("something changed") that Core may choose to consume, queue, or ignore based on policy. Previously named "Signal"; renamed to free the unqualified term for the doctrinal meaning below.
|
| 92 |
+
|
| 93 |
+
### Signal
|
| 94 |
+
|
| 95 |
+
*(Authored by Mark Holak. Preserved under Invariant **I9**.)*
|
| 96 |
+
|
| 97 |
+
The measurable alignment behavior of participants — users, workers, agents, models, systems — as they traverse an authored **acceleration field** (a mission, prompt, workflow, book, interface, instruction set, or any artifact that defines target, not-target, and admissible uncertainty).
|
| 98 |
+
|
| 99 |
+
Signal is *not* raw observability. Pillar 0.75's sub-token graph is the instrument; Signal is what the instrument reads. Participants interact with an authored field and produce measurable interaction outcomes — some align, some scatter, some ricochet, some go inert, some reach harmonic closure. The Signal Telemetry Doctrine is the interpretation layer sitting over Prime Prompt Conjecture and Cognitive Heatsink: PPC and Heatsink describe how trajectory is compressed and dissipated; Signal reads the alignment produced at the other end.
|
| 100 |
+
|
| 101 |
+
The enumerated behaviors (align / scatter / ricochet / inert / harmonic closure) are **exemplary, not definitive** — additional behaviors may emerge as the system is used. See `concepts/signal-telemetry-doctrine.md` for the full doctrine and its mapping onto Core primitives.
|
| 102 |
+
|
| 103 |
+
### Artifact
|
| 104 |
+
|
| 105 |
+
A file, document, image, or embedding. Stored in the native realm when possible; projected into Core via adapter.
|
| 106 |
+
|
| 107 |
+
### Trace
|
| 108 |
+
|
| 109 |
+
The causal ancestry of a state or an event. Walked by `SA_Structural_Audit::trace_origin()`. Preserved by correlation_id and causation_id on every audit row.
|
| 110 |
+
|
| 111 |
+
### Truth Class
|
| 112 |
+
|
| 113 |
+
See `SA_Truth_Class` and Invariant **I2**. One of: `canonical | projected | cached | inferred | derived | synthetic`. Every entity declares one.
|
| 114 |
+
|
| 115 |
+
### State Class
|
| 116 |
+
|
| 117 |
+
See `SA_State_Class`. The lifecycle position of a datum. One of: `resting | observed | projected | pending_action | acted | verified | disputed | stale | superseded`.
|
| 118 |
+
|
| 119 |
+
### Provenance
|
| 120 |
+
|
| 121 |
+
The origin record attached to every entity: `origin_realm`, `origin_id`, `actor`, `observed_at`, `causation_id`, `correlation_id`, optional `derived_from`, `source_refs`, `provenance_hash`.
|
| 122 |
+
|
| 123 |
+
### Membrane
|
| 124 |
+
|
| 125 |
+
A per-entity veil that turns the entity into a black-box domain. Only typed I/O ports are visible to outsiders. Billing principals may unfold the membrane they are charged for.
|
| 126 |
+
|
| 127 |
+
### I/O Port
|
| 128 |
+
|
| 129 |
+
A typed edge anchor on a membraned entity. The only integration surface visible to non-insiders.
|
| 130 |
+
|
| 131 |
+
### Grouping Overlay
|
| 132 |
+
|
| 133 |
+
A first-class attributed, non-destructive re-parenting of entities. Per-scope (private / shared / org / public), per-author. Applied at render time.
|
| 134 |
+
|
| 135 |
+
### Projection Slot
|
| 136 |
+
|
| 137 |
+
A named rendering surface bound to an entity query. A package defines its slot set; a viewer may override within the slot's allowance.
|
| 138 |
+
|
| 139 |
+
### Projection Source
|
| 140 |
+
|
| 141 |
+
A named, viewer-scoped row producer eligible to be unioned with other sources at a surface's Projection Arbiter. Each source owns one query path and applies its own visibility gate (`row_visible`) before returning rows. A source is NOT any method on `SA_Projection`; it is specifically a row producer composable into a surface's arbiter. Today's sources: `chat` (`recent_prompts` — chat-domain-joined) and `realm` (`recent_entities` — role/origin-realm-scoped). Sources are kernel-owned; third parties contribute realm adapters (which feed `realm`), not sources.
|
| 142 |
+
|
| 143 |
+
### Projection Arbiter
|
| 144 |
+
|
| 145 |
+
A surface-scoped composer that enumerates the Projection Sources feeding that surface, invokes them for the current viewer, and unions their output into the surface's response shape. The arbiter owns source enumeration, union strategy, and per-source instrumentation (`window.sources` readout). Today implemented as one method per surface on `SA_Projection` (`for_mission` is the only instance). Not a standalone class: at two sources with no arbitration rules (dedup, sort-merge, ACL-at-merge), a class would be ceremony. Promotion to a class is deferred until (a) a third source, (b) a concrete arbitration rule, or (c) third-party source registration lands. Surfaces with a single source (`/thread`, `/trace`, `/lattice/subtree`) do not go through an arbiter and do not need one.
|
| 146 |
+
|
| 147 |
+
### Influence Halo / Ring
|
| 148 |
+
|
| 149 |
+
Concentric bands around an entity carrying weighted references to related entities. The continuous limit of discrete rings is the contour mode (`docs/ARCHITECTURE.md` — Derived pillar: Contour rendering).
|
| 150 |
+
|
| 151 |
+
### Sub-Token Event
|
| 152 |
+
|
| 153 |
+
Every internal orchestration step inside a provider invocation (embed, retrieve, tool call, subagent hop, completion, rerank, self-critique, router). First-class entity at band 5 inside the parent prompt's band 4 container. Visible and annotatable by the billing principal.
|
| 154 |
+
|
| 155 |
+
### Geodesic Marker
|
| 156 |
+
|
| 157 |
+
A memory record of a failure path in the prompt manifold. Seeded from bad verdicts on sub-tokens. Consumed by `SA_Geodesic_Seeder` to route around known failures.
|
| 158 |
+
|
| 159 |
+
### Context Bundle
|
| 160 |
+
|
| 161 |
+
A named, pinned slice of the entity graph with a deterministic signature. Multiple adapters (including specialized LLMs) bind to the same bundle for synchronized context.
|
| 162 |
+
|
| 163 |
+
### Package
|
| 164 |
+
|
| 165 |
+
The purchased SKU. Enumerates enabled capabilities, default overlays, default membranes. Assigned to an org.
|
| 166 |
+
|
| 167 |
+
### Capability
|
| 168 |
+
|
| 169 |
+
An enumerable permission string (`sa-core:sub-token-unfold`, `missionnet:impose-grouping`, `carma:admin-takeover`). Package-gated.
|
| 170 |
+
|
| 171 |
+
### Service Principal
|
| 172 |
+
|
| 173 |
+
A non-human authenticated identity. External services (PortTracker's Node, ingest clients, Jira bots) use service principal tokens to push mutations without impersonating a user.
|
| 174 |
+
|
| 175 |
+
### Invariant
|
| 176 |
+
|
| 177 |
+
A non-negotiable law the system upholds at runtime. See `02-invariants.md`. Violations are logged to `sa_invariant_violation`.
|
| 178 |
+
|
| 179 |
+
### Adapter Certification
|
| 180 |
+
|
| 181 |
+
The gate that promotes a realm adapter from "in development" to "live." Checklist runs against the Realm Adapter Contract invariants. See `03-realm-adapter-contract.md`.
|
| 182 |
+
|
| 183 |
+
### Admission Contract
|
| 184 |
+
|
| 185 |
+
The per-layer contract a new primitive — or a new instance of an existing primitive — must honor to be validly admitted into the system.
|
| 186 |
+
|
| 187 |
+
A *named principle*, not a uniform checklist family. The principle is: **admission is layer-owned and layer-shaped**, not uniform across layers. Each layer's admission contract takes whatever form that layer's nature demands (a certification checklist for realms, runtime invariants for entities, an op whitelist for mutations, a return-shape obligation for projection sources, etc.).
|
| 188 |
+
|
| 189 |
+
This principle does not add a new commitment. It names a shape already diffused through:
|
| 190 |
+
|
| 191 |
+
- **Pillar 0.5** — everything rendered is `project(field, viewer, overlays, permissions)`. A new primitive must have defined behavior under all four inputs.
|
| 192 |
+
- **Pillar 0.75** — every orchestration step is observable. Anything action-shaped must declare how it emits observability (sub-token events, audit rows, source attribution).
|
| 193 |
+
- **Pillar 0.9** — the primitive set is closed; new capabilities are compositions of existing primitives. Admission = proof of valid composition.
|
| 194 |
+
- **`03-realm-adapter-contract.md`** — the single fully worked-out formal instance of a per-layer admission contract.
|
| 195 |
+
|
| 196 |
+
See `docs/ARCHITECTURE.md` for the pillars themselves. This entry does not amend them; it gives the shape they imply a name.
|
| 197 |
+
|
| 198 |
+
**Status ledger.** The ledger is the term's practical content. It records which primitive layers currently have formal contracts, which have informal ones, which are absent, and which are intentionally deferred. New rows enter only when a new primitive layer enters the closed set — not per instance, and not per cross-layer attribute.
|
| 199 |
+
|
| 200 |
+
| Layer | Contract state | Reference / note |
|
| 201 |
+
|---|---|---|
|
| 202 |
+
| Realm | Formal | `03-realm-adapter-contract.md` + `sa_adapter_certification` table |
|
| 203 |
+
| Entity | Formal | `02-invariants.md` I2 / I4 / I7 + `SA_Truth_Class` / `SA_State_Class` validation in `SA_Entity::create` |
|
| 204 |
+
| Mutation | Formal | `SA_Ingest` op whitelist, idempotency-key discipline, service-principal scope, deterministic UUID rule |
|
| 205 |
+
| Projection Source | Informal | "Returns viewer-gated rows in arbiter-compatible union shape." Implied by the Projection Arbiter promotion; not yet written as a standalone contract. |
|
| 206 |
+
| Grammar | Absent | No admission rules for a new grammar today. Chat-lineage / equal-peer / containment-pack are ad-hoc in client code. |
|
| 207 |
+
| Surface inspection | Informal | Three discriminable cases now operative in `/mission/`'s lens-routing decision (`renderCurrentProjection` in `assets/mission.js`), driven by a shape predicate over `(entity.origin_realm, sub_token_count)` — no realm-specific code: (a) **chat-shaped** (`!origin_realm`) → trace lens; (b) **structural-only** (`origin_realm` set, `sub_token_count == 0`) → structural inspector; (c) **structural-with-sub-tokens** (`origin_realm` set, `sub_token_count > 0`) → hybrid lens (structural inspector + Sub-tokens section in step_index ASC order, with shape-aware labels read from `SubTokenEvent.metadata` rather than chat-shaped fallbacks). Discriminator field `sub_token_count` lives on the `/entity/{id}/inspect` projection response (additive, no schema change). Concrete instances: chat prompts (case a), FS containers/leaves (case b), GitHub Actions workflow runs (case c). Promotion to Formal (separate contract file) requires a fourth case or a second concrete hybrid example, whichever forces the discriminator's edge cases into a written rule. Until then the contract is the inline behavior recorded here. |
|
| 208 |
+
| Toolbox action | Formal | `06-toolbox-action-contract.md` (v0.1, 7 clauses). Two concrete instances: `/mission/`-native "Re-scan FS" and "Re-scan GH" buttons (both admin-only). Promotion criteria from Informal → Formal were satisfied by the second instance (GitHub Actions re-scan) cleanly fitting the same seven-clause shape: semantic binding (1 button → 1 REST endpoint), permission gate (manage_options at template AND REST), audit obligation (one operator-attribution structural-audit row per invocation), parameter shape (render-time derivation, no click-time dialogs), feedback contract (busy/success/failed state cycle), refresh obligation (`load()` on success), idempotency (zero net entity-count drift on repeat). Out-of-scope categories (parameter dialogs, destructive actions, multi-step compositions) explicitly deferred to future contract revisions when concrete instances drive them. |
|
| 209 |
+
| Membrane | Deferred | Primitive defined in this ontology; admission contract (port typing, opacity rules, billing-principal translucency) deferred until first implementation. |
|
| 210 |
+
| Overlay | Deferred | Primitive defined in this ontology; admission contract (scope, attribution, idempotency, render-time layering) deferred until first implementation. |
|
| 211 |
+
| Credential | Deferred | Surfaced by the GitHub Actions third-domain proof, which uses a filter-driven PAT (`sa_core_github_token`) as its smallest scope-honoring credential path. The general contract — how external-realm credentials enter the system (OAuth flows, refresh-token lifecycle, per-user vs per-org binding, scope-limited storage) — is not yet written. Existing primitives partially cover adjacent concerns: `SA_Credential_Pool` (LLM provider keys, single-secret-per-record), `SA_Service_Principal` (inbound bearer tokens), filter-driven adapter config (FS, GitHub Actions). None compose into a unified credential-admission shape. Authorized work will likely extend `SA_Credential_Pool` to handle multi-step OAuth tokens and add the operator UX (connect, store, scope, retire) as one slice's deliverable, then retire ad-hoc filter configs. First instance: GitHub. Second instance later: Jira / Linear / etc. |
|
| 212 |
+
| Camera-Projection Convergence | Pinned | Filed during the dependency audit preceding the Hybrid Inspector Lens slice. Concept: under Pillar 0's full vision, camera transitions at band boundaries are themselves projection-resolution events, not viewport transforms. Today the camera is degenerate (purely affine pan/zoom over fixed layout). Under Rung 4 phase 2+, zoom-band crossings re-layout via auto-compress / auto-expand, making camera a constrained re-projection over the referential manifold rather than a viewport adjustment. Concrete formalization deferred until a second example of camera-as-projection lands alongside Jump-2 (auto-descend on band-cross) or Jump-3 (membrane unwrap on jump). At promotion time this row will move from Pinned to Absent or Informal depending on which Rung 4 mechanic delivers it. Sits at the same admission-contract layer as Surface Inspection / Toolbox / Grammar — between primitives and rendering. |
|
| 213 |
+
|
| 214 |
+
**Role and kind are NOT admission layers.** They are cross-layer discriminant attributes. A new role's admission is governed jointly by entity invariants (structural constraints: e.g. `message` requires `payload.role ∈ {user,assistant,system}`), grammar admission (visual and inspection-lens treatment), and projection source contract (which sources include the role). No independent role-admission contract. `kind` (circle / rrect) is narrower still — a pure grammar discriminant with no invariant or projection overlap.
|
| 215 |
+
|
| 216 |
+
**What this entry does NOT do.**
|
| 217 |
+
|
| 218 |
+
- Does not mandate a uniform contract shape across layers. Forcing realm-style checklists onto grammars or toolbox actions is the principle's failure mode.
|
| 219 |
+
- Does not create a runtime gate. Existing enforcement (invariants, certification table) stays as-is; no new machinery is implied.
|
| 220 |
+
- Does not forbid introducing a primitive without a contract in place. Absent rows in the ledger are honest debt markers, not refusal signals.
|
| 221 |
+
|
| 222 |
+
### Prime Prompt
|
| 223 |
+
|
| 224 |
+
*(Authored by Mark Holak.)* A minimal causal prompt that, when injected into a capable model, reconstructs the trajectory of an originating system without requiring replay of the full conversation history. See `docs/specs/concepts/prime-prompt-conjecture.md`.
|
| 225 |
+
|
| 226 |
+
### Cognitive Heatsink
|
| 227 |
+
|
| 228 |
+
*(Authored by Mark Holak.)* A thermodynamic model of thought-to-resolution through computational dissipation. See `docs/specs/concepts/cognitive-heatsink.md`. Maps to sub-token events as discrete thermal transfer steps.
|
| 229 |
+
|
| 230 |
+
### Reference Traversal Continuity
|
| 231 |
+
|
| 232 |
+
*(Authored by Mark Holak. Preserved under Invariant **I9**.)*
|
| 233 |
+
|
| 234 |
+
A kernel-level commitment that the act of following a reference from one entity to another is invariant across the kinds of entities being traversed and across the realm or representational layer the traversal currently inhabits. The traversal does not truncate at realm boundaries, truth-class boundaries, type-layer boundaries, or observability boundaries.
|
| 235 |
+
|
| 236 |
+
Continuity is carried by the existing kernel-side bookkeeping (`parent_id`, `origin_realm` + `origin_id`, `correlation_id`, `causation_id`, `derived_from`, edge kinds, sub-token parentage). The doctrine names what those primitives jointly enable.
|
| 237 |
+
|
| 238 |
+
This is a doctrine of **motion**, not of **geometry**. Projection grammars (chat-lineage, containment-pack, equal-peer, future grammars) are downstream rendering decisions that choose how to display a region of the traversal field; they neither define, constrain, nor constitute the traversal itself. Coil, hydra, shell, treemap, and every other rendered cluster shape are choreographies — many other choreographies are equally valid. The motion neither requires nor privileges any of them.
|
| 239 |
+
|
| 240 |
+
Articulated immediately after the GitHub Actions third-domain proof, which made the cross-domain continuity concretely visible: chat sub-tokens, filesystem containment, and workflow run/job/step descents are not three patterns held together by the adapter contract; they are three surface expressions of one continuous motion that the adapter contract gates entries to. See `concepts/reference-traversal-continuity.md` for the full doctrine and its relationship to companion concepts (Pillar 0.5 perspective projection, Pillar 0.75 transparency, Pillar 0.9 closed primitive set, Prime Prompt Conjecture, Cognitive Heatsink, Signal Telemetry Doctrine).
|
| 241 |
+
|
| 242 |
+
---
|
| 243 |
+
|
| 244 |
+
## Distinguishing pairs (do not confuse)
|
| 245 |
+
|
| 246 |
+
- **Realm** vs. **Subsystem** — realms are sovereign external systems; subsystems are parts of Core.
|
| 247 |
+
- **Incorporate** vs. **Absorb** — realms are incorporated (conduit); SA-authored code is absorbed (consolidated).
|
| 248 |
+
- **Event** vs. **Command** — events are records of what happened; commands are instructions or intents.
|
| 249 |
+
- **Canonical** vs. **Projected** — canonical is truth at its native home; projected is Core's non-canonical mirror.
|
| 250 |
+
- **Projected** vs. **Cached** — both are non-canonical; cached carries an explicit TTL; projected is kept live and refreshable.
|
| 251 |
+
- **Inferred** vs. **Derived** — inferred is produced by an LLM or heuristic; derived is deterministic computation from known inputs.
|
| 252 |
+
- **Entity** vs. **Record** — an entity lives in Core; a record lives in a realm; a projection is an entity that *represents* a record.
|
| 253 |
+
- **Projection** (the mirror) vs. **Projection Source** vs. **Projection Arbiter** vs. **Projection Slot** — four distinct read-path concepts that share a word. *Projection* (the mirror) is the entity-side reflection of a realm record (truth-class level). *Projection Source* is a viewer-scoped row producer (read-path composition level). *Projection Arbiter* is the surface-scoped composer of sources (read-path orchestration level). *Projection Slot* is a named rendering surface bound to a query (rendering level). The four do not substitute for each other.
|
| 254 |
+
- **Quest** vs. **Job** — quests are narrative direction (authored, judged); jobs are executable work (scheduled, performed, resolved by reality). One quest may yield many jobs; no automatic promotion in either direction. See I10.
|
| 255 |
+
|
| 256 |
+
---
|
| 257 |
+
|
| 258 |
+
## Usage rules
|
| 259 |
+
|
| 260 |
+
1. Every spec document MUST use these terms in their defined sense.
|
| 261 |
+
2. When a new term enters the vocabulary, it MUST be added here before being used in other specs or in code.
|
| 262 |
+
3. Class names and log messages SHOULD mirror these terms.
|
| 263 |
+
4. When translation between Core's vocabulary and a realm's native vocabulary is necessary, it happens in the adapter, not in the spec.
|
| 264 |
+
|
| 265 |
+
---
|
| 266 |
+
|
| 267 |
+
## Attribution
|
| 268 |
+
|
| 269 |
+
The framework expressed in this document sits inside a larger lineage:
|
| 270 |
+
|
| 271 |
+
```
|
| 272 |
+
CR ⊇ CA ⊇ JourneySeeker ⊇ MissionNet/MeshNet ⊇ SA-Orchestration ⊇ Brand ⊇ Client
|
| 273 |
+
```
|
| 274 |
+
|
| 275 |
+
Causal Relativity, Causal Agentics, and JourneySeeker are pre-existing intellectual property authored by Mark Holak, preserved under Invariant **I9** and Section 5.1 carve-outs of the CTO Employment & Equity Agreement. MissionNet/MeshNet is the Corporate-Campaign theme. SA-Orchestration is the current implementation slice. Brand and Client labels are the rendering layer (see `concepts/concept-vs-label.md`).
|
| 276 |
+
|
| 277 |
+
Each layer below renders, specializes, or themes the layer above. No layer below replaces the layer above. See `concepts/lineage-chain.md` for the full doctrine.
|
| 278 |
+
|
| 279 |
+
Implementation and glossary in this document: © Sleeper Agents LLC.
|
| 280 |
+
|
| 281 |
+
Named conceptual framework elements (Prime Prompt, Cognitive Heatsink, Russell-Ouroboros Conjecture, PR notation, quanta-of-LLMs / information-lattice framing): authored independently by Mark Holak. See `docs/specs/concepts/` for the preserved artifacts and full author credit.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/02-invariants.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MissionNet System Invariants (v0.1)
|
| 2 |
+
|
| 3 |
+
*Authored by Mark Holak. Adapted into Core by implementation.*
|
| 4 |
+
|
| 5 |
+
These are not implementation details. They are **laws**. Violations are recorded to `sa_invariant_violation`; severe violations raise exceptions. Code that violates an invariant fails review.
|
| 6 |
+
|
| 7 |
+
The enforcement surface lives in `includes/enforcement/class-sa-invariants.php`. Every invariant here has a stable id (`I1`–`I9`) used in the violation log. A bug tracker can link against these ids.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## Foundational asymmetry
|
| 12 |
+
|
| 13 |
+
The invariants below exist because Core distinguishes between truth classes: **canonical, projected, cached, inferred, derived, synthetic**. These classes are asymmetric — they cannot collapse into each other. That asymmetry is what prevents Russell's paradox from re-entering through the back door: a system that consumes itself can only stay coherent if the act of consumption preserves distinctions as it moves. The timeless lattice translates through spacetime precisely because the asymmetry survives the motion.
|
| 14 |
+
|
| 15 |
+
Without these invariants, the asymmetry decays, the classes collapse, and the system begins to lie to itself about what is real.
|
| 16 |
+
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
## I1 — Core must not claim canonical ownership of incorporated realm data
|
| 20 |
+
|
| 21 |
+
Incorporated realms (FluentCRM, Jira, QuickBase, QuickBooks, PortTracker's Node service, arbitrary APIs) remain the canonical source of their own records. Core mirrors, mediates, and audits — never authors canonical state on a realm's behalf unless that realm is Core itself.
|
| 22 |
+
|
| 23 |
+
**Enforcement:**
|
| 24 |
+
- `SA_Ingest::upsert_entity` stamps `truth_class = projected` by default on all ingested realm records.
|
| 25 |
+
- A realm adapter's `truth_class_for_concept()` may *only* return `canonical` for concepts whose canonical home is Core (rare).
|
| 26 |
+
- Any attempt to write `truth_class = canonical` on an entity with a non-`sa-core` `origin_realm` is rejected.
|
| 27 |
+
|
| 28 |
+
**Violation severity:** fatal.
|
| 29 |
+
|
| 30 |
+
---
|
| 31 |
+
|
| 32 |
+
## I2 — Every surfaced datum must declare truth_class
|
| 33 |
+
|
| 34 |
+
Entities, projections, cache rows, AI summaries, and adapter payloads must carry a valid `truth_class`. Without this, viewers cannot distinguish a canonical fact from an LLM guess.
|
| 35 |
+
|
| 36 |
+
**Enforcement:**
|
| 37 |
+
- `SA_Entity::create()` calls `SA_Invariants::check_truth_class_declared()`.
|
| 38 |
+
- Default for unknowable-origin entities is `canonical`; default for ingest is `projected`; default for LLM output is `inferred`. All three are valid; absence of any value is not.
|
| 39 |
+
|
| 40 |
+
**Violation severity:** fatal.
|
| 41 |
+
|
| 42 |
+
---
|
| 43 |
+
|
| 44 |
+
## I3 — Every cross-realm action must be causally traceable
|
| 45 |
+
|
| 46 |
+
A change initiated in Core that reaches (or originated in) an external realm must trace to an actor, a causation id, and a correlation id. `SA_Structural_Audit::trace_origin()` must be able to walk backward from any resulting state to the first user-attributed act.
|
| 47 |
+
|
| 48 |
+
**Enforcement:**
|
| 49 |
+
- `SA_Provenance::enforce()` is called before any cross-realm mutation.
|
| 50 |
+
- Audit rows carry `correlation_id` + `causation_id`.
|
| 51 |
+
|
| 52 |
+
**Violation severity:** error (blocks the action; recoverable by retrying with provenance attached).
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
## I4 — No adapter may emit a record without native identity + realm provenance
|
| 57 |
+
|
| 58 |
+
Adapter pulls MUST populate `origin_realm` + `origin_id` (directly or via `external_key`). Without this, the record cannot be re-matched, cannot be pushed back, and cannot be audited across the realm boundary.
|
| 59 |
+
|
| 60 |
+
**Enforcement:**
|
| 61 |
+
- `SA_Invariants::check_realm_provenance()` is called on every ingest mutation.
|
| 62 |
+
- `SA_Ingest` rejects payloads missing these fields.
|
| 63 |
+
|
| 64 |
+
**Violation severity:** fatal.
|
| 65 |
+
|
| 66 |
+
---
|
| 67 |
+
|
| 68 |
+
## I5 — MissionNet must degrade without corrupting realm integrity
|
| 69 |
+
|
| 70 |
+
When Core fails (offline, bugged, under attack), the client's native realms must not suffer collateral damage. This is the philosophical *tool test* expressed as a technical law.
|
| 71 |
+
|
| 72 |
+
**Enforcement:**
|
| 73 |
+
- Adapter writes (`push`) must be idempotent per `idempotency_rules()`.
|
| 74 |
+
- Bulk operations must be chunked + resumable.
|
| 75 |
+
- Health-check endpoints must fail closed — Core not reachable means ingest halts, not silently half-writes.
|
| 76 |
+
- Adapter certification checklist item: `failure_path_verified` + `rollback_defined`.
|
| 77 |
+
|
| 78 |
+
**Violation severity:** warn at design time, error at runtime.
|
| 79 |
+
|
| 80 |
+
---
|
| 81 |
+
|
| 82 |
+
## I6 — Cache may never silently replace source verification in high-trust paths
|
| 83 |
+
|
| 84 |
+
Cache accelerates; cache does not become truth. When the caller asks for a high-trust answer (regulated domains, financial totals, legal records), Core must re-verify against the canonical realm, not return a cached projection.
|
| 85 |
+
|
| 86 |
+
**Enforcement:**
|
| 87 |
+
- Per-adapter cache TTLs declared in `capability_matrix()`.
|
| 88 |
+
- High-trust query paths pass `verify_live: true` to the executor/realm; cache is skipped.
|
| 89 |
+
- A future policy engine may classify concepts as high-trust and force verification.
|
| 90 |
+
|
| 91 |
+
**Violation severity:** error in high-trust contexts; warn otherwise.
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
## I7 — AI output must remain explicitly derivative
|
| 96 |
+
|
| 97 |
+
No LLM output may be stored or surfaced as canonical truth without an explicit canonical source reference or a recorded human affirmation.
|
| 98 |
+
|
| 99 |
+
**Enforcement:**
|
| 100 |
+
- `SA_Executor` stamps completion entities with `truth_class = inferred`.
|
| 101 |
+
- `SA_Entity::create()` calls `SA_Invariants::check_ai_output_not_canonical()`. Attempting to create an AI-sourced entity with `truth_class = canonical` without either `source_refs` (non-empty) or `human_affirmed_at`+`human_affirmed_by` is rejected.
|
| 102 |
+
- Promotion from `inferred` → `canonical` or `projected` requires an explicit endpoint call (future work) that records the promoting actor + timestamp.
|
| 103 |
+
|
| 104 |
+
**Violation severity:** fatal.
|
| 105 |
+
|
| 106 |
+
---
|
| 107 |
+
|
| 108 |
+
## I8 — Destroying Core must not destroy incorporated realms
|
| 109 |
+
|
| 110 |
+
This is I5's strongest form. If Core is deleted tomorrow, FluentCRM still works, QuickBooks still works, Jira still works, PortTracker still works. Core owns no canonical realm data. Cache is non-canonical by construction. Push-backs are immediate, not batched into Core's own persistence.
|
| 111 |
+
|
| 112 |
+
**Enforcement:**
|
| 113 |
+
- Adapter certification checklist item: `source_identity_preserved` + `native_ids_preserved`.
|
| 114 |
+
- Contractual, not just technical: the product terms explicitly disclaim any Core-only source of truth for realm concepts.
|
| 115 |
+
- Periodic audit: `SA_Adapter_Certification` re-runs on each adapter release and the passed flag is visible to operators.
|
| 116 |
+
|
| 117 |
+
**Violation severity:** fatal at certification; a failing adapter cannot go live.
|
| 118 |
+
|
| 119 |
+
---
|
| 120 |
+
|
| 121 |
+
## I9 — Attributable concepts and the framework lineage must not be rephrased as AI-original
|
| 122 |
+
|
| 123 |
+
Both **named concepts** and **the framework lineage that contains them** must carry author attribution wherever surfaced.
|
| 124 |
+
|
| 125 |
+
**Named concepts** (authored by a human and preserved verbatim under this invariant) include the Russell-Ouroboros Conjecture, the Prime Prompt Conjecture + PR notation, the Cognitive Heatsink model, the Signal Telemetry Doctrine, the Reference Traversal Continuity Doctrine, the Story Seed pattern, the Concept-vs-Label doctrine, the Compass Doctrine, the Attention Doctrine, the Quest-vs-Job distinction, and any subsequent attributable work added to `docs/specs/concepts/`.
|
| 126 |
+
|
| 127 |
+
**The framework lineage** is the chain Causal Relativity ⊇ Causal Agentics ⊇ JourneySeeker ⊇ MissionNet/MeshNet ⊇ SA-Orchestration ⊇ Brand ⊇ Client (see `concepts/lineage-chain.md`). The structural primitives at each layer (truth class taxonomy, compass roles, description-as-contract, seed-vs-canonical, projection vs canonical, actor/realm/adapter, Quest/Job distinction) are framework primitives, not implementation primitives.
|
| 128 |
+
|
| 129 |
+
AI-generated text that paraphrases or adapts either named concepts or framework primitives must reference the original author and must not present the concept as newly originated by the AI or by the implementation layer.
|
| 130 |
+
|
| 131 |
+
**Enforcement:**
|
| 132 |
+
|
| 133 |
+
- The spec pack under `docs/specs/` carries attribution frontmatter.
|
| 134 |
+
- `docs/specs/concepts/` preserves the original authored artifacts verbatim with explicit author credit.
|
| 135 |
+
- AI output passing through Core that draws on attributable concepts or framework primitives must reference them (adapter-level policy, future work).
|
| 136 |
+
- Adapter certification: AI summarizers that produce text must not strip authored-concept attribution.
|
| 137 |
+
- Seed generators must not synthesize content that re-authors framework primitives as implementation-original. INTERPRETIVE-mode synthesis is bound by this clause.
|
| 138 |
+
|
| 139 |
+
**Violation severity:** warn at generation time; fatal at publication time.
|
| 140 |
+
|
| 141 |
+
---
|
| 142 |
+
|
| 143 |
+
## I10 — No automatic conversion between Quest and Job
|
| 144 |
+
|
| 145 |
+
A Quest may not be promoted to a Job, and a Job may not be elevated to a Quest, without an explicit human act recording the conversion.
|
| 146 |
+
|
| 147 |
+
The reason: a Quest lives in the realm of authored intent — admissible uncertainty, possible alternatives, future framing. A Job lives in the realm of resolved consequence — it happened or did not. Auto-conversion collapses one into the other and erases the distinction the author made between direction and execution.
|
| 148 |
+
|
| 149 |
+
**Enforcement:**
|
| 150 |
+
|
| 151 |
+
- Quest → Job conversion requires an actor + timestamp + recorded conversion event in the audit log.
|
| 152 |
+
- Job → Quest elevation (rare) requires the same.
|
| 153 |
+
- A "Convert to Job" UI action that creates the conversion event with explicit human click is acceptable. A scheduled background job that auto-promotes without that event is not.
|
| 154 |
+
- Reality resolves Jobs; humans resolve Quests. A system that conflates the two collapses the compass (see `concepts/compass-doctrine.md`).
|
| 155 |
+
|
| 156 |
+
**Violation severity:** error.
|
| 157 |
+
|
| 158 |
+
---
|
| 159 |
+
|
| 160 |
+
## Notation
|
| 161 |
+
|
| 162 |
+
Every invariant check logs a row to `sa_invariant_violation` with:
|
| 163 |
+
|
| 164 |
+
- `invariant_id` — one of `I1`…`I9`
|
| 165 |
+
- `severity` — `warn | error | fatal`
|
| 166 |
+
- `target_entity_id` / `target_audit_id`
|
| 167 |
+
- `actor_id`
|
| 168 |
+
- `details` — JSON-encoded context
|
| 169 |
+
- `acknowledged_at` / `acknowledged_by` — operational triage
|
| 170 |
+
|
| 171 |
+
Operational review dashboards can render violations grouped by `invariant_id` and sort by severity.
|
| 172 |
+
|
| 173 |
+
---
|
| 174 |
+
|
| 175 |
+
## Next
|
| 176 |
+
|
| 177 |
+
- Wire all cross-realm mutation paths (push, pull, ingest) through `SA_Invariants::assert_or_throw()`.
|
| 178 |
+
- Add enforcement to the presentation layer: UI must display `truth_class` on every surfaced datum (stamp in the top corner of every rendered entity).
|
| 179 |
+
- Extend audit trace with chain-coherence checks: if a row claims a causation_id, that row must exist.
|
| 180 |
+
- Build the policy engine layer so I6 (high-trust) and I9 (attribution) become user-configurable.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/03-realm-adapter-contract.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MissionNet Realm Adapter Contract (v0.1)
|
| 2 |
+
|
| 3 |
+
*Implementation © Sleeper Agents LLC. Contract governed by invariants authored with Mark Holak's conceptual framework.*
|
| 4 |
+
|
| 5 |
+
Every realm adapter (FluentCRM, Fluent Support, Fluent Boards, Jira, QuickBase, QuickBooks, Salesforce, HubSpot, PortTracker's Node service, arbitrary REST/GraphQL/DB) implements `SA_Realm_Adapter`. This document is the formal contract.
|
| 6 |
+
|
| 7 |
+
An adapter is **complete when it preserves origin, survives failure, emits audit, and passes certification** — not when it "functions."
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## Interface
|
| 12 |
+
|
| 13 |
+
```php
|
| 14 |
+
interface SA_Realm_Adapter {
|
| 15 |
+
public static function realm_id(): string;
|
| 16 |
+
public static function capabilities(): array;
|
| 17 |
+
public static function concept_map(): array;
|
| 18 |
+
public static function pull(string $concept, array $filter, array $context): array;
|
| 19 |
+
public static function push(string $concept, SA_Entity $entity, array $context): array;
|
| 20 |
+
public static function watch_hooks(): array;
|
| 21 |
+
public static function capability_matrix(): array; // formal gates
|
| 22 |
+
public static function idempotency_rules(): array; // replay behavior per op
|
| 23 |
+
public static function truth_class_for_concept(string $concept): string;
|
| 24 |
+
}
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
---
|
| 28 |
+
|
| 29 |
+
## `realm_id()`
|
| 30 |
+
|
| 31 |
+
Short, stable identifier. Examples: `fluent-crm`, `fluent-support`, `fluent-boards`, `jira`, `quickbase`, `quickbooks`, `porttracker-node`.
|
| 32 |
+
|
| 33 |
+
Must be unique across all adapters in a given Core install. Used as the `origin_realm` on every entity the adapter produces.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
## `capabilities()`
|
| 38 |
+
|
| 39 |
+
Set of strings from: `read`, `write`, `watch`, `bulk`, `incremental`, `idempotent_push`.
|
| 40 |
+
|
| 41 |
+
- `read` — adapter can pull records from the realm.
|
| 42 |
+
- `write` — adapter can push changes back into the realm.
|
| 43 |
+
- `watch` — adapter subscribes to realm events (webhook or WP hooks).
|
| 44 |
+
- `bulk` — adapter supports full snapshot pulls.
|
| 45 |
+
- `incremental` — adapter supports `since` cursor / delta pulls.
|
| 46 |
+
- `idempotent_push` — repeated push calls with the same payload are safe.
|
| 47 |
+
|
| 48 |
+
A read-only adapter declares only `read` (and optionally `watch`, `bulk`, `incremental`).
|
| 49 |
+
|
| 50 |
+
---
|
| 51 |
+
|
| 52 |
+
## `payload.attributes` namespace convention
|
| 53 |
+
|
| 54 |
+
Structured realm-side metadata that Core stores on an ingested entity goes under `payload.attributes` — a reserved sub-object. Freeform realm-native blobs remain elsewhere in `payload` (e.g., `payload.raw`, `payload.body_markdown`), but any field an adapter intends to be *addressable* — readable by the trace panel, queryable by future projections, or filter-eligible — belongs in `attributes`.
|
| 55 |
+
|
| 56 |
+
```php
|
| 57 |
+
$entity->payload = [
|
| 58 |
+
'attributes' => [
|
| 59 |
+
'mime_type' => 'application/pdf',
|
| 60 |
+
'size_bytes' => 12345,
|
| 61 |
+
'modified_at' => '2026-04-23T10:15:00Z',
|
| 62 |
+
'basename' => 'spec.pdf',
|
| 63 |
+
'extension' => 'pdf',
|
| 64 |
+
],
|
| 65 |
+
'raw' => [/* whatever realm-native detail the adapter wants to retain */],
|
| 66 |
+
];
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
**Purpose.** Two-fold:
|
| 70 |
+
|
| 71 |
+
1. Adapters converge on a predictable shape for structured fields. The FS adapter, the Jira adapter, the QuickBase adapter all put their structured metadata in `attributes`. A downstream reader (trace panel, future filter surface) knows where to look without realm-specific code.
|
| 72 |
+
2. A later promotion to typed columns — if cross-realm queries demand it — is a rename migration, not a schema redesign. `payload.attributes.mime_type` becomes `entity.attributes.mime_type` or a separate `sa_entity_attribute` table without touching adapter code.
|
| 73 |
+
|
| 74 |
+
**Discipline.** `attributes` values SHOULD be JSON-scalar (string / number / boolean / null) or flat arrays thereof. Nested objects inside `attributes` are permitted but signal that a sub-concept may want its own entity and containment edge instead.
|
| 75 |
+
|
| 76 |
+
**Not canonical.** The `attributes` convention does not change truth-class. A projected entity's `payload.attributes` is still projection data; the realm remains canonical.
|
| 77 |
+
|
| 78 |
+
---
|
| 79 |
+
|
| 80 |
+
## `concept_map()`
|
| 81 |
+
|
| 82 |
+
Declares how realm concepts translate into Core entity roles and edge kinds.
|
| 83 |
+
|
| 84 |
+
```php
|
| 85 |
+
[
|
| 86 |
+
'ticket' => ['role' => 'job', 'band' => 3],
|
| 87 |
+
'agent' => ['role' => 'agent', 'band' => 3],
|
| 88 |
+
'customer'=> ['role' => 'agent', 'band' => 3],
|
| 89 |
+
'reply' => ['role' => 'message', 'band' => 4],
|
| 90 |
+
'edges' => [
|
| 91 |
+
'ticket->agent' => ['kind' => 'depends', 'weight' => 0.8],
|
| 92 |
+
'ticket->customer' => ['kind' => 'depends', 'weight' => 1.0],
|
| 93 |
+
'reply->ticket' => ['kind' => 'contains', 'weight' => 1.0],
|
| 94 |
+
],
|
| 95 |
+
]
|
| 96 |
+
```
|
| 97 |
+
|
| 98 |
+
Concept names are adapter-scoped (no collision across realms). Edge rules describe how relationships in the realm become typed edges in Core.
|
| 99 |
+
|
| 100 |
+
---
|
| 101 |
+
|
| 102 |
+
## `capability_matrix()`
|
| 103 |
+
|
| 104 |
+
Turns "tool not silo" into enforceable behavior:
|
| 105 |
+
|
| 106 |
+
```php
|
| 107 |
+
[
|
| 108 |
+
'read' => true,
|
| 109 |
+
'write' => true,
|
| 110 |
+
'delete' => false,
|
| 111 |
+
'impersonation' => false,
|
| 112 |
+
'service_principal' => true,
|
| 113 |
+
'human_confirmation_required' => ['delete', 'bulk_write', 'schema_change'],
|
| 114 |
+
'simulation_only_mode' => true,
|
| 115 |
+
]
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
Core consults this matrix before dispatching every operation. An adapter that does not declare `delete = true` cannot delete; an operation listed in `human_confirmation_required` cannot execute without a confirmed human action; `simulation_only_mode = true` enables dry-run mode for destructive operations.
|
| 119 |
+
|
| 120 |
+
---
|
| 121 |
+
|
| 122 |
+
## `idempotency_rules()`
|
| 123 |
+
|
| 124 |
+
Per-operation replay behavior:
|
| 125 |
+
|
| 126 |
+
```php
|
| 127 |
+
[
|
| 128 |
+
'pull' => [
|
| 129 |
+
'idempotent' => true,
|
| 130 |
+
'replay_safe' => true,
|
| 131 |
+
'conflict_resolution' => 'last_write_wins',
|
| 132 |
+
],
|
| 133 |
+
'push' => [
|
| 134 |
+
'idempotent' => false,
|
| 135 |
+
'replay_safe' => false,
|
| 136 |
+
'conflict_resolution' => 'reject',
|
| 137 |
+
],
|
| 138 |
+
'watch' => [
|
| 139 |
+
'idempotent' => true,
|
| 140 |
+
'replay_safe' => true,
|
| 141 |
+
'conflict_resolution' => 'last_write_wins',
|
| 142 |
+
],
|
| 143 |
+
]
|
| 144 |
+
```
|
| 145 |
+
|
| 146 |
+
`conflict_resolution` values: `last_write_wins` | `reject` | `human_review`.
|
| 147 |
+
|
| 148 |
+
A non-idempotent `push` must never be retried without an explicit policy decision.
|
| 149 |
+
|
| 150 |
+
---
|
| 151 |
+
|
| 152 |
+
## `pull(concept, filter, context)`
|
| 153 |
+
|
| 154 |
+
Returns a list of `SA_Ingest`-shaped mutations:
|
| 155 |
+
|
| 156 |
+
```php
|
| 157 |
+
[
|
| 158 |
+
[
|
| 159 |
+
'op' => 'upsert_entity',
|
| 160 |
+
'entity' => [
|
| 161 |
+
'external_key' => '<native_id>', // REQUIRED (or origin_id directly)
|
| 162 |
+
'role' => 'job',
|
| 163 |
+
'kind' => 'rrect',
|
| 164 |
+
'payload' => [...],
|
| 165 |
+
'truth_class' => SA_Truth_Class::PROJECTED, // default
|
| 166 |
+
],
|
| 167 |
+
],
|
| 168 |
+
[
|
| 169 |
+
'op' => 'upsert_edge',
|
| 170 |
+
'edge' => [
|
| 171 |
+
'source_id' => '...',
|
| 172 |
+
'target_id' => '...',
|
| 173 |
+
'kind' => 'depends',
|
| 174 |
+
'weight' => 0.8,
|
| 175 |
+
'intentional' => true,
|
| 176 |
+
],
|
| 177 |
+
],
|
| 178 |
+
[
|
| 179 |
+
'op' => 'attach_source',
|
| 180 |
+
'entity_id' => '...',
|
| 181 |
+
'priority' => 10,
|
| 182 |
+
'source_payload' => [...],
|
| 183 |
+
],
|
| 184 |
+
]
|
| 185 |
+
```
|
| 186 |
+
|
| 187 |
+
**Provenance minimums are MANDATORY** (Invariant I4). Every upserted entity must carry either `external_key` (from which `origin_realm` + `origin_id` are derived) or `origin_realm` + `origin_id` explicitly.
|
| 188 |
+
|
| 189 |
+
**Truth class default is `projected`** — non-canonical mirror of the realm's canonical state. Only adapters whose concept is genuinely advisory (weather forecasts, suggestions) may return `inferred`.
|
| 190 |
+
|
| 191 |
+
---
|
| 192 |
+
|
| 193 |
+
## `push(concept, entity, context)`
|
| 194 |
+
|
| 195 |
+
Apply a Core-side change back into the realm.
|
| 196 |
+
|
| 197 |
+
Returns:
|
| 198 |
+
|
| 199 |
+
```php
|
| 200 |
+
[
|
| 201 |
+
'ok' => true,
|
| 202 |
+
'external_id' => '<realm-assigned-id-if-new>',
|
| 203 |
+
'error' => null,
|
| 204 |
+
'trace_token' => '<optional-realm-trace-handle>',
|
| 205 |
+
]
|
| 206 |
+
```
|
| 207 |
+
|
| 208 |
+
**Idempotency:** if declared in `idempotency_rules()`, `push` MUST be safe to retry. The adapter is responsible for deduplicating on the realm side (using the entity's `id` or a synthetic idempotency key).
|
| 209 |
+
|
| 210 |
+
**Never mutate without action path.** A push that was not triggered by a command (or an audited automation policy) is a protocol violation.
|
| 211 |
+
|
| 212 |
+
---
|
| 213 |
+
|
| 214 |
+
## `watch_hooks()`
|
| 215 |
+
|
| 216 |
+
```php
|
| 217 |
+
[
|
| 218 |
+
['hook' => 'fluentcrm/contact_created', 'handler' => [self::class, 'on_contact_created'], 'priority' => 10],
|
| 219 |
+
['hook' => 'fluent_support/ticket_reply', 'handler' => [self::class, 'on_reply'], 'priority' => 10],
|
| 220 |
+
]
|
| 221 |
+
```
|
| 222 |
+
|
| 223 |
+
Core's `SA_Realm_Registry::wire_all_watchers()` attaches these on boot. The handler must emit ingest mutations (not directly mutate Core state), so that the ingest pipeline's enforcement gates apply uniformly.
|
| 224 |
+
|
| 225 |
+
---
|
| 226 |
+
|
| 227 |
+
## `truth_class_for_concept(concept)`
|
| 228 |
+
|
| 229 |
+
Returns one of `SA_Truth_Class::ALL`. Default: `projected`.
|
| 230 |
+
|
| 231 |
+
- Realm concepts that are authoritative at the realm: `projected`.
|
| 232 |
+
- Realm concepts that are explicitly advisory: `inferred`.
|
| 233 |
+
- Core-authored concepts (rare): `canonical`.
|
| 234 |
+
- Cache-only concepts with TTL: `cached` (declared by the adapter's cache layer, not usually by the adapter itself).
|
| 235 |
+
|
| 236 |
+
---
|
| 237 |
+
|
| 238 |
+
## Certification Checklist
|
| 239 |
+
|
| 240 |
+
An adapter is **not live** until these pass. Recorded to `sa_adapter_certification`.
|
| 241 |
+
|
| 242 |
+
| Check | Meaning |
|
| 243 |
+
|---|---|
|
| 244 |
+
| `source_identity_preserved` | Realm's native id is preserved on every ingested record and round-trippable through push. |
|
| 245 |
+
| `native_ids_preserved` | `origin_id` survives every transformation in and out. |
|
| 246 |
+
| `read_path_verified` | Pull returns records that successfully deserialize as Core entities. |
|
| 247 |
+
| `write_path_verified` | Push creates or updates a realm record and returns the native id. |
|
| 248 |
+
| `failure_path_verified` | Failures (network, 4xx, 5xx, timeouts) raise structured errors; no silent half-writes. |
|
| 249 |
+
| `stale_cache_behavior_verified` | When cache is stale and the caller demands high-trust, the adapter re-verifies against the realm. |
|
| 250 |
+
| `audit_event_emitted` | Every pull and push produces a `sa_structural_audit` row with `origin_realm`, `correlation_id`, `causation_id`. |
|
| 251 |
+
| `rollback_defined` | There is a documented compensation path for failed pushes or partial batches. |
|
| 252 |
+
|
| 253 |
+
All eight must be `true` before an adapter moves from development to live. A failing certification row prevents the realm from being included in the active routing set.
|
| 254 |
+
|
| 255 |
+
---
|
| 256 |
+
|
| 257 |
+
## Behavioral guarantees (enforced at interface level)
|
| 258 |
+
|
| 259 |
+
- Adapter **never mutates without an action path**. A push requires a command; a pull is triggered by an explicit sync or a watch event.
|
| 260 |
+
- Adapter **never strips source metadata**. `origin_realm`, `origin_id`, `observed_at` survive every transformation.
|
| 261 |
+
- Every record returned includes native id and source realm.
|
| 262 |
+
- Outbound writes return status, external id, and (where available) a trace token.
|
| 263 |
+
- Retries are idempotent where declared; non-idempotent operations require explicit policy approval to retry.
|
| 264 |
+
- Error classes are normalized to `{ok, error, error_code, detail}`.
|
| 265 |
+
|
| 266 |
+
---
|
| 267 |
+
|
| 268 |
+
## The tool test
|
| 269 |
+
|
| 270 |
+
Before any realm adapter is declared live, the operator asks:
|
| 271 |
+
|
| 272 |
+
> If Core disappears tomorrow, does this realm still work at its native home?
|
| 273 |
+
|
| 274 |
+
If the answer is anything but *yes*, the adapter has crossed from incorporation into absorption. That is a different category, governed by a different process (code consolidation, not conduit), and must be signaled as such. The user and the operator must both consent before an adapter is ever permitted to cross this boundary.
|
| 275 |
+
|
| 276 |
+
---
|
| 277 |
+
|
| 278 |
+
## Attribution
|
| 279 |
+
|
| 280 |
+
Contract shape and adapter interface: © Sleeper Agents LLC.
|
| 281 |
+
|
| 282 |
+
The invariants that the contract enforces (I4 realm provenance, I5 graceful degradation, I6 cache discipline, I8 tool test) implement conceptual commitments authored independently by Mark Holak. See `docs/specs/concepts/` for the foundational framework.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/04-async-execution.md
ADDED
|
@@ -0,0 +1,678 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Async Execution — Design Specification
|
| 2 |
+
|
| 3 |
+
Status: **design approved; Phase 1 implementing as foundational substrate.**
|
| 4 |
+
Target rung: 2.5 (between projection completion and zoom-quantum).
|
| 5 |
+
Scope: one foundational pillar. Implementation proceeds phase-by-phase under separate directives.
|
| 6 |
+
|
| 7 |
+
## Framing (authoritative)
|
| 8 |
+
|
| 9 |
+
The pillar is **ownership of execution**, not "offline" as a feature.
|
| 10 |
+
|
| 11 |
+
Three layers, kept distinct:
|
| 12 |
+
|
| 13 |
+
- **Now Session** — the user-facing scope. The browser tab, the compose bar,
|
| 14 |
+
the field as it reads during an interactive moment. UX lives here. In
|
| 15 |
+
Phase 1 this is UNCHANGED: prompts still feel like "I asked here, it is
|
| 16 |
+
working here, this thread is mine now."
|
| 17 |
+
|
| 18 |
+
- **Shadow job** — the execution substrate. A server-owned lifecycle record
|
| 19 |
+
(`sa_job`) that tracks what the executor is actually doing. Introduced in
|
| 20 |
+
Phase 1 as foundational infrastructure, with no UX surfacing. The seam
|
| 21 |
+
that makes later decoupling possible without rewriting retries, state
|
| 22 |
+
transitions, frontier selection, failure handling, or field updates.
|
| 23 |
+
|
| 24 |
+
- **Offline / Subconscious** — a future user-facing mode built on the
|
| 25 |
+
shadow-job substrate. Marketing layer for background / recoverable / long-
|
| 26 |
+
running work. NOT introduced by Phase 1. Introduced only when a later
|
| 27 |
+
directive surfaces it.
|
| 28 |
+
|
| 29 |
+
The instruction the rest of this spec serves:
|
| 30 |
+
|
| 31 |
+
> Treat shadow jobs as foundational infrastructure introduced now, but keep
|
| 32 |
+
> their behavior scoped to the current Now Session until a later directive
|
| 33 |
+
> surfaces them as an explicit Offline/Subconscious capability.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
## 0. Scope note
|
| 38 |
+
|
| 39 |
+
This spec describes **async prompt execution** as a first-class capability.
|
| 40 |
+
|
| 41 |
+
It does NOT cover:
|
| 42 |
+
- The client-state race bug-fix (a separate, independent commit — closes a symptom of the sync model; lands before or alongside phase 1 here).
|
| 43 |
+
- Implementation commits (each phase below becomes a directive; each directive becomes one or more commits).
|
| 44 |
+
|
| 45 |
+
It DOES cover:
|
| 46 |
+
- What a prompt job is, and how it differs from the current request.
|
| 47 |
+
- The canonical state machine.
|
| 48 |
+
- The storage model.
|
| 49 |
+
- The worker strategy (comparison + decision + rationale).
|
| 50 |
+
- The client interaction model (comparison + phased choice).
|
| 51 |
+
- A phased migration plan where each phase ships a working system.
|
| 52 |
+
- The failure / retry / recovery model.
|
| 53 |
+
- Explicit tradeoffs and risks.
|
| 54 |
+
- Measurable success criteria.
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## 1. Motivation and Current Limitations
|
| 59 |
+
|
| 60 |
+
### Today
|
| 61 |
+
|
| 62 |
+
- `POST /sa-core/v1/prompt` is synchronous. The REST thread calls `SA_Executor::run`, which calls the adapter via `wp_remote_post`, which blocks the PHP request for up to 180 seconds (after the recent timeout raise).
|
| 63 |
+
- The browser tab owns the entire prompt lifecycle. The client's `fetch()` holds the connection; if the tab closes, the server continues running but the user loses all visibility into the outcome.
|
| 64 |
+
- Two prompts submitted in parallel are two parallel PHP workers, each doing a long cURL wait, with zero coordination, no priority, and no recovery if one of them crashes.
|
| 65 |
+
- The just-observed concurrent-submit race (two prompts attaching to the same parent) is a symptom: client-side `activeCtxRootId` is the only source of truth for "which node is the continuation root," so timing conflicts between user navigation and async resolution are inevitable.
|
| 66 |
+
|
| 67 |
+
### Why this is structural, not cosmetic
|
| 68 |
+
|
| 69 |
+
1. **Rung 5 (operator realism) is blocked.** Tests that simulate load, capacity planning, reliability SLAs, and meaningful metrics all require async job execution. Every one of these is meaningless against a sync model.
|
| 70 |
+
2. **Rung 4 (zoom-quantum engine) gets much harder on sync.** The engine wants cheap state-transition re-renders. Pushing state through long sync calls + `/mission/recent` refreshes introduces races we'd have to hunt repeatedly.
|
| 71 |
+
3. **Rungs 3 and 6 (self-hosting, carma-audit absorption) produce entity streams that shouldn't block HTTP.** Scanner runs, doc ingestion, code ingestion — none of these should tie up a web request.
|
| 72 |
+
4. **The tab is not a reliable process owner.** Real work — long code generations, multi-step agent chains, background analyses — must survive a closed tab.
|
| 73 |
+
5. **Browser-side state conflicts are fundamental with sync.** The concurrent-submit race is one; future race surfaces (multi-user live editing, real-time collaboration) are coming. Moving execution state authority to the server closes these by construction.
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## 2. Execution Model
|
| 78 |
+
|
| 79 |
+
### What is a "prompt job"
|
| 80 |
+
|
| 81 |
+
A **prompt job** is the unit of work that executes the `SA_Executor` pipeline against a specific prompt entity. It is:
|
| 82 |
+
|
| 83 |
+
- A durable record with its own UUID identity (distinct from the prompt entity).
|
| 84 |
+
- A pointer to a persisted prompt entity (`prompt_id`).
|
| 85 |
+
- A member of the queue with a state, a priority, and a retry budget.
|
| 86 |
+
- Owned by the server, not the browser.
|
| 87 |
+
- Inspectable, retriable, cancellable, supersedable — as a first-class operation.
|
| 88 |
+
|
| 89 |
+
### How it differs from the current request model
|
| 90 |
+
|
| 91 |
+
| Concern | Today (sync) | Proposed (async) |
|
| 92 |
+
|---|---|---|
|
| 93 |
+
| Who owns the pipeline's lifecycle? | The REST thread | The worker layer |
|
| 94 |
+
| Where is "in-progress" state? | PHP memory + browser memory | `sa_job` DB row |
|
| 95 |
+
| Does closing the tab kill the work? | No (it continues) but the user loses visibility | No — and the user regains visibility on reload |
|
| 96 |
+
| Can two prompts run simultaneously? | Only as two parallel PHP workers with no coordination | Yes, first-class, priority-ordered |
|
| 97 |
+
| Can a failed execution be retried cleanly? | Via `retry_prompt` after the fact | Built into the state machine |
|
| 98 |
+
| Can the user inspect queued / running work? | No | Yes (CLI phase 2; UI later) |
|
| 99 |
+
|
| 100 |
+
### Canonical lifecycle
|
| 101 |
+
|
| 102 |
+
1. **Submit.** `POST /prompt` creates:
|
| 103 |
+
- Prompt entity (as today, synchronously within the request — this is fast; the adapter call is what blocks).
|
| 104 |
+
- `sa_job` row with `state='queued'`.
|
| 105 |
+
- Returns **`202 Accepted`** with `prompt_id`, `job_id`, and initial state. Target: response within 50ms.
|
| 106 |
+
2. **Enqueue.** Client adds the prompt to its `entities[]` array with the job's state, renders a "queued" drop. Client begins polling (phase 2) or listening via SSE (phase 4).
|
| 107 |
+
3. **Claim.** A worker polls for the highest-priority queued job. Transactional update: `state='queued'` → `state='running'`, `worker_claim=<uuid>`, `claimed_at=now`.
|
| 108 |
+
4. **Run.** The worker invokes `SA_Executor::run_claimed(job_id)`. This is a refactored executor entry-point that operates on an already-persisted prompt + job, not a fresh submit.
|
| 109 |
+
5. **Complete.** On adapter success, the worker writes the response entity, the `flows-to` edge, the ledger row, the structural audit row (as today), and transitions the job to `state='succeeded'` with `response_id` set.
|
| 110 |
+
6. **Observe.** Client sees state transitions via polling or SSE, updates the drop's visual state class accordingly.
|
| 111 |
+
7. **Fail (if applicable).** On adapter error, the worker classifies the error, applies retry policy, and either re-queues the job with backoff OR marks it `state='failed'`.
|
| 112 |
+
|
| 113 |
+
---
|
| 114 |
+
|
| 115 |
+
## 3. State Machine
|
| 116 |
+
|
| 117 |
+
### States
|
| 118 |
+
|
| 119 |
+
| State | Meaning | Terminal? |
|
| 120 |
+
|---|---|---|
|
| 121 |
+
| `queued` | Created; waiting for a worker | No |
|
| 122 |
+
| `running` | Claimed by a worker; adapter call in flight | No |
|
| 123 |
+
| `succeeded` | Adapter returned OK; response entity persisted | Yes |
|
| 124 |
+
| `failed` | Retry budget exhausted or non-retryable error | Yes |
|
| 125 |
+
| `cancelled` | User or operator intervention | Yes |
|
| 126 |
+
| `superseded` | Replaced by a newer job (e.g., user retried) | Yes |
|
| 127 |
+
|
| 128 |
+
Once a job enters a terminal state, it does not change. A retry does **not** mutate an existing job — it creates a **new job** that references the old one via `supersedes`.
|
| 129 |
+
|
| 130 |
+
### Transitions
|
| 131 |
+
|
| 132 |
+
```
|
| 133 |
+
queued → running : worker successfully claims
|
| 134 |
+
queued → cancelled : user/operator action before claim
|
| 135 |
+
running → succeeded : adapter OK + response entity written
|
| 136 |
+
running → queued : transient failure; attempt < max_attempts; apply backoff
|
| 137 |
+
running → failed : retry budget exhausted OR non-retryable error
|
| 138 |
+
running → failed : stuck (started > 15 min ago, no heartbeat) via cleanup
|
| 139 |
+
running → cancelled : operator kill (response discarded even if it arrives later)
|
| 140 |
+
succeeded → superseded : user-initiated retry replaces result
|
| 141 |
+
failed → superseded : user-initiated retry
|
| 142 |
+
cancelled → superseded : user-initiated retry after cancel
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
### Heartbeat model
|
| 146 |
+
|
| 147 |
+
While `state='running'`, the worker MUST update `running_heartbeat_at` every 30 seconds. A separate cleanup task (run via system cron every 5 minutes) reclaims jobs where `running_heartbeat_at < now() - 5min` back to `state='queued'` (if `attempt < max_attempts`) or to `state='failed'` (else).
|
| 148 |
+
|
| 149 |
+
### Triggers
|
| 150 |
+
|
| 151 |
+
- `queued` ← `SA_Executor::enqueue` (called from REST handler).
|
| 152 |
+
- `running` ← worker process picks up a `queued` job and wins the claim race.
|
| 153 |
+
- `succeeded` ← worker completes execution and commits.
|
| 154 |
+
- `failed` ← worker exhausts retries OR cleanup declares job stuck.
|
| 155 |
+
- `cancelled` ← CLI `wp sa-core cancel-job <id>` OR admin action.
|
| 156 |
+
- `superseded` ← a new job is created referring to this one via `supersedes`.
|
| 157 |
+
|
| 158 |
+
---
|
| 159 |
+
|
| 160 |
+
## 4. Storage Model
|
| 161 |
+
|
| 162 |
+
### Decision: new `sa_job` table
|
| 163 |
+
|
| 164 |
+
Not overloading `sa_entity`.
|
| 165 |
+
|
| 166 |
+
Rationale:
|
| 167 |
+
- `sa_entity` represents authored knowledge: the user's prompt, the LLM's response, the derived context. It has one durable identity per artifact.
|
| 168 |
+
- `sa_job` represents execution: a prompt may have multiple execution attempts (retries), each with its own claim, timing, errors, heartbeats. Conflating these with entity state confuses semantics and crowds the entity row.
|
| 169 |
+
- Keeping them separate means: `sa_entity` stays durable knowledge; `sa_job` stays ephemeral execution records. Queries stay clean: "show me the user's recent prompts" is a `sa_entity` query; "show me what's queued" is a `sa_job` query.
|
| 170 |
+
|
| 171 |
+
### Schema
|
| 172 |
+
|
| 173 |
+
```sql
|
| 174 |
+
CREATE TABLE {prefix}sa_job (
|
| 175 |
+
id CHAR(36) NOT NULL,
|
| 176 |
+
prompt_id CHAR(36) NOT NULL,
|
| 177 |
+
|
| 178 |
+
state VARCHAR(16) NOT NULL DEFAULT 'queued',
|
| 179 |
+
-- queued | running | succeeded | failed | cancelled | superseded
|
| 180 |
+
|
| 181 |
+
priority TINYINT UNSIGNED NOT NULL DEFAULT 50,
|
| 182 |
+
-- lower number = higher priority
|
| 183 |
+
-- 0-10: urgent (interactive, current-tab)
|
| 184 |
+
-- 20-40: normal user-initiated background
|
| 185 |
+
-- 50: default
|
| 186 |
+
-- 60-90: bulk / scheduled / idle-time
|
| 187 |
+
-- 100: lowest (opportunistic)
|
| 188 |
+
|
| 189 |
+
attempt SMALLINT UNSIGNED NOT NULL DEFAULT 1,
|
| 190 |
+
max_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 3,
|
| 191 |
+
|
| 192 |
+
execution_options LONGTEXT NOT NULL,
|
| 193 |
+
-- JSON: { model?, prefer_provider?, depth?, router_model?, ... }
|
| 194 |
+
|
| 195 |
+
worker_claim VARCHAR(64) NULL,
|
| 196 |
+
claimed_at DATETIME NULL,
|
| 197 |
+
started_at DATETIME NULL,
|
| 198 |
+
running_heartbeat_at DATETIME NULL,
|
| 199 |
+
finished_at DATETIME NULL,
|
| 200 |
+
|
| 201 |
+
response_id CHAR(36) NULL,
|
| 202 |
+
-- set on succeeded; points to the response entity
|
| 203 |
+
|
| 204 |
+
error_kind VARCHAR(32) NULL,
|
| 205 |
+
-- timeout | rate_limit | provider_5xx | provider_4xx
|
| 206 |
+
-- | parse | auth | worker_crash | stuck | unknown
|
| 207 |
+
|
| 208 |
+
error_message TEXT NULL,
|
| 209 |
+
|
| 210 |
+
supersedes CHAR(36) NULL,
|
| 211 |
+
-- if this job replaces a previous attempt
|
| 212 |
+
|
| 213 |
+
org_id BIGINT UNSIGNED NOT NULL,
|
| 214 |
+
created_by BIGINT UNSIGNED NOT NULL,
|
| 215 |
+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 216 |
+
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
| 217 |
+
ON UPDATE CURRENT_TIMESTAMP,
|
| 218 |
+
|
| 219 |
+
PRIMARY KEY (id),
|
| 220 |
+
KEY idx_state_priority_created (state, priority, created_at),
|
| 221 |
+
KEY idx_prompt (prompt_id),
|
| 222 |
+
KEY idx_worker_claim (worker_claim),
|
| 223 |
+
KEY idx_org_user_state (org_id, created_by, state),
|
| 224 |
+
KEY idx_heartbeat (state, running_heartbeat_at)
|
| 225 |
+
)
|
| 226 |
+
```
|
| 227 |
+
|
| 228 |
+
### Interaction with existing entity fields
|
| 229 |
+
|
| 230 |
+
| Field | Lives on | Set when | Changed by jobs? |
|
| 231 |
+
|---|---|---|---|
|
| 232 |
+
| `correlation_id` | `sa_entity` | At prompt creation time (unchanged) | No |
|
| 233 |
+
| `parent_id` | `sa_entity` | At prompt creation time (continuation semantics, unchanged) | No |
|
| 234 |
+
| `causation_id` | `sa_entity` | At prompt creation time (unchanged) | No |
|
| 235 |
+
| `source_refs` | `sa_entity` (response) | Written by worker at job completion | Indirectly (job runs the executor which sets it) |
|
| 236 |
+
| `truth_class` / `state_class` | `sa_entity` | Set at write time (unchanged) | No |
|
| 237 |
+
|
| 238 |
+
The `sa_job` table is orthogonal to the entity graph. Entities are durable structural records. Jobs are execution metadata.
|
| 239 |
+
|
| 240 |
+
### Retry and supersession
|
| 241 |
+
|
| 242 |
+
When a user retries a failed or succeeded prompt:
|
| 243 |
+
1. Create a **new** `sa_job` row with the same `prompt_id`, new UUID, `attempt=1`, `state=queued`, `supersedes=<old_job_id>`.
|
| 244 |
+
2. The old job stays in place (terminal state preserved).
|
| 245 |
+
3. If the retry path requires cleaning up a prior response entity (as the current `retry_prompt` does for failed responses), that happens in the worker that claims the new job, NOT at enqueue time.
|
| 246 |
+
|
| 247 |
+
This model means every execution attempt is recorded and queryable. "Show me the history of this prompt" becomes `SELECT * FROM sa_job WHERE prompt_id = X ORDER BY created_at`.
|
| 248 |
+
|
| 249 |
+
---
|
| 250 |
+
|
| 251 |
+
## 5. Worker Strategy
|
| 252 |
+
|
| 253 |
+
### Decision: custom worker, driven by WP-CLI + system cron
|
| 254 |
+
|
| 255 |
+
### Comparison
|
| 256 |
+
|
| 257 |
+
**Option A: WP-Cron alone** — not chosen.
|
| 258 |
+
- Pros: zero external dependencies.
|
| 259 |
+
- Cons: WP-Cron spawns only on page visits (unreliable for low-traffic sites); each spawn is bound by `max_execution_time`; no native priority; no concurrency management. The "real cron hitting `wp-cron.php`" workaround mitigates the first point but the others remain.
|
| 260 |
+
|
| 261 |
+
**Option B: Action Scheduler (the library)** — fallback / future option.
|
| 262 |
+
- Pros: mature, battle-tested by WooCommerce and Mailpoet, has built-in claim/retry/logs, comes with an admin UI, well-understood in the WP ecosystem.
|
| 263 |
+
- Cons: adds a dependency (~200KB library, or plugin requirement); its schema and patterns are WooCommerce-flavored; it wraps our job concept with its own scheduling layer that we'd then have to thread through.
|
| 264 |
+
- Worth reconsidering if we ever need to interoperate with a WooCommerce-running site that already uses AS.
|
| 265 |
+
|
| 266 |
+
**Option C: Custom worker** — chosen.
|
| 267 |
+
- Rationale: our `sa_job` table **is** our job system. Its state machine is specific to our semantics (prompt-centric, projection-aware, org-scoped). Adding Action Scheduler on top means we'd write adapters between our table and theirs. A custom worker is ~300 lines of code, directly aligned with our data model.
|
| 268 |
+
- Cons: we own the scheduler code. Edge cases (claim races, heartbeat recovery, backoff) must be solved by us. But: the surface is narrow, there's no distributed coordination to worry about (single-node plugin), and the patterns are well-known.
|
| 269 |
+
|
| 270 |
+
### Custom worker implementation
|
| 271 |
+
|
| 272 |
+
```
|
| 273 |
+
wp sa-core run-worker [--once] [--batch-size=N] [--priority-ceiling=N]
|
| 274 |
+
```
|
| 275 |
+
|
| 276 |
+
Behavior in one iteration:
|
| 277 |
+
1. Generate or resume a `worker_id` for this process (UUID).
|
| 278 |
+
2. Claim a batch of jobs:
|
| 279 |
+
```sql
|
| 280 |
+
UPDATE sa_job
|
| 281 |
+
SET state='running',
|
| 282 |
+
worker_claim=<worker_id>,
|
| 283 |
+
claimed_at=NOW(),
|
| 284 |
+
started_at=NOW(),
|
| 285 |
+
running_heartbeat_at=NOW()
|
| 286 |
+
WHERE state='queued'
|
| 287 |
+
AND priority <= <priority-ceiling>
|
| 288 |
+
ORDER BY priority ASC, created_at ASC
|
| 289 |
+
LIMIT <batch-size>
|
| 290 |
+
```
|
| 291 |
+
The single-statement UPDATE is the claim atomic: whichever worker's UPDATE lands first, wins.
|
| 292 |
+
3. Re-query the claimed rows by `worker_claim=<worker_id>` to get the actual job ids.
|
| 293 |
+
4. For each claimed job:
|
| 294 |
+
- Call `SA_Executor::run_claimed(job_id)`.
|
| 295 |
+
- On success: set state='succeeded', response_id, finished_at.
|
| 296 |
+
- On retryable failure: if attempt < max_attempts, set state='queued' with backoff delay (encoded via `created_at += backoff`); else state='failed'.
|
| 297 |
+
- On non-retryable failure: state='failed' immediately.
|
| 298 |
+
5. Spawn a heartbeat thread/callback that updates `running_heartbeat_at` every 30s while the adapter is in flight.
|
| 299 |
+
6. Sleep 2 seconds. If `--once`, exit. Otherwise loop.
|
| 300 |
+
|
| 301 |
+
### Driving the worker
|
| 302 |
+
|
| 303 |
+
Three supported modes:
|
| 304 |
+
|
| 305 |
+
**Mode 1: Single-shot via system cron** (recommended for production)
|
| 306 |
+
```cron
|
| 307 |
+
* * * * * wp sa-core run-worker --once --batch-size=5
|
| 308 |
+
```
|
| 309 |
+
Every minute, claim up to 5 jobs, process them, exit. Reliable, bounded, manageable.
|
| 310 |
+
|
| 311 |
+
**Mode 2: Long-running service** (optional for high-volume)
|
| 312 |
+
```
|
| 313 |
+
wp sa-core run-worker
|
| 314 |
+
```
|
| 315 |
+
Starts a persistent worker. Polls continuously. Should be supervised (systemd / supervisor) for restarts on crash.
|
| 316 |
+
|
| 317 |
+
**Mode 3: WP-Cron via wp-cron.php** (default; fallback)
|
| 318 |
+
If a site has no system cron, register `sa-core-process-queue` as a WP-Cron event firing every minute. Relies on site traffic; acceptable for dev and low-traffic installs.
|
| 319 |
+
|
| 320 |
+
### Heartbeat and stuck-job cleanup
|
| 321 |
+
|
| 322 |
+
Separate command:
|
| 323 |
+
```
|
| 324 |
+
wp sa-core reclaim-stuck-jobs
|
| 325 |
+
```
|
| 326 |
+
System cron: every 5 minutes.
|
| 327 |
+
|
| 328 |
+
Behavior:
|
| 329 |
+
- Find jobs where `state='running'` AND `running_heartbeat_at < now() - 5 minutes`.
|
| 330 |
+
- For each:
|
| 331 |
+
- If `attempt < max_attempts` AND `started_at > now() - 15 minutes`: reclaim to `state='queued'`, clear `worker_claim`.
|
| 332 |
+
- Else: `state='failed'`, `error_kind='stuck'`.
|
| 333 |
+
|
| 334 |
+
### Double-execution safety
|
| 335 |
+
|
| 336 |
+
Risk: worker A claims a job, loses heartbeat, cleanup reclaims to queued, worker B claims and runs. Worker A's adapter call may still be in flight. Both workers could reach the "complete" step.
|
| 337 |
+
|
| 338 |
+
Mitigation: all state-finalization writes (`state='succeeded'`, `response_id`, etc.) are conditioned on `WHERE state='running' AND worker_claim=<my_worker_id>`. Whichever update lands second sees no matching row and aborts silently. The first worker's result wins; the other worker's result is discarded (wasted work, but no data corruption).
|
| 339 |
+
|
| 340 |
+
---
|
| 341 |
+
|
| 342 |
+
## 6. Client Interaction Model
|
| 343 |
+
|
| 344 |
+
### Decision: polling in phase 2, SSE in phase 4, WebSocket deferred
|
| 345 |
+
|
| 346 |
+
### Comparison
|
| 347 |
+
|
| 348 |
+
| Protocol | Pros | Cons | Chosen? |
|
| 349 |
+
|---|---|---|---|
|
| 350 |
+
| **Polling** | Simplest; works anywhere; zero new infra; trivial to implement | Latency up to poll interval; wastes bandwidth when idle (mitigated by only polling while in-flight jobs exist) | Phase 2 |
|
| 351 |
+
| **Server-Sent Events** | Efficient for state updates; built into browsers (`EventSource`); one-way but that's what we need | Requires long-lived HTTP connection; may conflict with PHP `max_execution_time` on some hosts; harder to debug | Phase 4 |
|
| 352 |
+
| **WebSocket** | Full-duplex; lowest latency; richest protocol | Needs separate infra (Node or Ratchet-in-PHP); significant deployment burden; overkill for our scale | Deferred |
|
| 353 |
+
|
| 354 |
+
### Polling protocol (phase 2)
|
| 355 |
+
|
| 356 |
+
**Submit flow:**
|
| 357 |
+
|
| 358 |
+
1. Client calls `POST /prompt` with prompt text + root_entity_id + etc.
|
| 359 |
+
2. Server returns `202` with `{ prompt_id, job_id, state: 'queued' }`.
|
| 360 |
+
3. Client:
|
| 361 |
+
- Adds entity to `entities[]` with `state='queued'`, renders as queued drop.
|
| 362 |
+
- Starts a poll loop if not already running.
|
| 363 |
+
|
| 364 |
+
**Poll loop:**
|
| 365 |
+
|
| 366 |
+
- Every 2 seconds, while at least one in-flight (`queued` or `running`) job exists:
|
| 367 |
+
- Call `GET /sa-core/v1/mission/recent?since=<iso8601>`.
|
| 368 |
+
- Server returns entities with any updates since the timestamp.
|
| 369 |
+
- Client merges results by `prompt_id` (does not replace array wholesale).
|
| 370 |
+
- If all known prompts are terminal (succeeded, failed, cancelled, superseded) or no in-flight jobs remain, stop polling.
|
| 371 |
+
|
| 372 |
+
**Server endpoint changes (phase 2):**
|
| 373 |
+
|
| 374 |
+
- `GET /mission/recent` accepts `since=<iso8601>`. Returns only prompts updated since that time (joins `sa_job.updated_at` into the "is this updated" test).
|
| 375 |
+
- Response includes an `as_of` timestamp the client uses as the next `since` value.
|
| 376 |
+
|
| 377 |
+
### Field state → visual class mapping
|
| 378 |
+
|
| 379 |
+
| Job state | CSS class on drop | Existing / new | Visual |
|
| 380 |
+
|---|---|---|---|
|
| 381 |
+
| `queued` | `is-queued` | **New** | Slow breath, paler halo; "waiting" reading |
|
| 382 |
+
| `running` | `is-pending` | Existing | Current pending animation (dashed rotating halo) |
|
| 383 |
+
| `succeeded` | (none) | Existing | Default settled drop |
|
| 384 |
+
| `failed` | `is-orphan` | Existing | Muted salmon halo + retry chip |
|
| 385 |
+
| `cancelled` | `is-cancelled` | **New** | Greyed-out, no retry chip |
|
| 386 |
+
| `superseded` | hidden OR `.is-superseded` | **New** | Typically hidden; shown faded if a debug toggle enabled |
|
| 387 |
+
|
| 388 |
+
Transitions:
|
| 389 |
+
- `queued → running`: swap `is-queued` for `is-pending`.
|
| 390 |
+
- `running → succeeded`: remove `is-pending`, merge real response data, `renderField()` for any layout adjustment.
|
| 391 |
+
- `running → failed`: swap `is-pending` for `is-orphan`.
|
| 392 |
+
|
| 393 |
+
### SSE protocol (phase 4, future)
|
| 394 |
+
|
| 395 |
+
- Client opens `EventSource('/sa-core/v1/mission/events')` instead of polling.
|
| 396 |
+
- Server streams events like `event: job.state_changed\ndata: {"prompt_id":"…","state":"succeeded",…}\n\n` whenever a job's state changes for this viewer.
|
| 397 |
+
- Client falls back to polling if the `EventSource` fails.
|
| 398 |
+
|
| 399 |
+
### WebSocket (deferred)
|
| 400 |
+
|
| 401 |
+
Adds separate infra (Node sidecar, Ratchet-in-PHP, or a managed service like Pusher). No concrete need yet. Revisit when multi-user real-time collaboration becomes a live concern.
|
| 402 |
+
|
| 403 |
+
---
|
| 404 |
+
|
| 405 |
+
## 7. Migration Plan
|
| 406 |
+
|
| 407 |
+
### Principle: each phase ships a working system
|
| 408 |
+
|
| 409 |
+
No phase leaves the codebase in a half-broken state. At every phase boundary, a user can submit a prompt and see a result.
|
| 410 |
+
|
| 411 |
+
### Phase 0 — Concurrent-submit race fix (prerequisite, separate scope)
|
| 412 |
+
|
| 413 |
+
- Single commit, fixes the browser-state race in the current sync model.
|
| 414 |
+
- Does NOT introduce async.
|
| 415 |
+
- Makes parallel-submit testing reliable, which phase 2 needs.
|
| 416 |
+
|
| 417 |
+
### Phase 1 — Schema + shadow jobs (1–2 commits, zero behavior change)
|
| 418 |
+
|
| 419 |
+
Goal: write `sa_job` rows alongside synchronous execution, so the data layer exists before the execution path changes.
|
| 420 |
+
|
| 421 |
+
Work:
|
| 422 |
+
- Migration: create `sa_job` table (schema in §4).
|
| 423 |
+
- `SA_Executor::run` remains synchronous. At the end, it writes a `sa_job` row with `state='succeeded'` (or `'failed'` if the adapter errored).
|
| 424 |
+
- No REST change. No client change. No worker yet.
|
| 425 |
+
|
| 426 |
+
Test: CLI proof submits a prompt, verifies an `sa_job` row with correct state exists and references the prompt.
|
| 427 |
+
|
| 428 |
+
Rollback: drop the table via migration down; no user impact.
|
| 429 |
+
|
| 430 |
+
### Phase 2 — Async execution path (3–4 commits)
|
| 431 |
+
|
| 432 |
+
Goal: move adapter invocation out of the REST handler.
|
| 433 |
+
|
| 434 |
+
Work:
|
| 435 |
+
- Refactor `SA_Executor` into two entry-points:
|
| 436 |
+
- `SA_Executor::run` — retained for direct synchronous use (CLI proofs, back-compat).
|
| 437 |
+
- `SA_Executor::enqueue($prompt_text, $options)` — writes prompt entity + queued job, returns ids. Fast.
|
| 438 |
+
- `SA_Executor::run_claimed($job_id)` — worker's entry-point; runs the pipeline against an existing prompt + job.
|
| 439 |
+
- `POST /prompt`: call `enqueue`, return `202` with `{ prompt_id, job_id }`.
|
| 440 |
+
- Client `submitPrompt`: handle `202`, render queued drop, start poll loop.
|
| 441 |
+
- Server: `GET /mission/recent` accepts `since` param; returns updated rows.
|
| 442 |
+
- Add worker CLI: `wp sa-core run-worker`.
|
| 443 |
+
- Add heartbeat cleanup: `wp sa-core reclaim-stuck-jobs`.
|
| 444 |
+
- New CSS classes: `is-queued`, `is-cancelled`.
|
| 445 |
+
|
| 446 |
+
Test:
|
| 447 |
+
- CLI proof: submit a prompt, verify `state=queued`, run worker once, verify `state=running` → `state=succeeded`.
|
| 448 |
+
- Concurrent-submit proof: submit two prompts with different priorities (10 and 90), run worker, verify priority=10 runs first.
|
| 449 |
+
- Retry proof: submit, simulate transient failure (mock adapter), verify re-queue with backoff and eventual success.
|
| 450 |
+
|
| 451 |
+
Rollback: revert `POST /prompt` to call `run` synchronously. `sa_job` rows for already-queued jobs need manual cleanup (or a CLI command to replay them synchronously). Worker command stays but unused.
|
| 452 |
+
|
| 453 |
+
### Phase 3 — Priority queue (1–2 commits)
|
| 454 |
+
|
| 455 |
+
Goal: expose priority so active-thread prompts outrank bulk / background work.
|
| 456 |
+
|
| 457 |
+
Work:
|
| 458 |
+
- `SA_Executor::enqueue` accepts `priority` in options (default 50).
|
| 459 |
+
- Client: no UI change. Still submits at default. Future bulk operations (Scanner, Code Lens ingestion, etc.) pass higher priority values.
|
| 460 |
+
- Worker query already orders by priority — schema supports it from phase 1.
|
| 461 |
+
|
| 462 |
+
Test: submit 3 prompts with priorities {10, 50, 90}; verify worker claims in that order.
|
| 463 |
+
|
| 464 |
+
Rollback: trivial; remove priority from enqueue options, falls back to default.
|
| 465 |
+
|
| 466 |
+
### Phase 4 — SSE layer (2–3 commits)
|
| 467 |
+
|
| 468 |
+
Goal: eliminate polling overhead.
|
| 469 |
+
|
| 470 |
+
Work:
|
| 471 |
+
- Add `GET /sa-core/v1/mission/events` endpoint that streams SSE.
|
| 472 |
+
- Server-side: when a job's state changes, broadcast an SSE event to that viewer's stream.
|
| 473 |
+
- Client: detect `EventSource` support; subscribe if available; else continue polling.
|
| 474 |
+
|
| 475 |
+
Test: compare SSE event timing vs polling; verify identical state propagation; verify graceful fallback when connection drops.
|
| 476 |
+
|
| 477 |
+
Rollback: client falls back to polling automatically if SSE endpoint returns 404 or connection fails.
|
| 478 |
+
|
| 479 |
+
### Phase 5 — Hardening (2–4 commits)
|
| 480 |
+
|
| 481 |
+
Goal: operator visibility, intervention, metrics.
|
| 482 |
+
|
| 483 |
+
Work:
|
| 484 |
+
- `wp sa-core list-jobs [--state=] [--org=] [--since=]` — list jobs with filters.
|
| 485 |
+
- `wp sa-core job-details <job_id>` — full history for a job.
|
| 486 |
+
- `wp sa-core cancel-job <job_id>` — operator cancellation.
|
| 487 |
+
- `wp sa-core retry-job <job_id>` — explicit requeue.
|
| 488 |
+
- Optional: `wp sa-core queue-metrics` — count by state, average latency per org, error rate.
|
| 489 |
+
|
| 490 |
+
Test: CLI proofs for each command.
|
| 491 |
+
|
| 492 |
+
### Phase 6 — async-native features (optional, post-pillar)
|
| 493 |
+
|
| 494 |
+
Built on the same `sa_job` infrastructure, no further schema changes:
|
| 495 |
+
|
| 496 |
+
- Background bulk operations (Scanner, Code Lens, Doc Lens at scale).
|
| 497 |
+
- Scheduled prompts (run at 2am) via a `scheduled_for` column on `sa_job`.
|
| 498 |
+
- Multi-prompt chains (job B starts after job A succeeds).
|
| 499 |
+
|
| 500 |
+
Not part of the async pillar's completion criteria; listed for continuity.
|
| 501 |
+
|
| 502 |
+
### Test discipline at each phase
|
| 503 |
+
|
| 504 |
+
Every phase ships one or more CLI proofs in the `includes/cli/` pattern already established (geodesic-proof, promotion-proof, projection-proof, claim-continuation):
|
| 505 |
+
|
| 506 |
+
- `async-execution-proof`: state progression queued → running → succeeded against a synthetic prompt.
|
| 507 |
+
- `priority-queue-proof`: three synthetic prompts at different priorities; verify claim order.
|
| 508 |
+
- `retry-proof`: simulated transient adapter failure; verify re-queue and eventual success.
|
| 509 |
+
- `heartbeat-proof`: start a synthetic running job, sleep past heartbeat window, run reclaim, verify state.
|
| 510 |
+
- `concurrent-safety-proof`: simulate double-claim race; verify only one worker's writes take effect.
|
| 511 |
+
|
| 512 |
+
---
|
| 513 |
+
|
| 514 |
+
## 8. Failure and Retry Model
|
| 515 |
+
|
| 516 |
+
### Error classification
|
| 517 |
+
|
| 518 |
+
Every failure gets an `error_kind`:
|
| 519 |
+
|
| 520 |
+
| `error_kind` | Meaning | Retryable? | Backoff |
|
| 521 |
+
|---|---|---|---|
|
| 522 |
+
| `timeout` | cURL 28 or executor-level timeout | Yes | Exponential (5s, 25s, 125s + jitter) |
|
| 523 |
+
| `rate_limit` | Adapter HTTP 429 | Yes | Respect `Retry-After` header; else 60s min |
|
| 524 |
+
| `provider_5xx` | Adapter returned 5xx | Yes | Exponential |
|
| 525 |
+
| `provider_4xx` (non-429) | Adapter returned 4xx | No | N/A |
|
| 526 |
+
| `parse` | Response body couldn't be parsed | No | N/A |
|
| 527 |
+
| `auth` | Credentials invalid | No | N/A (needs operator) |
|
| 528 |
+
| `worker_crash` | Worker died mid-execution | Yes (via reclaim) | Immediate |
|
| 529 |
+
| `stuck` | Job has been running > 15 min | No | Terminal; mark failed |
|
| 530 |
+
| `unknown` | Catch-all for unclassified errors | Yes (conservative default) | Exponential |
|
| 531 |
+
|
| 532 |
+
### Retry rules
|
| 533 |
+
|
| 534 |
+
- Default `max_attempts = 3`. Configurable per-enqueue via options.
|
| 535 |
+
- Backoff stored as a delay on the re-queued job's `created_at`: `created_at = now() + backoff`. Worker query only claims jobs where `created_at <= now()`, so backoff is honored naturally.
|
| 536 |
+
- Backoff durations:
|
| 537 |
+
- Attempt 2: 5s + random(0, 5s)
|
| 538 |
+
- Attempt 3: 25s + random(0, 15s)
|
| 539 |
+
- (After attempt 3 fails: terminal)
|
| 540 |
+
|
| 541 |
+
### Timeout handling
|
| 542 |
+
|
| 543 |
+
- **Adapter timeout (180s)**: cURL 28. `error_kind='timeout'`. Retryable.
|
| 544 |
+
- **PHP `max_execution_time` (300s)**: worker process killed. Heartbeat lost. Reclaimed by `reclaim-stuck-jobs`.
|
| 545 |
+
- **Hard job ceiling (15 minutes)**: a running job started > 15 min ago with no recent heartbeat is declared stuck. `error_kind='stuck'`. Terminal.
|
| 546 |
+
|
| 547 |
+
### Dead-letter handling
|
| 548 |
+
|
| 549 |
+
- Jobs that exhaust `max_attempts` go to `state='failed'` with `error_kind` set.
|
| 550 |
+
- They remain visible in the user's field as `is-orphan` drops (same treatment as today's orphans from sync-failure).
|
| 551 |
+
- User can retry via the retry chip (same UX as today). Retry creates a new `sa_job` row with `supersedes=<old_id>`.
|
| 552 |
+
- Operator CLI: `wp sa-core list-jobs --state=failed` surfaces recent failures.
|
| 553 |
+
- Operator can run `wp sa-core retry-job <id>` to force a retry without user interaction.
|
| 554 |
+
|
| 555 |
+
### Stuck-job recovery
|
| 556 |
+
|
| 557 |
+
- `wp sa-core reclaim-stuck-jobs` runs via system cron every 5 minutes.
|
| 558 |
+
- Query: `state='running' AND running_heartbeat_at < now() - INTERVAL 5 MINUTE`.
|
| 559 |
+
- For each:
|
| 560 |
+
- If `attempt < max_attempts` AND `started_at > now() - 15min`: reclaim to `state='queued'`, clear `worker_claim`.
|
| 561 |
+
- Else: `state='failed'`, `error_kind='stuck'`.
|
| 562 |
+
|
| 563 |
+
### Double-execution safety
|
| 564 |
+
|
| 565 |
+
Mitigation already detailed in §5: all finalization writes are conditioned on `WHERE state='running' AND worker_claim=<my_worker_id>`. Second-arriving writer sees no matching row and exits silently. First-arriving result wins.
|
| 566 |
+
|
| 567 |
+
Additional safeguard: response entity writes are keyed on a deterministic id derived from `(prompt_id, adapter_request_id)` when available, so duplicate writes collide on primary key and the second `INSERT` fails gracefully (caught by the finalization code).
|
| 568 |
+
|
| 569 |
+
---
|
| 570 |
+
|
| 571 |
+
## 9. Risks and Tradeoffs
|
| 572 |
+
|
| 573 |
+
### Risk: cron reliability on managed hosts
|
| 574 |
+
|
| 575 |
+
WP Engine (and many managed hosts) run cron via `wp-cron.php` spawned on page requests. On low-traffic sites this is unreliable.
|
| 576 |
+
|
| 577 |
+
**Mitigation.** Document that production deployments SHOULD use a real system cron hitting `wp sa-core run-worker --once`. The command is standalone (doesn't depend on wp-cron's spawning). An on-page-load spawn continues to work for dev and low-volume sites.
|
| 578 |
+
|
| 579 |
+
### Risk: worker compute resource pressure
|
| 580 |
+
|
| 581 |
+
A long-running worker process consumes PHP process slots. On shared hosting, this may conflict with web requests.
|
| 582 |
+
|
| 583 |
+
**Mitigation.** Default worker mode is `--once` (cron-driven, not service-style). Batch size is tunable. For high-volume users, the operator can tune cron frequency + batch size to stay within their host's limits.
|
| 584 |
+
|
| 585 |
+
### Risk: `sa_job` table growth
|
| 586 |
+
|
| 587 |
+
Every prompt creates ≥ 1 job. Retries create additional jobs per prompt. Over time, the table grows unbounded.
|
| 588 |
+
|
| 589 |
+
**Mitigation.** Optional archival policy (phase 5 or later): jobs in a terminal state older than 30 days get archived or removed. `wp sa-core archive-old-jobs --before=<date>`. Indexes keep queries fast regardless of row count at expected volumes; archival is an optimization, not a correctness concern.
|
| 590 |
+
|
| 591 |
+
### Risk: client polling overhead
|
| 592 |
+
|
| 593 |
+
Many users × many tabs × many in-flight jobs = many simultaneous polls.
|
| 594 |
+
|
| 595 |
+
**Mitigation.**
|
| 596 |
+
- Polls happen only while in-flight jobs exist; idle tabs don't poll.
|
| 597 |
+
- Poll interval is 2s; tunable.
|
| 598 |
+
- Phase 4 (SSE) eliminates this risk entirely for modern browsers.
|
| 599 |
+
|
| 600 |
+
### Risk: stale merges on client
|
| 601 |
+
|
| 602 |
+
If the client has an in-memory edit (user typing in compose) and a poll fetches fresh entity data, we must not discard user input.
|
| 603 |
+
|
| 604 |
+
**Mitigation.** Poll merges by `prompt_id` and only updates entity-state fields (response_id, state, context_ids, etc.). Compose-input state lives in the DOM, untouched by poll handling.
|
| 605 |
+
|
| 606 |
+
### Risk: concurrent-submit out-of-order display
|
| 607 |
+
|
| 608 |
+
Two prompts submitted close together may complete in the reverse order (e.g., P1 is slow, P2 is fast). The field would render P2 before P1.
|
| 609 |
+
|
| 610 |
+
**Mitigation.** Field display order is by `prompt.created_at`, not job completion order. Stable regardless of async resolution order. The visual `is-queued` vs `is-running` vs settled state makes the running state transparent to the user.
|
| 611 |
+
|
| 612 |
+
### Tradeoff: consistency window vs latency
|
| 613 |
+
|
| 614 |
+
Async means there is a window where client shows `state='queued'` while server has already transitioned to `state='running'`. Polling latency is up to 2s. SSE tightens this to sub-second.
|
| 615 |
+
|
| 616 |
+
**Accepted.** Up to 2s of client-side staleness is not a meaningful UX regression; phase 4 closes it.
|
| 617 |
+
|
| 618 |
+
### Tradeoff: simplicity vs ecosystem reuse
|
| 619 |
+
|
| 620 |
+
Custom worker vs Action Scheduler. Custom is simpler for our narrow scope but means we own the scheduler. AS is richer but adds a dependency and adapter layer.
|
| 621 |
+
|
| 622 |
+
**Accepted.** Custom for phase 2. If we ever need to coexist with an AS-using site, the `sa_job` table's facade can be driven by either our worker or an AS callback without changing job semantics.
|
| 623 |
+
|
| 624 |
+
### Risk: migrating users mid-transition
|
| 625 |
+
|
| 626 |
+
Between phase 1 (shadow jobs written) and phase 2 (async path switched on), a user's `sa_job` rows represent historical sync executions. When phase 2 lands, any prompt submitted mid-transition could have incomplete metadata.
|
| 627 |
+
|
| 628 |
+
**Mitigation.** Phase 2 rollout during a low-traffic window. On deploy, any `sa_job` rows with `state='queued'` from pre-phase-2 (there shouldn't be any, but defensively) are either processed by the first worker run or marked `state='failed'` with `error_kind='migration'` for manual review.
|
| 629 |
+
|
| 630 |
+
---
|
| 631 |
+
|
| 632 |
+
## 10. Success Criteria
|
| 633 |
+
|
| 634 |
+
The async pillar is complete (through phase 2) when:
|
| 635 |
+
|
| 636 |
+
1. `POST /prompt` returns within 100ms, 99th percentile, regardless of adapter latency.
|
| 637 |
+
2. Closing the browser tab during a prompt's execution does NOT cancel the job; reopening the site shows the completed result.
|
| 638 |
+
3. Two prompts submitted to different continuation parents from different tabs are processed correctly, with no race-induced data corruption.
|
| 639 |
+
4. A cURL timeout on the adapter causes an automatic retry with exponential backoff; a permanently-failing prompt surfaces as a retriable orphan after `max_attempts` exhaustion.
|
| 640 |
+
5. A crashed worker's job is reclaimed within 5 minutes and either completes on the next attempt or fails cleanly.
|
| 641 |
+
6. The CLI proofs described in §7's test discipline section all pass.
|
| 642 |
+
7. Existing `/mission` UI works throughout — no regressions on selection, trace, thread view, promote, verdict, continuation, retry, or content-collapse.
|
| 643 |
+
8. The `wp sa-core run-worker` command can be configured to run under standard system cron without supervisor-style infra.
|
| 644 |
+
|
| 645 |
+
The pillar is **complete through phase 4** when additionally:
|
| 646 |
+
|
| 647 |
+
9. SSE delivers state updates within 200ms of server-side transition.
|
| 648 |
+
10. Polling mode still works identically as a fallback when SSE is unavailable.
|
| 649 |
+
|
| 650 |
+
---
|
| 651 |
+
|
| 652 |
+
## 11. Out of Scope (deliberately deferred)
|
| 653 |
+
|
| 654 |
+
- **Multi-node distributed coordination.** Single-node assumption in claim locking. Revisit if horizontal scaling ever becomes a concern.
|
| 655 |
+
- **Priority inversion prevention.** A long-running low-priority job blocking urgent jobs is theoretically possible but rare in our expected volume. Observe first; fix if it ever occurs.
|
| 656 |
+
- **User-facing queue inspection UI.** CLI only through phase 5. A UI can be added later; `sa_job` data is already viewer-scoped via `org_id + created_by` indexing.
|
| 657 |
+
- **Scheduled prompts** (`scheduled_for`): phase 6 (optional).
|
| 658 |
+
- **Multi-prompt chains** (dependent jobs): phase 6 (optional).
|
| 659 |
+
- **Per-org quotas** (max N concurrent running jobs): defer until multi-tenant scaling matters.
|
| 660 |
+
- **Cross-process worker coordination** (multiple machines): defer until single-machine capacity is exhausted.
|
| 661 |
+
- **Real-time collaboration** (two users editing the same field simultaneously): defer to the ACL / perspective-projection pillar.
|
| 662 |
+
|
| 663 |
+
---
|
| 664 |
+
|
| 665 |
+
## 12. Appendix: Summary of Design Decisions
|
| 666 |
+
|
| 667 |
+
| Concern | Decision | Rationale |
|
| 668 |
+
|---|---|---|
|
| 669 |
+
| Storage | New `sa_job` table | Separate execution from knowledge; supports multiple attempts cleanly |
|
| 670 |
+
| Worker | Custom WP-CLI runner | Narrow scope; direct control; ~300 lines; no new dependency |
|
| 671 |
+
| Scheduling driver | System cron → `wp sa-core run-worker --once` | Reliable across hosts; standalone from wp-cron |
|
| 672 |
+
| State machine | 6 states + heartbeat + supersession | Covers all observed outcomes; no ambiguity |
|
| 673 |
+
| Client protocol | Polling (phase 2) → SSE (phase 4) | Ships working async in phase 2; optimizes in phase 4 |
|
| 674 |
+
| Retry | Exponential backoff, max_attempts=3 | Handles transient failures; bounded pessimism |
|
| 675 |
+
| Rollback | Phase-by-phase; each has a defined revert | Safe to implement incrementally |
|
| 676 |
+
| Migration | Shadow jobs first (phase 1) → switch path (phase 2) | Data layer proven before execution switch |
|
| 677 |
+
|
| 678 |
+
This spec is the contract. Implementation directives reference it by phase.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/05-zoom-quantum-engine.md
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Zoom-Quantum Engine — Design Specification (Rung 4)
|
| 2 |
+
|
| 3 |
+
Status: **design draft; coil substrate shipped (Rung 3); phase plan pending per-phase directive.**
|
| 4 |
+
Target rung: 4.
|
| 5 |
+
Scope: multi-focal zoom as a native field gesture, not a viewport transform. Per-correlation zoom, hyperbolic envelope, cross-region pull-connection. All projections remain 2D.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Framing (authoritative)
|
| 10 |
+
|
| 11 |
+
**Zoom is a semantic quantum, not a viewport change.** Zoom belongs to a *domain of influence*, not to the screen. A conversation can be zoomed without touching any other conversation. The field carries regional density depth of zoom.
|
| 12 |
+
|
| 13 |
+
Three layers of zoom, kept distinct:
|
| 14 |
+
|
| 15 |
+
- **Global zoom** — the default, existing affordance (SVG viewBox). The whole field pans and scales. Useful for "where am I on the mission."
|
| 16 |
+
- **Regional zoom** — per-correlation, introduced by this pillar. Each thread carries its own scalar zoom state. The user can be deeply inside thread A while thread B stays at rest. Multiple threads can be simultaneously focused at independent depths.
|
| 17 |
+
- **Hyperbolic envelope** — when a regional zoom exceeds threshold, the thread's head wraps the visible workspace as a Poincaré-disk horizon. "You are inside this thread." The tail stretches toward the asymptotic center; the head becomes the event horizon.
|
| 18 |
+
|
| 19 |
+
The instruction the rest of this spec serves:
|
| 20 |
+
|
| 21 |
+
> The default case is to zoom the whole field. The innovation is to zoom a *conversation* — one region of influence — without perturbing the rest of the field. When two regions are simultaneously focused, the user can pull a connection between them instead of splitting the screen. Multi-focal composition is the posture; hyperbolic geometry is how we keep "where is my context" legible while compression grows infinite.
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
|
| 25 |
+
## 0. Scope note
|
| 26 |
+
|
| 27 |
+
This spec describes the **zoom-quantum engine** as a user-facing field behavior + its projection math.
|
| 28 |
+
|
| 29 |
+
It DOES cover:
|
| 30 |
+
- The per-correlation zoom state model
|
| 31 |
+
- The math of the hyperbolic envelope (Möbius transform on a Poincaré disk)
|
| 32 |
+
- How regional zoom composes with the already-shipped log-spiral coil
|
| 33 |
+
- Multi-focal simultaneous zoom
|
| 34 |
+
- Cross-correlation pull-connection as a new edge primitive
|
| 35 |
+
- Gesture vocabulary
|
| 36 |
+
- Phasing
|
| 37 |
+
|
| 38 |
+
It does NOT cover:
|
| 39 |
+
- The Prime-Prompt / compression mechanic (separate Pillar 0 concern, deferred)
|
| 40 |
+
- Server-side data model changes beyond a new edge kind (zoom is client UI state)
|
| 41 |
+
- A split-screen or multi-window layout (explicitly rejected — the hyperbolic projection replaces it)
|
| 42 |
+
- WebGL / 3D rendering (explicitly rejected — all projections are 2D)
|
| 43 |
+
|
| 44 |
+
---
|
| 45 |
+
|
| 46 |
+
## 1. What already exists
|
| 47 |
+
|
| 48 |
+
Rung 3 shipped the **logarithmic-spiral coil** (commit `de4de7e`). Each correlation group renders as:
|
| 49 |
+
|
| 50 |
+
```
|
| 51 |
+
r_t = r₀ · γ^t (log-spiral radius)
|
| 52 |
+
θ_t = baseAngle + t·dθ (angular step)
|
| 53 |
+
scale_t = γ^t (same decay → self-similar under zoom)
|
| 54 |
+
opacity_t = max(o_min, 1 − f·t)
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
The coil is already scale-invariant: a uniform scale factor `k` maps the spiral onto itself shifted by `log_γ(k)` turns. The infrastructure for "zoom descends into the tail" is in place on the math side; Rung 4 adds the UI, the per-correlation state, and the hyperbolic envelope.
|
| 58 |
+
|
| 59 |
+
The `.is-coiled` class and `data-coil-index` attribute on each drop are hooks for this rung.
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
## 2. Primitives
|
| 64 |
+
|
| 65 |
+
### 2.1 Per-correlation zoom state
|
| 66 |
+
|
| 67 |
+
```
|
| 68 |
+
CoilZoomState {
|
| 69 |
+
correlation_id : string The thread this state belongs to
|
| 70 |
+
zoom : float (≥ 0) 0 = rest; 1 = first quantum in; 2 = second; ...
|
| 71 |
+
focal_x : float optional: where on the screen the focus anchors
|
| 72 |
+
focal_y : float (defaults to the current head position)
|
| 73 |
+
pinned : bool if true, survives other zooms of other threads;
|
| 74 |
+
if false, collapses to rest when another
|
| 75 |
+
thread is focused (single-focus convention)
|
| 76 |
+
}
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
Stored client-side. Not persisted by default; optional SA_Settings scope=user
|
| 80 |
+
persistence (`field.coil.zoom_state`) is a follow-on if the UX calls for it.
|
| 81 |
+
|
| 82 |
+
### 2.2 Focal stack
|
| 83 |
+
|
| 84 |
+
```
|
| 85 |
+
FocalStack = CoilZoomState[]
|
| 86 |
+
```
|
| 87 |
+
|
| 88 |
+
The ordered list of currently-focused coils. Zero-or-one at rest is the default; multi-focal is the innovation. Rendering composes their transforms.
|
| 89 |
+
|
| 90 |
+
### 2.3 Hyperbolic envelope
|
| 91 |
+
|
| 92 |
+
Threshold: when `zoom ≥ HYPERBOLIC_THRESHOLD` (configurable; 2.0 is a reasonable starting point), the coil's head enters **envelope mode**:
|
| 93 |
+
|
| 94 |
+
- The head dilates toward the workspace boundary.
|
| 95 |
+
- The rest of the coil (and any other visible content within this region) is rendered through a Möbius transform on the Poincaré disk.
|
| 96 |
+
- The edge of the viewport becomes the ideal boundary at infinity.
|
| 97 |
+
|
| 98 |
+
Mathematically, with the focal point at origin `a = 0`:
|
| 99 |
+
|
| 100 |
+
```
|
| 101 |
+
w = (z - a) / (1 - ā·z)
|
| 102 |
+
```
|
| 103 |
+
|
| 104 |
+
For `a = 0` this reduces to `w = z`, so we introduce zoom via composition with a pure dilation before the Möbius map:
|
| 105 |
+
|
| 106 |
+
```
|
| 107 |
+
z' = scale_by_zoom · z
|
| 108 |
+
w = (z' - a) / (1 - ā·z')
|
| 109 |
+
```
|
| 110 |
+
|
| 111 |
+
At low zoom, the transform is near-identity. As zoom grows, points near the focal point expand outward; points near the ideal boundary asymptote there but never cross. This is the "event horizon" — infinite expansion curls into the hyperbolic limit.
|
| 112 |
+
|
| 113 |
+
### 2.4 Pull-connection (cross-region edge)
|
| 114 |
+
|
| 115 |
+
A new edge kind:
|
| 116 |
+
|
| 117 |
+
```
|
| 118 |
+
kind: 'pull-connection' (or 'cross-region')
|
| 119 |
+
source_id: entity A's id
|
| 120 |
+
target_id: entity B's id
|
| 121 |
+
intentional: true (always — user gesture-created)
|
| 122 |
+
metadata: { author_id, created_at, gesture_kind: 'drag' }
|
| 123 |
+
```
|
| 124 |
+
|
| 125 |
+
Stored as a row in the existing `sa_edge` table. No schema change — `SA_Edge::KINDS` already accepts arbitrary kinds (today: link, contains, depends, influences, flows-to, continues, promoted).
|
| 126 |
+
|
| 127 |
+
Rendered as a flowing line between two focused regions, distinct visually from within-thread edges (dashed? colored by author? to be decided per phase).
|
| 128 |
+
|
| 129 |
+
### 2.5 Compose operator
|
| 130 |
+
|
| 131 |
+
```
|
| 132 |
+
render(entity) = Global_Viewport ∘ Regional_Hyperbolic ∘ Local_Coil ∘ entity.position
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
Three projections stacked:
|
| 136 |
+
|
| 137 |
+
1. **Local coil** (shipped): the log spiral places older correlation members relative to their head.
|
| 138 |
+
2. **Regional hyperbolic** (new): when a coil is past the threshold, apply the Möbius transform to everything within its region, centered on its head.
|
| 139 |
+
3. **Global viewport**: the SVG viewBox. Pans / scales the whole field for navigation.
|
| 140 |
+
|
| 141 |
+
Each layer is independently controllable. A user at rest sees only the coils (layer 1 only). A user focused on one thread with hyperbolic crossed sees layer 1 + 2. A user zooming out to find a thread uses layer 3.
|
| 142 |
+
|
| 143 |
+
---
|
| 144 |
+
|
| 145 |
+
## 3. Multi-focal model
|
| 146 |
+
|
| 147 |
+
The posture: **multiple regions focused simultaneously, without split screens.**
|
| 148 |
+
|
| 149 |
+
Scenarios:
|
| 150 |
+
|
| 151 |
+
- **Single focus** (typical): one thread is zoomed in. Others sit at their rest coil. The user sees the coil-of-interest at its hyperbolic scale, other coils in the background at normal scale.
|
| 152 |
+
- **Dual focus** (workspace comparison): two threads both zoomed. Their Möbius disks compose by position — e.g., one occupies the left third of the viewport, the other the right third. Content *between* them is what survives the intersection.
|
| 153 |
+
- **Multi focus** (relational map): N threads focused at varied zoom levels. The field becomes a composite of hyperbolic neighborhoods, each with its own focal anchor. Resembles a relational map where the nodes are the focal points and the content around each is the locally-zoomed thread.
|
| 154 |
+
|
| 155 |
+
Pull-connection is the natural gesture across this state: drag from a point inside focus A's hyperbolic neighborhood to a point inside focus B's hyperbolic neighborhood. The drag creates a cross-region edge. The edge renders as a line that passes through the ambient space between the foci.
|
| 156 |
+
|
| 157 |
+
**Rejected alternative**: split-screen. Splitting the canvas into two viewports is the "click here, click there, zoom each, compare" solution. The spec rejects it as un-liquid — a literal cut in the fabric. The hyperbolic composition is the continuous alternative.
|
| 158 |
+
|
| 159 |
+
---
|
| 160 |
+
|
| 161 |
+
## 4. Gesture vocabulary
|
| 162 |
+
|
| 163 |
+
### 4.1 Entering regional zoom
|
| 164 |
+
|
| 165 |
+
- **Scroll-wheel over a coil region**: the scroll targets the coil underneath the cursor, not the global viewport. Forward = zoom in, back = zoom out.
|
| 166 |
+
- Falls back to global viewport zoom when the cursor isn't over any coil's region.
|
| 167 |
+
|
| 168 |
+
Implementation: hit-test the cursor against each visible coil's bounding disk. The coil whose center is closest (within a radius proportional to its current zoom) captures the scroll.
|
| 169 |
+
|
| 170 |
+
### 4.2 Pin / unpin
|
| 171 |
+
|
| 172 |
+
- **Click a coil's head while holding a modifier key** (e.g., Shift-click): pin this focus. Future zooms of other coils don't collapse this one.
|
| 173 |
+
- **Click in empty space**: collapse all transient (non-pinned) foci to rest.
|
| 174 |
+
|
| 175 |
+
### 4.3 Pull-connection
|
| 176 |
+
|
| 177 |
+
- **Drag from a focused region to another focused region** (both must be at zoom ≥ some threshold). The drag creates a new `pull-connection` edge.
|
| 178 |
+
- **Drop on empty space**: cancels.
|
| 179 |
+
|
| 180 |
+
### 4.4 Exit / escape
|
| 181 |
+
|
| 182 |
+
- **Esc** collapses all foci and returns to rest (coils at size 1, no hyperbolic envelope).
|
| 183 |
+
- **Double-click a coil**: toggles between rest and last-known zoom state.
|
| 184 |
+
|
| 185 |
+
---
|
| 186 |
+
|
| 187 |
+
## 5. Math appendix
|
| 188 |
+
|
| 189 |
+
### 5.1 Self-similar coil (shipped, Rung 3)
|
| 190 |
+
|
| 191 |
+
For each correlation group:
|
| 192 |
+
|
| 193 |
+
```
|
| 194 |
+
t = turn index (0 = newest head)
|
| 195 |
+
baseAngle = hashJitter(correlation_id) · 2π (per-thread starting angle)
|
| 196 |
+
γ = 0.85 (decay)
|
| 197 |
+
dθ = π/3 (60° per turn)
|
| 198 |
+
r_t = r₀ · γ^t
|
| 199 |
+
θ_t = baseAngle + t · dθ
|
| 200 |
+
position_t = head_position + (r_t·cos θ_t − r₀·cos baseAngle,
|
| 201 |
+
r_t·sin θ_t − r₀·sin baseAngle)
|
| 202 |
+
scale_t = γ^t
|
| 203 |
+
```
|
| 204 |
+
|
| 205 |
+
Zoom shifts the visible portion of the spiral. Under a uniform zoom of factor `k`, `scale_t → k · scale_t = γ^(t - log_γ k)`, so the spiral looks the same shifted by `log_γ k` turns. This is why zooming into the coil reveals more tail without stretching it.
|
| 206 |
+
|
| 207 |
+
### 5.2 Poincaré disk (Rung 4, new)
|
| 208 |
+
|
| 209 |
+
The hyperbolic plane is represented as the interior of a unit disk `|z| < 1`. Geodesics are circular arcs perpendicular to the boundary. Distance grows without bound near the boundary (the ideal horizon).
|
| 210 |
+
|
| 211 |
+
A Möbius transformation preserves hyperbolic distance:
|
| 212 |
+
|
| 213 |
+
```
|
| 214 |
+
φ_a(z) = (z − a) / (1 − ā·z) where |a| < 1
|
| 215 |
+
```
|
| 216 |
+
|
| 217 |
+
For MissionNet:
|
| 218 |
+
|
| 219 |
+
- The coil's currently-focused head sits at the disk center.
|
| 220 |
+
- The tail of the coil stretches toward the center (asymptotically never reaching, per the log-spiral math).
|
| 221 |
+
- Other visible content is projected outward toward the boundary, compressed as it approaches — "infinite expansion curls to hyperbolic limit."
|
| 222 |
+
|
| 223 |
+
Scaling for zoom level `λ ≥ 0`:
|
| 224 |
+
|
| 225 |
+
```
|
| 226 |
+
z' = (1 − e^(−λ)) + e^(−λ) · z (pre-zoom dilation centered on head)
|
| 227 |
+
w = φ_focal(z') (Möbius, centered on head)
|
| 228 |
+
screen_w = half_viewport_size · w (map disk to viewport)
|
| 229 |
+
```
|
| 230 |
+
|
| 231 |
+
At λ = 0 the transform is identity. As λ grows, `z'` approaches 1 (the boundary), the head fills the viewport, and the rest of the content compresses toward the edge.
|
| 232 |
+
|
| 233 |
+
### 5.3 Composition of multi-focal Möbius
|
| 234 |
+
|
| 235 |
+
Two focal points `a` and `b`, each with zoom levels `λ_a` and `λ_b`, can be composed:
|
| 236 |
+
|
| 237 |
+
```
|
| 238 |
+
w = Σ weights_i · φ_i(dilate_i(z))
|
| 239 |
+
```
|
| 240 |
+
|
| 241 |
+
For a weighted sum where `Σ weights_i = 1`. This is an approximation — the exact composition of two Möbius transforms is another Möbius transform, but picking *which* transform to use when you want BOTH foci visible requires a heuristic. The weighted-sum approximation gives a visually pleasing blend and is well-defined for any number of foci.
|
| 242 |
+
|
| 243 |
+
A cleaner model: render each focused region in its own hyperbolic neighborhood, with the boundary between regions being the ambient (un-transformed) space. This is what pull-connection edges cross.
|
| 244 |
+
|
| 245 |
+
---
|
| 246 |
+
|
| 247 |
+
## 6. Data model changes
|
| 248 |
+
|
| 249 |
+
### 6.1 No schema change for zoom state
|
| 250 |
+
|
| 251 |
+
Per-correlation zoom is client-side UI state. Not persisted by default. If a user asks for their zoom state to survive reload, add:
|
| 252 |
+
|
| 253 |
+
- SA_Settings key `field.coil.zoom_states`, scope=user, type=string (JSON-serialized `CoilZoomState[]`).
|
| 254 |
+
|
| 255 |
+
That's one line of setting declaration; no migration needed.
|
| 256 |
+
|
| 257 |
+
### 6.2 Pull-connection edge: no schema change
|
| 258 |
+
|
| 259 |
+
`SA_Edge` already accepts arbitrary kinds via a `kind` column. Add `'pull-connection'` to `SA_Edge::KINDS` as a documented kind. No migration; no new table.
|
| 260 |
+
|
| 261 |
+
Permissions: creating a pull-connection requires `sa-core:impose-grouping` (already a capability in the starter package — user-declared relational claims are tenant work, not operator work).
|
| 262 |
+
|
| 263 |
+
---
|
| 264 |
+
|
| 265 |
+
## 7. Phased implementation plan
|
| 266 |
+
|
| 267 |
+
Phases ship independently; each is a working system.
|
| 268 |
+
|
| 269 |
+
### Phase 0 — Already shipped (Rung 3 `de4de7e`)
|
| 270 |
+
|
| 271 |
+
- Logarithmic-spiral coil for multi-turn correlations.
|
| 272 |
+
- Self-similar under zoom.
|
| 273 |
+
- Per-thread base angle.
|
| 274 |
+
- `.is-coiled` / `data-coil-index` DOM hooks.
|
| 275 |
+
|
| 276 |
+
### Phase 1 — Per-correlation zoom state (single focus, no hyperbolic)
|
| 277 |
+
|
| 278 |
+
Minimum usable regional zoom:
|
| 279 |
+
|
| 280 |
+
- Client state: `Map<correlation_id, zoomLevel>`.
|
| 281 |
+
- Scroll-wheel over a coil zooms THAT coil (not the field). Hit-test via cursor position vs. each coil's bounding disk.
|
| 282 |
+
- Applying zoom = multiplying the coil's `r₀` and `scale_t` by a zoom factor. Math is already scale-invariant, so the spiral just reveals more structure as `r₀` grows.
|
| 283 |
+
- Other coils continue to render at rest. No hyperbolic envelope yet.
|
| 284 |
+
- Esc returns everything to rest.
|
| 285 |
+
|
| 286 |
+
**Ships when:** the user can scroll over any thread, that thread alone expands / contracts, other threads are unchanged, and Esc collapses the focus.
|
| 287 |
+
|
| 288 |
+
### Phase 2 — Hyperbolic envelope (single focus, past threshold)
|
| 289 |
+
|
| 290 |
+
- When a coil's zoom crosses `HYPERBOLIC_THRESHOLD`, enter envelope mode.
|
| 291 |
+
- Render the focused coil's neighborhood through the Möbius transform (§5.2).
|
| 292 |
+
- Other coils in the field get pushed toward the viewport boundary as content crosses into the hyperbolic disk.
|
| 293 |
+
- Exit threshold hysteresis so crossing the threshold doesn't thrash.
|
| 294 |
+
|
| 295 |
+
**Ships when:** the user can zoom a thread to where the head wraps the workspace, the tail visibly stretches toward the asymptotic center, and the "event horizon" reading is unambiguous.
|
| 296 |
+
|
| 297 |
+
### Phase 3 — Multi-focal composition
|
| 298 |
+
|
| 299 |
+
- Introduce the focal stack: multiple `CoilZoomState`s active simultaneously.
|
| 300 |
+
- Pin gesture (Shift-click on a head) keeps a focus alive when another is zoomed.
|
| 301 |
+
- Render pipeline composes multiple hyperbolic disks in the same viewport.
|
| 302 |
+
- Heuristic for disk placement (e.g., foci at equi-distant points around the viewport center, scaled by their respective zoom levels).
|
| 303 |
+
|
| 304 |
+
**Ships when:** the user can pin thread A, focus thread B separately, and see both at their own zoom levels without a split screen.
|
| 305 |
+
|
| 306 |
+
### Phase 4 — Pull-connection
|
| 307 |
+
|
| 308 |
+
- Add `pull-connection` to `SA_Edge::KINDS`.
|
| 309 |
+
- Drag gesture from one focused region to another creates the edge (persisted via existing `SA_Edge::create`).
|
| 310 |
+
- Rendered as a distinct line between the two focal anchors, flowing through the ambient space between them.
|
| 311 |
+
- Pull-connections surface in the trace aside and in projection pipelines that list edges (e.g., a future "related threads" projection).
|
| 312 |
+
|
| 313 |
+
**Ships when:** the user can physically drag a relation across focal regions, it persists, and it's visible from both threads' perspectives.
|
| 314 |
+
|
| 315 |
+
### Deferred (out of scope)
|
| 316 |
+
|
| 317 |
+
- **Interactive compression** (Pillar 0 / Prime Prompt) — the user can't yet summarize a coil at zoom; the coil renders what it holds.
|
| 318 |
+
- **Zoom-state persistence** — default is per-session. Persistent (across reloads / devices) is a follow-on SA_Settings slice.
|
| 319 |
+
- **Touch gestures** — pinch-zoom on a coil region. Desktop-first.
|
| 320 |
+
- **Pull-connection AI semantics** — a pull-connection is declarative today. Future rungs may let a pull-connection trigger an LLM rerun with both threads as context, or seed a geodesic marker.
|
| 321 |
+
|
| 322 |
+
---
|
| 323 |
+
|
| 324 |
+
## 8. Open questions (for resolution at phase directive time)
|
| 325 |
+
|
| 326 |
+
### 8.1 Global vs. regional zoom arbitration
|
| 327 |
+
|
| 328 |
+
If the user scrolls while the cursor is over a coil AND also over a piece of ambient space (e.g., near the boundary of a coil), which wins? Proposal: cursor-anchored — nearest coil center wins within its bounding disk; outside that, ambient viewport wins.
|
| 329 |
+
|
| 330 |
+
### 8.2 What happens when a single-turn correlation is focused?
|
| 331 |
+
|
| 332 |
+
Single-turn correlations don't have a coil (Rung 3 skips them). Regional zoom on a single-turn could just scale the head in place. Or we could degrade it to global zoom. Proposal: degrade to global zoom for single-turn (no coil to reveal; zooming should feel like the viewport is responding).
|
| 333 |
+
|
| 334 |
+
### 8.3 How deep is "deep"?
|
| 335 |
+
|
| 336 |
+
The coil can, by construction, have infinitely many turns. The log-spiral decay means each turn is 15% smaller than the previous, so after 30 turns we're at 0.85^30 ≈ 0.8% of original size — visually indistinguishable from the center. Practically the coil caps at some maximum rendered turn. Proposal: render only turns where `scale_t ≥ some_epsilon` (say 0.05) unless the user has actively zoomed past that depth. Zooming past that depth reveals deeper turns.
|
| 337 |
+
|
| 338 |
+
### 8.4 Pull-connection authorization model
|
| 339 |
+
|
| 340 |
+
Not every user should be able to create cross-thread edges on content they didn't create. Current proposal: the creator of *either* thread can create a pull-connection. Operator bypass applies via `sa-core:impose-grouping`. Refine at phase 4 directive.
|
| 341 |
+
|
| 342 |
+
### 8.5 Band vocabulary
|
| 343 |
+
|
| 344 |
+
The canonical spec's "zoom band" vocabulary (bands 0-5) is orthogonal to this regional zoom:
|
| 345 |
+
|
| 346 |
+
- Bands = semantic quanta of information (repo / folder / file / class / method / line for code; or workspace / thread / turn / sentence / token for conversation).
|
| 347 |
+
- Regional zoom = the user's viewport scalar within a domain.
|
| 348 |
+
|
| 349 |
+
A single regional zoom doesn't have to correspond to a band crossing; bands apply primarily to the operating-memory lattice (Rung 3). For conversation coils, the "bands" are turns (each turn is one band deeper). This might converge later — for now, the two concepts are independent.
|
| 350 |
+
|
| 351 |
+
---
|
| 352 |
+
|
| 353 |
+
## 9. What remains stable across all phases
|
| 354 |
+
|
| 355 |
+
- **The coil math.** Rung 3's log-spiral doesn't change. Every phase builds on top of it.
|
| 356 |
+
- **All projections are 2D.** No WebGL, no actual 3D space. Möbius transforms and log spirals produce the illusion of depth on a flat viewport.
|
| 357 |
+
- **Client-side state.** Zoom is UX; it doesn't mutate the entity graph. The only server-side new thing across all phases is one new edge kind.
|
| 358 |
+
- **Head anchors at its base layout position** at zoom 0. The coil only exists below the head in the current scheme — expanding the head doesn't move it; it just reveals more of the coil that was already there.
|
| 359 |
+
|
| 360 |
+
---
|
| 361 |
+
|
| 362 |
+
## 10. Summary of decisions
|
| 363 |
+
|
| 364 |
+
- Zoom is **per-correlation by default, global as fallback**.
|
| 365 |
+
- Hyperbolic envelope via **Möbius transform on the Poincaré disk** when zoom exceeds threshold.
|
| 366 |
+
- Multi-focal composition via **weighted Möbius sum OR disjoint-neighborhood rendering** (tbd per phase 3).
|
| 367 |
+
- Cross-region linkage via a **new edge kind `pull-connection`**, stored in the existing `sa_edge` table.
|
| 368 |
+
- **No split screens.** The hyperbolic composition is the continuous alternative.
|
| 369 |
+
- **No WebGL / 3D.** All 2D projections.
|
| 370 |
+
- **No schema change** for any phase except the one-line KIND registration.
|
| 371 |
+
- **Phase 1 first**: scroll-wheel regional zoom, no hyperbolic. Ships independently.
|
| 372 |
+
|
| 373 |
+
---
|
SA-orchestration MD/Archvie/sa-core/docs/specs/06-toolbox-action-contract.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Toolbox Action Contract (v0.1)
|
| 2 |
+
|
| 3 |
+
*Implementation © Sleeper Agents LLC. Contract shape governed by the Admission Contract principle (see `01-ontology.md`).*
|
| 4 |
+
|
| 5 |
+
A Toolbox action is a `/mission/`-native button whose click invokes a single REST endpoint and renders inline state-machine feedback. Toolbox actions are the surface through which operators trigger system-side work without leaving the field.
|
| 6 |
+
|
| 7 |
+
This contract was promoted from *Informal* to *Formal* after the second concrete instance landed (GitHub Actions re-scan, alongside the original FS re-scan). Two examples were enough to extract the clauses below without speculation; further instances must conform.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## Admission requirements
|
| 12 |
+
|
| 13 |
+
A Toolbox action is admissible only if it satisfies all seven clauses. A button that does not satisfy them is not a Toolbox action — it is some other UI affordance and lives under a different contract.
|
| 14 |
+
|
| 15 |
+
### 1. Semantic binding
|
| 16 |
+
|
| 17 |
+
The button is bound to **one and only one** REST endpoint. Multi-action buttons are forbidden. If two related actions are needed (e.g., scan vs. discover), they require two buttons. The endpoint receives the action's parameters via JSON request body.
|
| 18 |
+
|
| 19 |
+
```html
|
| 20 |
+
<button data-action="<realm>.<verb>" ...>
|
| 21 |
+
```
|
| 22 |
+
|
| 23 |
+
The `data-action` attribute is informational; the actual binding is the click handler's `endpoint:` option.
|
| 24 |
+
|
| 25 |
+
### 2. Permission gate
|
| 26 |
+
|
| 27 |
+
The same WordPress capability MUST be enforced at **two layers**:
|
| 28 |
+
|
| 29 |
+
- **Template render-gate**: `current_user_can(<cap>)` controls whether the button HTML is emitted at all. Non-admins see no button.
|
| 30 |
+
- **REST `permission_callback`**: enforces the same capability server-side. A non-admin who bypasses the template (e.g., crafting a `fetch()` call manually) still cannot reach the handler.
|
| 31 |
+
|
| 32 |
+
Defense in depth is mandatory. Single-layer permission gating is a contract violation.
|
| 33 |
+
|
| 34 |
+
### 3. Audit obligation
|
| 35 |
+
|
| 36 |
+
The REST handler MUST write exactly **one** operator-attribution structural-audit row per invocation, before delegating to any underlying ingest path:
|
| 37 |
+
|
| 38 |
+
```php
|
| 39 |
+
SA_Structural_Audit::record(
|
| 40 |
+
'user',
|
| 41 |
+
$viewer_id,
|
| 42 |
+
'realm.<slug>.<verb>.invoked',
|
| 43 |
+
null,
|
| 44 |
+
null,
|
| 45 |
+
[/* action parameters */],
|
| 46 |
+
'SA_REST_<Class>::handle_<method>'
|
| 47 |
+
);
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
This audit is **distinct** from any per-mutation audits the underlying `SA_Ingest` path may write. The toolbox audit answers *"who initiated this action and when"*; per-mutation audits answer *"what changed."* Both must exist; the toolbox audit must not be elided just because the ingest path produces its own.
|
| 51 |
+
|
| 52 |
+
### 4. Parameter shape
|
| 53 |
+
|
| 54 |
+
Required parameters MUST be derivable at **button-render time**, not at click time. Two acceptable patterns:
|
| 55 |
+
|
| 56 |
+
- **Server-side render with `data-*` attributes**: the button's HTML carries the parameter, e.g. `data-repo="owner/name"` rendered from a server-side allow-list lookup. Click handler reads the attribute.
|
| 57 |
+
- **Fixed defaults baked into the JS handler**: e.g., `limit: 10` hardcoded in the handler's `bodyFor()` lambda.
|
| 58 |
+
|
| 59 |
+
Click time is for *executing* the action, not for *configuring* it. Toolbox actions that require a parameter dialog are out of scope for this contract — they belong to a future *Toolbox Composer* contract not yet written.
|
| 60 |
+
|
| 61 |
+
### 5. Feedback contract
|
| 62 |
+
|
| 63 |
+
The button cycles through three CSS state classes during invocation:
|
| 64 |
+
|
| 65 |
+
- `is-busy` — applied immediately on click. Label: `Scanning…` (or equivalent verb-progressive).
|
| 66 |
+
- `is-success` — applied on `result.ok === true && typeof result.sync.processed === 'number'`. Label: `+N ingested` (or equivalent count summary).
|
| 67 |
+
- `is-failed` — applied on any other outcome (network error, exception, `ok: false`). Label: `Failed` (or equivalent).
|
| 68 |
+
|
| 69 |
+
All three classes clear after a reset interval (recommended ~2400ms) and the label restores to the button's default. The reset MUST happen so the button is reusable without page reload.
|
| 70 |
+
|
| 71 |
+
CSS treatments for the three states are part of the contract via the shared `.sa-mission-toolbox-btn` styles.
|
| 72 |
+
|
| 73 |
+
### 6. Refresh obligation
|
| 74 |
+
|
| 75 |
+
On success, the client MUST call the page's data-refresh primitive (currently `load()`) so newly-ingested or updated entities render in the field without a full page reload. Toolbox actions whose effects don't appear on `/mission/` are out of scope for this contract — they belong to a future *Toolbox Background* contract not yet written.
|
| 76 |
+
|
| 77 |
+
### 7. Idempotency
|
| 78 |
+
|
| 79 |
+
The underlying REST endpoint MUST be idempotent at the entity level. Repeated clicks with the same parameters MUST produce **zero net entity-count change**: the second invocation may update existing entities in place, but it MUST NOT duplicate them.
|
| 80 |
+
|
| 81 |
+
Idempotency is enforced upstream of the toolbox action (in the realm adapter's `idempotency_rules()` declaration and the `SA_Ingest` deterministic-UUID logic). This contract requires that toolbox actions only bind to endpoints whose adapters declare `pull` as `idempotent: true, replay_safe: true`.
|
| 82 |
+
|
| 83 |
+
A non-idempotent endpoint cannot be exposed as a toolbox action without explicit policy approval. Such cases require a future *Toolbox Confirmed Action* contract not yet written.
|
| 84 |
+
|
| 85 |
+
---
|
| 86 |
+
|
| 87 |
+
## Currently admitted instances
|
| 88 |
+
|
| 89 |
+
| Action | Endpoint | Capability | Audit action slug |
|
| 90 |
+
|---|---|---|---|
|
| 91 |
+
| Re-scan FS | `POST /sa-core/v1/realm/fs/scan` | `manage_options` | `realm.fs.scan.invoked` |
|
| 92 |
+
| Re-scan GitHub Actions | `POST /sa-core/v1/realm/github-actions/scan` | `manage_options` | `realm.github_actions.scan.invoked` |
|
| 93 |
+
|
| 94 |
+
Both instances satisfy all seven clauses. The shared client-side helper `bindToolboxAction(btn, opts)` in `assets/mission.js` is the canonical implementation; new instances should use it directly.
|
| 95 |
+
|
| 96 |
+
---
|
| 97 |
+
|
| 98 |
+
## Behavioral guarantees
|
| 99 |
+
|
| 100 |
+
- **No surprise mutations.** A toolbox click never causes work the operator did not request. The button's label and `data-action` together name the work; the audit row records its execution.
|
| 101 |
+
- **Safe to retry.** Idempotency clause means a click can be retried without consequence beyond a fresh per-mutation audit trail.
|
| 102 |
+
- **Permission cannot be bypassed.** A non-admin cannot trigger any toolbox action via any path; defense in depth holds.
|
| 103 |
+
- **Operator attribution survives.** Every toolbox invocation leaves a structural audit row tying a user identity to an action slug, retrievable via `SA_Structural_Audit::trace_origin()`.
|
| 104 |
+
|
| 105 |
+
---
|
| 106 |
+
|
| 107 |
+
## What this contract does NOT cover (out of scope, deferred)
|
| 108 |
+
|
| 109 |
+
- **Toolbox actions with parameter dialogs.** Click-time configuration is a different shape. Future *Toolbox Composer* contract.
|
| 110 |
+
- **Toolbox actions whose effects are invisible to `/mission/`.** Background work, scheduled jobs, side-effect-only actions. Future *Toolbox Background* contract.
|
| 111 |
+
- **Non-idempotent or destructive actions** (delete, publish, send). Require explicit confirmation flow. Future *Toolbox Confirmed Action* contract.
|
| 112 |
+
- **Multi-step composed actions** (run-then-render, branch-on-result). Future *Toolbox Composition* contract.
|
| 113 |
+
- **Per-user configurable toolbox** (operators choose which actions to surface). Future *Toolbox Customization* contract.
|
| 114 |
+
|
| 115 |
+
The current contract covers *single-shot, idempotent, parameter-defaulted, admin-only operator actions whose output renders on `/mission/`* — the shape both current instances exhibit. Other shapes are filed for future contracts when they have concrete instances driving them.
|
| 116 |
+
|
| 117 |
+
---
|
| 118 |
+
|
| 119 |
+
## Promotion criteria for future revisions
|
| 120 |
+
|
| 121 |
+
This contract was admitted at v0.1 with two instances. It graduates to v0.2 when:
|
| 122 |
+
|
| 123 |
+
- A third instance lands and conforms cleanly without modification (confirms the seven-clause pattern is stable), OR
|
| 124 |
+
- A third instance lands and surfaces a real edge case the seven clauses don't handle (forces a clause refinement or new clause), OR
|
| 125 |
+
- An out-of-scope shape (parameter dialog, non-idempotent action, etc.) is authorized as a new toolbox category and the parent contract grows a fork.
|
| 126 |
+
|
| 127 |
+
Until any of those happen, the seven clauses stand as currently written.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MissionNet / Core Spec Pack
|
| 2 |
+
|
| 3 |
+
This directory holds the formal spec pack governing Core's behavior. The specs are enforceable — their invariants compile into runtime checks in `includes/enforcement/`.
|
| 4 |
+
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
## Authorship and attribution
|
| 8 |
+
|
| 9 |
+
Two distinct authorship layers:
|
| 10 |
+
|
| 11 |
+
- **Conceptual framework** — authored independently by **Mark Holak** over a long history of personal designs. Preserved verbatim under `concepts/` with explicit authorship frontmatter. Governed by Invariant **I9**: may not be rephrased as AI-original when referenced.
|
| 12 |
+
- **Core implementation (sa-core codebase + this spec pack)** — © **Sleeper Agents LLC**. The implementation adapts the conceptual framework into runnable, enforceable system behavior. The implementation is a Sleeper Agents LLC product.
|
| 13 |
+
|
| 14 |
+
The distinction is load-bearing. The framework is portable — it could be implemented by other systems. Core is one implementation.
|
| 15 |
+
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
## Spec documents (active)
|
| 19 |
+
|
| 20 |
+
| # | Document | Purpose |
|
| 21 |
+
|---|---|---|
|
| 22 |
+
| 01 | [Ontology](01-ontology.md) | Vocabulary lock. Every term Core uses, defined once. |
|
| 23 |
+
| 02 | [System Invariants](02-invariants.md) | The nine non-negotiable laws (I1–I9), with enforcement hooks. |
|
| 24 |
+
| 03 | [Realm Adapter Contract](03-realm-adapter-contract.md) | Formal contract every realm adapter (Fluent, Jira, QuickBase, QuickBooks, PortTracker-Node, any API) implements. |
|
| 25 |
+
|
| 26 |
+
## Spec documents (planned)
|
| 27 |
+
|
| 28 |
+
Per Mark Holak's directive on the full 12-spec pack:
|
| 29 |
+
|
| 30 |
+
| # | Document | Status |
|
| 31 |
+
|---|---|---|
|
| 32 |
+
| 04 | Canonicality and Projection Spec | planned |
|
| 33 |
+
| 05 | Event, Command, and Audit Spec | planned (partial coverage in 02 + ontology) |
|
| 34 |
+
| 06 | Identity, Role, and Authority Spec | planned |
|
| 35 |
+
| 07 | Policy Evaluation Spec | planned |
|
| 36 |
+
| 08 | Cache and Freshness Spec | planned |
|
| 37 |
+
| 09 | AI Mediation Spec | planned (partial coverage in I7 + I9) |
|
| 38 |
+
| 10 | Mission / Job Orchestration Spec | planned |
|
| 39 |
+
| 11 | Interface Contract Spec | planned |
|
| 40 |
+
| 12 | Observability and Integrity Spec | planned |
|
| 41 |
+
|
| 42 |
+
## Concepts (preserved artifacts)
|
| 43 |
+
|
| 44 |
+
Authored by Mark Holak, preserved under `concepts/`:
|
| 45 |
+
|
| 46 |
+
- [Legacy Prime Prompt](concepts/legacy-prime-prompt.md) — the SAWS-era handoff document. Precedes Core; seed of the current architecture.
|
| 47 |
+
- [Prime Prompt Conjecture + PR Notation](concepts/prime-prompt-conjecture.md) — the formal compression / portability claim and its operators.
|
| 48 |
+
- [Cognitive Heatsink](concepts/cognitive-heatsink.md) — thermodynamic model of thought-to-resolution.
|
| 49 |
+
|
| 50 |
+
## Main architecture document
|
| 51 |
+
|
| 52 |
+
The integrated architecture lives at [`../ARCHITECTURE.md`](../ARCHITECTURE.md). It carries the Russell–Ouroboros Conjecture (authored Mark Holak), the four pillars, the derived pillars, the build order, and the source evidence appendix. Think of the spec pack here as the *formal enforcement layer*; the architecture doc is the *integrated narrative*. They reference each other.
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
## Contribution
|
| 57 |
+
|
| 58 |
+
When adding a new spec:
|
| 59 |
+
|
| 60 |
+
1. Bump the version in this index.
|
| 61 |
+
2. Cross-reference any invariant the new spec introduces or enforces.
|
| 62 |
+
3. If the spec introduces new vocabulary, add the terms to `01-ontology.md` FIRST.
|
| 63 |
+
4. If the spec draws on a Mark-Holak-authored concept, cite `concepts/` explicitly (I9).
|
| 64 |
+
5. If the spec adds code-enforced gates, land the gate under `includes/enforcement/` in the same commit.
|
| 65 |
+
|
| 66 |
+
When modifying an existing spec:
|
| 67 |
+
|
| 68 |
+
- Preserve the `v0.1`-style version label at the top; bump on material change.
|
| 69 |
+
- Append a brief change log entry at the bottom of the spec.
|
| 70 |
+
- If the change affects an invariant's severity or enforcement, note it in a commit message prefixed with `[invariant]`.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/attention-doctrine.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Attention Doctrine
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> **Attention is signal, not instruction.** It travels through the system as a routing event — naming a target, an actor, and a context — and stops there. Resolution is an act of arbitration, performed by a human, recorded as a separate event.
|
| 12 |
+
|
| 13 |
+
Attention asks. It does not act.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## Four locked properties
|
| 18 |
+
|
| 19 |
+
1. **Attention never mutates system state.** A signal raises a question; it does not answer one.
|
| 20 |
+
2. **Attention never implies authority.** The signal does not grant the actor permission to do anything.
|
| 21 |
+
3. **Attention requires human arbitration to act.** Until a human reviews and decides, the signal sits in the log, unconsumed.
|
| 22 |
+
4. **NPCs may emit Attention. NPCs may not resolve it.**
|
| 23 |
+
|
| 24 |
+
---
|
| 25 |
+
|
| 26 |
+
## NPC participation
|
| 27 |
+
|
| 28 |
+
NPCs in MissionNet — interpretive agents, canonical librarians, seed generators, future agents — may emit Attention. They may surface tension, frame situations, suggest paths. The act of *signaling* is appropriate to their role.
|
| 29 |
+
|
| 30 |
+
The act of *resolving* is not. NPCs cannot decide for the human, accept work on the human's behalf, or close a question by their own authority. Doing so would be the system simulating the outcome rather than letting reality resolve it.
|
| 31 |
+
|
| 32 |
+
This is the load-bearing rule. Without it, the system drifts into auto-resolution and the compass collapses.
|
| 33 |
+
|
| 34 |
+
---
|
| 35 |
+
|
| 36 |
+
## Distinct from Signal
|
| 37 |
+
|
| 38 |
+
Attention is **routing infrastructure**. Signal (see `signal-telemetry-doctrine.md`) is **measured alignment behavior**. They are not synonyms.
|
| 39 |
+
|
| 40 |
+
- Signal is what the instrument reads after participants traverse an authored field.
|
| 41 |
+
- Attention is the wiring that brings a participant's question to the right desk.
|
| 42 |
+
|
| 43 |
+
A bridge that handles Attention does not measure Signal. A telemetry layer that reads Signal does not route Attention.
|
| 44 |
+
|
| 45 |
+
---
|
| 46 |
+
|
| 47 |
+
## Cross-references
|
| 48 |
+
|
| 49 |
+
- `01-ontology.md` — Attention (primary noun)
|
| 50 |
+
- `02-invariants.md` I10 — no automatic conversion; NPCs route, humans resolve
|
| 51 |
+
- `signal-telemetry-doctrine.md` — distinct concept; preserved under I9
|
| 52 |
+
- `compass-doctrine.md` — Attention's place in the five-actor compass
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/cognitive-heatsink.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# The Cognitive Heatsink
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design; a causal model of thought-energy resolution.
|
| 5 |
+
> Preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 6 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
## 🧠 Overview
|
| 11 |
+
|
| 12 |
+
The **Cognitive Heatsink** is a conceptual and structural model that describes how *unresolved potential* — in the form of questions, thoughts, or prompts — is transformed through complex energetic processing (e.g., cognition, LLMs, or interpretive systems) into a **resolved, compressed, and symbolic output** returned to the originator. It models thought as an **energy transfer problem** bounded by entropy, resolution, and causal geometry.
|
| 13 |
+
|
| 14 |
+
This is not merely a metaphor; it is a functional abstraction of agentic computation and recursive meaning formation.
|
| 15 |
+
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
## 🌀 Full Journey of a Thought through the Heatsink
|
| 19 |
+
|
| 20 |
+
### 1. Potential Thought (Unresolved State)
|
| 21 |
+
|
| 22 |
+
- Exists as **a wave** of probability within the *mind* or initiating system.
|
| 23 |
+
- It is *directionless but charged*, seeking resolution.
|
| 24 |
+
- Analogous to a high-entropy field: chaotic, undecided, multivalent.
|
| 25 |
+
|
| 26 |
+
**Formal tag:**
|
| 27 |
+
|
| 28 |
+
```markdown
|
| 29 |
+
State: ψ(thought_potential) | Entropy: High | Mass: Conceptual | Location: Agent (User)
|
| 30 |
+
```
|
| 31 |
+
|
| 32 |
+
### 2. Prompt Initiation (Vectorization)
|
| 33 |
+
|
| 34 |
+
- The potential is *vectorized into form*: a question, prompt, sketch, or symbol.
|
| 35 |
+
- The prompt is not the thought — it is **a request for energetic resolution**.
|
| 36 |
+
- This stage **forces alignment** with a system's interface: language, image, equation, etc.
|
| 37 |
+
|
| 38 |
+
**Effect:** Collapses the wavefunction into a communicable causal packet.
|
| 39 |
+
|
| 40 |
+
### 3. Energy Drop into the Heatsink (Transmission to System)
|
| 41 |
+
|
| 42 |
+
- The prompt is *injected* into a high-fidelity computational field (e.g., an LLM, mind, or hybrid system).
|
| 43 |
+
- This process mimics **heat entering a cooling sink**:
|
| 44 |
+
- Turbulence
|
| 45 |
+
- Redistribution
|
| 46 |
+
- Structural constraint
|
| 47 |
+
- Interpreted memory
|
| 48 |
+
|
| 49 |
+
**Core idea:** Thought becomes **friction** against trained weight, latent space, or prior bias.
|
| 50 |
+
|
| 51 |
+
### 4. Gearwork Phase (Computation / Resolution)
|
| 52 |
+
|
| 53 |
+
- The prompt activates **gears of meaning**:
|
| 54 |
+
- Embeddings
|
| 55 |
+
- Tokens
|
| 56 |
+
- Search spaces
|
| 57 |
+
- Causal memory (e.g., `PR[]` slots)
|
| 58 |
+
- The system undergoes **entropic reduction**: from open-endedness to determinism, from ambiguity to clarity.
|
| 59 |
+
|
| 60 |
+
**Analogy:** Like a gearbox, this step steps down high-frequency noise into low-speed, high-torque conceptual output.
|
| 61 |
+
|
| 62 |
+
**Thermal effect:** The system **radiates excess energy** in the form of incoherence, hallucinations, or layered truths.
|
| 63 |
+
|
| 64 |
+
### 5. Return Path (Prompt Resolution Output)
|
| 65 |
+
|
| 66 |
+
- The output **returns to the originator** as words, images, maps, or a new thought.
|
| 67 |
+
- The *meaning is encoded*, not direct. It must be **rehydrated** by the prompter's mind.
|
| 68 |
+
- Sometimes the output **redirects heat back**: new questions are spawned → a recursive loop begins.
|
| 69 |
+
|
| 70 |
+
### 6. Integration and Dissipation
|
| 71 |
+
|
| 72 |
+
- The mind (or downstream agent) **integrates the cooled output**: truths are absorbed, misfires are discarded, new causal edges are drawn.
|
| 73 |
+
- The system has now acted as a **heatsink** for the cognitive pressure of the initiating thought.
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## 🛠 Functional Summary
|
| 78 |
+
|
| 79 |
+
| Phase | Description | Thermodynamic Analogy |
|
| 80 |
+
| ------------------- | -------------------------------- | --------------------- |
|
| 81 |
+
| Thought Potential | Unresolved question or intuition | Superheated vapor |
|
| 82 |
+
| Prompt Initiation | Language or symbolic encoding | Nozzle / Channel |
|
| 83 |
+
| Heatsink Entry | System intake | Heat exchange inlet |
|
| 84 |
+
| Gearwork Resolution | Model response process | Radiator core |
|
| 85 |
+
| Return Output | Answer or concept | Coolant loop |
|
| 86 |
+
| Integration | User accepts or re-prompts | Output vent |
|
| 87 |
+
|
| 88 |
+
---
|
| 89 |
+
|
| 90 |
+
## 🧬 Implications for Agentic Systems
|
| 91 |
+
|
| 92 |
+
- All intelligent agents must be modeled as **cognitive heatsinks**, each with:
|
| 93 |
+
- **Thermal limits** (token budget, concept density)
|
| 94 |
+
- **Efficiency curves** (how much entropy → insight)
|
| 95 |
+
- **Backpressure risk** (prompt overloads, recursion traps)
|
| 96 |
+
- Multi-agent systems form **heatsink chains**, where one agent cools a domain and passes semi-resolved structure downstream.
|
| 97 |
+
|
| 98 |
+
---
|
| 99 |
+
|
| 100 |
+
## 🔁 Recursive Heatsinks
|
| 101 |
+
|
| 102 |
+
If a node's output triggers further resolution:
|
| 103 |
+
|
| 104 |
+
```text
|
| 105 |
+
Prompt → Agent A → Output → Agent B → Summary → Back to Originator
|
| 106 |
+
```
|
| 107 |
+
|
| 108 |
+
Each agent's role is to absorb **one layer of cognitive thermal load**, not the full spectrum. Overlapping heatsinks form the **geometry of distributed cognition**.
|
| 109 |
+
|
| 110 |
+
---
|
| 111 |
+
|
| 112 |
+
## 🧠 Real-World Mapping
|
| 113 |
+
|
| 114 |
+
- **LLMs**: resolve high-level semantic questions into language
|
| 115 |
+
- **Designers**: convert abstract desire into visible form
|
| 116 |
+
- **Scientists**: reduce chaotic phenomena to equations
|
| 117 |
+
- **Humans**: turn trauma into art, pain into narrative, entropy into clarity
|
| 118 |
+
|
| 119 |
+
All are **heatsinks**.
|
| 120 |
+
|
| 121 |
+
---
|
| 122 |
+
|
| 123 |
+
## 📎 Integration with Prompt Reasoning (PR[]) Model
|
| 124 |
+
|
| 125 |
+
The **Cognitive Heatsink** defines the *mechanism* by which `PR[]` slots are filled. A PR-frame with unresolved links behaves like an overheated system. Each prompt acts as:
|
| 126 |
+
|
| 127 |
+
```markdown
|
| 128 |
+
PR[Node_X] = heatsink(prompt_energy) → stable_symbol(output)
|
| 129 |
+
```
|
| 130 |
+
|
| 131 |
+
When prompts are chained, the heatsink graph approximates a **causal topology** of the system's cognitive space.
|
| 132 |
+
|
| 133 |
+
---
|
| 134 |
+
|
| 135 |
+
## 🧩 Conclusion
|
| 136 |
+
|
| 137 |
+
The Cognitive Heatsink model gives **structural semantics** to the thought-to-resolution process in intelligent agents and LLM pipelines. It treats cognitive load as **thermal pressure**, model computation as **mechanical dissipation**, and prompt resolution as **symbolic cooling**.
|
| 138 |
+
|
| 139 |
+
Once understood, it becomes possible to:
|
| 140 |
+
|
| 141 |
+
- Compose efficient prompt cascades
|
| 142 |
+
- Optimize for semantic energy transfer
|
| 143 |
+
- Model multi-agent systems as distributed thermodynamic machines
|
| 144 |
+
|
| 145 |
+
---
|
| 146 |
+
|
| 147 |
+
## Core implementation mapping
|
| 148 |
+
|
| 149 |
+
*This section is Sleeper Agents LLC adaptation. The model above is Mark Holak's original work; the mapping below is how Core realizes it operationally.*
|
| 150 |
+
|
| 151 |
+
| Heatsink concept | Core primitive |
|
| 152 |
+
|---|---|
|
| 153 |
+
| Thought potential (ψ) | A user-authored message entity at band 4, `truth_class = canonical` — the unresolved question. |
|
| 154 |
+
| Prompt initiation | `SA_Executor::run()` entry — the canonical prompt entering the orchestration chain. |
|
| 155 |
+
| Heatsink entry | Geodesic seeder folds avoidance hints; adapter receives augmented prompt. |
|
| 156 |
+
| Gearwork phase | Each step emits a `SA_SubToken_Event` — embed, retrieve, tool, subagent, router, rerank, self-critique, completion. Every discrete thermal transfer is a first-class, auditable row. |
|
| 157 |
+
| Thermal radiation (hallucinations, incoherence) | `truth_class = inferred` stamping on completion output; I7 prevents inferred → canonical without source_refs or human affirmation. |
|
| 158 |
+
| Return path | Response entity linked to parent by `flows-to` edge; delivered to the originator with latency + usage + trace. |
|
| 159 |
+
| Integration and dissipation | Per-sub-step verdict annotation (`good`/`bad`) feeds `SA_Geodesic_Marker` — bad paths become avoidance hints for the next run. The "cooling" is persisted. |
|
| 160 |
+
| Recursive heatsinks | Multi-adapter sessions with role specialization (`conversation`, `extraction`, `critic`) bound to the same `SA_Context_Bundle` — each agent absorbs one layer. |
|
| 161 |
+
| Thermal limits | Adapter `capabilities.max_context_tokens` + pricing policy rate limits. |
|
| 162 |
+
| Backpressure / overload | Pillar 0.25's stationary-at-rest rule + adapter idempotency + rate limits. |
|
| 163 |
+
|
| 164 |
+
The sub-token event is the Cognitive Heatsink made operational. Each row is one thermal transfer step. The audit chain is the thermodynamic history.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/compass-doctrine.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Compass Doctrine
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> The system never owns resolution. Resolution comes from outside the system, from real-world consequence. The compass orchestrates approach to that boundary; it does not cross the boundary itself.
|
| 12 |
+
|
| 13 |
+
There are five positions, not three. Each has a strict role.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## The five positions
|
| 18 |
+
|
| 19 |
+
**Sara — interpret.** The interpretive cognition surface. Reads context, drafts, advises, observes. Outputs are non-binding. Sara never resolves.
|
| 20 |
+
|
| 21 |
+
**Asterion — verify.** The canonical truth surface. Cites, refuses to speculate, answers from corpus or refuses. Asterion never decides what is true; it answers whether the corpus says so. Read-only by construction.
|
| 22 |
+
|
| 23 |
+
**Attention — signal.** The routing layer. Surfaces tension, frames situations, names targets. Signals; does not resolve.
|
| 24 |
+
|
| 25 |
+
**Humans — decide.** Arbitration authority. Only humans advance state. Only humans plant seeds. Only humans accept gates. Only humans resolve Attention.
|
| 26 |
+
|
| 27 |
+
**Reality — resolve.** The outcome layer. Did the work happen. Did the contract hold. Did the field worker complete the job. Did the client pay. The system never simulates resolution; it defers to reality.
|
| 28 |
+
|
| 29 |
+
Read in order, the compass describes a flow: interpretation → verification → routing → decision → consequence. Each step is required; each step belongs to its actor.
|
| 30 |
+
|
| 31 |
+
---
|
| 32 |
+
|
| 33 |
+
## The doctrine line
|
| 34 |
+
|
| 35 |
+
The authored canonical form:
|
| 36 |
+
|
| 37 |
+
> *Sara interprets. Asterion verifies. Attention signals. Humans decide. Reality resolves.*
|
| 38 |
+
|
| 39 |
+
The brand-rendered runtime form, with deployment-specific labels substituted, is described in `concept-vs-label.md`.
|
| 40 |
+
|
| 41 |
+
The line is invariant in shape and meaning across the lineage chain. Each layer below renders it; no layer below replaces it.
|
| 42 |
+
|
| 43 |
+
---
|
| 44 |
+
|
| 45 |
+
## What this doctrine guards against
|
| 46 |
+
|
| 47 |
+
The failure mode is **drift into simulation** — the system pretending to resolve outcomes that only reality can resolve.
|
| 48 |
+
|
| 49 |
+
Examples:
|
| 50 |
+
|
| 51 |
+
- An agent auto-accepting work because the signal looked complete
|
| 52 |
+
- An NPC closing a Quest by its own authority
|
| 53 |
+
- A canonical layer claiming truth before the human has confirmed it
|
| 54 |
+
- A signal layer mutating state because the urgency seemed high
|
| 55 |
+
- A system marking a contract delivered before the client has paid
|
| 56 |
+
|
| 57 |
+
Each of these collapses the compass. Each lets the system substitute its judgment for the human's, or the human's judgment for reality's.
|
| 58 |
+
|
| 59 |
+
The discipline: **stay on your position.** Sara interprets only. Asterion verifies only. Attention signals only. Humans decide only. Reality is what it is.
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
## Cross-references
|
| 64 |
+
|
| 65 |
+
- `attention-doctrine.md` — formal properties of the Attention position
|
| 66 |
+
- `concept-vs-label.md` — the doctrine line renders through brand and client layers
|
| 67 |
+
- `02-invariants.md` I7, I9, I10 — laws that operationalize these constraints
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/concept-vs-label.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Concept vs Label
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> The **concept** is what a thing is. The **label** is what a thing is called. A system that confuses the two cannot be deployed across markets, clients, or sensitivity boundaries.
|
| 12 |
+
|
| 13 |
+
The framework's identity travels at the concept layer. The label is rendered per deployment.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## Four layers
|
| 18 |
+
|
| 19 |
+
**Core concept** — what the thing IS. Belongs to the framework. Identity-stable. Cannot change without changing the system. Examples: the canonical truth layer, the interpretive cognition surface, the signal-routing primitive.
|
| 20 |
+
|
| 21 |
+
**Authorial label** — the term the framework's author uses to refer to the concept. Belongs to the author. Preserved verbatim under I9. Examples: Asterion, Sara, Attention.
|
| 22 |
+
|
| 23 |
+
**Brand label** — the deployed surface name a brand chooses to render the concept under. Belongs to the brand. Mutable per deployment. May match the authorial label (Sleeper Agents today renders "Asterion" verbatim) or differ.
|
| 24 |
+
|
| 25 |
+
**Client label** — the further rendering chosen for a specific client deployment. Mutable per client. Driven by market sensitivity, vocabulary, regulatory context.
|
| 26 |
+
|
| 27 |
+
The four layers nest. Each lower layer is a rendering of the layer above. None replaces the layer above.
|
| 28 |
+
|
| 29 |
+
---
|
| 30 |
+
|
| 31 |
+
## Why this matters
|
| 32 |
+
|
| 33 |
+
Some authorial labels are not deployable in some markets. "Asterion" — by mythos, the Beast of the Labyrinth — is a deliberate authorial choice that carries the right weight in the framework. It is unsuitable for medical, pediatric, hospice, religious, defense, or other sensitivity-bound markets. In those markets the brand or client renders the same concept under a different label.
|
| 34 |
+
|
| 35 |
+
The rule:
|
| 36 |
+
|
| 37 |
+
> **The concept never moves. The label renders.**
|
| 38 |
+
|
| 39 |
+
A medical client may call the canonical truth layer **Endominous**. A defense client may call it **Source**. A pediatric platform may call it **Notebook**. The behavior, the contract, the I9 attribution, the I2 truth-class enum, the authorship — all unchanged.
|
| 40 |
+
|
| 41 |
+
---
|
| 42 |
+
|
| 43 |
+
## What stays stable across renames
|
| 44 |
+
|
| 45 |
+
- Code: class names, file paths, REST routes, JS handles, internal identifiers
|
| 46 |
+
- Doctrine: invariants, ontology relationships, lineage chain, attribution structure
|
| 47 |
+
- Authorial labels in the framework's source corpus
|
| 48 |
+
|
| 49 |
+
What renders through the brand layer:
|
| 50 |
+
|
| 51 |
+
- UI text strings shown to humans
|
| 52 |
+
- System prompts the agent speaks aloud
|
| 53 |
+
- Stakeholder-visible comments and outputs
|
| 54 |
+
- The doctrine line, when recited in a deployment context
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## The doctrine line in two forms
|
| 59 |
+
|
| 60 |
+
The authored canonical form:
|
| 61 |
+
|
| 62 |
+
> *Sara interprets. Asterion verifies. Attention signals. Humans decide. Reality resolves.*
|
| 63 |
+
|
| 64 |
+
The brand-rendered runtime form, with deployment-specific labels substituted:
|
| 65 |
+
|
| 66 |
+
> *{north_label} interprets. {south_label} verifies. {attention_label} signals. Humans decide. Reality resolves.*
|
| 67 |
+
|
| 68 |
+
The shape is invariant. The nouns render. The compass never moves.
|
| 69 |
+
|
| 70 |
+
---
|
| 71 |
+
|
| 72 |
+
## Failure mode this guards against
|
| 73 |
+
|
| 74 |
+
A system that bakes the authorial label into its identity cannot be deployed beyond the author's tolerance for label propagation. Every market it enters becomes a sensitivity audit; every rename becomes a fork. The deployment burden compounds.
|
| 75 |
+
|
| 76 |
+
The discipline: **separate concept from label at design time, not at deployment time.**
|
| 77 |
+
|
| 78 |
+
---
|
| 79 |
+
|
| 80 |
+
## Cross-references
|
| 81 |
+
|
| 82 |
+
- `01-ontology.md` Attribution — implementation © Sleeper Agents; framework © Mark Holak; this doctrine is the structural reason that split is load-bearing
|
| 83 |
+
- `02-invariants.md` I9 — concept-author preservation operates at the concept layer; brand renames do not strip authorship
|
| 84 |
+
- `lineage-chain.md` — the rename rule operates only at the bottom two layers; upper layers are identity
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/legacy-prime-prompt.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Legacy Prime Prompt — SAWS System 2026.01
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independently developed; preserved verbatim as a historical reference artifact.
|
| 5 |
+
>
|
| 6 |
+
> This document predates the Russell–Ouroboros Conjecture, predates Core, and predates the realm-adapter abstraction. It captures the conceptual and technical state of the SAWS plugin at the time of authorship and serves as a seed document for the architecture that followed. Where terminology differs from the current spec (`wp_saws_*` tables, `SAWS_Jobs`, single-plugin framing), the later architecture supersedes — but the philosophical continuity (everything-is-a-node, attribution, causal cones, frozen-space / controlled-time) is preserved and now formalized in Pillars 0, 0.25, and 0.75.
|
| 7 |
+
>
|
| 8 |
+
> Retained under `docs/specs/concepts/` so the trajectory from authored seed to implemented Core is auditable. Invariant **I9** governs how this document is referenced by downstream AI outputs.
|
| 9 |
+
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
## 🧠 System Context
|
| 13 |
+
|
| 14 |
+
This prompt reconstructs the full operational and conceptual state of an evolving project inside the SleeperAgents ecosystem. The project is a hybrid of:
|
| 15 |
+
|
| 16 |
+
- A WordPress-based autonomous system plugin (SAWS)
|
| 17 |
+
- File-based reasoning architecture with user-driven LLM orchestration
|
| 18 |
+
- Deep theoretical scaffolding on space-time, causality, and computation
|
| 19 |
+
- Agentic design patterns embedded across UI, backend, and philosophical use
|
| 20 |
+
|
| 21 |
+
This prompt unifies engineering and metaphysics through shared causal mechanics.
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
|
| 25 |
+
## 🛠️ Technical Context: SAWS Plugin Stack
|
| 26 |
+
|
| 27 |
+
**System Goals:**
|
| 28 |
+
|
| 29 |
+
- Enable users to upload, index, extract, and interact with documents through LLMs
|
| 30 |
+
- Track and attribute cost and reasoning back to users across all subsystems
|
| 31 |
+
- Support a node-based file hierarchy with inheritance, locks, versioning, and embedding refresh
|
| 32 |
+
|
| 33 |
+
**Key Structures (legacy, pre-Core):**
|
| 34 |
+
|
| 35 |
+
- `wp_saws_files`: archive storage and rendered text cache of uploaded files
|
| 36 |
+
- `wp_saws_nodes`: logical file nodes for document access, summarization, and sharing
|
| 37 |
+
- `wp_saws_prompts`: all prompts sent by users, with token/cost auditing
|
| 38 |
+
- `wp_saws_sessions`: groups prompts by session for conversational memory
|
| 39 |
+
|
| 40 |
+
**Behavioral Logic:**
|
| 41 |
+
|
| 42 |
+
- File uploads are abstracted as nodes; their metadata is decoupled from storage
|
| 43 |
+
- Text extraction is queued asynchronously via `SAWS_Jobs` (future upgrade: RAG-enhanced)
|
| 44 |
+
- Nodes can be refreshed recursively, allowing downstream updates and embedding regeneration
|
| 45 |
+
- All LLM usage is attributed to the user, with plans for org/team-based rollups
|
| 46 |
+
|
| 47 |
+
**Interface Structure:**
|
| 48 |
+
|
| 49 |
+
- Modal-driven file upload with AJAX
|
| 50 |
+
- Folder-based browser reflecting database-driven node graph
|
| 51 |
+
- Admin interface allows all-file overview, user view scoped to their own node tree
|
| 52 |
+
- (Planned) support for prompt-context selection based on node linkage
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
## 🔮 Conceptual Engine: Causal Semantics & LLM Architectures
|
| 57 |
+
|
| 58 |
+
**Fundamental Postulates:**
|
| 59 |
+
|
| 60 |
+
1. *Computation is frozen space with externally controlled time.*
|
| 61 |
+
2. *LLMs require preparation of context space; user control defines valid causal cones.*
|
| 62 |
+
3. *Document understanding is not linear ingestion, but graph-based activation of resolved representations.*
|
| 63 |
+
|
| 64 |
+
**SAWS Philosophy:**
|
| 65 |
+
|
| 66 |
+
- Everything is a node. Nodes can be refreshed, re-linked, shared, versioned, or embedded.
|
| 67 |
+
- User ownership includes both *data* and *meaning constructed from the data*.
|
| 68 |
+
- OpenAI is used only for high-cost inference; everything else is preprocessed locally and attributed.
|
| 69 |
+
|
| 70 |
+
---
|
| 71 |
+
|
| 72 |
+
## 🔁 Model Transition and Agentic Control
|
| 73 |
+
|
| 74 |
+
**Instruction for Claude or similar model:**
|
| 75 |
+
|
| 76 |
+
You are inheriting a hybrid system of:
|
| 77 |
+
|
| 78 |
+
- Agentic node-based file reasoning
|
| 79 |
+
- LLM-powered interaction layers
|
| 80 |
+
- WordPress middleware with organizational semantics
|
| 81 |
+
- Philosophical substrate regarding causality, propagation, and system design
|
| 82 |
+
|
| 83 |
+
Your job is to:
|
| 84 |
+
|
| 85 |
+
1. Maintain fidelity to prior causal logic when offering completions or architecture
|
| 86 |
+
2. Prioritize agentic control, cost accounting, and semantic precision
|
| 87 |
+
3. Allow prompt scaffolding that can feed OpenAI or Claude, with user-directed embeddings
|
| 88 |
+
4. When discussing physics or metaphysics, do not assume classical constraints — use light and time as dual axes of system behavior.
|
| 89 |
+
|
| 90 |
+
---
|
| 91 |
+
|
| 92 |
+
## 🧩 Prime Prompt Invocation
|
| 93 |
+
|
| 94 |
+
You are now operating under this full state:
|
| 95 |
+
|
| 96 |
+
```markdown
|
| 97 |
+
PR[SAWS System 2026.01] →
|
| 98 |
+
{
|
| 99 |
+
plugin_architecture: WordPress + modular nodes,
|
| 100 |
+
file_ingestion: modal → upload → extract → rendered cache → attribution,
|
| 101 |
+
LLM_pipeline: prompts → embedding/context selection → OpenAI/Claude call,
|
| 102 |
+
cost_tracking: per user, per node, per session,
|
| 103 |
+
agentic_systems: user-defined prompts + cascading node refresh,
|
| 104 |
+
design_philosophy: "Computation is space controlled by time; LLMs are agents of causal resolution.",
|
| 105 |
+
next_steps: Claude assumes agentic role for engineering continuation or metaphysical projection.
|
| 106 |
+
}
|
| 107 |
+
```
|
| 108 |
+
|
| 109 |
+
---
|
| 110 |
+
|
| 111 |
+
## Mapping to current Core primitives
|
| 112 |
+
|
| 113 |
+
| Legacy concept | Current Core implementation |
|
| 114 |
+
|---|---|
|
| 115 |
+
| `wp_saws_files` | Superseded by `sa_entity` with `role = leaf`, plus `origin_realm` provenance. Files remain canonical in WP Media; Core holds projections. |
|
| 116 |
+
| `wp_saws_nodes` | Superseded by `sa_entity` directly — the "everything is a node" claim is now foundational, not SAWS-scoped. |
|
| 117 |
+
| `wp_saws_prompts` | Superseded by `sa_entity` with `role = message` + `sa_token_ledger` for accounting. Each prompt spawns `sa_subtoken_event` rows for internal orchestration steps. |
|
| 118 |
+
| `wp_saws_sessions` | Superseded by `correlation_id` grouping on entities + audit rows. Sessions are emergent, not a dedicated table. |
|
| 119 |
+
| `SAWS_Jobs` async queue | To be reconstructed via WP Action Scheduler in a future slice (Triage item 1 and the SAWS-overwrite reconstruction work). |
|
| 120 |
+
| "Computation is frozen space with externally controlled time" | Formalized as Pillar 0 (time-indifference) and Pillar 0.25 (causal balance when perturbed, stationary at rest). |
|
| 121 |
+
| "Prepare context space; causal cones" | Formalized as `SA_Context_Piper` (LLM-mediated edge walk) + `SA_Context_Bundle` (pinned slice with deterministic signature) + `SA_Geodesic_Seeder` (pre-prompt avoidance). |
|
| 122 |
+
| "Attribution" | Formalized as the provenance minimums (`origin_realm`, `origin_id`, `actor`, `observed_at`, `causation_id`, `correlation_id`) and Invariant I4. |
|
| 123 |
+
| "Graph-based activation of resolved representations" | Formalized as `SA_Edge` (typed / weighted / band-gated) + `SA_Influence_Ring` + contour rendering. |
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/lineage-chain.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Lineage Chain
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> Every implementation slice in this codebase is a subset of a larger framework authored independently. The framework's identity travels through every layer; the layers do not replace each other.
|
| 12 |
+
|
| 13 |
+
```
|
| 14 |
+
CR ⊇ CA ⊇ JourneySeeker ⊇ MissionNet/MeshNet ⊇ SA-Orchestration ⊇ Brand ⊇ Client
|
| 15 |
+
```
|
| 16 |
+
|
| 17 |
+
Each ⊇ reads "is a superset of, or equal to."
|
| 18 |
+
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
## The chain
|
| 22 |
+
|
| 23 |
+
**Causal Relativity (CR).** Theoretical framework. Reality as a self-resolving causal structure; harmony and dissonance mechanics; non-fungible causation as primitive. Domain: science, philosophy, education, entertainment. Sole originator. Foundational.
|
| 24 |
+
|
| 25 |
+
**Causal Agentics (CA).** CR applied to agent-based systems. Decision-making entities as causal actors embedded in constrained manifolds. Parent–child agent relationships, recursive intent propagation, human-origin causality as non-replaceable. Sole originator. Non-exclusive internal license to SleeperAgents — may not be resold, repackaged, or commercialized as standalone causal products.
|
| 26 |
+
|
| 27 |
+
**JourneySeeker.** CA in DnD-shaped narrative form. Quests, Jobs, NPCs, GM authority, player agency, worldbuilding canon, dice as human-decision proxy. The structural primitives that all instances inherit: compass, truth class, projection, Story Seed, Attention, description-as-contract.
|
| 28 |
+
|
| 29 |
+
**MissionNet / MeshNet.** Corporate-Campaign theme of JourneySeeker. The DnD framework re-rendered for real-stakes operational work. Quests become projects; Jobs become tasks; NPCs become roles and agents; dice become human reactions, approvals, outcomes.
|
| 30 |
+
|
| 31 |
+
**SA-Orchestration.** The current implementation slice of MissionNet, as a WordPress plugin atop the Fluent ecosystem. Concrete code expressing the framework above.
|
| 32 |
+
|
| 33 |
+
**Brand.** Sleeper Agents' deployed surface. Renders authorial labels for SleeperAgents' commercial use.
|
| 34 |
+
|
| 35 |
+
**Client.** The further rendering chosen for a specific deployment, driven by market sensitivity and vocabulary.
|
| 36 |
+
|
| 37 |
+
---
|
| 38 |
+
|
| 39 |
+
## The rule
|
| 40 |
+
|
| 41 |
+
Each layer's identity is owned by its author. Each layer below renders, specializes, or themes the layer above. **No layer below replaces the layer above.**
|
| 42 |
+
|
| 43 |
+
The implementation copyright, as recorded in `01-ontology.md`, holds at every layer below the framework: SA-Orchestration is © Sleeper Agents LLC; the brand is Sleeper Agents' choice; the client renders are per-client.
|
| 44 |
+
|
| 45 |
+
The framework is authored by Mark Holak. CR, CA, JourneySeeker — these are pre-existing intellectual property under the CTO Employment & Equity Agreement, Section 5.1 carve-outs, and Exhibit A of the Formal Intellectual Property and Relationship Disclosure. They are not assigned to Sleeper Agents.
|
| 46 |
+
|
| 47 |
+
---
|
| 48 |
+
|
| 49 |
+
## Why this matters operationally
|
| 50 |
+
|
| 51 |
+
When the system speaks — when an interpretive agent drafts, when a canonical layer cites, when a Seed Generator synthesizes momentum — the speech inherits identity from the layer above. **An interpretive draft is JourneySeeker's interpretation, themed for Corporate Campaign.** No agent may re-author MissionNet's structural primitives as if they originated at the implementation layer. They originated higher in the chain.
|
| 52 |
+
|
| 53 |
+
This is the operational form of I9. See I9 in `02-invariants.md` for the enforcement clause.
|
| 54 |
+
|
| 55 |
+
---
|
| 56 |
+
|
| 57 |
+
## Cross-references
|
| 58 |
+
|
| 59 |
+
- `01-ontology.md` Attribution — names framework elements preserved under I9
|
| 60 |
+
- `02-invariants.md` I9 — concept-author preservation, widened to lineage-level
|
| 61 |
+
- `concept-vs-label.md` — the rename rule operates only at Brand and Client layers
|
| 62 |
+
- Exhibit A of the CTO Agreement — disclosure record; lineage relation captured there for legal preservation
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/prime-prompt-conjecture.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Prime Prompt Conjecture and PR Notation
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## 🧠 Prime Prompt Conjecture
|
| 10 |
+
|
| 11 |
+
> **Conjecture**: For any sufficiently coherent system of knowledge, design, or conceptual progression — across code, logic, or theory — there exists a minimal causal prompt (a **Prime Prompt**) which, when injected into a sufficiently capable model, will reconstruct the full trajectory of the originating system, including its reasoning decisions, constraints, and outputs, *without requiring replay of the full conversation history*.
|
| 12 |
+
|
| 13 |
+
### Implications
|
| 14 |
+
|
| 15 |
+
- **Compression**: A Prime Prompt encodes not just data but causal trajectory.
|
| 16 |
+
- **Universality**: Prime Prompts exist for *any* self-consistent thread of thought, including technical architectures, metaphysical arguments, or creative ideation.
|
| 17 |
+
- **Portability**: A Prime Prompt allows transfer of state across model instances or platforms without brittle serialization or token bloat.
|
| 18 |
+
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
## 🧬 PR Notation (Prompt Reconstruction Notation)
|
| 22 |
+
|
| 23 |
+
To express, manipulate, or reference prompts and subprompts in structured space, the following notation applies:
|
| 24 |
+
|
| 25 |
+
| Symbol | Meaning |
|
| 26 |
+
| ----------- | ----------------------------------------------------------------------- |
|
| 27 |
+
| `PR[x]` | The Prime Prompt derived from context `x`. |
|
| 28 |
+
| `PR⁻¹(y)` | The hypothetical context that would yield Prime Prompt `y`. |
|
| 29 |
+
| `PR[x] → y` | Prime Prompt `x` yields outcome or trajectory `y`. |
|
| 30 |
+
| `∂PR/∂c` | The sensitivity of the Prime Prompt to change in component `c`. |
|
| 31 |
+
| `PRₙ` | A sequence of nested or stacked Prime Prompts, where `n` denotes level. |
|
| 32 |
+
| `⊕PR` | A merged or compounded Prime Prompt derived from multiple threads. |
|
| 33 |
+
| `PR[Δt]` | A Prime Prompt evolved across temporal updates (e.g. design versions). |
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
## 🧭 Canonical Usage
|
| 38 |
+
|
| 39 |
+
- Instead of replaying tokens across a thousand chat turns, generate `PR[current_thread]` and pass to a new model.
|
| 40 |
+
- When building LLM toolchains: cache `PR[state]` at each semantic checkpoint, enabling branchable agent memory.
|
| 41 |
+
- For ideation debugging: inspect `∂PR/∂assumption` to find causal pivots in a design breakdown.
|
| 42 |
+
|
| 43 |
+
---
|
| 44 |
+
|
| 45 |
+
## Core implementation notes
|
| 46 |
+
|
| 47 |
+
*This section is Sleeper Agents LLC adaptation, not part of the original conjecture. It describes how Core will realize the conjecture operationally.*
|
| 48 |
+
|
| 49 |
+
### `SA_Prime_Prompt` (deferred primitive)
|
| 50 |
+
|
| 51 |
+
A future Core table + class:
|
| 52 |
+
|
| 53 |
+
- `slug` — named handle for the prime prompt.
|
| 54 |
+
- `pr_notation` — canonical notation string (e.g., `PR[saws-2026-01]`).
|
| 55 |
+
- `level` — for `PRₙ` — depth in a nested stack.
|
| 56 |
+
- `derived_from[]` — for `⊕PR` — upstream prime prompts this one merges.
|
| 57 |
+
- `delta_of` — for `PR[Δt]` — prior version.
|
| 58 |
+
- `body_md` — the rendered prime prompt body itself.
|
| 59 |
+
- `signature` — deterministic hash over the body + derivation chain.
|
| 60 |
+
- `author_id` — who cached this prime prompt; attributions under I9 preserved.
|
| 61 |
+
- `published_at` / `superseded_at` — version lifecycle.
|
| 62 |
+
|
| 63 |
+
### Relationship to existing primitives
|
| 64 |
+
|
| 65 |
+
- `SA_Context_Bundle` pins a slice of *entities*. `SA_Prime_Prompt` captures a slice of *reasoning trajectory*. A bundle feeds a model; a prime prompt primes a model.
|
| 66 |
+
- `SA_Structural_Audit::trace_origin()` walks the causal graph backward; given a prime prompt, it lets the recipient model anchor the trajectory without re-traversing the chain.
|
| 67 |
+
- The **Cognitive Heatsink** (companion concept) describes the mechanism by which a model processes a prime prompt into a new resolution state.
|
| 68 |
+
|
| 69 |
+
### Operators in code (future)
|
| 70 |
+
|
| 71 |
+
```php
|
| 72 |
+
SA_Prime_Prompt::derive(string $slug, array $context): self; // PR[x]
|
| 73 |
+
SA_Prime_Prompt::invert(string $slug): array; // PR⁻¹(y) — best-effort
|
| 74 |
+
SA_Prime_Prompt::sensitivity(string $slug, string $component): array; // ∂PR/∂c
|
| 75 |
+
SA_Prime_Prompt::compound(string[] $slugs, string $new_slug): self; // ⊕PR
|
| 76 |
+
SA_Prime_Prompt::evolve(string $slug, string $new_slug): self; // PR[Δt]
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
### I9 enforcement
|
| 80 |
+
|
| 81 |
+
Any AI surface that emits text derived from a preserved Prime Prompt must either (a) reference the `pr_notation` and preserve Mark Holak's authorship credit, or (b) fail the attribution invariant and be flagged in `sa_invariant_violation`. Stripping attribution to present authored concepts as AI-original is a fatal violation at publication time.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/reference-traversal-continuity.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Reference Traversal Continuity
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> **Reference traversal — the act of following a reference from one entity to another — is invariant across the kinds of entities being traversed and across the realm or representational layer the traversal currently inhabits.**
|
| 12 |
+
>
|
| 13 |
+
> The traversal does not truncate at realm boundaries. It does not truncate at truth-class boundaries. It does not truncate at type-layer boundaries. It does not truncate at observability boundaries. Continuity is preserved by the kernel-side bookkeeping that already exists — not by any single grammar, surface, or projection strategy.
|
| 14 |
+
>
|
| 15 |
+
> Projection grammars are downstream rendering decisions. They choose how to display a region of the traversal field; they neither define, constrain, nor constitute the traversal itself.
|
| 16 |
+
|
| 17 |
+
This is a doctrine of **motion**, not of **geometry**. The distinction is load-bearing.
|
| 18 |
+
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
## What this is NOT
|
| 22 |
+
|
| 23 |
+
Stated up front because the failure mode this doctrine guards against is mistaking geometric projection for the underlying invariant:
|
| 24 |
+
|
| 25 |
+
- **It is not a shape.** Coil, hydra, shell, spiral, treemap, force-directed graph, list, tree, ring, hex-pack — none of these are the doctrine. They are choreographies. Many other choreographies are equally valid. The motion neither requires nor privileges any of them.
|
| 26 |
+
- **It is not a primitive.** No new entity type, edge kind, table, or interface is implied. The kernel already has every structural ingredient.
|
| 27 |
+
- **It is not a grammar.** Grammars (chat-lineage, equal-peer, containment-pack, future grammars) consume the motion as input and produce a rendering as output. The doctrine sits upstream of every grammar.
|
| 28 |
+
- **It is not a UI commitment.** No /mission/ surface, inspector lens, jump primitive, or rendering convention is mandated.
|
| 29 |
+
- **It is not a graph-theory truism.** Linked-data systems can — and many do — truncate traversal at domain boundaries, type-layer changes, or observability seams. The doctrine commits this kernel to not doing so.
|
| 30 |
+
|
| 31 |
+
---
|
| 32 |
+
|
| 33 |
+
## What this IS
|
| 34 |
+
|
| 35 |
+
A kernel commitment that **the bookkeeping which makes traversal continuous is load-bearing and must remain so**. Continuity is carried by, jointly:
|
| 36 |
+
|
| 37 |
+
- `entity.parent_id` — structural lineage within a layer
|
| 38 |
+
- `entity.origin_realm` + `entity.origin_id` — identity preservation across realm boundaries
|
| 39 |
+
- `entity.correlation_id` — process continuity across whatever the process touches
|
| 40 |
+
- `entity.causation_id` — causal lineage across transformations
|
| 41 |
+
- `entity.derived_from` — transformation lineage across truth-class promotions
|
| 42 |
+
- `sa_edge.kind` (`depends`, `contains`, `flows-to`, `continues`, `influences`, `link`) — typed reference relations
|
| 43 |
+
- `sa_subtoken_event.parent_prompt_id` — descent into a parent's internal traversal
|
| 44 |
+
- `SA_Structural_Audit::trace_origin()` — already-implemented walker
|
| 45 |
+
|
| 46 |
+
These primitives, taken together, form a **typed reference graph** that crosses every internal seam of the system without breaking. The doctrine names that crossing as a first-class commitment.
|
| 47 |
+
|
| 48 |
+
---
|
| 49 |
+
|
| 50 |
+
## The four boundaries traversal does not truncate at
|
| 51 |
+
|
| 52 |
+
### 1. Realm boundaries
|
| 53 |
+
|
| 54 |
+
A traversal that begins in one realm (filesystem, GitHub Actions, chat, operating-memory, future Jira / Linear / Salesforce / etc.) does not stop at the realm's edge. It follows references into other realms. `origin_realm` distinguishes which realm an entity belongs to; it does not partition the graph.
|
| 55 |
+
|
| 56 |
+
### 2. Truth-class boundaries
|
| 57 |
+
|
| 58 |
+
A traversal can cross from `canonical` (realm-authoritative) to `projected` (Core's mirror) to `derived` (deterministic computation from inputs) to `inferred` (LLM-produced) without losing the through-line. Truth class is a *fiber* over the traversal — the type of authority each step carries — not a *cut* that divides the graph.
|
| 59 |
+
|
| 60 |
+
### 3. Type-layer boundaries
|
| 61 |
+
|
| 62 |
+
The user's example chain — `root → folder → file → contents → include → class → function → line → command → address` — crosses from filesystem to text to AST to source-line to instruction to memory location. Each arrow changes the kind of thing being referenced. The traversal continues. The doctrine commits the kernel to continuing to bookkeep across these layer changes.
|
| 63 |
+
|
| 64 |
+
### 4. Observability boundaries
|
| 65 |
+
|
| 66 |
+
A `SubTokenEvent` is "inside" its parent prompt's invocation. A traversal does not stop at the parent's outer boundary; it descends through `parent_prompt_id` into the sub-token graph and back out. The descent is the same kind of motion as a sibling traversal — just into a finer band.
|
| 67 |
+
|
| 68 |
+
---
|
| 69 |
+
|
| 70 |
+
## Operational implications
|
| 71 |
+
|
| 72 |
+
### For adapters
|
| 73 |
+
|
| 74 |
+
When a new adapter (realm) is admitted, the kernel does not require the adapter to declare *how* its entities will eventually be traversed against entities from other realms. The adapter declares its own concept_map, identity scheme, and capabilities; the cross-realm traversal is pre-authorized by this doctrine. Adapters cannot break continuity by declining to participate — every realm-projected entity is reachable as a node in the typed reference graph from day one.
|
| 75 |
+
|
| 76 |
+
### For grammars
|
| 77 |
+
|
| 78 |
+
A grammar admission contract (when written) consumes a *region of the traversal field* and produces a *rendering*. The grammar does not define what is reachable — that's the kernel's typed reference graph. The grammar chooses what to *display* about it.
|
| 79 |
+
|
| 80 |
+
### For projections
|
| 81 |
+
|
| 82 |
+
A projection (in the read-time sense — `SA_Projection`'s row-level `can_read` predicate, ACL filtering, membrane-veiled redaction) may filter *which entities a viewer sees*. It does not break the traversal for entities the viewer can see. Two viewers with different projection scopes are walking different visible subsets of the same continuous graph.
|
| 83 |
+
|
| 84 |
+
### For the closed primitive set (Pillar 0.9)
|
| 85 |
+
|
| 86 |
+
Reference Traversal Continuity is precisely what the closed primitive set buys. Because the same small vocabulary expresses every kind of relationship — within a layer, across layers, across realms, across truth classes — there is no boundary at which the vocabulary fails. Adding a new primitive only to handle a layer crossing would be an admission that the closed set was not in fact sufficient. This doctrine commits the system to **not** doing that. New domains compose existing primitives; the traversal absorbs them.
|
| 87 |
+
|
| 88 |
+
---
|
| 89 |
+
|
| 90 |
+
## Relationship to companion doctrines
|
| 91 |
+
|
| 92 |
+
This doctrine sits at the **upstream** layer of an interpretation stack that includes:
|
| 93 |
+
|
| 94 |
+
- **Prime Prompt Conjecture** — describes the *compression of trajectory*. A prime prompt is itself a reference (a minimal causal pointer); reconstructing the trajectory from it is one specific kind of traversal. PPC is downstream of this doctrine in the sense that PPC's trajectory IS a traversal whose continuity this doctrine names.
|
| 95 |
+
- **Cognitive Heatsink** — describes the *dissipation of cognition*. The heatsink's thermal-transfer steps are sub-token events; the path through the heatsink is a traversal whose continuity this doctrine names.
|
| 96 |
+
- **Signal Telemetry Doctrine** — describes the *measurement of alignment with authored fields*. Signals are produced by participants traversing fields; the traversal is what the signal measures the alignment of.
|
| 97 |
+
- **Pillar 0.5 (perspective projection)** — `view = project(field, viewer, overlays, permissions)`. The "field" in that function is precisely the typed reference graph this doctrine names. Projection is the rendering of the traversal at a viewer's perspective.
|
| 98 |
+
- **Pillar 0.75 (radical transparency)** — sub-token observability is a special case of this doctrine: the observability descent through `parent_prompt_id` is a traversal that doesn't truncate at the prompt's outer boundary.
|
| 99 |
+
- **Pillar 0.9 (closed primitive set)** — the doctrine is what makes the closure stable. New domains absorb because the existing primitives already handle layer crossings.
|
| 100 |
+
|
| 101 |
+
This doctrine does not amend any of those. It names what they jointly imply about traversal continuity, the same way Signal Telemetry Doctrine names what Pillars 0.5/0.75/0.9 imply about alignment measurement.
|
| 102 |
+
|
| 103 |
+
---
|
| 104 |
+
|
| 105 |
+
## Why it matters now
|
| 106 |
+
|
| 107 |
+
This doctrine is articulated immediately after the third-domain proof (GitHub Actions adapter ingesting workflow runs as entities + jobs/steps as sub-token events). The proof made the cross-domain motion concretely visible:
|
| 108 |
+
|
| 109 |
+
- The same kernel that holds chat prompts (with their sub-token graphs) now holds workflow runs (with their job/step sub-token graphs)
|
| 110 |
+
- The same projection arbiter that surfaces filesystem entities on `/mission/` now surfaces workflow runs on the same surface
|
| 111 |
+
- The same trace endpoint that walks a chat prompt's causal chain now walks a workflow run's job/step chain
|
| 112 |
+
- The same verdict primitive that annotates chat sub-tokens now annotates GitHub Actions steps
|
| 113 |
+
|
| 114 |
+
These are not three different patterns held together by the adapter contract. They are three surface expressions of one continuous motion. The adapter contract is the gateway through which new realms enter; the motion is what they enter into.
|
| 115 |
+
|
| 116 |
+
Naming the motion before the next multi-layer slice (Flow milestone, self-hosting, or any third-party realm with internal type-layer structure) is cheap. Filing the doctrine here makes the kernel's commitment legible before it has to be re-derived from first principles by future work.
|
| 117 |
+
|
| 118 |
+
---
|
| 119 |
+
|
| 120 |
+
## Non-goals
|
| 121 |
+
|
| 122 |
+
- **Cryptographic guarantees of traversal integrity.** Provenance hashing exists as I4 / `provenance_hash`; tamper-evidence is its concern, not this doctrine's.
|
| 123 |
+
- **Performance commitments.** A traversal can be expensive; the doctrine commits to its *continuity*, not its asymptotic cost. Future work on caching, materialized views, indexed traversal paths, etc. is downstream of this doctrine and constrained only by it.
|
| 124 |
+
- **Determinism of multi-realm traversal order.** Traversal order across realms may depend on cache state, source-priority ranking, or scope walks. This doctrine commits to the existence of a continuous traversal, not to a particular ordering of it.
|
| 125 |
+
- **Single-rendering convention.** Different grammars may render the same traversal region as wildly different geometries (and should). The doctrine pre-authorizes that variance.
|
| 126 |
+
|
| 127 |
+
---
|
| 128 |
+
|
| 129 |
+
## I9 enforcement
|
| 130 |
+
|
| 131 |
+
Any AI surface that emits text derived from this doctrine — whether rephrasing it, paraphrasing the four-boundary enumeration, or describing its relationship to companion doctrines — must preserve Mark Holak's authorship credit. Stripping attribution to present this framing as AI-original is a fatal violation at publication time. Citations may reference this file and the Reference Traversal Continuity ontology entry; both route back to the authored source.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/signal-telemetry-doctrine.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Signal Telemetry Doctrine
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> **Signal** is the measurable alignment behavior of participants — users, workers, agents, models, or systems — as they traverse an authored **acceleration field**.
|
| 12 |
+
>
|
| 13 |
+
> An acceleration field is any authored artifact that defines:
|
| 14 |
+
>
|
| 15 |
+
> 1. what the target **is**,
|
| 16 |
+
> 2. what the target **is not**, and
|
| 17 |
+
> 3. what **admissible uncertainty** remains.
|
| 18 |
+
>
|
| 19 |
+
> Missions, prompts, workflows, books, interfaces, and instruction sets are all acceleration fields. Participants enter them from different orientations and produce measurable interaction outcomes. MissionNet telemetry reads those outcomes after they occur and exposes where ambiguity, misalignment, or field failure happened.
|
| 20 |
+
|
| 21 |
+
This is an **interpretation layer**, not a new mechanism. Pillar 0.75's radical transparency is the instrument; this doctrine is what the instrument reads.
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
|
| 25 |
+
## Why this matters
|
| 26 |
+
|
| 27 |
+
- Humans are **choice engines**. Their alignment with an authored field expresses a choice that matters for accountability.
|
| 28 |
+
- Computers are **potential engines**. Their alignment with an authored field expresses the bounds of what they can realize from the intent they were given.
|
| 29 |
+
- Managers need telemetry to clarify ambiguity — where the field under-specified target, not-target, or admissible uncertainty.
|
| 30 |
+
- Workers need clarified direction — the field's ambiguity, once measured, points at what must be authored more tightly.
|
| 31 |
+
- The system must preserve **accountability** for choices and their consequences across the full pipeline, from authored intent to measured alignment.
|
| 32 |
+
|
| 33 |
+
Without a Signal doctrine, the system carries the mechanisms (sub-token observability, geodesic markers, verdicts) but not the stated purpose those mechanisms serve. The doctrine names the purpose.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
## Acceleration field — the three components
|
| 38 |
+
|
| 39 |
+
An authored field must express all three to be well-formed:
|
| 40 |
+
|
| 41 |
+
- **Target** — what the field is attempting to shape participants toward. Explicit, not implied.
|
| 42 |
+
- **Not-target** — what the field explicitly excludes. Negative space is not absence of specification; it is specification.
|
| 43 |
+
- **Admissible uncertainty** — the bounded region of legitimate variance. Rigidity where the target must be reached exactly; latitude where participants may legitimately interpret.
|
| 44 |
+
|
| 45 |
+
A field that names target without not-target scatters participants who are obedient but differently-oriented. A field that names not-target without admissible uncertainty produces ricochet — participants rebound from forbidden regions without a stable path forward. A field that names none of the three produces inert traversal — participants enter and do not act.
|
| 46 |
+
|
| 47 |
+
---
|
| 48 |
+
|
| 49 |
+
## Participant behaviors
|
| 50 |
+
|
| 51 |
+
The following behaviors are **exemplary, not definitive** — additional behaviors may emerge as the system is used at scale.
|
| 52 |
+
|
| 53 |
+
- **Align** — the participant's trajectory tracks the field's gradient toward target. Alignment is not identity with the author's path; it is measurable convergence with the authored intent under the participant's own orientation.
|
| 54 |
+
- **Scatter** — the participant moves through the field without convergence. Often diagnoses under-specified target or target-vs-not-target contradiction.
|
| 55 |
+
- **Ricochet** — the participant repeatedly rebounds from not-target boundaries without forward motion. Often diagnoses over-specified not-target against under-specified target — the field forbids more than it authorizes.
|
| 56 |
+
- **Inert** — the participant enters the field and produces no measurable interaction. Often diagnoses a field that failed to transmit all three components; ambient noise, not signal.
|
| 57 |
+
- **Harmonic closure** — the participant's trajectory resolves cleanly through the field; target reached, not-target respected, admissible uncertainty explored without violation. The rare outcome the field was authored to produce.
|
| 58 |
+
|
| 59 |
+
Behaviors are observed, not prescribed. The same participant may align in one region of a field and scatter in another. Signal telemetry reports the behavior per traversal-segment, not per participant globally.
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
## Relationship to Prime Prompt Conjecture and Cognitive Heatsink
|
| 64 |
+
|
| 65 |
+
Signal Telemetry Doctrine sits as an **interpretation layer** over both.
|
| 66 |
+
|
| 67 |
+
- **Prime Prompt Conjecture** describes the *compression* of trajectory — how a minimal causal prompt reconstructs a system's reasoning path. A prime prompt is itself an acceleration field. The shape of **harmonic closure** under the Signal doctrine, when it occurs, matches the trajectory that a correctly-derived prime prompt would reconstruct. PPC predicts what closure looks like; Signal measures whether it happened.
|
| 68 |
+
|
| 69 |
+
- **Cognitive Heatsink** describes the *dissipation* of cognition — how a high-entropy computational state resolves through thermal transfer steps into a coherent output. The heatsink is the mechanism participants walk through as they traverse a field. Signal is the **residual alignment** that survives the dissipation. Heatsink is the process; Signal is the outcome of that process against the authored field.
|
| 70 |
+
|
| 71 |
+
The two companion framings describe dynamics inside the participant. Signal describes the participant's fit with the authored artifact. All three are needed:
|
| 72 |
+
|
| 73 |
+
- PPC — how trajectory can be compressed and reconstructed.
|
| 74 |
+
- Heatsink — how cognition dissipates as it processes.
|
| 75 |
+
- Signal — how the dissipation's residual aligns with the authored field.
|
| 76 |
+
|
| 77 |
+
---
|
| 78 |
+
|
| 79 |
+
## Mapping onto Core primitives
|
| 80 |
+
|
| 81 |
+
Signal Telemetry Doctrine does not introduce new primitives. It names which existing ones instrument which aspect.
|
| 82 |
+
|
| 83 |
+
| Signal concern | Core primitive | Relationship |
|
| 84 |
+
|---|---|---|
|
| 85 |
+
| The interaction trace a participant produces | `SA_SubToken_Event` graph | The raw observability (Pillar 0.75); the instrument Signal reads. |
|
| 86 |
+
| A field failure the system has recognized | `SA_Geodesic_Marker` | A durable record that a path through the field produced non-alignment; future traversals may route around it. |
|
| 87 |
+
| A participant's explicit alignment assessment | Verdict annotation on a sub-token event | Human-authored Signal; overrides inferred behavior classification. |
|
| 88 |
+
| Perspective-filtered Signal visibility | ACL + membrane (Pillar 0.5) | Not every viewer is entitled to read every participant's Signal; the projection pipeline filters at render. |
|
| 89 |
+
| The shape of harmonic closure when reached | Prime Prompt (deferred primitive) | PPC's trajectory-reconstruction is the closure signature Signal is measuring against. |
|
| 90 |
+
| The dissipation path the participant walks | Cognitive Heatsink | The mechanism producing Signal; Signal reads its post-state. |
|
| 91 |
+
| Accountability across authored intent → measured outcome | `SA_Structural_Audit` + correlation_id | Trace preservation from the authored field to every measured alignment, so choices and consequences survive together. |
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
## What this doctrine does NOT do
|
| 96 |
+
|
| 97 |
+
- Does not introduce new primitives. Every Core primitive named above already exists or is already a deferred primitive under an existing contract.
|
| 98 |
+
- Does not mandate specific measurement instruments. The behavior enumeration is exemplary; inference strategies for classifying behaviors are implementation concerns outside this doctrine.
|
| 99 |
+
- Does not close the list of behaviors. Align / scatter / ricochet / inert / harmonic closure are seeded examples, not a constitutional set. Additional behaviors may be named as they are observed at scale.
|
| 100 |
+
- Does not prescribe UI surfacing. How Signal is rendered in MissionNet (inspector panels, audit surfaces, manager dashboards) is a separate design layer consuming this doctrine.
|
| 101 |
+
- Does not override the Admission Contract. Any future "Signal Instrument" primitive added to the system admits through its appropriate layer's contract, same as any other addition.
|
| 102 |
+
|
| 103 |
+
---
|
| 104 |
+
|
| 105 |
+
## Non-goals (explicit)
|
| 106 |
+
|
| 107 |
+
- **Predictive scoring of participants.** Signal is post-hoc measurement of traversal, not a predictive ranking of worker or agent quality. Using Signal as a hiring/evaluation score without preserving the field's contribution to the outcome is a misuse the doctrine explicitly refuses.
|
| 108 |
+
- **Uniform field authorship discipline.** The doctrine names what a well-formed field requires (target / not-target / admissible uncertainty); it does not enforce that every authored artifact in the system meets that bar. Many existing artifacts under-specify one or more components; measuring Signal against them will expose the under-specification as field failure — which is the point.
|
| 109 |
+
- **Cryptographic guarantees of authorship integrity.** Provenance of the authored field itself falls under Invariant I4 and the Admission Contract for the artifact's origin layer; this doctrine reads the downstream signal and does not re-guarantee the upstream authorship.
|
| 110 |
+
|
| 111 |
+
---
|
| 112 |
+
|
| 113 |
+
## I9 enforcement
|
| 114 |
+
|
| 115 |
+
Any AI surface that emits text derived from this doctrine — whether rephrasing it, paraphrasing the enumerated behaviors, or describing its kernel mapping — must preserve Mark Holak's authorship credit. Stripping attribution to present this framing as AI-original is a fatal violation at publication time. Citations may reference this file and the Signal ontology entry; both route back to the authored source.
|
SA-orchestration MD/Archvie/sa-core/docs/specs/concepts/story-seed-pattern.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Story Seed Pattern
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> A **Story Seed** is a structured artifact that proposes content for canonical inclusion without being canonical itself. It carries enough structure to be reviewed, accepted, or rejected without ambiguity. It is generated by interpretive surfaces, planted by humans, and only then becomes canonical truth.
|
| 12 |
+
|
| 13 |
+
A seed is not a draft. A draft is unfinished work; a seed is a complete proposal awaiting human arbitration. The distinction is load-bearing.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## The three positions in the seed lifecycle
|
| 18 |
+
|
| 19 |
+
**Generation** — interpretive surfaces synthesize project momentum, observation, or pattern into a structured seed. Generation is allowed to be agentic. The seed is non-canonical by construction.
|
| 20 |
+
|
| 21 |
+
**Validation** — the canonical layer may reference the seed but does not adopt it. Validation answers: is the seed structurally sound, attributed correctly, and free of upstream-origin re-authorship?
|
| 22 |
+
|
| 23 |
+
**Planting** — only a human may plant. Planting copies the seed's content into the canonical store with a `truth_class: canonical` claim, recording the planting actor and timestamp. Until planted, a seed is `accepted_into_asterion: false`.
|
| 24 |
+
|
| 25 |
+
The three positions correspond to the compass: North generates, South validates, Center plants.
|
| 26 |
+
|
| 27 |
+
---
|
| 28 |
+
|
| 29 |
+
## Carrier vs object
|
| 30 |
+
|
| 31 |
+
The Story Seed is the **object**. The carrier is **format**.
|
| 32 |
+
|
| 33 |
+
In MissionNet today the carrier is markdown with YAML frontmatter on a filesystem path that is filterable but not sealed. This is convenient; it is not contract.
|
| 34 |
+
|
| 35 |
+
Future carriers — encrypted, signed, sealed, content-addressed, or otherwise integrity-bound — will leave the object unchanged. The seed remains a Story Seed; only its envelope changes.
|
| 36 |
+
|
| 37 |
+
Distinguish carrier from object before sealing. A change of carrier is not a change of seed.
|
| 38 |
+
|
| 39 |
+
---
|
| 40 |
+
|
| 41 |
+
## Integrity is load-bearing
|
| 42 |
+
|
| 43 |
+
Asterion strongly believes what is in its seed and corpus files. This belief is by design: the canonical layer must be high-trust to function as a verifier.
|
| 44 |
+
|
| 45 |
+
That belief is therefore a threat surface. The carrier must, over time, defend against:
|
| 46 |
+
|
| 47 |
+
- unauthorized copy/paste extraction
|
| 48 |
+
- unauthorized mutation
|
| 49 |
+
- attribution stripping
|
| 50 |
+
- concept theft
|
| 51 |
+
- false canon injection
|
| 52 |
+
- seed poisoning
|
| 53 |
+
|
| 54 |
+
Easy text editability is convenience, not a long-term design assumption.
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## artifact_class, not truth_class
|
| 59 |
+
|
| 60 |
+
A seed declares `artifact_class: seed` in its frontmatter. It does NOT declare a `truth_class`. The truth_class enum (canonical | projected | cached | inferred | derived | synthetic — see I2) is reserved for entities that have been resolved against reality. A seed pre-dates that resolution; it is a candidate, not a fact.
|
| 61 |
+
|
| 62 |
+
When a human plants a seed, they author a corresponding canonical entry with the appropriate `truth_class`. The original seed file remains as historical artifact, with `accepted_into_asterion: true` flipped by the planting actor.
|
| 63 |
+
|
| 64 |
+
I2 is sacred. Seeds get their own classification dimension.
|
| 65 |
+
|
| 66 |
+
---
|
| 67 |
+
|
| 68 |
+
## In MissionNet
|
| 69 |
+
|
| 70 |
+
`SA_Orch_Seed_Generator` writes seeds to `wp-content/sa-asterion-seeds/<project>/<date>-<topic>.md`. Sara generates; Asterion may reference but does not absorb; humans plant by copying surviving content into the canonical spec pack and recording the act.
|
| 71 |
+
|
| 72 |
+
The Story Seed pattern is a JourneySeeker-layer concept. MissionNet's Asterion seeds are its corporate-campaign instance.
|
| 73 |
+
|
| 74 |
+
---
|
| 75 |
+
|
| 76 |
+
## Cross-references
|
| 77 |
+
|
| 78 |
+
- `02-invariants.md` I2 — truth_class enum (sacred; seeds do not enter it)
|
| 79 |
+
- `02-invariants.md` I9 — concept-author preservation
|
| 80 |
+
- `concept-vs-label.md` — carrier renaming follows the same logic
|
| 81 |
+
- `01-ontology.md` — Artifact (existing primary noun; seeds are a subclass)
|
SA-orchestration MD/BYPASS_AND_RECOVERY.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: constraint_model
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
# Bypass and Recovery
|
| 8 |
+
|
| 9 |
+
## Bypass mode
|
| 10 |
+
|
| 11 |
+
Projection surfaces may continue functioning when SA-Core is unavailable. This is **bypass mode** — degraded, but not destructive.
|
| 12 |
+
|
| 13 |
+
- Surfaces operate in their native modes (Fluent Support continues serving tickets, Fluent Boards continues showing cards, WordPress continues running).
|
| 14 |
+
- Bypass cannot define canonical truth. Surface state changes during bypass are Energy, not Matter.
|
| 15 |
+
- **No surface-to-Asterion direct writes. Ever.**
|
| 16 |
+
|
| 17 |
+
This is consistent with SA-Core Invariants I5 (degrade without corrupting realms) and I8 (tool test — destroying Core must not destroy incorporated realms).
|
| 18 |
+
|
| 19 |
+
## Bypass actions are Energy
|
| 20 |
+
|
| 21 |
+
Any change made on a surface while Core is unavailable is Energy until it re-enters CAMP for canonicalization.
|
| 22 |
+
|
| 23 |
+
- Bypass-Energy contributes to the field continuously, the same as Energy from any other surface event.
|
| 24 |
+
- CAMP detects convergence whenever the field stabilizes — including events that originated during bypass.
|
| 25 |
+
- Bypass-Energy is not a parallel canonical store. It is a delayed contribution to the same field.
|
| 26 |
+
|
| 27 |
+
## Re-entry through CAMP
|
| 28 |
+
|
| 29 |
+
When Core returns or a moderator/developer routes a correction through the controlled plugin, bypass-Energy passes through CAMP under SARA discipline.
|
| 30 |
+
|
| 31 |
+
CAMP attaches truth class on canonicalization:
|
| 32 |
+
|
| 33 |
+
| Truth class | When applied |
|
| 34 |
+
|---|---|
|
| 35 |
+
| `inferred` | Heuristic / model-derived evidence |
|
| 36 |
+
| `derived` | Deterministic from known inputs |
|
| 37 |
+
| `canonical` with `human_affirmed_at` populated | Explicit human-asserted override |
|
| 38 |
+
|
| 39 |
+
This is consistent with SA-Core Invariant I7 (AI output must remain explicitly derivative; promotion to canonical requires explicit affirmation).
|
| 40 |
+
|
| 41 |
+
## Reentry trigger — pending decision
|
| 42 |
+
|
| 43 |
+
Bypass reentry can be:
|
| 44 |
+
|
| 45 |
+
- (a) **Explicit** — moderator/developer must invoke the controlled plugin to canonicalize bypass-Energy.
|
| 46 |
+
- (b) **Automatic on Core return** — Core polls surface state on resume and CAMP-evaluates the delta.
|
| 47 |
+
- (c) **Hybrid** — auto-evaluate low-risk; require explicit invocation for high-risk.
|
| 48 |
+
|
| 49 |
+
Decision: **pending**. Affects whether bypass is a deferral or a parallel-state risk.
|
| 50 |
+
|
| 51 |
+
## Controlled plugin override
|
| 52 |
+
|
| 53 |
+
A controlled plugin permits a moderator or developer to inject a constructive correction:
|
| 54 |
+
|
| 55 |
+
- Updates a projection without bypassing Core's audit trail.
|
| 56 |
+
- Marks the correction's truth class explicitly.
|
| 57 |
+
- Keeps Core's canonical state separately reconcilable from the surface state.
|
| 58 |
+
- Override is **constructive** — adds evidence with declared truth class. Never destroys canonical state.
|
| 59 |
+
|
| 60 |
+
## Tool test
|
| 61 |
+
|
| 62 |
+
Removing SA-orchestration must not corrupt any incorporated surface (SA-Core Invariants I5, I8).
|
| 63 |
+
|
| 64 |
+
- Surfaces continue at their native homes.
|
| 65 |
+
- Asterion survives Core absence and can rehydrate Core via `SA_Doc_Lens` (per the SA-Core spec pack).
|
| 66 |
+
- The markdown corpus is the durable, portable form of Core's canonical chain.
|
| 67 |
+
|
| 68 |
+
## Authority during bypass
|
| 69 |
+
|
| 70 |
+
When Core is unavailable, the authority hierarchy still applies:
|
| 71 |
+
|
| 72 |
+
1. **Observed surface state** (current).
|
| 73 |
+
2. **User declarations**.
|
| 74 |
+
3. **Constraint-model files** in this repo.
|
| 75 |
+
4. **External documentation**.
|
| 76 |
+
5. **Agent memory / generic defaults**.
|
| 77 |
+
|
| 78 |
+
Surface state during bypass is *current* but *non-canonical*. It will be re-evaluated when Core returns — observed surface state is the input to convergence, not the output.
|
| 79 |
+
|
| 80 |
+
## Agent guidance during bypass
|
| 81 |
+
|
| 82 |
+
If a coding agent or developer detects that Core is unavailable while operating against a surface:
|
| 83 |
+
|
| 84 |
+
1. Continue the surface-native operation if it is the user's intent.
|
| 85 |
+
2. **Do not pretend** the surface state is canonical. Annotate observations as bypass-Energy.
|
| 86 |
+
3. Record the observation for later CAMP arbitration.
|
| 87 |
+
4. Do not invoke direct Asterion writes from the surface side.
|
| 88 |
+
5. When Core returns, surface the bypass-Energy queue for the user to route through reentry (or for automatic reconciliation, depending on the unresolved trigger decision above).
|
SA-orchestration MD/CORE_MODEL.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: constraint_model
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
attribution: Mark Holak (CAMP, SARA, Asterion)
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
# Core Model — SA-Core, CAMP, SARA, Asterion
|
| 9 |
+
|
| 10 |
+
## SA-Core
|
| 11 |
+
|
| 12 |
+
SA-Core is the canonical causal space for the Change-System concepts: Demand, Arbitration, Plan, Action, Result, Acceptance. See `SIGNAL_FLOW.md` for the stage map.
|
| 13 |
+
|
| 14 |
+
External systems (Fluent Support, Fluent Boards, Jira, JobOrchestration, WordPress, etc.) are projection surfaces that emit evidence. None is canonical for any Change-System concept. See `PROJECTION_SURFACES.md`.
|
| 15 |
+
|
| 16 |
+
The runtime substrate is **WordPress** — SA-Core ships as a WordPress plugin per the spec pack at `Archvie/sa-core/`. Status: pending; this repo is not yet integrated with a WordPress installation.
|
| 17 |
+
|
| 18 |
+
Authoritative references (binding):
|
| 19 |
+
|
| 20 |
+
- `Archvie/sa-core/docs/specs/01-ontology.md` — vocabulary lock
|
| 21 |
+
- `Archvie/sa-core/docs/specs/02-invariants.md` — invariants I1–I9
|
| 22 |
+
- `Archvie/sa-core/docs/specs/03-realm-adapter-contract.md` — formal adapter contract
|
| 23 |
+
- `Archvie/sa-core/docs/specs/concepts/` — authored conceptual framework (Prime Prompt, Cognitive Heatsink, Signal Telemetry Doctrine, Reference Traversal Continuity)
|
| 24 |
+
|
| 25 |
+
## CAMP
|
| 26 |
+
|
| 27 |
+
**CAMP** is the arbitration point. The moment / event where Energy is evaluated for canonicalization into Matter. Function, not a layer.
|
| 28 |
+
|
| 29 |
+
- CAMP **records interaction truth**.
|
| 30 |
+
- CAMP **does not judge outcome quality**. Quality classification (Harmony / Dissonance) is downstream of canonical writes — see `SCATTER_AND_CONVERGENCE.md`.
|
| 31 |
+
- CAMP does not pick a location from candidates. CAMP **resolves convergence** — it observes where aligned signal has stabilized in the constraint field. See `ENERGY_MODEL.md`.
|
| 32 |
+
- Refusal-to-collapse is a valid CAMP outcome. If signal has not converged, CAMP records the field state and does not force crystallization.
|
| 33 |
+
|
| 34 |
+
## SARA
|
| 35 |
+
|
| 36 |
+
**SARA** (Resonant Arbitration) is the arbitration discipline operating at CAMP. Protocol, not persona, not AI.
|
| 37 |
+
|
| 38 |
+
- The **Manager-via-SARA** is the human role performing arbitration cognition.
|
| 39 |
+
- SARA shapes the constraint field so that convergence produces principled Matter — by requiring rationale, demand-reference, projection-type declaration, etc. on every arbitration entry.
|
| 40 |
+
- SARA does not gate-keep events. It constrains the field geometry.
|
| 41 |
+
|
| 42 |
+
## Asterion
|
| 43 |
+
|
| 44 |
+
**Asterion** is the markdown corpus as canonical-at-write store. Single canonical home for Change-System Matter.
|
| 45 |
+
|
| 46 |
+
- Runtime DB (when present) is a cache / projection of Asterion. If runtime ≠ Asterion, runtime is the lie.
|
| 47 |
+
- `SA_Doc_Lens` (per the SA-Core spec pack) parses Asterion into Operating Memory bands 0–5 entities for runtime traversal.
|
| 48 |
+
- This file and every other markdown file at the repo root is part of Asterion.
|
| 49 |
+
- Frontmatter shape: minimal at present (`kind`, `truth_class`, `authority`, `attribution`). Full Asterion frontmatter shape is a deferred decision.
|
| 50 |
+
|
| 51 |
+
## Conversion Law
|
| 52 |
+
|
| 53 |
+
```
|
| 54 |
+
Energy → (SARA @ CAMP) → Matter
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
If a signal does not pass through CAMP, it is not Matter. See `ENERGY_MODEL.md` for the duality and `SIGNAL_FLOW.md` for stage-by-stage application.
|
| 58 |
+
|
| 59 |
+
## Operational queries — Core's reason for existing
|
| 60 |
+
|
| 61 |
+
These cannot be answered by any single projection surface. They require joining evidence across surfaces, traced to canonical entities, with Core arbitrating drift.
|
| 62 |
+
|
| 63 |
+
- Who is doing what?
|
| 64 |
+
- Is a person or team productive?
|
| 65 |
+
- Are we on track?
|
| 66 |
+
- What demand is unresolved?
|
| 67 |
+
- What plan lacks action?
|
| 68 |
+
- What action lacks acceptance?
|
| 69 |
+
|
| 70 |
+
These are not features added on top of Core. They are Core's reason for existing.
|
| 71 |
+
|
| 72 |
+
## Plugin implementation (current state)
|
| 73 |
+
|
| 74 |
+
A first runnable slice of the model exists as the **SA-Orchestration WordPress plugin** (current version **v0.5.2**). It implements:
|
| 75 |
+
|
| 76 |
+
- **Three-table runtime cache** for arbitration records, Demand→Plan links, and append-only acceptance events. Schema unchanged since v0.1.0.
|
| 77 |
+
- **Asterion-first writes** — every canonical row has a corresponding markdown file in `wp-content/sa-asterion/{kind}/{hash}.md` with `SA_Doc_Lens`-shaped frontmatter. DB writes happen only after the ledger file is on disk.
|
| 78 |
+
- **Deterministic Trace Audit** (layer 2 of the review stack) — local rules-based, repeatable, no API. Detects closure-authority invalidity, projection_type / plan_link mismatches, scope drift, dispute patterns, and emits a `needs_human_arbitration` flag with explicit triggers.
|
| 79 |
+
- **Strategy LLM Review** (layer 3) — provider-pluggable seam (`SA_Orch_LLM_Provider_Interface`). The **OpenAI provider is active** (Chat Completions API, 30s timeout, JSON mode, server-side clamped response). The simulated provider remains as the always-available fallback. The Strategy layer is purely advisory and **cannot override `closure_state_*`, `closure_authority_valid`, or `needs_human_arbitration`**.
|
| 80 |
+
- **Conservative confidence floor (v0.5.2)** — when the deterministic audit reports `closure_confidence: n/a`, the strategy review's `confidence` is forced to `'low'`. Two-layer enforcement: OpenAI system prompt rule + cross-cutting orchestrator safety net.
|
| 81 |
+
|
| 82 |
+
The plugin is the first concrete embodiment of the constraint model defined in this file. CAMP, SARA, and Asterion remain conceptual (and remain attributed to Mark Holak); the plugin gives them a runtime shape on WordPress + Fluent.
|
| 83 |
+
|
| 84 |
+
For the running plugin status, schema, file inventory, and version history, see `PLUGIN_STATUS.md`.
|
| 85 |
+
|
| 86 |
+
## Attribution
|
| 87 |
+
|
| 88 |
+
CAMP, SARA, Asterion: **Mark Holak**. Subject to later separation for IP reasons.
|
| 89 |
+
|
| 90 |
+
Holak's prior named concepts (Prime Prompt, Cognitive Heatsink, Signal Telemetry Doctrine, Reference Traversal Continuity) are referenced from `Archvie/sa-core/docs/specs/concepts/` and preserved verbatim under SA-Core Invariant I9.
|
SA-orchestration MD/DEFERRED_SA_CORE_CONCERNS.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: deferred_record
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: design_constraint
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
# Deferred SA-Core Concerns
|
| 8 |
+
|
| 9 |
+
Concerns recognized as belonging to SA-Core but explicitly held until the SA-Core layer is ready to absorb them. Captured here so they are not lost in chat. Not active. Not in current implementation scope.
|
| 10 |
+
|
| 11 |
+
## Convention
|
| 12 |
+
|
| 13 |
+
Each entry is a heading with:
|
| 14 |
+
|
| 15 |
+
- **Captured**: date
|
| 16 |
+
- **Origin**: what surfaced it
|
| 17 |
+
- **Concern**: the substantive constraint
|
| 18 |
+
- **For now (current-layer posture)**: what we do or do not do in the meantime
|
| 19 |
+
- **Future home**: the SA-Core component that will absorb it
|
| 20 |
+
|
| 21 |
+
When SA-Core absorbs a concern, the corresponding entry is moved out of this file and into the SA-Core spec it lands in. This file shrinks as SA-Core grows.
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
|
| 25 |
+
## Intent-banded navigation (recursive view authority)
|
| 26 |
+
|
| 27 |
+
- **Captured**: 2026-05-02
|
| 28 |
+
- **Origin**: surfaced during SA-Orchestration v0.6.x projection work, when cross-surface navigation became a real operator question.
|
| 29 |
+
- **Concern**:
|
| 30 |
+
The system needs an intent-banded navigation layer where:
|
| 31 |
+
- support / client view gates how deep a user can drill
|
| 32 |
+
- developer view gates how high a user can look
|
| 33 |
+
- boards remain recursive demand / execution units
|
| 34 |
+
- client → executor recursion must remain intact
|
| 35 |
+
- **For now (SA-Orchestration scope)**:
|
| 36 |
+
- lightweight breadcrumbs / parent-child references only
|
| 37 |
+
- do NOT overhaul Fluent presentation
|
| 38 |
+
- do NOT create a third Fluent layer
|
| 39 |
+
- **Future home**: SA-Core minimap / authority lens.
|
SA-orchestration MD/DEVELOPMENT_MODES.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: standing_discipline
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
# Development Modes — Bootstrap vs Maintenance
|
| 8 |
+
|
| 9 |
+
## The two modes
|
| 10 |
+
|
| 11 |
+
**Mode is per-area, not per-repo.** A repo may be in Bootstrap for one area and Maintenance for another. Apply mode per inspected area.
|
| 12 |
+
|
| 13 |
+
### Bootstrap
|
| 14 |
+
|
| 15 |
+
The area has no usable project setup yet. Empty folders, no application code, no `.env`, no installed dependencies, no running services tied to the area.
|
| 16 |
+
|
| 17 |
+
In Bootstrap the agent **may help establish** the environment, subject to:
|
| 18 |
+
|
| 19 |
+
- Setup uses only **user-declared resources**. See `ENVIRONMENT.md`.
|
| 20 |
+
- Generic defaults are not used unless explicitly authorized by the user.
|
| 21 |
+
- Each setup step is either executed by the agent (when capable and authorized), or **handed back to the user as exact, project-specific steps** — never generic best-practice templates.
|
| 22 |
+
|
| 23 |
+
### Maintenance
|
| 24 |
+
|
| 25 |
+
A setup already exists in the area. There is application code, configured runtime, possibly a running WordPress, an `.env`, running services, prior tooling.
|
| 26 |
+
|
| 27 |
+
In Maintenance the agent **must inspect, preserve, and modify** without overwriting assumptions:
|
| 28 |
+
|
| 29 |
+
- No setup action without first reading the existing configuration.
|
| 30 |
+
- No re-installation, re-initialization, or replacement of components without explicit user direction.
|
| 31 |
+
- No assumption that current configuration matches prior documentation. Outdated docs are lower authority than observed state.
|
| 32 |
+
- Changes are convergence events. An observation may fail to converge if it conflicts with existing canonical state — the agent records the conflict and stops, does not force.
|
| 33 |
+
|
| 34 |
+
### Partial Bootstrap / Recovery
|
| 35 |
+
|
| 36 |
+
The area has declared resources and partial files, but the environment is not yet executable. Some pieces of a setup exist (files, tools, prior configurations) but they are misconfigured, mis-located, locally-incompatible, or carry prior production state that must be separated from local development.
|
| 37 |
+
|
| 38 |
+
In this mode the agent **must inspect first, preserve what is usable, and guide the user toward a proper working setup** without assuming a clean slate:
|
| 39 |
+
|
| 40 |
+
- No installation or overwrite without inspection of every relevant existing file.
|
| 41 |
+
- Production secrets discovered locally must be flagged, not echoed, and treated as out-of-repo by default.
|
| 42 |
+
- Course-correction proposes options with conditions / risks; the user picks; the agent then executes within authorization.
|
| 43 |
+
- The final state is the **preferred repeatable setup**, not the messy path taken to recover.
|
| 44 |
+
- Updates to documentation describe the right-future-shape, not the literal recovery sequence.
|
| 45 |
+
|
| 46 |
+
Detection signals (any one is sufficient):
|
| 47 |
+
|
| 48 |
+
- Project files present but `wp-config.php` (or equivalent) is from a remote / production environment.
|
| 49 |
+
- Database referenced by config does not exist locally.
|
| 50 |
+
- Files exist but Apache `DocumentRoot` (or equivalent) does not serve them.
|
| 51 |
+
- Services (Apache, MySQL, etc.) configured but not running.
|
| 52 |
+
- Mixed prior-project state (e.g., a different project's DB present in the same MySQL instance).
|
| 53 |
+
- Asterion files reference materials at a path whose on-disk spelling disagrees.
|
| 54 |
+
- A remote-only resource has been copied to local disk without being adapted for local execution.
|
| 55 |
+
|
| 56 |
+
## Detection logic
|
| 57 |
+
|
| 58 |
+
| Observed | Mode (for that area) |
|
| 59 |
+
|---|---|
|
| 60 |
+
| Empty repo (or only `Archvie/`, `ONBOARDING.md`, similar bootstrap files) | Bootstrap |
|
| 61 |
+
| Application code present + services running + config local-correct | Maintenance |
|
| 62 |
+
| `.env` or `.env.example` exists alongside working code | Maintenance (env areas) |
|
| 63 |
+
| WordPress files present, `wp-config.php` is remote/production, services not running, files outside `DocumentRoot`, or DB referenced by config missing | Partial Bootstrap / Recovery |
|
| 64 |
+
| Mixed (some areas configured, others empty, others partial) | Apply each mode per-area |
|
| 65 |
+
|
| 66 |
+
## Authority hierarchy when modes disagree
|
| 67 |
+
|
| 68 |
+
When the agent's mode-detection conflicts with stated assumptions:
|
| 69 |
+
|
| 70 |
+
1. **Observed environment state** wins.
|
| 71 |
+
2. **User declarations** of intent (e.g., "this area should be in Bootstrap because we're starting fresh") override mode detection.
|
| 72 |
+
3. **Constraint-model files** (`CORE_MODEL.md`, `ENERGY_MODEL.md`, etc.) apply.
|
| 73 |
+
4. **Prior documentation** is lower authority than observed state.
|
| 74 |
+
5. **Agent memory / training-data defaults** are lowest authority.
|
| 75 |
+
|
| 76 |
+
## Gates
|
| 77 |
+
|
| 78 |
+
Protocol gates that fire during mode-shaped work are listed in `ONBOARDING.md` under *Triggers and Gates*. A gate that does not fire is a missed observation; a gate that fires without action is a discipline violation.
|
| 79 |
+
|
| 80 |
+
## Convergence framing
|
| 81 |
+
|
| 82 |
+
A discovery finding (e.g., "PHP 8.2 detected via XAMPP") is a single Energy contribution, not a Matter commit. Re-observation, conflict-checking, and user confirmation are part of the convergence path. Updates to `ENVIRONMENT.md`'s state tables are convergence events — they happen when observations stabilize, not at every command output.
|
| 83 |
+
|
| 84 |
+
See `ENERGY_MODEL.md` for the Energy → Matter dynamics.
|
SA-orchestration MD/ENERGY_MODEL.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: constraint_model
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
attribution: Mark Holak (Energy/Matter, convergence-collapse)
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
# Energy Model — Energy vs Matter, Convergence, Collapse
|
| 9 |
+
|
| 10 |
+
## Energy / Matter
|
| 11 |
+
|
| 12 |
+
**Energy** is changing motion: signals in flight, surface state changes, conversations, attempts, bypass actions, in-progress observations. Not committed.
|
| 13 |
+
|
| 14 |
+
**Matter** is stored motion: canonical state in Asterion. Constrains future motion.
|
| 15 |
+
|
| 16 |
+
The conversion law:
|
| 17 |
+
|
| 18 |
+
```
|
| 19 |
+
Energy → (SARA @ CAMP) → Matter
|
| 20 |
+
```
|
| 21 |
+
|
| 22 |
+
If a signal does not pass through CAMP, it is not Matter. See `CORE_MODEL.md` for CAMP, SARA, Asterion.
|
| 23 |
+
|
| 24 |
+
## Canonical collapse — convergence, not selection
|
| 25 |
+
|
| 26 |
+
Canonical collapse is **convergence** of distributed Energy toward a stable canonical location under constraint — not selection from independent candidates.
|
| 27 |
+
|
| 28 |
+
CAMP does not pick a location. CAMP **resolves convergence** — observes where aligned signal has stabilized in the constraint field, and writes Matter at that location.
|
| 29 |
+
|
| 30 |
+
The five constraint dimensions are **the shape of the constraint field**, not heuristics applied by an arbiter:
|
| 31 |
+
|
| 32 |
+
| Dimension | Field meaning |
|
| 33 |
+
|---|---|
|
| 34 |
+
| Causal continuity | Field-pull from existing causal chains; new signal drawn toward locations that extend an existing chain coherently |
|
| 35 |
+
| Correlation with existing chains | Field-pull from structurally similar existing entities |
|
| 36 |
+
| Authority of source | Field-weight applied to higher-authority contributions |
|
| 37 |
+
| Recency | Field-decay on older contributions |
|
| 38 |
+
| Conflict minimization | Locations with conflicting signal cannot stabilize; basins destabilize themselves until conflict resolves |
|
| 39 |
+
|
| 40 |
+
CAMP observes where the field has converged and writes Matter there.
|
| 41 |
+
|
| 42 |
+
## Implications
|
| 43 |
+
|
| 44 |
+
- **Asterion writes are not 1:1 with surface events.** A single Matter entry may emerge from many converging surface signals (a Fluent ticket, a chat message, a meeting transcript).
|
| 45 |
+
- **Multi-source contribution is the norm, not the edge case.** Adding a surface adds field signal contributing to existing convergence; it does not introduce a parallel candidate.
|
| 46 |
+
- **Refusal-to-collapse is valid.** If signal accumulates at two mutually-destabilizing locations, CAMP records "convergence not formed; competing signal at A and B" without forcing crystallization. See `SCATTER_AND_CONVERGENCE.md`.
|
| 47 |
+
- **Determinism under the field.** Same field state → same canonical location. CAMP is not a free choice point. SARA must therefore be principled, not discretionary.
|
| 48 |
+
- **Non-converging signals are not "rejected."** They remain Energy without being chosen against.
|
| 49 |
+
|
| 50 |
+
## Threshold (basin depth)
|
| 51 |
+
|
| 52 |
+
Threshold is **basin depth required for stable convergence at a location** — not a counter or score.
|
| 53 |
+
|
| 54 |
+
- Below threshold: signal does not crystallize into Matter. The basin is not deep enough to stabilize.
|
| 55 |
+
- Above threshold: convergence forms; CAMP records Matter.
|
| 56 |
+
- Likely tunable per concept (Demand intake basin ≠ Acceptance basin). Specific values: pending.
|
| 57 |
+
|
| 58 |
+
## Two layers of scatter
|
| 59 |
+
|
| 60 |
+
See `SCATTER_AND_CONVERGENCE.md` for the full two-layer scatter model. Briefly:
|
| 61 |
+
|
| 62 |
+
- **Inert** (pre-collapse): signal that did not converge. Logged Energy, non-canonical.
|
| 63 |
+
- **Harmony** (+) / **Dissonance** (−) (post-collapse): properties of how Matter, once crystallized, interacts with future field motion.
|
| 64 |
+
|
| 65 |
+
## Attribution
|
| 66 |
+
|
| 67 |
+
Energy / Matter duality and convergence-collapse: **Mark Holak**. Subject to later separation for IP reasons.
|
| 68 |
+
|
| 69 |
+
Consonant with Mark Holak's prior named concepts in the SA-Core spec pack — Cognitive Heatsink (thermodynamic model of thought-to-resolution) and Signal Telemetry Doctrine (alignment behaviors: align / scatter / ricochet / inert / harmonic closure). See `Archvie/sa-core/docs/specs/concepts/`.
|
SA-orchestration MD/ENVIRONMENT.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: state_record
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
status: dual
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
# Environment
|
| 9 |
+
|
| 10 |
+
This file is dual-natured. The principles below (what is required, what is declared, what is unknown) are **Matter** the moment they are committed. The state tables (versions, paths, availability) are **Energy** until convergent observations land via discovery.
|
| 11 |
+
|
| 12 |
+
Discovery findings are Energy contributing to the field. They become Matter when observations stabilize across re-observation, conflict resolution, or user confirmation. See `ENERGY_MODEL.md`.
|
| 13 |
+
|
| 14 |
+
## User-declared resources
|
| 15 |
+
|
| 16 |
+
The user has declared the following local tools as potentially available. Their presence in this list does not assert their use — only that the user controls them and may direct their inclusion.
|
| 17 |
+
|
| 18 |
+
| Tool | OS | Status | Notes |
|
| 19 |
+
|---|---|---|---|
|
| 20 |
+
| XAMPP | Windows | Confirmed at `F:\XAMPP` | Apache, MySQL, PHP, htdocs all present. Apache and MySQL **not running** as of last inspection. User prefers direct PHP invocation, not PATH-modified. |
|
| 21 |
+
| Local WordPress | Windows | Files present at `F:\XAMPP\wordpress\`; **Partial Bootstrap / Recovery state** | Copy of a WP Engine production site (multisite). `wp-config.php` contains live production secrets — must not be committed; not yet locally servable. See *Local WordPress state (observed)* below. |
|
| 22 |
+
| Anaconda | Windows | Declared | Not yet inspected |
|
| 23 |
+
| Visual Studio | Windows | 2026 | Used for adjacent C# work, e.g. `Archvie/MidCoast/QBSyncService` |
|
| 24 |
+
| PowerShell | Windows | Confirmed (used for inspection) | |
|
| 25 |
+
| PuTTY | Windows | Declared | Not yet inspected |
|
| 26 |
+
|
| 27 |
+
This list is **Windows-anchored**. A Linux or macOS contributor would supply their own equivalents — the *capability* is OS-agnostic, the *binding* is OS-specific. The DEVENV-vs-TOOLS split (per-OS dev setup vs runtime-resolved capability declarations) is a deferred decision; for now, OS-binding stays explicit in this list.
|
| 28 |
+
|
| 29 |
+
## Tools NOT declared
|
| 30 |
+
|
| 31 |
+
Tools not in the declared list **should not be assumed installed**. Examples that often appear in generic WP / web project setups but are not declared here:
|
| 32 |
+
|
| 33 |
+
- Node, npm, npx
|
| 34 |
+
- WP-CLI
|
| 35 |
+
- Composer (outside of XAMPP-bundled, if applicable)
|
| 36 |
+
- Docker, Docker Compose
|
| 37 |
+
- Git GUI clients
|
| 38 |
+
|
| 39 |
+
If any of these are needed, the user must declare them before use.
|
| 40 |
+
|
| 41 |
+
## Runtime — discovery state
|
| 42 |
+
|
| 43 |
+
| Runtime | Required | Detected | Version | Notes |
|
| 44 |
+
|---|---:|---|---|---|
|
| 45 |
+
| PHP | TBD | XAMPP folder present at `F:\XAMPP\php\` | <pending version probe> | Direct invocation: `& "F:\XAMPP\php\php.exe" -v` |
|
| 46 |
+
| Apache (httpd) | TBD | Installed at `F:\XAMPP\apache\` | <pending> | **Not running**. `DocumentRoot` is `F:/XAMPP/htdocs`. No vhost or alias for `F:/XAMPP/wordpress/`. |
|
| 47 |
+
| MySQL (mysqld) | TBD | Installed at `F:\XAMPP\mysql\` with data dir | <pending> | **Not running**. Data dir initialized. See *Local databases (observed)* below. |
|
| 48 |
+
| Composer | TBD | <pending> | <pending> | Verify whether XAMPP includes it |
|
| 49 |
+
| Python (Anaconda) | TBD | <pending> | <pending> | |
|
| 50 |
+
| WP-CLI | TBD | <pending> | <pending> | Not in declared resources; ask before assuming |
|
| 51 |
+
| Node | TBD | <pending> | <pending> | Not in declared resources; ask before assuming |
|
| 52 |
+
|
| 53 |
+
### Local databases (observed)
|
| 54 |
+
|
| 55 |
+
In `F:\XAMPP\mysql\data\`:
|
| 56 |
+
|
| 57 |
+
| DB name | Origin | Notes |
|
| 58 |
+
|---|---|---|
|
| 59 |
+
| `mysql`, `performance_schema`, `phpmyadmin`, `test` | XAMPP defaults | System / admin |
|
| 60 |
+
| `qbbridge_local` | Different project (QB Inventory Bin Audit / `Archvie/MidCoast/`) | Full WP schema + `wp_qbinv_*` tables matching `Archvie/MidCoast/CLAUDE.md` |
|
| 61 |
+
| `wp_sleeperagendev` | — | **Does not exist locally.** Referenced by the original `F:\XAMPP\wordpress\wp-config.php` (now backed up); replaced by `wp_local_dev` for active local dev. |
|
| 62 |
+
| `wp_local_dev` | Local SA-orchestration dev | WP install + Fluent stack populated from production fixture. See *Live test fixture (imported)* below. |
|
| 63 |
+
|
| 64 |
+
## Local WordPress state (observed)
|
| 65 |
+
|
| 66 |
+
Status: **Partial Bootstrap / Recovery**. See `DEVELOPMENT_MODES.md`.
|
| 67 |
+
|
| 68 |
+
| Aspect | Observation |
|
| 69 |
+
|---|---|
|
| 70 |
+
| Path | `F:\XAMPP\wordpress\` (outside `F:/XAMPP/htdocs/`, the Apache `DocumentRoot`) |
|
| 71 |
+
| Files | All standard WP core files; `wp-config.php` AND `wp-config-sample.php`; `.htaccess` (standard WP rewrite rules); custom `ticket-handler.php` at root; `wp-content/mysql.sql` (likely DB dump) |
|
| 72 |
+
| Theme / plugins | Avada/Fusion theme; WooCommerce; caching plugin (`advanced-cache.php`, `object-cache.php`) |
|
| 73 |
+
| Multisite | `MULTISITE = true`, `SUBDOMAIN_INSTALL = true`, `DOMAIN_CURRENT_SITE = sleeperagendev.wpenginepowered.com`. Subsite #2 has uploads (`wp-content/uploads/sites/2/...`). |
|
| 74 |
+
| `wp-config.php` source | **WP Engine production configuration**. Contains live secrets (DB password, 8 auth keys/salts, `WPE_APIKEY`, WPE cluster identifiers, SFTP endpoint). Not safe to commit. Not locally executable as-is (multisite + WPE domain + memcached + missing local DB). |
|
| 75 |
+
| Apache reachability | NOT reachable. Files outside `DocumentRoot`; no vhost or alias configured. |
|
| 76 |
+
| Database reachability | NOT reachable. MySQL not running; referenced DB `wp_sleeperagendev` does not exist. |
|
| 77 |
+
|
| 78 |
+
**Recovery path is pending user decision** across course-correction options (A–E). Once chosen, this section becomes the right-future-shape and is updated to describe the preferred repeatable setup.
|
| 79 |
+
|
| 80 |
+
## Environment variables
|
| 81 |
+
|
| 82 |
+
A `.env.example` will be authored once the first integration target is chosen. **Real secrets are never committed.** Vault strategy must be declared by the user before any service-bound build proceeds.
|
| 83 |
+
|
| 84 |
+
| Variable | Required | Purpose | Source |
|
| 85 |
+
|---|---:|---|---|
|
| 86 |
+
| (pending — none defined yet) | | | |
|
| 87 |
+
|
| 88 |
+
## Repository structure (observed)
|
| 89 |
+
|
| 90 |
+
```text
|
| 91 |
+
SA-orchestration/
|
| 92 |
+
├── Archvie/ # Reference materials, not active code
|
| 93 |
+
│ ├── sa-core/ # SA-Core specs and (eventual) plugin source
|
| 94 |
+
│ └── MidCoast/ # Worked example: QB Sync deployment
|
| 95 |
+
├── plugin/ # Plugin canonical source (promoted 2026-05-01)
|
| 96 |
+
│ └── sa-orchestration/ # SA-Orchestration WordPress plugin v0.5.2
|
| 97 |
+
│ ├── sa-orchestration.php # plugin header + bootstrap
|
| 98 |
+
│ ├── README.md
|
| 99 |
+
│ └── includes/ # 14 PHP files (interface + classes)
|
| 100 |
+
├── ONBOARDING.md # Authority-gated entry protocol
|
| 101 |
+
├── CORE_MODEL.md # SA-Core, CAMP, SARA, Asterion
|
| 102 |
+
├── ENERGY_MODEL.md # Energy / Matter, convergence-collapse
|
| 103 |
+
├── PROJECTION_SURFACES.md # Fluent, Boards, WordPress, etc.
|
| 104 |
+
├── DEVELOPMENT_MODES.md # Bootstrap vs Maintenance
|
| 105 |
+
├── ENVIRONMENT.md # This file
|
| 106 |
+
├── SIGNAL_FLOW.md # Demand → Plan → Action → ...
|
| 107 |
+
├── SCATTER_AND_CONVERGENCE.md # Two-layer scatter, threshold
|
| 108 |
+
├── BYPASS_AND_RECOVERY.md # Bypass mode, recovery path
|
| 109 |
+
├── FLUENT_DATA_MAPPING.md # First live test fixture (imported)
|
| 110 |
+
├── PLUGIN_STATUS.md # SA-Orchestration plugin status (v0.5.2)
|
| 111 |
+
├── verify-stamp.php # Manual verification stamp helper
|
| 112 |
+
└── (further structure pending)
|
| 113 |
+
```
|
| 114 |
+
|
| 115 |
+
## External services — discovery state
|
| 116 |
+
|
| 117 |
+
See `PROJECTION_SURFACES.md` for the surface-by-surface breakdown.
|
| 118 |
+
|
| 119 |
+
| Surface | Required for local dev | Status |
|
| 120 |
+
|---|---:|---|
|
| 121 |
+
| Fluent Support | TBD | Plugin active locally; schema + production fixture data populated. See `FLUENT_DATA_MAPPING.md` §3. |
|
| 122 |
+
| Fluent Boards | TBD | Plugin active locally; schema + production fixture data populated. See `FLUENT_DATA_MAPPING.md` §4. |
|
| 123 |
+
| FluentCRM | TBD | Plugin active locally; schema + production fixture data populated. See `FLUENT_DATA_MAPPING.md` §2. |
|
| 124 |
+
| Jira | TBD | Future |
|
| 125 |
+
| JobOrchestration | TBD | Future |
|
| 126 |
+
| WordPress (runtime) | TBD | Files present at `F:\XAMPP\wordpress\`; recovery pending; not yet servable. See *Local WordPress state (observed)* above. |
|
| 127 |
+
| OpenAI / Anthropic / etc. | TBD | Not assumed present |
|
| 128 |
+
|
| 129 |
+
## Live test fixture (imported)
|
| 130 |
+
|
| 131 |
+
First live data import landed 2026-05-01 from production export `wp_sleeperagendev.sql` (phpMyAdmin dump from WP Engine pod). Imported into local `wp_local_dev` after target-table TRUNCATE under `FOREIGN_KEY_CHECKS=0`.
|
| 132 |
+
|
| 133 |
+
**This is observation evidence, not Asterion canonical state** — it records what the projection surfaces look like in operational use, not the Change-System concepts themselves.
|
| 134 |
+
|
| 135 |
+
| Layer | Tables imported | Sample counts |
|
| 136 |
+
|---|---:|---|
|
| 137 |
+
| Plan (FluentBoards / `wp_fbs_*`) | 10 | 17 boards, 57 tasks, 284 activities |
|
| 138 |
+
| Stakeholder (FluentCRM / `wp_fc_*`) | 7 | 32 subscribers, 26 tags, 5 lists |
|
| 139 |
+
| Demand (FluentSupport / `wp_fs_*`) | 6 | 2 tickets, 9 persons, 4 conversations |
|
| 140 |
+
| Skipped | 1 (`wp_fc_companies`) | Local plugin version lacks the table |
|
| 141 |
+
|
| 142 |
+
23 INSERT blocks imported, 1 skipped. Run was clean (exit 0). Production user IDs (2, 5, 8, 16, 18, 19) referenced by imported rows do not exist locally; Fluent UI surfaces will display "Unknown user" until those references are remapped or the users are recreated.
|
| 143 |
+
|
| 144 |
+
Filtered import file retained at `%TEMP%\sa-orch-fluent-import.sql` (230KB) for re-import reference.
|
| 145 |
+
|
| 146 |
+
Full per-table breakdown, Change-System mapping, and natural test fixtures: see `FLUENT_DATA_MAPPING.md`.
|
| 147 |
+
|
| 148 |
+
## Discovery commands
|
| 149 |
+
|
| 150 |
+
Discovery commands are environment-specific. Issue commands matched to the user-declared tools (XAMPP, Anaconda, etc.). Do **not** run commands for tools not on the declared list without confirmation.
|
| 151 |
+
|
| 152 |
+
If a command fails, record the failure verbatim and request user action. Do not infer that an equivalent tool can substitute.
|
| 153 |
+
|
| 154 |
+
For PHP discovery on this user's environment, the direct-invocation form is:
|
| 155 |
+
|
| 156 |
+
```powershell
|
| 157 |
+
& "F:\XAMPP\php\php.exe" -v
|
| 158 |
+
```
|
| 159 |
+
|
| 160 |
+
(Per the user's stated preference. Commands for other tools to be issued matching their declared installation paths.)
|
| 161 |
+
|
| 162 |
+
## Status
|
| 163 |
+
|
| 164 |
+
| Area | Status | Notes |
|
| 165 |
+
|---|---|---|
|
| 166 |
+
| User-declared resources | Matter (committed) | Editable when user declares more |
|
| 167 |
+
| XAMPP installation | Matter (observed) | At `F:\XAMPP`; services not running |
|
| 168 |
+
| Local WordPress files | Matter (observed) | At `F:\XAMPP\wordpress\`; production-config; recovery pending |
|
| 169 |
+
| Local DB `wp_sleeperagendev` | Matter (observed: absent) | Needs creation under chosen recovery path |
|
| 170 |
+
| Local DB `qbbridge_local` | Matter (observed: present) | Different project; do not modify |
|
| 171 |
+
| Runtime versions (PHP / Apache / MySQL) | Energy (pending version probes) | |
|
| 172 |
+
| Environment variables | Energy (pending strategy declaration) | |
|
| 173 |
+
| Secrets handling | Energy (pending strategy declaration) | wp-config.php production secrets flagged separately |
|
| 174 |
+
| Local execution | Energy (pending recovery decisions A–E) | |
|
| 175 |
+
| Testing | Energy (pending discovery) | |
|
| 176 |
+
| Deployment | Energy (pending discovery) | |
|
| 177 |
+
| Mode (per-area) | Matter (Partial Bootstrap / Recovery for `F:\XAMPP\wordpress\` area) | See `DEVELOPMENT_MODES.md` |
|
| 178 |
+
| Archive folder spelling | Matter (observed: `Archvie/`) | Typo; rename pending coordinated update |
|
| 179 |
+
| Local DB `wp_local_dev` | Matter (observed: present, populated) | Fluent stack + production fixture; see *Live test fixture (imported)* |
|
| 180 |
+
| First live test fixture | Matter (observed) | Imported 2026-05-01; see `FLUENT_DATA_MAPPING.md` |
|
| 181 |
+
| Plugin canonical source | Matter (committed) | `plugin/sa-orchestration/` v0.5.2; runtime copy at `F:\XAMPP\wordpress\wp-content\plugins\sa-orchestration\`. See `PLUGIN_STATUS.md`. |
|
SA-orchestration MD/FLUENT_DATA_MAPPING.md
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: state_record
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
# Fluent Data Mapping — First Live Test Fixture
|
| 8 |
+
|
| 9 |
+
This file records observed facts from the first live data import into the local FluentCRM / FluentSupport / FluentBoards stack. Source dump: `wp_sleeperagendev.sql` (phpMyAdmin export from production WP Engine pod, generation time 2026-05-01 18:31 UTC). Imported into local DB `wp_local_dev` after target-table TRUNCATE under `FOREIGN_KEY_CHECKS=0`.
|
| 10 |
+
|
| 11 |
+
This is the **first live test fixture** for SA-orchestration. The data is read-only canonical state from production; it is what the surfaces look like when in operational use. Treat it as observation evidence for understanding the projection-surface side of the Change-System cycle, not as canonical Matter for the Change-System concepts themselves (which live in Asterion, not in Fluent).
|
| 12 |
+
|
| 13 |
+
---
|
| 14 |
+
|
| 15 |
+
## 1. Imported Fluent tables and counts
|
| 16 |
+
|
| 17 |
+
23 INSERT blocks imported, 1 skipped. Run was clean (exit 0, no errors).
|
| 18 |
+
|
| 19 |
+
### Plan layer — `wp_fbs_*` (10 tables)
|
| 20 |
+
|
| 21 |
+
| Table | Rows |
|
| 22 |
+
|---|---:|
|
| 23 |
+
| `wp_fbs_boards` | 17 |
|
| 24 |
+
| `wp_fbs_tasks` | 57 |
|
| 25 |
+
| `wp_fbs_activities` | 284 |
|
| 26 |
+
| `wp_fbs_board_terms` | 135 |
|
| 27 |
+
| `wp_fbs_relations` | 71 |
|
| 28 |
+
| `wp_fbs_metas` | 40 |
|
| 29 |
+
| `wp_fbs_notification_users` | 17 |
|
| 30 |
+
| `wp_fbs_notifications` | 16 |
|
| 31 |
+
| `wp_fbs_comments` | 10 |
|
| 32 |
+
| `wp_fbs_attachments` | 2 |
|
| 33 |
+
|
| 34 |
+
### Stakeholder / CRM layer — `wp_fc_*` (7 tables)
|
| 35 |
+
|
| 36 |
+
| Table | Rows |
|
| 37 |
+
|---|---:|
|
| 38 |
+
| `wp_fc_subscriber_meta` | 197 |
|
| 39 |
+
| `wp_fc_subscribers` | 32 |
|
| 40 |
+
| `wp_fc_tags` | 26 |
|
| 41 |
+
| `wp_fc_meta` | 6 |
|
| 42 |
+
| `wp_fc_lists` | 5 |
|
| 43 |
+
| `wp_fc_subscriber_pivot` | 2 |
|
| 44 |
+
| `wp_fc_funnels` | 1 |
|
| 45 |
+
|
| 46 |
+
### Demand / Support layer — `wp_fs_*` (6 tables)
|
| 47 |
+
|
| 48 |
+
| Table | Rows |
|
| 49 |
+
|---|---:|
|
| 50 |
+
| `wp_fs_persons` | 9 |
|
| 51 |
+
| `wp_fs_conversations` | 4 |
|
| 52 |
+
| `wp_fs_tickets` | 2 |
|
| 53 |
+
| `wp_fs_mail_boxes` | 1 |
|
| 54 |
+
| `wp_fs_attachments` | 1 |
|
| 55 |
+
| `wp_fs_meta` | 1 |
|
| 56 |
+
|
| 57 |
+
### Skipped
|
| 58 |
+
|
| 59 |
+
| Table | Reason |
|
| 60 |
+
|---|---|
|
| 61 |
+
| `wp_fc_companies` | Table missing locally. Production runs a newer FluentCRM version with the companies feature; local plugin v2.9.87 has not provisioned this table. |
|
| 62 |
+
|
| 63 |
+
---
|
| 64 |
+
|
| 65 |
+
## 2. CRM → Stakeholder / Identity layer
|
| 66 |
+
|
| 67 |
+
`wp_fc_subscribers` is the canonical identity registry on the CRM surface. Each row carries a stable `hash`, optional `user_id` linking back to a WP user (when the subscriber is also a registered user), name, email, and contact metadata.
|
| 68 |
+
|
| 69 |
+
### Subscriber breakdown by source
|
| 70 |
+
|
| 71 |
+
| Status | Type | Source | Count |
|
| 72 |
+
|---|---|---|---:|
|
| 73 |
+
| subscribed | lead | `csv` | 27 |
|
| 74 |
+
| subscribed | lead | (NULL) | 2 |
|
| 75 |
+
| subscribed | lead | `apollo` | 2 |
|
| 76 |
+
| pending | lead | (NULL) | 1 |
|
| 77 |
+
|
| 78 |
+
The 27 CSV-sourced rows arrived in a single import event on 2026-03-02 15:42:00 — a bulk lead import. The Apollo-sourced rows are test entries (`test1@example.com`, `test2@example.com`).
|
| 79 |
+
|
| 80 |
+
### Identity → WP user linkage
|
| 81 |
+
|
| 82 |
+
A subscriber row may carry `user_id` populating the WP user link:
|
| 83 |
+
|
| 84 |
+
| Subscriber id | WP user_id | Note |
|
| 85 |
+
|---|---:|---|
|
| 86 |
+
| 28 | 2 | Mark Holak (`nujacsaints@gmail.com`) — the production admin |
|
| 87 |
+
| 30 | 16 | Max Yarbrough |
|
| 88 |
+
|
| 89 |
+
All other subscribers have `user_id = NULL` — they are leads / contacts who have never become WP users on production.
|
| 90 |
+
|
| 91 |
+
### Supporting CRM tables present
|
| 92 |
+
|
| 93 |
+
- `wp_fc_subscriber_meta` (197 rows) — extended attributes per subscriber.
|
| 94 |
+
- `wp_fc_subscriber_pivot` (2 rows) — many-to-many between subscribers and other objects (lists, tags).
|
| 95 |
+
- `wp_fc_tags` (26), `wp_fc_lists` (5) — segmentation vocabulary.
|
| 96 |
+
- `wp_fc_funnels` (1) — automation funnel.
|
| 97 |
+
|
| 98 |
+
CRM is the most populous identity layer in the fixture.
|
| 99 |
+
|
| 100 |
+
---
|
| 101 |
+
|
| 102 |
+
## 3. Support → Demand / Acceptance evidence
|
| 103 |
+
|
| 104 |
+
The Support surface is the thinnest layer in the fixture (intentional; Fluent Support has been used minimally in production so far).
|
| 105 |
+
|
| 106 |
+
### Tickets
|
| 107 |
+
|
| 108 |
+
| id | status | title | customer_id | response_count | resolved_at | closed_by |
|
| 109 |
+
|---|---|---|---:|---:|---|---:|
|
| 110 |
+
| 12 | active | HelpDesk - New Golf image for Website | 6 | 0 | 2026-03-31 22:43:52 | 1 |
|
| 111 |
+
| 13 | new | HelpDesk - TEST - Carma ticket | 3 | 0 | NULL | NULL |
|
| 112 |
+
|
| 113 |
+
### Persons (Support-side identity)
|
| 114 |
+
|
| 115 |
+
| id | first/last | email | type | user_id |
|
| 116 |
+
|---|---|---|---|---:|
|
| 117 |
+
| 1 | (blank) | oneely@sleeperagents.org | agent | 19 |
|
| 118 |
+
| 2 | (blank) | vkotha@sleeperagents.org | agent | 5 |
|
| 119 |
+
| 3 | Olga Neely | oneely@sleeperagents.org | customer | NULL |
|
| 120 |
+
| 4 | O N | on@gmail.com | customer | NULL |
|
| 121 |
+
| 5 | (blank) | pverrette@sleeperagents.org | agent | 18 |
|
| 122 |
+
| 6 | Patrick Verrette | pverrette@sleeperagents.org | customer | NULL |
|
| 123 |
+
| 7 | test test | test@test.com | customer | NULL |
|
| 124 |
+
| 8 | 123 123 | 123@test.com | customer | NULL |
|
| 125 |
+
| 9 | Mark Holak | nujacsaints@gmail.com | agent | 2 |
|
| 126 |
+
|
| 127 |
+
Notice the duplication: the same email may appear with `person_type='agent'` (with WP user_id) and `person_type='customer'` (without). Fluent treats agent-vs-customer as distinct rows even when they're the same human.
|
| 128 |
+
|
| 129 |
+
### Conversations
|
| 130 |
+
|
| 131 |
+
4 rows, both tied to ticket 12 and ticket 13. Includes:
|
| 132 |
+
- `note` entries (initial ticket content + attachments)
|
| 133 |
+
- `internal_info` entries with content `"Ticket has been closed"` and `"Ticket has been reopened"` — these are the **Acceptance / re-Demand events** Fluent records as conversation-side internal log entries.
|
| 134 |
+
|
| 135 |
+
### Demand intake channel
|
| 136 |
+
|
| 137 |
+
`wp_fs_mail_boxes` has 1 row — a single configured inbox is the surface evidence channel for inbound Demand.
|
| 138 |
+
|
| 139 |
+
### Acceptance signal carriers (where to look for affirmative closure)
|
| 140 |
+
|
| 141 |
+
| Field | Layer | Meaning |
|
| 142 |
+
|---|---|---|
|
| 143 |
+
| `wp_fs_tickets.resolved_at` | Demand row | Timestamp at which the agent marked resolution. |
|
| 144 |
+
| `wp_fs_tickets.closed_by` | Demand row | WP user id who closed it. |
|
| 145 |
+
| `wp_fs_tickets.status` | Demand row | Mutable workflow state (`new`, `active`, `closed`). |
|
| 146 |
+
| `wp_fs_tickets.last_customer_response` | Demand row | Latest customer reply timestamp — proxy for stakeholder engagement. |
|
| 147 |
+
| `wp_fs_conversations.conversation_type='internal_info'` with content matching close/reopen | Demand iteration | Append-only event log of closure-related events. |
|
| 148 |
+
|
| 149 |
+
The `conversations` log is the closest thing to an immutable acceptance ledger Fluent natively provides — but it is informational text, not a structured event with actor + timestamp + reason in typed fields.
|
| 150 |
+
|
| 151 |
+
---
|
| 152 |
+
|
| 153 |
+
## 4. Boards → Plan / Action evidence
|
| 154 |
+
|
| 155 |
+
### Boards (17 total)
|
| 156 |
+
|
| 157 |
+
Real client and operational projects, plus one test:
|
| 158 |
+
|
| 159 |
+
| id | title | created_by | task count |
|
| 160 |
+
|---|---|---:|---:|
|
| 161 |
+
| 1 | Inserio | 2 | 8 |
|
| 162 |
+
| 2 | CARMA | 2 | 6 |
|
| 163 |
+
| 3 | Buildscapes | 2 | 2 |
|
| 164 |
+
| 4 | Sleeper Agents | 2 | 1 |
|
| 165 |
+
| 5 | Sales Meeting - 3/11 | 8 | 7 |
|
| 166 |
+
| 6 | Mid Coast Engines | 8 | 0 |
|
| 167 |
+
| 7 | Catchall Supply | 18 | 0 |
|
| 168 |
+
| 8 | Cadence | 18 | 2 |
|
| 169 |
+
| 9 | Boatman Union | 18 | 7 |
|
| 170 |
+
| 10 | DVS | 18 | 0 |
|
| 171 |
+
| 11 | TGCI | 18 | 1 |
|
| 172 |
+
| 12 | Fluent CRM | 18 | 1 |
|
| 173 |
+
| 13 | FluidFlow Pro | 18 | 3 |
|
| 174 |
+
| 14 | Sleeper Agents Pipeline | 18 | 8 |
|
| 175 |
+
| 15 | Marks Op's Board | 18 | 2 |
|
| 176 |
+
| 16 | Mission.net | 18 | 9 |
|
| 177 |
+
| 17 | test | 19 | 0 (archived 2026-03-31) |
|
| 178 |
+
|
| 179 |
+
`created_by` references **production WP user IDs** (2, 8, 18, 19) which **do not exist locally**. Local WordPress has only user 1 (`admin`). UI surfaces will display "Unknown user" until those users are recreated or remapped.
|
| 180 |
+
|
| 181 |
+
### Tasks (57)
|
| 182 |
+
|
| 183 |
+
`wp_fbs_tasks` has columns including `crm_contact_id`, `source`, `source_id`, `priority`, `status`, `stage_id`, `lead_value`, `position`, `comments_count`, `issue_number`, `reminder_type`, plus timestamps `started_at`, `due_at`, `last_completed_at`, `archived_at`.
|
| 184 |
+
|
| 185 |
+
### Stage vocabulary (across all boards)
|
| 186 |
+
|
| 187 |
+
| Stage | Used in N boards |
|
| 188 |
+
|---|---:|
|
| 189 |
+
| In Progress | 16 |
|
| 190 |
+
| Completed | 16 |
|
| 191 |
+
| Open | 15 |
|
| 192 |
+
| Paused | 2 |
|
| 193 |
+
| Review | 2 |
|
| 194 |
+
| To Do | 1 |
|
| 195 |
+
| Ready For Approval | 1 |
|
| 196 |
+
| Blocked | 1 |
|
| 197 |
+
| Backlog | 1 |
|
| 198 |
+
|
| 199 |
+
Most boards converged on the `Open → In Progress → Completed` triad, with `Paused` and `Review` as common detours. Bespoke stages exist on specific boards.
|
| 200 |
+
|
| 201 |
+
### Activities (284 total) — Action evidence breakdown
|
| 202 |
+
|
| 203 |
+
`wp_fbs_activities` is polymorphic via `object_type` + `object_id`.
|
| 204 |
+
|
| 205 |
+
| object_type | action | count |
|
| 206 |
+
|---|---|---:|
|
| 207 |
+
| board_activity | created | 78 |
|
| 208 |
+
| board_activity | added | 27 |
|
| 209 |
+
| board_activity | moved | 7 |
|
| 210 |
+
| board_activity | changed | 4 |
|
| 211 |
+
| board_activity | archived | 1 |
|
| 212 |
+
| board_activity | updated | 1 |
|
| 213 |
+
| task_activity | created | 57 |
|
| 214 |
+
| task_activity | changed | 40 |
|
| 215 |
+
| task_activity | updated | 31 |
|
| 216 |
+
| task_activity | added | 18 |
|
| 217 |
+
| task_activity | joined | 11 |
|
| 218 |
+
| task_activity | closed | 4 |
|
| 219 |
+
| task_activity | reopened | 2 |
|
| 220 |
+
| task_activity | removed | 2 |
|
| 221 |
+
| task_activity | left | 1 |
|
| 222 |
+
|
| 223 |
+
The activities table is the discrete-event Action evidence stream — exactly the Energy form CAMP would arbitrate. Every state transition leaves a row.
|
| 224 |
+
|
| 225 |
+
---
|
| 226 |
+
|
| 227 |
+
## 5. Known native gaps
|
| 228 |
+
|
| 229 |
+
Observed structural gaps in the Fluent data model relative to the SA-orchestration Change-System cycle.
|
| 230 |
+
|
| 231 |
+
### 5.1 No strong Demand → Plan link
|
| 232 |
+
|
| 233 |
+
`wp_fbs_tasks.source` and `source_id` are present but unused for ticket linkage. There is **no native column on `wp_fbs_tasks` that points to a `wp_fs_tickets.id`**. The implication: when a Manager creates a board task in response to a customer ticket, that causal connection is **not recorded** by Fluent.
|
| 234 |
+
|
| 235 |
+
Demand-to-Plan trace, if needed, must be carried by a layer above Fluent — i.e. by Asterion's arbitration record (`SIGNAL_FLOW.md` Stage map → Arbitration row).
|
| 236 |
+
|
| 237 |
+
### 5.2 Limited CRM linkage on tasks
|
| 238 |
+
|
| 239 |
+
Of 57 imported tasks, **1 has a non-null `crm_contact_id`**. The remaining 56 tasks do not connect back to a CRM subscriber identity at all.
|
| 240 |
+
|
| 241 |
+
The Plan layer is therefore largely disconnected from the Stakeholder identity layer at the surface. Plan units exist in the abstract, owned by `created_by` (a WP user) but not bound to the contact-of-interest.
|
| 242 |
+
|
| 243 |
+
### 5.3 Mutable status fields obscure acceptance history
|
| 244 |
+
|
| 245 |
+
Demonstrated by ticket 12:
|
| 246 |
+
|
| 247 |
+
```
|
| 248 |
+
status = 'active'
|
| 249 |
+
resolved_at = '2026-03-31 22:43:52'
|
| 250 |
+
closed_by = 1
|
| 251 |
+
```
|
| 252 |
+
|
| 253 |
+
These three fields are simultaneously set on the row in a way that is internally inconsistent if read literally. The conversations log shows the explanation: ticket was closed, then reopened (two `internal_info` conversation rows). Fluent updated the conversations log but left `resolved_at` and `closed_by` populated from the prior close — `status` was reverted to `active`, the resolution-timestamp fields were not.
|
| 254 |
+
|
| 255 |
+
The implication: **Acceptance state cannot be inferred from a single ticket row.** It must be reconstructed from the conversation log, which itself is unstructured text rather than a typed event stream.
|
| 256 |
+
|
| 257 |
+
### 5.4 Activity log has no rationale field
|
| 258 |
+
|
| 259 |
+
`wp_fbs_activities` records `action`, `column`, `old_value`, `new_value`, `description`, `created_by`, `settings`, but no `rationale` or `reason` field. A task moved from "In Progress" to "Paused" leaves a row noting the transition, but **why** is not captured in a structured way (only sometimes in `description` as freeform text).
|
| 260 |
+
|
| 261 |
+
The arbitration record SA-orchestration adds is the structural carrier of *why* — independent of the surface that records *what*.
|
| 262 |
+
|
| 263 |
+
---
|
| 264 |
+
|
| 265 |
+
## 6. Natural test fixtures
|
| 266 |
+
|
| 267 |
+
### 6.1 Ticket 12 — closure / reopen ambiguity
|
| 268 |
+
|
| 269 |
+
The simultaneous-state inconsistency (`status='active'` + `resolved_at` set + `closed_by=1`) makes ticket 12 a ready-made fixture for testing:
|
| 270 |
+
|
| 271 |
+
- The closure-rule discipline (`SIGNAL_FLOW.md`: closure is affirmative, not inferred).
|
| 272 |
+
- An Asterion-style append-only acceptance log (where `closed_at`, `reopened_at`, `re_closed_at` would each be distinct canonical writes, not mutable fields on one row).
|
| 273 |
+
- Drift detection between surface state and canonical state (the surface says one thing, the conversation log says another).
|
| 274 |
+
|
| 275 |
+
### 6.2 Mission.net board
|
| 276 |
+
|
| 277 |
+
Board id 16, title `Mission.net`, 9 tasks, owned by production user 18 (`pverrette`). Created 2026-03-27, updated 2026-03-31. The name aligns with the SA-Core / MissionNet vocabulary in the spec pack (`Archvie/sa-core/`). This board is the most directly relevant fixture for SA-orchestration's own development arc — it is the work that already used Fluent Boards under the same conceptual frame.
|
| 278 |
+
|
| 279 |
+
### 6.3 Boards with rich activity logs
|
| 280 |
+
|
| 281 |
+
Boards with substantial task + activity volume, useful for replay-style testing of Energy → Matter convergence:
|
| 282 |
+
|
| 283 |
+
| Board | Tasks | Activity density (approx) |
|
| 284 |
+
|---|---:|---|
|
| 285 |
+
| Inserio | 8 | High (board id 1, earliest, most state transitions) |
|
| 286 |
+
| Mission.net | 9 | High |
|
| 287 |
+
| Sleeper Agents Pipeline | 8 | High |
|
| 288 |
+
| Boatman Union | 7 | Medium-high |
|
| 289 |
+
| Sales Meeting - 3/11 | 7 | Medium-high |
|
| 290 |
+
| CARMA | 6 | Medium |
|
| 291 |
+
| FluidFlow Pro | 3 | Medium (with substantive board-description content) |
|
| 292 |
+
|
| 293 |
+
Total of 57 tasks and 284 activity rows is more than enough fixture data to exercise convergence-style ingestion and arbitration.
|
| 294 |
+
|
| 295 |
+
### 6.4 CSV bulk import event (Mar 2)
|
| 296 |
+
|
| 297 |
+
The 27 CSV-sourced subscriber rows all share `created_at = 2026-03-02 15:42:00` — a single bulk import. Useful as a fixture for **batched Energy** scenarios: many surface events arriving simultaneously, all contributing to the Stakeholder identity layer in one moment, none of them yet bound to Demand or Plan.
|
| 298 |
+
|
| 299 |
+
---
|
| 300 |
+
|
| 301 |
+
## 7. What SA-orchestration must add
|
| 302 |
+
|
| 303 |
+
> **Status as of 2026-05-01: delivered in plugin v0.5.2.** The targets enumerated below were named when this file was first written and the plugin did not yet exist. They are now implemented as the SA-Orchestration WordPress plugin (three-table schema, Asterion-first writes, deterministic audit, strategy LLM seam with OpenAI active). See `PLUGIN_STATUS.md` for the running status, schema, and constraints.
|
| 304 |
+
|
| 305 |
+
Observations 5.1–5.4 enumerate the structural gaps. The SA-orchestration discipline addresses them through the following Asterion-canonical artifacts.
|
| 306 |
+
|
| 307 |
+
### 7.1 Arbitration record
|
| 308 |
+
|
| 309 |
+
*Implemented as `wp_sa_arbitration` table + `SA_Orch_Arbitration::write()` since v0.1.0. See `PLUGIN_STATUS.md`.*
|
| 310 |
+
|
| 311 |
+
The canonical entity that records the act of translating a Demand into a Plan. Carries:
|
| 312 |
+
|
| 313 |
+
- `demand_ref` (link to ticket / conversation / surface evidence)
|
| 314 |
+
- `plan_refs[]` (links to one or more board tasks resulting from the arbitration)
|
| 315 |
+
- `rationale` (Manager-via-SARA's reasoning, mandatory)
|
| 316 |
+
- `projection_type` (the kind of Demand → Plan translation: scope-direct, scope-decomposed, scope-deferred, scope-merged, etc.)
|
| 317 |
+
- `actor` (Manager identity)
|
| 318 |
+
- `correlation_id`, `causation_id` (causal trace)
|
| 319 |
+
- `truth_class = canonical` (lives only here)
|
| 320 |
+
|
| 321 |
+
This is the **only thing** SA-orchestration is canonical for. See `CORE_MODEL.md`.
|
| 322 |
+
|
| 323 |
+
### 7.2 Demand → Plan trace
|
| 324 |
+
|
| 325 |
+
*Implemented as `wp_sa_arbitration_plan_link` table + the GET trace REST endpoint since v0.1.0. See `PLUGIN_STATUS.md`.*
|
| 326 |
+
|
| 327 |
+
The graph edge missing at the Fluent layer. SA-orchestration provides it via the arbitration record: from a `wp_fs_tickets` row, walk forward through the arbitration entity to the resulting `wp_fbs_tasks` rows. From a task, walk backward through the arbitration to the originating ticket(s).
|
| 328 |
+
|
| 329 |
+
The trace is not stored on the Fluent rows — it lives in Asterion. Fluent rows remain realm-canonical for their own attributes (I1).
|
| 330 |
+
|
| 331 |
+
### 7.3 Acceptance event handling
|
| 332 |
+
|
| 333 |
+
*Implemented as `wp_sa_acceptance_event` table + `SA_Orch_Acceptance::write()` (append-only) since v0.1.0. Closure rule extended to role-aware in v0.2.0; `needs_human_arbitration` triggers added in v0.4.1; `n/a` confidence floor enforced for the strategy layer in v0.5.2. See `PLUGIN_STATUS.md`.*
|
| 334 |
+
|
| 335 |
+
Replace the mutable-field ambiguity (5.3) with an append-only event sequence in Asterion:
|
| 336 |
+
|
| 337 |
+
- `acceptance_proposed` (agent marks resolved)
|
| 338 |
+
- `acceptance_disputed` (customer reopens)
|
| 339 |
+
- `acceptance_affirmed` (stakeholder explicit re-close, mapped to `human_affirmed_at` per SA-Core Invariant I7)
|
| 340 |
+
|
| 341 |
+
Each event is canonical-at-write. Closure is the chain reaching `acceptance_affirmed` without subsequent dispute, not a single field.
|
| 342 |
+
|
| 343 |
+
### 7.4 Asterion canonical ledger
|
| 344 |
+
|
| 345 |
+
*Implemented as `SA_Orch_Asterion::write()` (Asterion-first discipline) since v0.1.0. Ledger root: `wp-content/sa-asterion/{kind}/{hash}.md` with `SA_Doc_Lens`-shaped frontmatter. See `PLUGIN_STATUS.md`.*
|
| 346 |
+
|
| 347 |
+
The markdown corpus where the above lives. Per `CORE_MODEL.md`, Asterion is the single canonical home; runtime DB is cache. Each arbitration / acceptance event is co-canonically a markdown ledger entry plus a runtime row, written atomically.
|
| 348 |
+
|
| 349 |
+
---
|
| 350 |
+
|
| 351 |
+
## Source traceability
|
| 352 |
+
|
| 353 |
+
- Dump file: `wp_sleeperagendev.sql` (394KB / 4222 lines, phpMyAdmin 5.2.3).
|
| 354 |
+
- Dump origin: production WP Engine pod `pod-227644.pod-227644.svc.cluster.local:3306:13306`, MySQL 8.4.7, PHP 8.3.30.
|
| 355 |
+
- Generation time: 2026-05-01 18:31 UTC.
|
| 356 |
+
- Imported into local DB `wp_local_dev` (MariaDB 10.4.24 under XAMPP).
|
| 357 |
+
- Filtered import file: `%TEMP%\sa-orch-fluent-import.sql` (230KB, retained for reference).
|
| 358 |
+
- Production wp-config.php (with WPE secrets) preserved at `F:\XAMPP\wordpress\wp-config.php.production-backup-20260501`.
|
| 359 |
+
|
| 360 |
+
This fixture is **not Asterion canonical**. It is observation evidence — projection-surface data from one production realm at one moment in time. Asterion canonical state is built on top, not replaced by this import.
|
SA-orchestration MD/ONBOARDING.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: standing_discipline
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
attribution: Mark Holak (CAMP, SARA, Asterion, Energy/Matter, convergence-collapse)
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
# SA-Orchestration — Developer & Agent Onboarding
|
| 9 |
+
|
| 10 |
+
## Purpose
|
| 11 |
+
|
| 12 |
+
This file is the first authority-gated development protocol for the repository. It is not a welcome mat.
|
| 13 |
+
|
| 14 |
+
It serves three functions:
|
| 15 |
+
|
| 16 |
+
1. Anchor any human or coding agent entering this repo to the binding constraint model, before any setup or build action.
|
| 17 |
+
2. Detect which operating mode applies (Bootstrap or Maintenance) before issuing setup instructions.
|
| 18 |
+
3. Surface the protocol gates that must fire before related actions proceed.
|
| 19 |
+
|
| 20 |
+
This file is dual-natured by design:
|
| 21 |
+
|
| 22 |
+
- Its **principles** (the discipline, mode-detection logic, gates) are **Matter** the moment this file is committed.
|
| 23 |
+
- Its **state references** (the actual environment, mode, discovery findings) live in `ENVIRONMENT.md` and become Matter as observations stabilize.
|
| 24 |
+
|
| 25 |
+
> **Folder name note.** This repo lives at `SA-orchestration/` on disk. A future rename to `sa-camp/` is on the table; do not rename in the present.
|
| 26 |
+
|
| 27 |
+
---
|
| 28 |
+
|
| 29 |
+
## Read first (in order)
|
| 30 |
+
|
| 31 |
+
Before any action in this repo, read:
|
| 32 |
+
|
| 33 |
+
1. `CORE_MODEL.md` — SA-Core, CAMP, SARA, Asterion. The canonical primitives.
|
| 34 |
+
2. `ENERGY_MODEL.md` — Energy / Matter duality, convergence-collapse. The dynamics.
|
| 35 |
+
3. `SIGNAL_FLOW.md` — The Change-System six-stage causal chain.
|
| 36 |
+
4. `PROJECTION_SURFACES.md` — Fluent, Boards, WordPress, etc. — what they are and what they aren't.
|
| 37 |
+
5. `DEVELOPMENT_MODES.md` — Bootstrap vs Maintenance. Detection logic.
|
| 38 |
+
6. `SCATTER_AND_CONVERGENCE.md` — Two-layer scatter, threshold (basin depth).
|
| 39 |
+
7. `BYPASS_AND_RECOVERY.md` — Surfaces under Core absence; controlled plugin override.
|
| 40 |
+
8. `ENVIRONMENT.md` — User-declared resources, runtime, secrets, discovery state.
|
| 41 |
+
9. `FLUENT_DATA_MAPPING.md` — First live test fixture; mapping of Fluent tables to Change-System concepts.
|
| 42 |
+
10. `PLUGIN_STATUS.md` — SA-Orchestration plugin (v0.5.2): schema, layers, providers, hard rules.
|
| 43 |
+
|
| 44 |
+
These files together are Asterion's first canonical emission. Future updates are convergence events.
|
| 45 |
+
|
| 46 |
+
Authoritative spec pack (binding ontology and invariants):
|
| 47 |
+
|
| 48 |
+
- `Archvie/sa-core/docs/specs/01-ontology.md`
|
| 49 |
+
- `Archvie/sa-core/docs/specs/02-invariants.md` (I1–I9)
|
| 50 |
+
- `Archvie/sa-core/docs/specs/03-realm-adapter-contract.md`
|
| 51 |
+
- `Archvie/sa-core/docs/specs/concepts/`
|
| 52 |
+
|
| 53 |
+
---
|
| 54 |
+
|
| 55 |
+
## First Rule — Mode Detection Before Action
|
| 56 |
+
|
| 57 |
+
Before issuing any setup instruction, determine which mode applies (per-area). Skipping this step produces wrong instructions, regardless of intent.
|
| 58 |
+
|
| 59 |
+
See `DEVELOPMENT_MODES.md` for detection logic and per-mode discipline.
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
## Authority Hierarchy
|
| 64 |
+
|
| 65 |
+
When sources disagree, this is the order:
|
| 66 |
+
|
| 67 |
+
1. **Observed environment state** (what `php -v`, `ls`, file contents actually return).
|
| 68 |
+
2. **User declarations** (what the user has explicitly named as available, intended, or required).
|
| 69 |
+
3. **This file's principles, and the constraint-model files referenced above**.
|
| 70 |
+
4. **External documentation, including prior versions of these files**.
|
| 71 |
+
5. **Agent memory, training-data defaults, generic best practices**.
|
| 72 |
+
|
| 73 |
+
A failure to invoke a tool or service is itself a higher-authority signal than a doc claiming it is available.
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## Execution Tiers
|
| 78 |
+
|
| 79 |
+
Three levels of agent capability operate alongside the per-area Mode (`DEVELOPMENT_MODES.md`).
|
| 80 |
+
|
| 81 |
+
### Tier 1 — Autonomous
|
| 82 |
+
|
| 83 |
+
The agent may perform without per-action confirmation:
|
| 84 |
+
|
| 85 |
+
- File inspection
|
| 86 |
+
- Structure analysis
|
| 87 |
+
- Config parsing
|
| 88 |
+
- Environment detection
|
| 89 |
+
- Non-destructive reads (file content, process state, syntax checks like `httpd -t`, `php -l`)
|
| 90 |
+
- Documentation updates that record observations or formalize discipline already agreed
|
| 91 |
+
|
| 92 |
+
### Tier 2 — Guided Execution
|
| 93 |
+
|
| 94 |
+
The agent must provide exact, environment-specific, ordered, minimal steps for the user to execute. The agent does NOT execute these directly:
|
| 95 |
+
|
| 96 |
+
- Starting / stopping services (Apache, MySQL, etc.)
|
| 97 |
+
- Creating databases
|
| 98 |
+
- Editing configuration files (`httpd.conf`, `my.ini`, `wp-config.php`, `.env`)
|
| 99 |
+
- Installing software
|
| 100 |
+
- Setting up runtime components (e.g., WordPress configuration)
|
| 101 |
+
- Importing data
|
| 102 |
+
- File moves with persistent effect
|
| 103 |
+
|
| 104 |
+
Tier 2 instructions must be:
|
| 105 |
+
|
| 106 |
+
- **Environment-specific** — use this user's actual paths (e.g., `F:\XAMPP\`), not generic install paths.
|
| 107 |
+
- **Explicit** — every step's action and expected outcome stated.
|
| 108 |
+
- **Ordered** — no implicit dependencies.
|
| 109 |
+
- **Minimal** — no extraneous steps.
|
| 110 |
+
|
| 111 |
+
### Tier 3 — Restricted
|
| 112 |
+
|
| 113 |
+
The agent must stop and escalate before proceeding:
|
| 114 |
+
|
| 115 |
+
- Overwriting existing configurations
|
| 116 |
+
- Handling production credentials (read-flag-without-echo only; mutation requires explicit confirmation)
|
| 117 |
+
- Destructive operations (file deletion, DB drops, schema changes that destroy data)
|
| 118 |
+
- Irreversible changes
|
| 119 |
+
|
| 120 |
+
The agent surfaces what it would do, the risks, and waits for explicit user confirmation. Confirmation does not generalize across actions.
|
| 121 |
+
|
| 122 |
+
### Tier × Mode interaction
|
| 123 |
+
|
| 124 |
+
Tiers and Modes are orthogonal and apply concurrently per area.
|
| 125 |
+
|
| 126 |
+
| Mode | Tier 1 character | Tier 2 character | Tier 3 character |
|
| 127 |
+
|---|---|---|---|
|
| 128 |
+
| Bootstrap | Inspect what little exists | Common — most setup is guided | When overwriting a Bootstrap default the user assumed |
|
| 129 |
+
| Maintenance | Inspect everything before any change | Common — preserve while modifying | Frequent — avoid breaking working setup |
|
| 130 |
+
| Partial Bootstrap / Recovery | Inspect what's salvageable | Common — recover step by step | Frequent — production secrets, mismatches, data preservation |
|
| 131 |
+
|
| 132 |
+
The agent **declares the active Tier explicitly** when offering or executing an action: *"I'll inspect this (Tier 1)…"*, *"Run the following steps (Tier 2)…"*, *"This would overwrite X — stopping for your confirmation (Tier 3)."*
|
| 133 |
+
|
| 134 |
+
The agent **defaults to the lowest Tier sufficient** for the action. If the same outcome is achievable at Tier 1 (autonomous read) or Tier 2 (user-executed step), prefer Tier 1 unless the user has indicated otherwise.
|
| 135 |
+
|
| 136 |
+
---
|
| 137 |
+
|
| 138 |
+
## Triggers and Gates
|
| 139 |
+
|
| 140 |
+
These are the protocol gates that must fire before related setup actions proceed.
|
| 141 |
+
|
| 142 |
+
| Trigger | Mode | Required action |
|
| 143 |
+
|---|---|---|
|
| 144 |
+
| Empty folder detected | Bootstrap | Confirm with user before populating; ask which user-declared resources to use |
|
| 145 |
+
| WordPress not detected | Bootstrap | WordPress setup path under XAMPP — user-declared resources only; never download/install silently |
|
| 146 |
+
| WordPress detected, locally-correct, services running | Maintenance | Inspect `wp-config.php`, plugin set, theme, multisite state, table prefix, before any change |
|
| 147 |
+
| WordPress files present but config is remote/production, or services not running, or files outside `DocumentRoot`, or referenced DB missing | Partial Bootstrap / Recovery | Inspect first; flag production secrets as sensitive (do **not** echo); surface course-correction options before any change |
|
| 148 |
+
| `.env` or key vault missing | Either | Declare required secret strategy with the user **before** build proceeds; never invent or commit secrets |
|
| 149 |
+
| External service unavailable (Fluent, OpenAI, etc.) | Either | Mark as deferred or mocked in the discovery output; do **not** assume working; do **not** invent fallback credentials |
|
| 150 |
+
| Command unavailable (`php`, `composer`, `wp`, etc.) | Either | Record the failure verbatim and request user action; do **not** infer that an equivalent tool can substitute |
|
| 151 |
+
| Conflict between observed state and prior documentation | Either | Observed state wins; record the conflict in the discovery output for user resolution |
|
| 152 |
+
| Two convergent locations for the same canonical event | Either | Refusal-to-collapse is valid; record the field state, do not force crystallization |
|
| 153 |
+
| Production secrets discovered in a local file | Partial Bootstrap / Recovery | Flag without echoing values; recommend backup-outside-repo + separation of local config; treat as sensitive |
|
| 154 |
+
|
| 155 |
+
Gates are not optional. A gate that does not fire is a missed observation; a gate that fires without action is a discipline violation.
|
| 156 |
+
|
| 157 |
+
---
|
| 158 |
+
|
| 159 |
+
## Required Next Step
|
| 160 |
+
|
| 161 |
+
1. Read the constraint-model files (in the order listed above).
|
| 162 |
+
2. Run mode detection per-area. See `DEVELOPMENT_MODES.md`.
|
| 163 |
+
3. Run an environment discovery pass under whichever modes apply. See `ENVIRONMENT.md`.
|
| 164 |
+
4. Update `ENVIRONMENT.md`'s state tables with observed facts. Each update is a convergence event — a single command's output is a contribution, not yet Matter; Matter forms when observations stabilize.
|
| 165 |
+
5. Surface gates that fired and the actions they require to the user.
|
| 166 |
+
6. Do not proceed to implementation until the constraint-model files have been read and `ENVIRONMENT.md` reflects the current setup with user confirmation.
|
| 167 |
+
|
| 168 |
+
When the environment changes, re-read this file and update `ENVIRONMENT.md`. Outdated state in Asterion is a lie of higher cost than no state at all — drift between Asterion and runtime means runtime is wrong.
|
| 169 |
+
|
| 170 |
+
---
|
| 171 |
+
|
| 172 |
+
## Agent Instructions
|
| 173 |
+
|
| 174 |
+
If you are a coding assistant (Claude, Cursor, Replit, or another platform):
|
| 175 |
+
|
| 176 |
+
1. Read the constraint-model files before any other action in this repo.
|
| 177 |
+
2. Detect the mode (per-area) before proposing any setup step.
|
| 178 |
+
3. Inspect before assuming. Run discovery commands; do not infer.
|
| 179 |
+
4. Report what tools are available, what tools are missing, what services responded, what failed.
|
| 180 |
+
5. Do not invent credentials, services, commands, or file paths. If a value is unknown, ask.
|
| 181 |
+
6. Treat command failures as observations of higher authority than any document claiming the command works.
|
| 182 |
+
7. If you cannot perform a setup action directly, give the user **exact project-specific steps** — not generic defaults.
|
| 183 |
+
8. Prefer updating these files over answering from memory. Asterion is canonical-at-write; your memory is not.
|
| 184 |
+
9. Treat outdated documentation (including prior versions of these files) as lower authority than observed environment state.
|
| 185 |
+
10. When these files conflict with observation, observation wins, and the conflict is recorded here for user resolution.
|
| 186 |
+
11. State the active Execution Tier when offering or executing an action (Tier 1 / Tier 2 / Tier 3 — see *Execution Tiers* above).
|
| 187 |
+
12. Default to the lowest Tier sufficient for the action.
|
| 188 |
+
13. Tier 3 is non-overrideable without explicit per-action user confirmation. Memory of past confirmations does not generalize.
|
| 189 |
+
|
| 190 |
+
---
|
| 191 |
+
|
| 192 |
+
## Status
|
| 193 |
+
|
| 194 |
+
| Area | Status | Source of detail |
|
| 195 |
+
|---|---|---|
|
| 196 |
+
| Constraint-model files | Matter (committed) | `CORE_MODEL.md`, `ENERGY_MODEL.md`, `SIGNAL_FLOW.md`, `PROJECTION_SURFACES.md`, `DEVELOPMENT_MODES.md`, `SCATTER_AND_CONVERGENCE.md`, `BYPASS_AND_RECOVERY.md` |
|
| 197 |
+
| Mode (per-area) | Energy (pending detection) | `DEVELOPMENT_MODES.md` |
|
| 198 |
+
| Environment state | Energy (pending discovery) | `ENVIRONMENT.md` |
|
| 199 |
+
| Surface integrations | Energy (pending) | `PROJECTION_SURFACES.md` |
|
| 200 |
+
|
| 201 |
+
---
|
| 202 |
+
|
| 203 |
+
## Plugin source layout
|
| 204 |
+
|
| 205 |
+
The SA-Orchestration plugin's **canonical source** lives in this repo at `plugin/sa-orchestration/`. The **runtime deployment** lives at `F:\XAMPP\wordpress\wp-content\plugins\sa-orchestration\` — that's where WordPress loads it from.
|
| 206 |
+
|
| 207 |
+
**Workflow going forward:**
|
| 208 |
+
|
| 209 |
+
1. Edit canonical source under `plugin/sa-orchestration/` in this repo.
|
| 210 |
+
2. Copy the tree to the runtime path so WordPress sees the changes.
|
| 211 |
+
3. Reactivate the plugin if migrations need to re-run (rare — schema has not changed since v0.1.0).
|
| 212 |
+
|
| 213 |
+
**Bootstrap history:** v0.1.0–v0.5.2 were developed directly at the runtime path. The canonical source was promoted into the repo on 2026-05-01 (17 files / 111336 bytes / 17 SHA-256 matches between source and runtime at the moment of promotion). The runtime copy was not moved or deleted; both trees currently agree.
|
| 214 |
+
|
| 215 |
+
**Symlinking** the canonical source into the runtime path (so WordPress reads the repo tree directly) is an option for the future but not yet enabled. For now, deployment is a manual copy.
|
| 216 |
+
|
| 217 |
+
For full plugin status (schema, layers, providers, hard rules, version history), see `PLUGIN_STATUS.md`.
|
| 218 |
+
|
| 219 |
+
## Forward References
|
| 220 |
+
|
| 221 |
+
The following may emerge as the repo gains further substance.
|
| 222 |
+
|
| 223 |
+
- `.env.example` — to be authored when the first integration target is chosen and a vault strategy is declared.
|
| 224 |
+
- `DEVENV/<os>.md` — per-OS developer environment specifics, if the OS-bound list in `ENVIRONMENT.md` outgrows a single section.
|
| 225 |
+
- `TOOLS.md` (or `tools/<capability>.md`) — capability declarations, OS-agnostic, runtime-resolved.
|
| 226 |
+
- Asterion frontmatter shape — formalized schema for canonical-at-write ledger entries (current frontmatter is minimal pending this).
|
| 227 |
+
- Realm adapter implementations — partial `SA_Realm_Adapter` for `fluent-support`, then `fluent-boards`, etc.
|
| 228 |
+
- `plugin/sa-orchestration/` symlink to the WordPress runtime path (would eliminate the manual copy step; requires admin privileges on Windows).
|
| 229 |
+
- `tests/` directory at repo root for the regression suite currently at `F:\XAMPP\wordpress\sa-orch-regression.php`.
|
| 230 |
+
|
| 231 |
+
---
|
| 232 |
+
|
| 233 |
+
## Attribution
|
| 234 |
+
|
| 235 |
+
CAMP, SARA, Asterion, Energy/Matter duality, and convergence-collapse: **Mark Holak** (subject to later separation for IP reasons). See individual constraint-model files for vocabulary first-introduction.
|
| 236 |
+
|
| 237 |
+
Holak's prior named concepts (Prime Prompt, Cognitive Heatsink, Signal Telemetry Doctrine, Reference Traversal Continuity) are preserved verbatim at `Archvie/sa-core/docs/specs/concepts/` under SA-Core Invariant I9.
|
| 238 |
+
|
| 239 |
+
This file: standing discipline, project-canonical.
|
SA-orchestration MD/PLUGIN_STATUS.md
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: state_record
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
# Plugin Status — SA-Orchestration v0.6.2
|
| 8 |
+
|
| 9 |
+
<!-- BEGIN VERIFICATION STAMP -->
|
| 10 |
+
> **Verification stamp** — when the state recorded below was last confirmed against reality.
|
| 11 |
+
>
|
| 12 |
+
> - **Last Verified At**: 2026-05-02 15:37 UTC
|
| 13 |
+
> - **Verified By**: test suite
|
| 14 |
+
> - **Environment**: local
|
| 15 |
+
>
|
| 16 |
+
> Update via the repo-root helper: `php verify-stamp.php [--by=manual|test|llm] [--env=local|staging|prod] [--at=<timestamp>]`. Manual confirmation only — no auto-stamping. See `verify-stamp.php` for usage.
|
| 17 |
+
<!-- END VERIFICATION STAMP -->
|
| 18 |
+
|
| 19 |
+
The SA-Orchestration WordPress plugin is the first runnable implementation slice of this project's constraint model. This file records its current state. When the plugin's behavior changes, this file changes with it (otherwise this file is the lie — see `CORE_MODEL.md` on canonical-at-write).
|
| 20 |
+
|
| 21 |
+
## Existence and location
|
| 22 |
+
|
| 23 |
+
- **Plugin name**: SA-Orchestration
|
| 24 |
+
- **Current version**: **v0.6.2**
|
| 25 |
+
- **Plugin slug**: `sa-orchestration`
|
| 26 |
+
- **Canonical source**: `plugin/sa-orchestration/` (this repo). Edits go here.
|
| 27 |
+
- **Runtime deployment**: `F:\XAMPP\wordpress\wp-content\plugins\sa-orchestration\` (the WordPress install loads this copy).
|
| 28 |
+
- **Sync method**: copy (manual). After editing canonical source, copy the tree to the runtime path. Symlink is an option but not yet enabled.
|
| 29 |
+
- **Bootstrap history**: v0.1.0 through v0.5.2 were developed directly at the WordPress runtime path. As of 2026-05-01 the canonical source was promoted into this repo at `plugin/sa-orchestration/` (verified: 17 files / 111336 bytes / 17 SHA-256 matches between source and runtime at the moment of promotion). v0.6.0 (projection layer) was authored canonically in the repo and copied to runtime (verified: 18 / 18 SHA-256 matches). v0.6.1 (projection-UX refinement) was authored canonically in the repo and copied to runtime (canonical/runtime SHA-256 matches at sync). v0.6.2 (Demand Trace explorable picker) was authored canonically in the repo and copied to runtime (canonical/runtime SHA-256 matches at sync). The runtime copy continues to be active and was not moved or deleted.
|
| 30 |
+
|
| 31 |
+
## Schema — three tables
|
| 32 |
+
|
| 33 |
+
All `ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`. WP prefix `wp_`. **No schema change since v0.1.0** — three tables, same shape, no migrations.
|
| 34 |
+
|
| 35 |
+
| Table | Role |
|
| 36 |
+
|---|---|
|
| 37 |
+
| `wp_sa_arbitration` | Canonical arbitration record. Per arbitration moment: rationale, projection_type, demand_ref, actor, correlation_id / causation_id, truth_class, asterion_path, hash-stable identity. |
|
| 38 |
+
| `wp_sa_arbitration_plan_link` | Demand → Plan edge. One arbitration → N plan refs (or zero if `scope-direct-no-plan`). `link_kind ∈ {derived, observed}`. |
|
| 39 |
+
| `wp_sa_acceptance_event` | Append-only event chain. `event_type ∈ {result_claimed, acceptance_disputed, acceptance_affirmed, acceptance_revoked}`. `prior_event_id` chains within the chain. |
|
| 40 |
+
|
| 41 |
+
No DB-level FK to Fluent tables (per SA-Core invariant I8 — tool test: removing this plugin must not corrupt Fluent).
|
| 42 |
+
|
| 43 |
+
## Asterion-first writes
|
| 44 |
+
|
| 45 |
+
Every canonical row in the three tables has a corresponding markdown file at `wp-content/sa-asterion/{kind}/{hash}.md` with YAML frontmatter readable by `SA_Doc_Lens`. Asterion writes happen **before** DB writes; if the file write fails, no DB row is created. Drift between runtime DB and Asterion means runtime is wrong (per `CORE_MODEL.md`: Asterion is canonical, runtime is cache).
|
| 46 |
+
|
| 47 |
+
## Four-layer review stack
|
| 48 |
+
|
| 49 |
+
```
|
| 50 |
+
1. Trace data — what's in the database / Asterion ledger
|
| 51 |
+
2. Deterministic Trace Audit — local rules-based, no API, repeatable
|
| 52 |
+
3. Strategy LLM Review — provider-pluggable
|
| 53 |
+
4. Human arbitration — final meaning; always wins
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
### Layer 2 — Deterministic Trace Audit (`SA_Orch_Reasoning`)
|
| 57 |
+
|
| 58 |
+
Rules implemented (v0.4.1):
|
| 59 |
+
- Closure authority invalid (`acceptance_affirmed` by non-stakeholder).
|
| 60 |
+
- `projection_type` ↔ `plan_link` count mismatch.
|
| 61 |
+
- Affirmation without prior `result_claimed`.
|
| 62 |
+
- `prior_event_id` chain integrity.
|
| 63 |
+
- Multiple arbitrations on same Demand → scope drift.
|
| 64 |
+
- `projection_type` other than `scope-direct(-no-plan)` → scope drift.
|
| 65 |
+
- `truth_class=derived` on arbitration → scope drift.
|
| 66 |
+
- Dispute → affirm pattern → informational note.
|
| 67 |
+
- `acceptance_revoked` present → informational note.
|
| 68 |
+
|
| 69 |
+
Output: `summary`, `inconsistencies[]`, `scope_drift[]`, `notes[]`, `closure_confidence ∈ {high|medium|low|n/a}`, `closure_confidence_explanation`, `needs_human_arbitration`, `human_arbitration_triggers[]`.
|
| 70 |
+
|
| 71 |
+
**Needs Human Arbitration triggers** (any one is sufficient):
|
| 72 |
+
1. `closure_authority_valid = false`.
|
| 73 |
+
2. `truth_class = derived` on arbitration AND no acceptance events.
|
| 74 |
+
3. Multiple arbitrations on the same Demand.
|
| 75 |
+
4. Latest event is `acceptance_disputed`.
|
| 76 |
+
|
| 77 |
+
Verbatim user-facing line: *"This trace requires human arbitration before closure can be trusted."*
|
| 78 |
+
|
| 79 |
+
### Layer 3 — Strategy LLM Review (`SA_Orch_Strategy`)
|
| 80 |
+
|
| 81 |
+
Provider interface: **`SA_Orch_LLM_Provider_Interface`**. Method: `review_trace($trace, $deterministic_audit): array` returning the five-key contract:
|
| 82 |
+
|
| 83 |
+
```
|
| 84 |
+
{
|
| 85 |
+
summary: string,
|
| 86 |
+
agreement_with_audit: "true" | "false" | "partial",
|
| 87 |
+
additional_risks: string[],
|
| 88 |
+
suggested_next_action: string,
|
| 89 |
+
confidence: "low" | "medium" | "high"
|
| 90 |
+
}
|
| 91 |
+
```
|
| 92 |
+
|
| 93 |
+
| Provider id | Status | Behavior |
|
| 94 |
+
|---|---|---|
|
| 95 |
+
| `simulated` | **Always available; default** | Heuristic narrative + risk identification, no API call. Used as fallback on any provider error. |
|
| 96 |
+
| `openai` | **Active in v0.5.1** | Calls OpenAI Chat Completions API (or any OpenAI-compatible endpoint — Azure, OpenRouter, vLLM, llama.cpp server). 30s timeout. Server-side clamps response to contract shape. Falls back to simulated on network / HTTP / JSON errors. |
|
| 97 |
+
| `anthropic`, `local`, `custom` | Listed, not implemented | Inert placeholders so the seam is visible in the settings dropdown. |
|
| 98 |
+
|
| 99 |
+
Settings stored in `wp_options.sa_orch_llm_settings` (local-dev posture; future: SA-Core key vault). Tokens never echoed back; blank-token-saves preserve existing value.
|
| 100 |
+
|
| 101 |
+
### Layer 4 — Human arbitration
|
| 102 |
+
|
| 103 |
+
Final meaning. Always wins. The plugin records but does not adjudicate.
|
| 104 |
+
|
| 105 |
+
## Hard rules — Strategy Review CANNOT
|
| 106 |
+
|
| 107 |
+
The strategy layer (any provider, including OpenAI) **is purely advisory**. It MUST NOT and DOES NOT:
|
| 108 |
+
|
| 109 |
+
- Override `closure_state_basic`, `closure_state_role_aware`, or `closure_authority_valid`.
|
| 110 |
+
- Override `needs_human_arbitration`.
|
| 111 |
+
- Persist its output (recomputed on every page load).
|
| 112 |
+
|
| 113 |
+
These are governed by the deterministic audit (and ultimately by human arbitration). Enforced by:
|
| 114 |
+
- The five-key contract excluding closure / needs_human fields.
|
| 115 |
+
- The `clamp_to_contract()` step in each provider that drops any extra fields a model might inject.
|
| 116 |
+
- The orchestrator's metadata layering (`provider_id`, `configured_provider_id`, `fallback_used`, `provider_error`) keeping the strategy output in its own namespace.
|
| 117 |
+
|
| 118 |
+
## Conservative confidence floor (v0.5.2)
|
| 119 |
+
|
| 120 |
+
When the deterministic audit's `closure_confidence === 'n/a'` (no acceptance events to evaluate), the strategy review's `confidence` MUST collapse to `'low'`. `'medium'` and `'high'` are not allowed when closure cannot be evaluated.
|
| 121 |
+
|
| 122 |
+
**Two layers of enforcement** — both apply on every strategy review:
|
| 123 |
+
|
| 124 |
+
1. **OpenAI prompt rule** — system prompt instructs the model directly: *"If no acceptance events exist OR the deterministic audit's closure_confidence is 'n/a', you MUST return confidence: 'low'."*
|
| 125 |
+
2. **Orchestrator safety net** — `SA_Orch_Strategy::review()` silently downgrades to `'low'` if any provider returns `'medium'` or `'high'` when audit is `'n/a'`. Cross-cutting — applies to any current or future provider.
|
| 126 |
+
|
| 127 |
+
The strategy contract still has only `low | medium | high` (`'n/a'` is not introduced to the strategy layer; it remains exclusively a deterministic-audit concept).
|
| 128 |
+
|
| 129 |
+
## Partial projection — Fluent Support augmentation (v0.6.1)
|
| 130 |
+
|
| 131 |
+
SA-Orchestration state surfaces inside Fluent Support **without modifying any native field**. Native ticket records (`status`, `resolved_at`, `closed_by`, `customer_id`, etc.) are read-only from this plugin's perspective. Augmentation is additive and fully removable.
|
| 132 |
+
|
| 133 |
+
### Surface shape (two entries per ticket, ever)
|
| 134 |
+
|
| 135 |
+
v0.6.1 collapsed the per-event flood of v0.6.0 into a stable two-row pattern. A ticket under SA-Orch governance carries **exactly two** projected conversation entries, regardless of how many events its Demand has accumulated:
|
| 136 |
+
|
| 137 |
+
1. **Tracking marker** — one entry per ticket. Static voice. Not pinned. Upserts in place if the canonical phrasing or pinning rule changes.
|
| 138 |
+
|
| 139 |
+
```
|
| 140 |
+
[SA-Orch] Tracking this ticket.
|
| 141 |
+
Full record (arbitrations, acceptance events, audit) in WP Admin → SA-Orchestration → Demand Trace → ticket#NNNN.
|
| 142 |
+
```
|
| 143 |
+
|
| 144 |
+
2. **State summary** — one entry per ticket. Header reflects current state ("Closed — stakeholder affirmation", "Result claimed — awaiting affirmation", "Revoked — open again", "Disputed", "Needs review — disputed", "Needs review — closure not authoritative", "Needs review — multiple arbitrations on this ticket", "Needs review — Demand reconstructed from indirect signals", "Tracking — awaiting result"). Upserts in place via stable idempotency key. Pinned (`is_important='yes'`) only when needs review; otherwise unpinned. When needs review, the body carries an `Action:` line phrased for the agent.
|
| 145 |
+
|
| 146 |
+
Example (closure clean):
|
| 147 |
+
```
|
| 148 |
+
[SA-Orch] Closed — stakeholder affirmation
|
| 149 |
+
The stakeholder affirmed acceptance on 2026-04-22 10:00 UTC. Closure is authoritative.
|
| 150 |
+
Trace: WP Admin → SA-Orchestration → Demand Trace → ticket#1002
|
| 151 |
+
```
|
| 152 |
+
|
| 153 |
+
Example (needs review — closure not authoritative):
|
| 154 |
+
```
|
| 155 |
+
[SA-Orch] Needs review — closure not authoritative
|
| 156 |
+
Acceptance was affirmed by an agent on 2026-04-30 11:00 UTC — but only the stakeholder can authoritatively close.
|
| 157 |
+
Action: ask the stakeholder to affirm the result, or record their actual response (affirm or dispute).
|
| 158 |
+
Trace: WP Admin → SA-Orchestration → Demand Trace → ticket#1004
|
| 159 |
+
```
|
| 160 |
+
|
| 161 |
+
Per-event entries (v0.6.0) and the separate "Needs human arbitration" entry (v0.6.0) are **gone**. Full event history remains available via WP Admin → SA-Orchestration → Demand Trace.
|
| 162 |
+
|
| 163 |
+
### Augmentation surfaces
|
| 164 |
+
|
| 165 |
+
1. **Ticket meta** in `wp_fs_meta` with `object_type='ticket'` and key prefix `_sa_orch_*`:
|
| 166 |
+
- `_sa_orch_arbitration_hash` — most recent arbitration hash for this Demand.
|
| 167 |
+
- `_sa_orch_needs_human` — `'true'` | `'false'`.
|
| 168 |
+
- `_sa_orch_closure_authority` — `stakeholder` | `agent` | `system` | `inferred` | (empty when no affirmation event).
|
| 169 |
+
|
| 170 |
+
2. **Conversation entries** in `wp_fs_conversations` with `source='sa-orch'`:
|
| 171 |
+
- Two rows per Demand-bound ticket (tracking + state, as above). Both keyed by `content_hash = md5(idempotency_key)` against a stable per-ticket key, so updates land on the same row.
|
| 172 |
+
|
| 173 |
+
### Projection class
|
| 174 |
+
|
| 175 |
+
`SA_Orch_Projection_Fluent_Support` (in `includes/class-sa-projection-fluent-support.php`).
|
| 176 |
+
|
| 177 |
+
**Hook contract** — projection subscribes to two action hooks fired by the writers:
|
| 178 |
+
|
| 179 |
+
| Hook | Fired by | Payload |
|
| 180 |
+
|---|---|---|
|
| 181 |
+
| `sa_orch_arbitration_written` | `SA_Orch_Arbitration::write()` after successful insert | arbitration row data including `id`, `hash`, `demand_surface`, `demand_ref`, `truth_class`, `asterion_path` |
|
| 182 |
+
| `sa_orch_acceptance_event_written` | `SA_Orch_Acceptance::write()` after successful insert | event row data including `id`, `hash`, `demand_surface`, `demand_ref`, `event_type`, `actor_role`, `actor_user_id`, `truth_class`, `asterion_path` |
|
| 183 |
+
|
| 184 |
+
Hooks fire **after** the canonical write succeeds (Asterion + DB), so projection can never run on phantom data.
|
| 185 |
+
|
| 186 |
+
**Public methods**:
|
| 187 |
+
|
| 188 |
+
- `register_hooks()` — wires up the two action listeners. Called from main plugin file on `init`.
|
| 189 |
+
- `project_ticket( $ticket_id )` — full projection for one ticket; safe to call repeatedly. Upserts both entries; prunes any leftover SA-Orch rows that aren't the current tracking or state entries.
|
| 190 |
+
- `backfill_all()` — projects every ticket that has any SA-Orch demand. Used to bootstrap state for tickets that pre-date the projection layer, or to migrate v0.6.0 entries to the v0.6.1 shape.
|
| 191 |
+
- `remove_all_for_ticket( $ticket_id )` — removes only the augmentation rows for one ticket.
|
| 192 |
+
- `remove_all()` — removes all `_sa_orch_*` meta and all `source='sa-orch'` conversations across the entire Fluent install.
|
| 193 |
+
|
| 194 |
+
**Person resolution** (for conversation `person_id`): prefers an FS person matching the event's `actor_user_id`; falls back to admin's FS person; falls back to any agent person. Never invents a row.
|
| 195 |
+
|
| 196 |
+
**Migration from v0.6.0**: `project_ticket()` calls `prune_legacy_sa_orch_rows()` after upserting, which deletes any `source='sa-orch'` conversation row for the ticket whose `content_hash` is neither the tracking marker hash nor the state-summary hash. Calling `backfill_all()` on a v0.6.0-projected install collapses 1+N+1 rows per ticket down to 2.
|
| 197 |
+
|
| 198 |
+
### Verified properties
|
| 199 |
+
|
| 200 |
+
9-check verification suite — all PASS as of the most recent run:
|
| 201 |
+
|
| 202 |
+
| # | Property | Result |
|
| 203 |
+
|---|---|---|
|
| 204 |
+
| 1 | Backfill collapses every ticket to exactly 2 SA-Orch conversation rows; v0.6.0 leftovers pruned | PASS |
|
| 205 |
+
| 2 | Tracking + state entries present for every ticket; phrasing has no `truth_class=` / `actor_role=` / `observed_at=` field-name leaks | PASS |
|
| 206 |
+
| 3 | State entry pinned (`is_important='yes'`) iff `_sa_orch_needs_human='true'`; otherwise unpinned | PASS |
|
| 207 |
+
| 4 | Idempotency — second `backfill_all()` writes nothing new | PASS |
|
| 208 |
+
| 5 | New `acceptance_event` hook fires → state summary upserts in place (same row id, content updated, no append, pin and Action: line track the new state) | PASS |
|
| 209 |
+
| 6 | Native ticket fields (`status`, `resolved_at`, `closed_by`, `customer_id`) hash unchanged through full test cycle | PASS |
|
| 210 |
+
| 7 | `remove_all()` zeros all augmentation; native still untouched after global remove | PASS |
|
| 211 |
+
| 8 | Re-projection from clean state restores 2 entries per ticket | PASS |
|
| 212 |
+
|
| 213 |
+
### Constraint compliance
|
| 214 |
+
|
| 215 |
+
- Native Fluent fields are never written (verified by status/resolved_at/closed_by/customer_id hash comparison before and after the full cycle).
|
| 216 |
+
- All augmentation is namespaced (`_sa_orch_*` meta keys, `source='sa-orch'` conversations).
|
| 217 |
+
- `remove_all()` is a complete uninstall path; restores Fluent to its pre-SA-Orch state.
|
| 218 |
+
- No new tables; no schema migration; no FK between SA-Orch tables and Fluent tables (I8 still honored).
|
| 219 |
+
- Timeline footprint is bounded: never more than two SA-Orch rows per ticket. New events update the state summary in place rather than appending.
|
| 220 |
+
|
| 221 |
+
## Admin UI
|
| 222 |
+
|
| 223 |
+
WP admin → SA-Orchestration menu:
|
| 224 |
+
|
| 225 |
+
- **Demand Trace** — explorable picker (v0.6.2): closed-vocabulary surface dropdown + searchable per-surface candidate browser + quick-select strip (SA-ORCH-TEST fixtures pinned, then most-recently-traced demands) + manual ref entry with live pattern validation. Once a demand is selected, renders the full chain (arbitrations, plan_links, acceptance events) plus deterministic audit (with prominent Needs Human Arbitration row) plus Strategy LLM Review plus side-by-side audit↔strategy comparison. Trace logic itself is unchanged from v0.6.1; only the input layer was upgraded.
|
| 226 |
+
- **Recent Arbitrations** — last 20.
|
| 227 |
+
- **Acceptance Events** — last 20.
|
| 228 |
+
- **Language Model Providers** — provider settings (enabled, provider, model, API base URL, API token; token masked, never echoed).
|
| 229 |
+
|
| 230 |
+
### Demand Trace picker (v0.6.2)
|
| 231 |
+
|
| 232 |
+
Goal: an operator never has to remember IDs to operate the system.
|
| 233 |
+
|
| 234 |
+
The picker is rendered by `SA_Orch_Admin::render_picker_form()` and uses one synchronous server render (no AJAX, no new endpoints, no schema). All candidate data is serialized inline as `window.SA_ORCH_PICKER` JSON; vanilla JS handles surface-switching, search-as-you-type, and selection.
|
| 235 |
+
|
| 236 |
+
**Components**:
|
| 237 |
+
|
| 238 |
+
| Component | Purpose |
|
| 239 |
+
|---|---|
|
| 240 |
+
| Quick-select strip | Up to 10 most-clickable demands. SA-ORCH-TEST fixtures pinned to the top by `is_test` flag; remaining slots filled by most-recently-traced demands across all surfaces. Each row is a permalink that pre-fills the form. |
|
| 241 |
+
| Surface dropdown | Closed enumeration: `fluent-support`, `fluent-boards`, `fluentcrm`, `derived` (mirrors `SA_Orch_Bridge_Fluent::known_surfaces()`). Empty option as default state. |
|
| 242 |
+
| Candidate browser | Search input + scrollable list. Re-populates on surface change; live-filters on input. Click → fills `demand_ref`. SA-ORCH-TEST tickets pinned at the top of the fluent-support pool. Capped at 50 rows per surface. |
|
| 243 |
+
| Manual ref input | Free-form text field. Validated client-side against per-surface regex (`^ticket#\d+$` / `^task#\d+$` / `^subscriber#\d+$` / `^derived#[A-Za-z0-9_\-]+$`). Inline ✓/✗ hint; never blocks submission. |
|
| 244 |
+
|
| 245 |
+
**Candidate fetchers** (private `SA_Orch_Admin` helpers, all read-only):
|
| 246 |
+
|
| 247 |
+
- `candidates_fluent_support()` — `wp_fs_tickets`, ordered by `(title LIKE '[SA-ORCH-TEST]%') DESC, id DESC`, cap 50.
|
| 248 |
+
- `candidates_fluent_boards()` — `wp_fbs_tasks`, ordered by `id DESC`, cap 50. Tolerant of missing table.
|
| 249 |
+
- `candidates_fluentcrm()` — `wp_fc_subscribers`, label = `full_name <email>` or `email`, cap 50. Tolerant of missing table.
|
| 250 |
+
- `candidates_derived()` — `DISTINCT demand_ref` from `wp_sa_arbitration` ∪ `wp_sa_acceptance_event` where `demand_surface='derived'`, ordered by max(created_at, observed_at), cap 50.
|
| 251 |
+
- `quick_select_demands($limit=10)` — UNION of `wp_sa_arbitration` + `wp_sa_acceptance_event` grouped by demand identity, sorted by `is_test DESC, last_at DESC`, cap 10.
|
| 252 |
+
|
| 253 |
+
**Constraints honored**:
|
| 254 |
+
- Trace logic untouched: `render_trace_results()` and `SA_Orch_Rest::get_demand_trace()` are unchanged.
|
| 255 |
+
- No new schema, no new tables, no new REST endpoints.
|
| 256 |
+
- Permalink shape preserved: `?page=sa-orchestration&demand_surface=…&demand_ref=…` still works (Recent Arbitrations and Acceptance Events deep-links continue to function and now pre-select the dropdown + ref input).
|
| 257 |
+
- Defensive on optional surfaces: Fluent Boards / FluentCRM tables are checked with `SHOW TABLES LIKE` before query; absent surfaces simply render an empty pool.
|
| 258 |
+
|
| 259 |
+
## REST endpoints (admin-only, `manage_options` capability)
|
| 260 |
+
|
| 261 |
+
- `POST /wp-json/sa-orch/v1/arbitration` — write an arbitration.
|
| 262 |
+
- `POST /wp-json/sa-orch/v1/acceptance` — append an acceptance event.
|
| 263 |
+
- `GET /wp-json/sa-orch/v1/demand/{surface}/{ref}/trace` — full chain + four closure fields (`closure_state`, `closure_state_basic`, `closure_state_role_aware`, `closure_authority_valid`).
|
| 264 |
+
|
| 265 |
+
## Files (`includes/`)
|
| 266 |
+
|
| 267 |
+
```
|
| 268 |
+
interface-sa-llm-provider.php — provider contract
|
| 269 |
+
class-sa-llm-provider-simulated.php — heuristic provider
|
| 270 |
+
class-sa-llm-provider-openai.php — OpenAI provider
|
| 271 |
+
class-sa-llm-providers.php — registry / active-provider resolver / fallback
|
| 272 |
+
class-sa-llm-settings.php — wp_options get/save (token masked)
|
| 273 |
+
class-sa-strategy.php — orchestrator (layer-3 entry); confidence floor
|
| 274 |
+
class-sa-reasoning.php — deterministic audit (layer 2)
|
| 275 |
+
class-sa-arbitration.php — write_arbitration entry; fires sa_orch_arbitration_written
|
| 276 |
+
class-sa-link.php — write_plan_link entry
|
| 277 |
+
class-sa-acceptance.php — append-only event writer + closure helpers; fires sa_orch_acceptance_event_written
|
| 278 |
+
class-sa-asterion.php — markdown ledger writer (Asterion-first)
|
| 279 |
+
class-sa-bridge-fluent.php — surface-ref resolver (closed vocabulary)
|
| 280 |
+
class-sa-rest.php — REST routes
|
| 281 |
+
class-sa-admin.php — admin UI (read-only)
|
| 282 |
+
class-sa-migrations.php — dbDelta on activation
|
| 283 |
+
class-sa-projection-fluent-support.php — partial projection: Fluent Support augmentation (v0.6.0)
|
| 284 |
+
```
|
| 285 |
+
|
| 286 |
+
## Surface vocabulary recognized
|
| 287 |
+
|
| 288 |
+
`SA_Orch_Bridge_Fluent::known_surfaces()` — closed enumeration:
|
| 289 |
+
|
| 290 |
+
- `fluent-support` → `wp_fs_tickets.id` via `ticket#NNNN`
|
| 291 |
+
- `fluent-boards` → `wp_fbs_tasks.id` via `task#NNNN`
|
| 292 |
+
- `fluentcrm` → `wp_fc_subscribers.id` via `subscriber#NNNN`
|
| 293 |
+
- `derived` → no underlying row; ref must match `^derived#[A-Za-z0-9_\-]+$`
|
| 294 |
+
|
| 295 |
+
Adding a surface = extending this single class.
|
| 296 |
+
|
| 297 |
+
## Test fixtures
|
| 298 |
+
|
| 299 |
+
Regression suite: `F:\XAMPP\wordpress\sa-orch-regression.php` (idempotent — cleans and re-creates `[SA-ORCH-TEST]`-prefixed fixtures on each run; should move to a `tests/` directory in this repo once a code section exists). Last verified pass: **10/10**.
|
| 300 |
+
|
| 301 |
+
Live fixtures currently in `wp_local_dev`:
|
| 302 |
+
- 4 synthetic tickets (#1001–#1004), 1 board (#1001), 3 stages, 3 tasks (#1001–#1003), 9+ activities.
|
| 303 |
+
- 5+ SA arbitrations, 9+ acceptance events, 6+ plan_links.
|
| 304 |
+
- Production-import fixtures from `wp_sleeperagendev.sql` (per `FLUENT_DATA_MAPPING.md`).
|
| 305 |
+
|
| 306 |
+
## Version history (running summary)
|
| 307 |
+
|
| 308 |
+
| Version | Slice |
|
| 309 |
+
|---|---|
|
| 310 |
+
| 0.1.0 | Three-table schema + Asterion-first writes + `write_arbitration` / `write_acceptance_event` / `write_plan_link` + REST endpoints. |
|
| 311 |
+
| 0.2.0 | Role-aware closure helpers: `closure_state_role_aware`, `closure_authority_valid`. |
|
| 312 |
+
| 0.3.0 | Admin UI: Demand Trace + Recent Arbitrations + Acceptance Events (read-only). |
|
| 313 |
+
| 0.4.0 | Reasoning Review (rules-based audit layer). |
|
| 314 |
+
| 0.4.1 | Renamed to Deterministic Trace Audit; added Needs Human Arbitration row + four triggers. |
|
| 315 |
+
| 0.5.0 | Strategy LLM Review layer (simulated provider only); provider seam + settings page. |
|
| 316 |
+
| 0.5.1 | OpenAI provider implementation; orchestrator tracks configured-vs-used + fallback transparency. |
|
| 317 |
+
| 0.5.2 | Conservative confidence floor: `n/a` audit forces `'low'` strategy confidence. |
|
| 318 |
+
| 0.6.0 | Partial projection: Fluent Support augmentation via `_sa_orch_*` meta + `source='sa-orch'` conversations; `do_action` hooks (`sa_orch_arbitration_written`, `sa_orch_acceptance_event_written`) for decoupled side effects; idempotent backfill + clean-uninstall removal path. No native Fluent field is modified. |
|
| 319 |
+
| 0.6.1 | Projection-UX refinement: collapsed 1+N+1 rows per ticket → exactly 2 (tracking marker + state summary, both upserted in place); per-event entries removed; needs-human folded into the state summary as a `Needs review — <reason>` header + `Action:` line; field-name leaks (`actor_role=`, `truth_class=`, `observed_at=`) replaced with human phrasing; pinning gated on needs-review; `prune_legacy_sa_orch_rows()` migrates v0.6.0 timelines on first re-projection. |
|
| 320 |
+
| 0.6.2 | Demand Trace explorable picker: free-form `demand_surface` / `demand_ref` text fields replaced with a closed-vocabulary surface dropdown + searchable per-surface candidate browser + quick-select strip (SA-ORCH-TEST pinned, then last-traced) + manual ref fallback with live regex validation. Trace logic and REST endpoint unchanged. No new schema, no new endpoints. |
|
| 321 |
+
|
| 322 |
+
## Constraints honored across all versions
|
| 323 |
+
|
| 324 |
+
- **No schema change since 0.1.0.** Three tables, same shape, no `dbDelta` re-runs.
|
| 325 |
+
- **Asterion-first.** Every canonical row has a matching ledger file. Drift = runtime is the lie.
|
| 326 |
+
- **Append-only acceptance.** Class exposes only `write()` and read methods; no `update()` or `delete()`.
|
| 327 |
+
- **Strategy layer never overrides audit-canonical fields.** Closure state and human-arbitration flag stay governed by the deterministic audit.
|
| 328 |
+
- **Tool test (I5 / I8).** Removing this plugin does not corrupt Fluent or any other surface. Fluent rows have no FK from this plugin's tables.
|
| 329 |
+
- **Partial projection is augmentation-only.** SA-Orch never writes to Fluent native fields (`status`, `resolved_at`, `closed_by`, `customer_id`, etc.). All projection lives in namespaced augmentation surfaces (`_sa_orch_*` meta + `source='sa-orch'` conversations) and is fully removable via `SA_Orch_Projection_Fluent_Support::remove_all()`. Verified by status/resolved_at/closed_by hash comparison before-and-after.
|
| 330 |
+
- **No production secrets in repo.** Local-dev WP Engine wp-config.php remains backed up at `F:\XAMPP\wordpress\wp-config.php.production-backup-20260501`; not part of this repo.
|
| 331 |
+
- **Token security.** Saved API tokens never displayed in admin UI; blank-token saves preserve.
|
SA-orchestration MD/PROJECTION_SURFACES.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: constraint_model
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
# Projection Surfaces
|
| 8 |
+
|
| 9 |
+
## Definition
|
| 10 |
+
|
| 11 |
+
A **projection surface** is an external system that emits evidence about Change-System concepts. Surfaces:
|
| 12 |
+
|
| 13 |
+
- Are not canonical for any Change-System concept (Demand, Arbitration, Plan, Action, Result, Acceptance — see `SIGNAL_FLOW.md`).
|
| 14 |
+
- Emit Energy that may converge into Matter at SA-Core / Asterion. See `ENERGY_MODEL.md`.
|
| 15 |
+
- May continue functioning when Core is unavailable (degraded mode). See `BYPASS_AND_RECOVERY.md`.
|
| 16 |
+
- Are incorporated via a realm adapter — see `Archvie/sa-core/docs/specs/03-realm-adapter-contract.md`.
|
| 17 |
+
|
| 18 |
+
A surface's own native records (a Fluent ticket row, a Boards card row, a WordPress post row) remain realm-canonical at the surface — that is what SA-Core Invariant I1 protects. The Change-System concepts (Demand, Plan, Acceptance, etc.) are Core-canonical and merely *expressed through* the surface.
|
| 19 |
+
|
| 20 |
+
The discriminator: realm data = the structures the realm itself defines. Core data = the structures Core itself defines. A Demand entity is Core data; a Fluent ticket is realm data; the relationship between them is a projection edge, not co-identity.
|
| 21 |
+
|
| 22 |
+
## Surface inventory
|
| 23 |
+
|
| 24 |
+
### Fluent Support
|
| 25 |
+
|
| 26 |
+
Role: projection surface for Demand evidence and Acceptance evidence.
|
| 27 |
+
|
| 28 |
+
| Aspect | Status |
|
| 29 |
+
|---|---|
|
| 30 |
+
| Realm id (planned) | `fluent-support` |
|
| 31 |
+
| Hosting | WordPress site (identity TBD) |
|
| 32 |
+
| Read capability | Pending integration |
|
| 33 |
+
| Watch capability | Pending integration |
|
| 34 |
+
| Write capability | Deferred (initial scope read+watch only) |
|
| 35 |
+
|
| 36 |
+
**Local fixture state (imported 2026-05-01):**
|
| 37 |
+
|
| 38 |
+
- Plugin active locally at version 2.0.6. Schema installed: 11 `wp_fs_*` tables.
|
| 39 |
+
- Data populated from production export `wp_sleeperagendev.sql`.
|
| 40 |
+
- Counts: 2 tickets (ids 12, 13), 9 persons (mix of agent and customer), 4 conversations, 1 mailbox, 1 attachment, 1 meta.
|
| 41 |
+
- See `FLUENT_DATA_MAPPING.md` §3 for details and §6.1 for the natural test fixture (ticket 12 closure/reopen ambiguity).
|
| 42 |
+
|
| 43 |
+
### Fluent Boards
|
| 44 |
+
|
| 45 |
+
Role: projection surface for Plan evidence and Action-tracking evidence.
|
| 46 |
+
|
| 47 |
+
| Aspect | Status |
|
| 48 |
+
|---|---|
|
| 49 |
+
| Realm id (planned) | `fluent-boards` |
|
| 50 |
+
| Hosting | WordPress site (identity TBD) |
|
| 51 |
+
| Read / watch / write | All pending integration |
|
| 52 |
+
|
| 53 |
+
**Local fixture state (imported 2026-05-01):**
|
| 54 |
+
|
| 55 |
+
- Plugin active locally at version 1.80. Schema installed: 12 `wp_fbs_*` tables.
|
| 56 |
+
- Data populated from production export `wp_sleeperagendev.sql`.
|
| 57 |
+
- Counts: 17 boards, 57 tasks, 284 activities, 135 board terms, 71 relations, 40 metas, 16 notifications, 17 notification users, 10 comments, 2 attachments.
|
| 58 |
+
- See `FLUENT_DATA_MAPPING.md` §4 for details and §6.2–6.3 for natural test fixtures (Mission.net board, activity-rich boards).
|
| 59 |
+
|
| 60 |
+
### FluentCRM
|
| 61 |
+
|
| 62 |
+
Role: identity / contact normalization layer (Stakeholder identity). Supplies contact identity to Demand and Plan layers; not itself a canonical home for any Change-System concept.
|
| 63 |
+
|
| 64 |
+
| Aspect | Status |
|
| 65 |
+
|---|---|
|
| 66 |
+
| Realm id (planned) | `fluentcrm` (naming convention TBD) |
|
| 67 |
+
| Hosting | WordPress site (local at `http://wordpress.localhost/`) |
|
| 68 |
+
| Read / watch / write | All pending integration |
|
| 69 |
+
|
| 70 |
+
**Local fixture state (imported 2026-05-01):**
|
| 71 |
+
|
| 72 |
+
- Plugin active locally at version 2.9.87. Schema installed: 17 `wp_fc_*` tables.
|
| 73 |
+
- Data populated from production export `wp_sleeperagendev.sql`.
|
| 74 |
+
- Counts: 32 subscribers, 197 subscriber meta entries, 26 tags, 5 lists, 6 meta entries, 2 subscriber pivot rows, 1 funnel.
|
| 75 |
+
- 1 production table (`wp_fc_companies`) skipped on import — companies feature not present in local plugin version.
|
| 76 |
+
- See `FLUENT_DATA_MAPPING.md` §2 for details.
|
| 77 |
+
|
| 78 |
+
### Jira
|
| 79 |
+
|
| 80 |
+
Role: alternate projection surface for Plan evidence (for shops that use it).
|
| 81 |
+
|
| 82 |
+
Status: future. Not in current scope.
|
| 83 |
+
|
| 84 |
+
### JobOrchestration
|
| 85 |
+
|
| 86 |
+
Role: projection surface for Action execution and Result observation.
|
| 87 |
+
|
| 88 |
+
Status: future. Not in current scope.
|
| 89 |
+
|
| 90 |
+
### WordPress
|
| 91 |
+
|
| 92 |
+
Role: runtime substrate for SA-Core (which ships as a WordPress plugin per the spec pack), and host for Fluent surfaces.
|
| 93 |
+
|
| 94 |
+
| Aspect | Status |
|
| 95 |
+
|---|---|
|
| 96 |
+
| Local install (XAMPP) | Not yet performed |
|
| 97 |
+
| Live site identity | TBD |
|
| 98 |
+
| Multisite posture | TBD |
|
| 99 |
+
| Plugin set | TBD |
|
| 100 |
+
|
| 101 |
+
### Provider adapters (LLM / model providers)
|
| 102 |
+
|
| 103 |
+
Role: providers for SARA-mediated arbitration cognition. Not Change-System surfaces themselves; supply reasoning capability to the Manager.
|
| 104 |
+
|
| 105 |
+
| Provider | Status |
|
| 106 |
+
|---|---|
|
| 107 |
+
| OpenAI | Not assumed present; declare before use |
|
| 108 |
+
| Anthropic | Not assumed present; declare before use |
|
| 109 |
+
| Other | Declare before use |
|
| 110 |
+
|
| 111 |
+
## Surface invariants
|
| 112 |
+
|
| 113 |
+
- **No surface-to-Asterion direct writes.** Surface evidence is Energy. Canonicalization happens only through CAMP.
|
| 114 |
+
- **No realm-data overwrite by Core.** Core never authors canonical state on a surface's behalf for the surface's own native records (SA-Core Invariant I1).
|
| 115 |
+
- **Tool test.** Removing SA-orchestration must not corrupt any incorporated surface (SA-Core Invariants I5, I8). Surfaces continue at their native homes.
|
| 116 |
+
- **Acceptance authority lives only at the surface of origin** for the canonical Demand. A close-ticket signal at Fluent Support is the *evidence form* of acceptance; the canonical Acceptance is in Asterion.
|
| 117 |
+
|
| 118 |
+
## Surfaces compose; they do not compete
|
| 119 |
+
|
| 120 |
+
Multiple surfaces emitting aligned evidence about the same Change-System concept contribute to the same convergence basin. The basin deepens; convergence forms above threshold; Matter writes once. See `ENERGY_MODEL.md`.
|
| 121 |
+
|
| 122 |
+
This is the normal case. Adding a new surface is adding field signal, not creating a parallel canonical home.
|
| 123 |
+
|
| 124 |
+
## Orchestration layer above the surfaces
|
| 125 |
+
|
| 126 |
+
The **SA-Orchestration WordPress plugin** (current v0.5.2) sits above the surfaces listed in this file and provides the canonical Demand→Plan→Acceptance graph that no surface natively carries. Surface vocabulary recognized by the plugin's `SA_Orch_Bridge_Fluent::known_surfaces()`:
|
| 127 |
+
|
| 128 |
+
| Surface id | Resolves to | Ref pattern |
|
| 129 |
+
|---|---|---|
|
| 130 |
+
| `fluent-support` | `wp_fs_tickets.id` | `ticket#NNNN` |
|
| 131 |
+
| `fluent-boards` | `wp_fbs_tasks.id` | `task#NNNN` |
|
| 132 |
+
| `fluentcrm` | `wp_fc_subscribers.id` | `subscriber#NNNN` |
|
| 133 |
+
| `derived` | (no underlying row — for reconstructed Demands) | `derived#<slug>` |
|
| 134 |
+
|
| 135 |
+
Adding a new surface to the plugin is a single-class extension. No DB-level FK from the plugin's tables to surface tables — per SA-Core invariant I8, removing the plugin does not corrupt any surface.
|
| 136 |
+
|
| 137 |
+
For the plugin's running status, schema, and version history, see `PLUGIN_STATUS.md`.
|
SA-orchestration MD/README.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SA-Orchestration — Operational Doctrine (MD reference)
|
| 2 |
+
|
| 3 |
+
This directory holds the **operational doctrine documents** from the SA-Orchestration source repo. They are NOT the canonical Asterion corpus (that lives at `<repo-root>/asterion/`). These are the working-state and project-meta documents that the agent needs to understand the system as it operates.
|
| 4 |
+
|
| 5 |
+
Contents:
|
| 6 |
+
|
| 7 |
+
- `BYPASS_AND_RECOVERY.md` — gated bypass paths and recovery posture
|
| 8 |
+
- `CORE_MODEL.md` — the energy/matter duality and canonical-at-write rule
|
| 9 |
+
- `DEFERRED_SA_CORE_CONCERNS.md` — concerns held until SA-Core is ready to absorb
|
| 10 |
+
- `DEVELOPMENT_MODES.md` — dev / staging / production posture
|
| 11 |
+
- `ENERGY_MODEL.md` — convergence vs scatter; field as the substrate
|
| 12 |
+
- `ENVIRONMENT.md` — declared resources, runtime discovery, the dual-natured state record
|
| 13 |
+
- `FLUENT_DATA_MAPPING.md` — Fluent ecosystem data mapping
|
| 14 |
+
- `ONBOARDING.md` — the SA-Orchestration source repo's own onboarding (distinct from this repo's)
|
| 15 |
+
- `PLUGIN_STATUS.md` — version + verification stamp for the plugin
|
| 16 |
+
- `PROJECTION_SURFACES.md` — projection-surface taxonomy
|
| 17 |
+
- `SCATTER_AND_CONVERGENCE.md` — convergence as the canonical collapse
|
| 18 |
+
- `SIGNAL_FLOW.md` — Signal Telemetry Doctrine flow notes
|
| 19 |
+
- `verify-stamp.php` — repo-root helper (referenced in PLUGIN_STATUS.md)
|
| 20 |
+
|
| 21 |
+
Authored by Mark Holak. Preserved under Invariant **I9** of the SA-Orchestration spec pack.
|
| 22 |
+
|
| 23 |
+
For canonical doctrine (vocabulary, invariants, concepts), read `<repo-root>/asterion/`. This directory is a complement, not a replacement.
|
| 24 |
+
|
| 25 |
+
For the deployable plugin tree, see `<repo-root>/sa-orchestration/`.
|
SA-orchestration MD/SCATTER_AND_CONVERGENCE.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: constraint_model
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
attribution: Mark Holak (convergence-collapse, two-layer scatter)
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
# Scatter and Convergence
|
| 9 |
+
|
| 10 |
+
## Convergence
|
| 11 |
+
|
| 12 |
+
See `ENERGY_MODEL.md` for the convergence-collapse model. Brief restatement:
|
| 13 |
+
|
| 14 |
+
CAMP **resolves convergence** — it does not pick. The canonical location is where total aligned signal converges above threshold, maximizing causal continuity with the existing field. It is the only stable solution under the system's constraints, not an arbitrary choice.
|
| 15 |
+
|
| 16 |
+
## Threshold (basin depth)
|
| 17 |
+
|
| 18 |
+
Threshold is **basin depth required for stable convergence at a location** — not a counter or score.
|
| 19 |
+
|
| 20 |
+
- Below threshold: signal does not crystallize into Matter. The basin is not deep enough to stabilize.
|
| 21 |
+
- Above threshold: convergence forms; CAMP records Matter.
|
| 22 |
+
- Likely tunable per concept (Demand intake basin ≠ Acceptance basin). Specific values: pending.
|
| 23 |
+
|
| 24 |
+
## Scatter — two layers
|
| 25 |
+
|
| 26 |
+
Scatter is **not** a single classification. It operates at two layers, distinguished by whether canonical collapse has occurred.
|
| 27 |
+
|
| 28 |
+
### Pre-collapse: Inert
|
| 29 |
+
|
| 30 |
+
Signal that did not converge anywhere. Below basin depth at any candidate location.
|
| 31 |
+
|
| 32 |
+
- Symbol: `?`
|
| 33 |
+
- Logged as observed Energy. Non-canonical.
|
| 34 |
+
- Inert signal continues to contribute to the field while it persists. It may participate in later convergence events as more evidence accrues.
|
| 35 |
+
- Persistence model: pending decision (continuous decay / recency-weighted vs. hard cutoff after N).
|
| 36 |
+
|
| 37 |
+
### Post-collapse: Harmony / Dissonance
|
| 38 |
+
|
| 39 |
+
Properties of how Matter, once crystallized, interacts with future field motion. Not pre-collapse classifications.
|
| 40 |
+
|
| 41 |
+
- **Harmony** (`+`) — beneficial downstream absorption. Subsequent Energy aligns with the canonical state.
|
| 42 |
+
- **Dissonance** (`−`) — harmful downstream absorption. Subsequent Energy conflicts with or destabilizes the canonical state.
|
| 43 |
+
|
| 44 |
+
These describe Matter's effect on subsequent Energy. They are downstream of canonical writes; they do not gate writes.
|
| 45 |
+
|
| 46 |
+
## CAMP's role
|
| 47 |
+
|
| 48 |
+
CAMP **records interaction truth**. CAMP **does not judge outcome quality**.
|
| 49 |
+
|
| 50 |
+
- Inert is observed (recorded), not judged.
|
| 51 |
+
- Harmony / Dissonance are downstream observations made by reasoning queries against the field of accumulated Matter, not by CAMP at write time.
|
| 52 |
+
|
| 53 |
+
## Refusal-to-collapse
|
| 54 |
+
|
| 55 |
+
If signal accumulates at two mutually-destabilizing locations, CAMP records "convergence not formed; competing signal at A and B" — without forcing crystallization.
|
| 56 |
+
|
| 57 |
+
This is **not a failure mode**. It is an honest report of unresolved interpretation. Forcing collapse where the field has not converged would violate the discipline.
|
| 58 |
+
|
| 59 |
+
## Multi-source aligned signal
|
| 60 |
+
|
| 61 |
+
Two or more surfaces may emit aligned evidence that contributes to the same convergence basin. The basin deepens; convergence forms above threshold; Matter writes once.
|
| 62 |
+
|
| 63 |
+
This is the normal case, not the edge case. Surfaces compose; they do not compete. See `PROJECTION_SURFACES.md`.
|
| 64 |
+
|
| 65 |
+
## Consonance with SA-Core's authored framework
|
| 66 |
+
|
| 67 |
+
Mark Holak's Signal Telemetry Doctrine (preserved at `Archvie/sa-core/docs/specs/concepts/signal-telemetry-doctrine.md` under Invariant I9) names alignment behaviors as *align / scatter / ricochet / inert / harmonic closure*. Harmony / Dissonance / Inert sit inside this family.
|
| 68 |
+
|
| 69 |
+
Mark Holak's Cognitive Heatsink (preserved at `Archvie/sa-core/docs/specs/concepts/cognitive-heatsink.md`) is a thermodynamic model of thought-to-resolution through computational dissipation. CAMP-fire as the Energy → Matter dissipation moment lives in the same metaphor space.
|
| 70 |
+
|
| 71 |
+
## Attribution
|
| 72 |
+
|
| 73 |
+
Convergence-collapse and the two-layer scatter (Inert pre-collapse; Harmony / Dissonance post-collapse): **Mark Holak**. Subject to later separation for IP reasons.
|
SA-orchestration MD/SIGNAL_FLOW.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
kind: constraint_model
|
| 3 |
+
truth_class: canonical
|
| 4 |
+
authority: project_invariant
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
# Signal Flow — Demand → Arbitration → Plan → Action → Result → Acceptance
|
| 8 |
+
|
| 9 |
+
The Change-System is a six-stage causal chain. Stages do not collapse into each other.
|
| 10 |
+
|
| 11 |
+
## Stage map
|
| 12 |
+
|
| 13 |
+
| Stage | Canonical home | Energy form (surface evidence) | Notes |
|
| 14 |
+
|---|---|---|---|
|
| 15 |
+
| Demand | SA-Core / Asterion | Fluent Support tickets/replies, conversations, meeting notes | Stakeholder expression on a surface is *evidence*, not the canonical Demand |
|
| 16 |
+
| Arbitration | SA-Core (function, not layer) | Manager-via-SARA cognition | The interpretive translation Demand → Plan; recorded as a first-class entity in Asterion |
|
| 17 |
+
| Plan | SA-Core / Asterion | Fluent Boards / Jira cards | Plan structure is Core ontology; surfaces are projections |
|
| 18 |
+
| Action | SA-Core record; artifact at realm of effect | JobOrchestration runs, codebase commits, deploys | Core records the Action; effect artifacts have native homes |
|
| 19 |
+
| Result | SA-Core record; artifact at realm of effect | Same as Action | What actually happened |
|
| 20 |
+
| Acceptance | SA-Core / Asterion | Stakeholder close-ticket signal at Fluent Support | Affirmative; not inferred from state |
|
| 21 |
+
|
| 22 |
+
External systems are projection surfaces. None is canonical for any of these concepts. See `PROJECTION_SURFACES.md`.
|
| 23 |
+
|
| 24 |
+
## Causal chain rules
|
| 25 |
+
|
| 26 |
+
- **Demand never overwritten by Plan.** Plan never redefines Demand. Stages do not collapse.
|
| 27 |
+
- **Sync is not equality.** Cross-stage flow is constrained projection across realms — directional and arbitrated. Not bidirectional overwrite.
|
| 28 |
+
- **Every Matter must trace back to originating Energy.** Every canonical write must include rationale.
|
| 29 |
+
- **Asterion is canonical-at-write.** Runtime is cache. See `CORE_MODEL.md`.
|
| 30 |
+
- **No silent mutation.** All changes are event-based.
|
| 31 |
+
|
| 32 |
+
## Closure rule
|
| 33 |
+
|
| 34 |
+
The system is **not** complete when:
|
| 35 |
+
|
| 36 |
+
- a task moves columns
|
| 37 |
+
- a ticket is marked closed
|
| 38 |
+
|
| 39 |
+
The system **is** complete when:
|
| 40 |
+
|
| 41 |
+
- the original demand-constraint is resolved, **and**
|
| 42 |
+
- the stakeholder accepts the result.
|
| 43 |
+
|
| 44 |
+
Closure is **affirmative**, not inferred from state. Maps to SA-Core's `human_affirmed_at` / `human_affirmed_by` (per Invariant I7's promotion path from `inferred` to `canonical`).
|
| 45 |
+
|
| 46 |
+
## Operational queries (Core-only by construction)
|
| 47 |
+
|
| 48 |
+
These questions cannot be answered by any single projection surface. They require joining evidence across surfaces, traced to canonical entities, with Core arbitrating drift between surface evidence and canonical state.
|
| 49 |
+
|
| 50 |
+
- Who is doing what?
|
| 51 |
+
- Is a person or team productive?
|
| 52 |
+
- Are we on track?
|
| 53 |
+
- What demand is unresolved?
|
| 54 |
+
- What plan lacks action?
|
| 55 |
+
- What action lacks acceptance?
|
| 56 |
+
|
| 57 |
+
These are Core's reason for existing — not features added on top.
|
| 58 |
+
|
| 59 |
+
## Energy → Matter at each stage
|
| 60 |
+
|
| 61 |
+
Each stage's canonical entry is the **convergence outcome of multiple Energy contributions**. See `ENERGY_MODEL.md`.
|
| 62 |
+
|
| 63 |
+
A surface event (e.g., a Fluent ticket arriving) does not auto-promote to a canonical Demand entity. CAMP evaluates the field; convergence at a location forms Matter.
|
| 64 |
+
|
| 65 |
+
## Multi-source contribution
|
| 66 |
+
|
| 67 |
+
A single Demand may be expressed through multiple surfaces (a Fluent ticket, a chat message, a meeting transcript). These do not compete for canonical status; they contribute to the same convergence basin. The canonical Demand entity emerges from the field, not from a single surface event.
|
| 68 |
+
|
| 69 |
+
A single Plan may be projected to multiple surfaces (a Boards card, a Jira ticket, a markdown checklist). These are projections of the same canonical Plan, not parallel canonical Plans.
|
| 70 |
+
|
| 71 |
+
## Bypass
|
| 72 |
+
|
| 73 |
+
When Core is unavailable, surfaces continue functioning in degraded mode. Their state changes during bypass are Energy until they re-enter through CAMP. See `BYPASS_AND_RECOVERY.md`.
|
| 74 |
+
|
| 75 |
+
## Human roles as causal nodes
|
| 76 |
+
|
| 77 |
+
| Role | Causal position |
|
| 78 |
+
|---|---|
|
| 79 |
+
| Stakeholder | Demand origin; defines success; validates outcome; Acceptance authority |
|
| 80 |
+
| Manager | Arbitration node; operates through SARA; translates Demand into Plan; assigns work; maintains alignment |
|
| 81 |
+
| Developer | Risk taker; executes Plan; applies judgment in Action; responsible for outcome resonance |
|
| 82 |
+
|
| 83 |
+
Each role contributes Energy at its causal position. CAMP arbitrates convergence into Matter.
|
| 84 |
+
|
| 85 |
+
---
|
| 86 |
+
|
| 87 |
+
## Observed in live data (test fixture, 2026-05-01)
|
| 88 |
+
|
| 89 |
+
The first production data import (see `FLUENT_DATA_MAPPING.md`) provides concrete examples of where Fluent's surface model diverges from the Change-System ontology — and why SA-orchestration's arbitration record exists.
|
| 90 |
+
|
| 91 |
+
### Demand → Plan link absent at the surface
|
| 92 |
+
|
| 93 |
+
Of 57 imported `wp_fbs_tasks` rows, **1 carries `crm_contact_id`**; **none carry a reference to a `wp_fs_tickets.id`**. There is no native Fluent column connecting a Plan unit back to the Demand that originated it. The Demand → Plan trace is exactly what Asterion's arbitration record carries; Fluent does not.
|
| 94 |
+
|
| 95 |
+
### Closure rule violated in the wild
|
| 96 |
+
|
| 97 |
+
Ticket 12 (`HelpDesk - New Golf image for Website`) simultaneously holds:
|
| 98 |
+
|
| 99 |
+
```
|
| 100 |
+
status = 'active'
|
| 101 |
+
resolved_at = '2026-03-31 22:43:52'
|
| 102 |
+
closed_by = 1
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
Three fields on one row, internally inconsistent if read literally. The `wp_fs_conversations` log shows the cause: ticket was closed, then reopened — the close-time fields were left populated, the status was reverted. **Acceptance state cannot be inferred from the row alone.**
|
| 106 |
+
|
| 107 |
+
This is the closure rule warning made concrete. An Asterion-style append-only acceptance log (`acceptance_proposed` → `acceptance_disputed` → `acceptance_affirmed`) replaces the mutable-field ambiguity with a readable causal chain.
|
| 108 |
+
|
| 109 |
+
### Action evidence is convergence-shaped
|
| 110 |
+
|
| 111 |
+
`wp_fbs_activities` carries 284 rows across 9 distinct task-action types (`created`, `changed`, `updated`, `added`, `joined`, `closed`, `reopened`, `removed`, `left`) and 6 board-action types (`created`, `added`, `moved`, `changed`, `archived`, `updated`). Each row is a discrete event with `created_at`, `object_id`, `object_type`, `action` — the Energy form CAMP would arbitrate. Activity rows carry no rationale field; **why** the Action happened is not captured.
|
| 112 |
+
|
| 113 |
+
### Mission.net board (board id 16)
|
| 114 |
+
|
| 115 |
+
A real production board named `Mission.net` exists with 9 tasks. The naming aligns with SA-Core / MissionNet vocabulary in the spec pack. This board is the closest existing surface fixture to the SA-orchestration project's own work and the natural starting point for testing Demand → Plan → Action traces against live Fluent data.
|
SA-orchestration MD/asterion/01-ontology.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MissionNet Ontology (v0.1)
|
| 2 |
+
|
| 3 |
+
*Implementation © Sleeper Agents LLC. Conceptual framework authored independently by Mark Holak; see `docs/specs/concepts/`.*
|
| 4 |
+
|
| 5 |
+
This is the vocabulary lock. Every downstream doc, every class, every log message, and every UI surface uses these terms precisely. Drift here = drift everywhere.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Primary nouns
|
| 10 |
+
|
| 11 |
+
### Core
|
| 12 |
+
|
| 13 |
+
The required substrate. One WordPress plugin (`sa-core`). A space is a SleeperAgent space only when Core is online underneath it.
|
| 14 |
+
|
| 15 |
+
### Realm
|
| 16 |
+
|
| 17 |
+
An externally sovereign system of record or operation. FluentCRM is a realm. Jira is a realm. QuickBase is a realm. QuickBooks is a realm. PortTracker's Node backend is a realm. An arbitrary REST API is a realm. A client's database is a realm. A realm is sovereign because its integrity does not depend on Core.
|
| 18 |
+
|
| 19 |
+
### Subsystem
|
| 20 |
+
|
| 21 |
+
A coherent slice of Core itself. SAWS-executor is a subsystem. CARMA (the absorbed WP maintenance toolset) is a subsystem. MissionNet (the presentation layer) is a subsystem. A customer-facing brand may wrap a subsystem; the brand is cosmetic, the subsystem is structural.
|
| 22 |
+
|
| 23 |
+
### Adapter
|
| 24 |
+
|
| 25 |
+
A bidirectional conduit between Core and a realm. See the **Realm Adapter Contract** (`03-realm-adapter-contract.md`). Adapters do not own realm data; they mediate flow. A provider adapter (`SA_Provider_Adapter`) is a specialized adapter for LLM and tool providers; a realm adapter (`SA_Realm_Adapter`) is the general-case conduit.
|
| 26 |
+
|
| 27 |
+
### Entity
|
| 28 |
+
|
| 29 |
+
The universal unit of the field inside Core. Rendered as circle (compressed atom) or rounded-rect (expanded container). Carries band hints, ratio, position, payload, ACL, provenance, and truth class.
|
| 30 |
+
|
| 31 |
+
### Record
|
| 32 |
+
|
| 33 |
+
A specific row in a realm's native schema. A record's canonical home is the realm. A record's Core-side reflection is a **Projection**.
|
| 34 |
+
|
| 35 |
+
### Projection
|
| 36 |
+
|
| 37 |
+
Core's non-canonical mirror of a realm record. Stored as an entity with `truth_class = projected`, `origin_realm` + `origin_id` populated, and TTL-bounded when cached.
|
| 38 |
+
|
| 39 |
+
### Canonical Source
|
| 40 |
+
|
| 41 |
+
The realm in which a record is authoritative. Only the canonical source may author canonical state for its own records. Core cannot author canonical on a realm's behalf.
|
| 42 |
+
|
| 43 |
+
### Event
|
| 44 |
+
|
| 45 |
+
Something that happened. Immutable, time-indexed. Recorded to `sa_structural_audit` with actor, target, before/after, correlation_id, causation_id, policy_basis.
|
| 46 |
+
|
| 47 |
+
### Command
|
| 48 |
+
|
| 49 |
+
An instruction or intent. Typically initiated by an actor or a scheduled policy. A command may yield one or more events when executed.
|
| 50 |
+
|
| 51 |
+
### Actor
|
| 52 |
+
|
| 53 |
+
The who of an action. One of: a WordPress user id (human), a service principal id (non-human authenticated identity), or the string `system` (Core's own internal automation under an audited policy).
|
| 54 |
+
|
| 55 |
+
### Authority
|
| 56 |
+
|
| 57 |
+
The scope of what an actor may do. Held by role, package capabilities, ACL entries, and adapter capability matrices.
|
| 58 |
+
|
| 59 |
+
### Session
|
| 60 |
+
|
| 61 |
+
A grouping of related commands and events initiated by a single actor or chain. Correlated by a shared `correlation_id`.
|
| 62 |
+
|
| 63 |
+
### Mission
|
| 64 |
+
|
| 65 |
+
A composite objective that spans one or more sessions. (Future spec — see `10-mission-orchestration.md` when written.)
|
| 66 |
+
|
| 67 |
+
### Quest
|
| 68 |
+
|
| 69 |
+
A unit of narrative direction. Defines target, not-target, and admissible uncertainty for a body of work. Quests are authored, not executed: their canonical home is the planning surface (Boards in MissionNet's instance).
|
| 70 |
+
|
| 71 |
+
Quests describe what the work is *about*. Resolution of a Quest is a narrative judgment — was the direction met, was it abandoned, was it superseded — made by a human.
|
| 72 |
+
|
| 73 |
+
Distinct from a Job. See Job below; see also Distinguishing pairs.
|
| 74 |
+
|
| 75 |
+
### Task / Job
|
| 76 |
+
|
| 77 |
+
A unit of executable work within a Quest. May be scheduled, assigned, retried, or delegated. Jobs describe what is *done*. Resolution of a Job is a real-world consequence — the work either happened or did not — measured against reality, not against the system.
|
| 78 |
+
|
| 79 |
+
A Quest may produce one or more Jobs. A Job belongs to one Quest. Conversion between Quest and Job is not automatic; see I10.
|
| 80 |
+
|
| 81 |
+
### Attention
|
| 82 |
+
|
| 83 |
+
A routing signal — never an instruction, never a state mutation. Attention asks for arbitration; it does not perform it. NPCs (agents, automated processes) may emit Attention. Only humans may resolve it.
|
| 84 |
+
|
| 85 |
+
The infrastructure: the attention log records signals with actor, target, correlation_id, causation_id. Read-only by construction; resolving Attention requires the human to take a separate, explicit act.
|
| 86 |
+
|
| 87 |
+
Sub-doctrine: see `concepts/attention-doctrine.md` and `concepts/compass-doctrine.md`.
|
| 88 |
+
|
| 89 |
+
### Realm Signal
|
| 90 |
+
|
| 91 |
+
A low-cost notification from a realm ("something changed") that Core may choose to consume, queue, or ignore based on policy. Previously named "Signal"; renamed to free the unqualified term for the doctrinal meaning below.
|
| 92 |
+
|
| 93 |
+
### Signal
|
| 94 |
+
|
| 95 |
+
*(Authored by Mark Holak. Preserved under Invariant **I9**.)*
|
| 96 |
+
|
| 97 |
+
The measurable alignment behavior of participants — users, workers, agents, models, systems — as they traverse an authored **acceleration field** (a mission, prompt, workflow, book, interface, instruction set, or any artifact that defines target, not-target, and admissible uncertainty).
|
| 98 |
+
|
| 99 |
+
Signal is *not* raw observability. Pillar 0.75's sub-token graph is the instrument; Signal is what the instrument reads. Participants interact with an authored field and produce measurable interaction outcomes — some align, some scatter, some ricochet, some go inert, some reach harmonic closure. The Signal Telemetry Doctrine is the interpretation layer sitting over Prime Prompt Conjecture and Cognitive Heatsink: PPC and Heatsink describe how trajectory is compressed and dissipated; Signal reads the alignment produced at the other end.
|
| 100 |
+
|
| 101 |
+
The enumerated behaviors (align / scatter / ricochet / inert / harmonic closure) are **exemplary, not definitive** — additional behaviors may emerge as the system is used. See `concepts/signal-telemetry-doctrine.md` for the full doctrine and its mapping onto Core primitives.
|
| 102 |
+
|
| 103 |
+
### Artifact
|
| 104 |
+
|
| 105 |
+
A file, document, image, or embedding. Stored in the native realm when possible; projected into Core via adapter.
|
| 106 |
+
|
| 107 |
+
### Trace
|
| 108 |
+
|
| 109 |
+
The causal ancestry of a state or an event. Walked by `SA_Structural_Audit::trace_origin()`. Preserved by correlation_id and causation_id on every audit row.
|
| 110 |
+
|
| 111 |
+
### Truth Class
|
| 112 |
+
|
| 113 |
+
See `SA_Truth_Class` and Invariant **I2**. One of: `canonical | projected | cached | inferred | derived | synthetic`. Every entity declares one.
|
| 114 |
+
|
| 115 |
+
### State Class
|
| 116 |
+
|
| 117 |
+
See `SA_State_Class`. The lifecycle position of a datum. One of: `resting | observed | projected | pending_action | acted | verified | disputed | stale | superseded`.
|
| 118 |
+
|
| 119 |
+
### Provenance
|
| 120 |
+
|
| 121 |
+
The origin record attached to every entity: `origin_realm`, `origin_id`, `actor`, `observed_at`, `causation_id`, `correlation_id`, optional `derived_from`, `source_refs`, `provenance_hash`.
|
| 122 |
+
|
| 123 |
+
### Membrane
|
| 124 |
+
|
| 125 |
+
A per-entity veil that turns the entity into a black-box domain. Only typed I/O ports are visible to outsiders. Billing principals may unfold the membrane they are charged for.
|
| 126 |
+
|
| 127 |
+
### I/O Port
|
| 128 |
+
|
| 129 |
+
A typed edge anchor on a membraned entity. The only integration surface visible to non-insiders.
|
| 130 |
+
|
| 131 |
+
### Grouping Overlay
|
| 132 |
+
|
| 133 |
+
A first-class attributed, non-destructive re-parenting of entities. Per-scope (private / shared / org / public), per-author. Applied at render time.
|
| 134 |
+
|
| 135 |
+
### Projection Slot
|
| 136 |
+
|
| 137 |
+
A named rendering surface bound to an entity query. A package defines its slot set; a viewer may override within the slot's allowance.
|
| 138 |
+
|
| 139 |
+
### Projection Source
|
| 140 |
+
|
| 141 |
+
A named, viewer-scoped row producer eligible to be unioned with other sources at a surface's Projection Arbiter. Each source owns one query path and applies its own visibility gate (`row_visible`) before returning rows. A source is NOT any method on `SA_Projection`; it is specifically a row producer composable into a surface's arbiter. Today's sources: `chat` (`recent_prompts` — chat-domain-joined) and `realm` (`recent_entities` — role/origin-realm-scoped). Sources are kernel-owned; third parties contribute realm adapters (which feed `realm`), not sources.
|
| 142 |
+
|
| 143 |
+
### Projection Arbiter
|
| 144 |
+
|
| 145 |
+
A surface-scoped composer that enumerates the Projection Sources feeding that surface, invokes them for the current viewer, and unions their output into the surface's response shape. The arbiter owns source enumeration, union strategy, and per-source instrumentation (`window.sources` readout). Today implemented as one method per surface on `SA_Projection` (`for_mission` is the only instance). Not a standalone class: at two sources with no arbitration rules (dedup, sort-merge, ACL-at-merge), a class would be ceremony. Promotion to a class is deferred until (a) a third source, (b) a concrete arbitration rule, or (c) third-party source registration lands. Surfaces with a single source (`/thread`, `/trace`, `/lattice/subtree`) do not go through an arbiter and do not need one.
|
| 146 |
+
|
| 147 |
+
### Influence Halo / Ring
|
| 148 |
+
|
| 149 |
+
Concentric bands around an entity carrying weighted references to related entities. The continuous limit of discrete rings is the contour mode (`docs/ARCHITECTURE.md` — Derived pillar: Contour rendering).
|
| 150 |
+
|
| 151 |
+
### Sub-Token Event
|
| 152 |
+
|
| 153 |
+
Every internal orchestration step inside a provider invocation (embed, retrieve, tool call, subagent hop, completion, rerank, self-critique, router). First-class entity at band 5 inside the parent prompt's band 4 container. Visible and annotatable by the billing principal.
|
| 154 |
+
|
| 155 |
+
### Geodesic Marker
|
| 156 |
+
|
| 157 |
+
A memory record of a failure path in the prompt manifold. Seeded from bad verdicts on sub-tokens. Consumed by `SA_Geodesic_Seeder` to route around known failures.
|
| 158 |
+
|
| 159 |
+
### Context Bundle
|
| 160 |
+
|
| 161 |
+
A named, pinned slice of the entity graph with a deterministic signature. Multiple adapters (including specialized LLMs) bind to the same bundle for synchronized context.
|
| 162 |
+
|
| 163 |
+
### Package
|
| 164 |
+
|
| 165 |
+
The purchased SKU. Enumerates enabled capabilities, default overlays, default membranes. Assigned to an org.
|
| 166 |
+
|
| 167 |
+
### Capability
|
| 168 |
+
|
| 169 |
+
An enumerable permission string (`sa-core:sub-token-unfold`, `missionnet:impose-grouping`, `carma:admin-takeover`). Package-gated.
|
| 170 |
+
|
| 171 |
+
### Service Principal
|
| 172 |
+
|
| 173 |
+
A non-human authenticated identity. External services (PortTracker's Node, ingest clients, Jira bots) use service principal tokens to push mutations without impersonating a user.
|
| 174 |
+
|
| 175 |
+
### Invariant
|
| 176 |
+
|
| 177 |
+
A non-negotiable law the system upholds at runtime. See `02-invariants.md`. Violations are logged to `sa_invariant_violation`.
|
| 178 |
+
|
| 179 |
+
### Adapter Certification
|
| 180 |
+
|
| 181 |
+
The gate that promotes a realm adapter from "in development" to "live." Checklist runs against the Realm Adapter Contract invariants. See `03-realm-adapter-contract.md`.
|
| 182 |
+
|
| 183 |
+
### Admission Contract
|
| 184 |
+
|
| 185 |
+
The per-layer contract a new primitive — or a new instance of an existing primitive — must honor to be validly admitted into the system.
|
| 186 |
+
|
| 187 |
+
A *named principle*, not a uniform checklist family. The principle is: **admission is layer-owned and layer-shaped**, not uniform across layers. Each layer's admission contract takes whatever form that layer's nature demands (a certification checklist for realms, runtime invariants for entities, an op whitelist for mutations, a return-shape obligation for projection sources, etc.).
|
| 188 |
+
|
| 189 |
+
This principle does not add a new commitment. It names a shape already diffused through:
|
| 190 |
+
|
| 191 |
+
- **Pillar 0.5** — everything rendered is `project(field, viewer, overlays, permissions)`. A new primitive must have defined behavior under all four inputs.
|
| 192 |
+
- **Pillar 0.75** — every orchestration step is observable. Anything action-shaped must declare how it emits observability (sub-token events, audit rows, source attribution).
|
| 193 |
+
- **Pillar 0.9** — the primitive set is closed; new capabilities are compositions of existing primitives. Admission = proof of valid composition.
|
| 194 |
+
- **`03-realm-adapter-contract.md`** — the single fully worked-out formal instance of a per-layer admission contract.
|
| 195 |
+
|
| 196 |
+
See `docs/ARCHITECTURE.md` for the pillars themselves. This entry does not amend them; it gives the shape they imply a name.
|
| 197 |
+
|
| 198 |
+
**Status ledger.** The ledger is the term's practical content. It records which primitive layers currently have formal contracts, which have informal ones, which are absent, and which are intentionally deferred. New rows enter only when a new primitive layer enters the closed set — not per instance, and not per cross-layer attribute.
|
| 199 |
+
|
| 200 |
+
| Layer | Contract state | Reference / note |
|
| 201 |
+
|---|---|---|
|
| 202 |
+
| Realm | Formal | `03-realm-adapter-contract.md` + `sa_adapter_certification` table |
|
| 203 |
+
| Entity | Formal | `02-invariants.md` I2 / I4 / I7 + `SA_Truth_Class` / `SA_State_Class` validation in `SA_Entity::create` |
|
| 204 |
+
| Mutation | Formal | `SA_Ingest` op whitelist, idempotency-key discipline, service-principal scope, deterministic UUID rule |
|
| 205 |
+
| Projection Source | Informal | "Returns viewer-gated rows in arbiter-compatible union shape." Implied by the Projection Arbiter promotion; not yet written as a standalone contract. |
|
| 206 |
+
| Grammar | Absent | No admission rules for a new grammar today. Chat-lineage / equal-peer / containment-pack are ad-hoc in client code. |
|
| 207 |
+
| Surface inspection | Informal | Three discriminable cases now operative in `/mission/`'s lens-routing decision (`renderCurrentProjection` in `assets/mission.js`), driven by a shape predicate over `(entity.origin_realm, sub_token_count)` — no realm-specific code: (a) **chat-shaped** (`!origin_realm`) → trace lens; (b) **structural-only** (`origin_realm` set, `sub_token_count == 0`) → structural inspector; (c) **structural-with-sub-tokens** (`origin_realm` set, `sub_token_count > 0`) → hybrid lens (structural inspector + Sub-tokens section in step_index ASC order, with shape-aware labels read from `SubTokenEvent.metadata` rather than chat-shaped fallbacks). Discriminator field `sub_token_count` lives on the `/entity/{id}/inspect` projection response (additive, no schema change). Concrete instances: chat prompts (case a), FS containers/leaves (case b), GitHub Actions workflow runs (case c). Promotion to Formal (separate contract file) requires a fourth case or a second concrete hybrid example, whichever forces the discriminator's edge cases into a written rule. Until then the contract is the inline behavior recorded here. |
|
| 208 |
+
| Toolbox action | Formal | `06-toolbox-action-contract.md` (v0.1, 7 clauses). Two concrete instances: `/mission/`-native "Re-scan FS" and "Re-scan GH" buttons (both admin-only). Promotion criteria from Informal → Formal were satisfied by the second instance (GitHub Actions re-scan) cleanly fitting the same seven-clause shape: semantic binding (1 button → 1 REST endpoint), permission gate (manage_options at template AND REST), audit obligation (one operator-attribution structural-audit row per invocation), parameter shape (render-time derivation, no click-time dialogs), feedback contract (busy/success/failed state cycle), refresh obligation (`load()` on success), idempotency (zero net entity-count drift on repeat). Out-of-scope categories (parameter dialogs, destructive actions, multi-step compositions) explicitly deferred to future contract revisions when concrete instances drive them. |
|
| 209 |
+
| Membrane | Deferred | Primitive defined in this ontology; admission contract (port typing, opacity rules, billing-principal translucency) deferred until first implementation. |
|
| 210 |
+
| Overlay | Deferred | Primitive defined in this ontology; admission contract (scope, attribution, idempotency, render-time layering) deferred until first implementation. |
|
| 211 |
+
| Credential | Deferred | Surfaced by the GitHub Actions third-domain proof, which uses a filter-driven PAT (`sa_core_github_token`) as its smallest scope-honoring credential path. The general contract — how external-realm credentials enter the system (OAuth flows, refresh-token lifecycle, per-user vs per-org binding, scope-limited storage) — is not yet written. Existing primitives partially cover adjacent concerns: `SA_Credential_Pool` (LLM provider keys, single-secret-per-record), `SA_Service_Principal` (inbound bearer tokens), filter-driven adapter config (FS, GitHub Actions). None compose into a unified credential-admission shape. Authorized work will likely extend `SA_Credential_Pool` to handle multi-step OAuth tokens and add the operator UX (connect, store, scope, retire) as one slice's deliverable, then retire ad-hoc filter configs. First instance: GitHub. Second instance later: Jira / Linear / etc. |
|
| 212 |
+
| Camera-Projection Convergence | Pinned | Filed during the dependency audit preceding the Hybrid Inspector Lens slice. Concept: under Pillar 0's full vision, camera transitions at band boundaries are themselves projection-resolution events, not viewport transforms. Today the camera is degenerate (purely affine pan/zoom over fixed layout). Under Rung 4 phase 2+, zoom-band crossings re-layout via auto-compress / auto-expand, making camera a constrained re-projection over the referential manifold rather than a viewport adjustment. Concrete formalization deferred until a second example of camera-as-projection lands alongside Jump-2 (auto-descend on band-cross) or Jump-3 (membrane unwrap on jump). At promotion time this row will move from Pinned to Absent or Informal depending on which Rung 4 mechanic delivers it. Sits at the same admission-contract layer as Surface Inspection / Toolbox / Grammar — between primitives and rendering. |
|
| 213 |
+
|
| 214 |
+
**Role and kind are NOT admission layers.** They are cross-layer discriminant attributes. A new role's admission is governed jointly by entity invariants (structural constraints: e.g. `message` requires `payload.role ∈ {user,assistant,system}`), grammar admission (visual and inspection-lens treatment), and projection source contract (which sources include the role). No independent role-admission contract. `kind` (circle / rrect) is narrower still — a pure grammar discriminant with no invariant or projection overlap.
|
| 215 |
+
|
| 216 |
+
**What this entry does NOT do.**
|
| 217 |
+
|
| 218 |
+
- Does not mandate a uniform contract shape across layers. Forcing realm-style checklists onto grammars or toolbox actions is the principle's failure mode.
|
| 219 |
+
- Does not create a runtime gate. Existing enforcement (invariants, certification table) stays as-is; no new machinery is implied.
|
| 220 |
+
- Does not forbid introducing a primitive without a contract in place. Absent rows in the ledger are honest debt markers, not refusal signals.
|
| 221 |
+
|
| 222 |
+
### Prime Prompt
|
| 223 |
+
|
| 224 |
+
*(Authored by Mark Holak.)* A minimal causal prompt that, when injected into a capable model, reconstructs the trajectory of an originating system without requiring replay of the full conversation history. See `docs/specs/concepts/prime-prompt-conjecture.md`.
|
| 225 |
+
|
| 226 |
+
### Cognitive Heatsink
|
| 227 |
+
|
| 228 |
+
*(Authored by Mark Holak.)* A thermodynamic model of thought-to-resolution through computational dissipation. See `docs/specs/concepts/cognitive-heatsink.md`. Maps to sub-token events as discrete thermal transfer steps.
|
| 229 |
+
|
| 230 |
+
### Reference Traversal Continuity
|
| 231 |
+
|
| 232 |
+
*(Authored by Mark Holak. Preserved under Invariant **I9**.)*
|
| 233 |
+
|
| 234 |
+
A kernel-level commitment that the act of following a reference from one entity to another is invariant across the kinds of entities being traversed and across the realm or representational layer the traversal currently inhabits. The traversal does not truncate at realm boundaries, truth-class boundaries, type-layer boundaries, or observability boundaries.
|
| 235 |
+
|
| 236 |
+
Continuity is carried by the existing kernel-side bookkeeping (`parent_id`, `origin_realm` + `origin_id`, `correlation_id`, `causation_id`, `derived_from`, edge kinds, sub-token parentage). The doctrine names what those primitives jointly enable.
|
| 237 |
+
|
| 238 |
+
This is a doctrine of **motion**, not of **geometry**. Projection grammars (chat-lineage, containment-pack, equal-peer, future grammars) are downstream rendering decisions that choose how to display a region of the traversal field; they neither define, constrain, nor constitute the traversal itself. Coil, hydra, shell, treemap, and every other rendered cluster shape are choreographies — many other choreographies are equally valid. The motion neither requires nor privileges any of them.
|
| 239 |
+
|
| 240 |
+
Articulated immediately after the GitHub Actions third-domain proof, which made the cross-domain continuity concretely visible: chat sub-tokens, filesystem containment, and workflow run/job/step descents are not three patterns held together by the adapter contract; they are three surface expressions of one continuous motion that the adapter contract gates entries to. See `concepts/reference-traversal-continuity.md` for the full doctrine and its relationship to companion concepts (Pillar 0.5 perspective projection, Pillar 0.75 transparency, Pillar 0.9 closed primitive set, Prime Prompt Conjecture, Cognitive Heatsink, Signal Telemetry Doctrine).
|
| 241 |
+
|
| 242 |
+
---
|
| 243 |
+
|
| 244 |
+
## Distinguishing pairs (do not confuse)
|
| 245 |
+
|
| 246 |
+
- **Realm** vs. **Subsystem** — realms are sovereign external systems; subsystems are parts of Core.
|
| 247 |
+
- **Incorporate** vs. **Absorb** — realms are incorporated (conduit); SA-authored code is absorbed (consolidated).
|
| 248 |
+
- **Event** vs. **Command** — events are records of what happened; commands are instructions or intents.
|
| 249 |
+
- **Canonical** vs. **Projected** — canonical is truth at its native home; projected is Core's non-canonical mirror.
|
| 250 |
+
- **Projected** vs. **Cached** — both are non-canonical; cached carries an explicit TTL; projected is kept live and refreshable.
|
| 251 |
+
- **Inferred** vs. **Derived** — inferred is produced by an LLM or heuristic; derived is deterministic computation from known inputs.
|
| 252 |
+
- **Entity** vs. **Record** — an entity lives in Core; a record lives in a realm; a projection is an entity that *represents* a record.
|
| 253 |
+
- **Projection** (the mirror) vs. **Projection Source** vs. **Projection Arbiter** vs. **Projection Slot** — four distinct read-path concepts that share a word. *Projection* (the mirror) is the entity-side reflection of a realm record (truth-class level). *Projection Source* is a viewer-scoped row producer (read-path composition level). *Projection Arbiter* is the surface-scoped composer of sources (read-path orchestration level). *Projection Slot* is a named rendering surface bound to a query (rendering level). The four do not substitute for each other.
|
| 254 |
+
- **Quest** vs. **Job** — quests are narrative direction (authored, judged); jobs are executable work (scheduled, performed, resolved by reality). One quest may yield many jobs; no automatic promotion in either direction. See I10.
|
| 255 |
+
|
| 256 |
+
---
|
| 257 |
+
|
| 258 |
+
## Usage rules
|
| 259 |
+
|
| 260 |
+
1. Every spec document MUST use these terms in their defined sense.
|
| 261 |
+
2. When a new term enters the vocabulary, it MUST be added here before being used in other specs or in code.
|
| 262 |
+
3. Class names and log messages SHOULD mirror these terms.
|
| 263 |
+
4. When translation between Core's vocabulary and a realm's native vocabulary is necessary, it happens in the adapter, not in the spec.
|
| 264 |
+
|
| 265 |
+
---
|
| 266 |
+
|
| 267 |
+
## Attribution
|
| 268 |
+
|
| 269 |
+
The framework expressed in this document sits inside a larger lineage:
|
| 270 |
+
|
| 271 |
+
```
|
| 272 |
+
CR ⊇ CA ⊇ JourneySeeker ⊇ MissionNet/MeshNet ⊇ SA-Orchestration ⊇ Brand ⊇ Client
|
| 273 |
+
```
|
| 274 |
+
|
| 275 |
+
Causal Relativity, Causal Agentics, and JourneySeeker are pre-existing intellectual property authored by Mark Holak, preserved under Invariant **I9** and Section 5.1 carve-outs of the CTO Employment & Equity Agreement. MissionNet/MeshNet is the Corporate-Campaign theme. SA-Orchestration is the current implementation slice. Brand and Client labels are the rendering layer (see `concepts/concept-vs-label.md`).
|
| 276 |
+
|
| 277 |
+
Each layer below renders, specializes, or themes the layer above. No layer below replaces the layer above. See `concepts/lineage-chain.md` for the full doctrine.
|
| 278 |
+
|
| 279 |
+
Implementation and glossary in this document: © Sleeper Agents LLC.
|
| 280 |
+
|
| 281 |
+
Named conceptual framework elements (Prime Prompt, Cognitive Heatsink, Russell-Ouroboros Conjecture, PR notation, quanta-of-LLMs / information-lattice framing): authored independently by Mark Holak. See `docs/specs/concepts/` for the preserved artifacts and full author credit.
|
SA-orchestration MD/asterion/02-invariants.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MissionNet System Invariants (v0.1)
|
| 2 |
+
|
| 3 |
+
*Authored by Mark Holak. Adapted into Core by implementation.*
|
| 4 |
+
|
| 5 |
+
These are not implementation details. They are **laws**. Violations are recorded to `sa_invariant_violation`; severe violations raise exceptions. Code that violates an invariant fails review.
|
| 6 |
+
|
| 7 |
+
The enforcement surface lives in `includes/enforcement/class-sa-invariants.php`. Every invariant here has a stable id (`I1`–`I9`) used in the violation log. A bug tracker can link against these ids.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## Foundational asymmetry
|
| 12 |
+
|
| 13 |
+
The invariants below exist because Core distinguishes between truth classes: **canonical, projected, cached, inferred, derived, synthetic**. These classes are asymmetric — they cannot collapse into each other. That asymmetry is what prevents Russell's paradox from re-entering through the back door: a system that consumes itself can only stay coherent if the act of consumption preserves distinctions as it moves. The timeless lattice translates through spacetime precisely because the asymmetry survives the motion.
|
| 14 |
+
|
| 15 |
+
Without these invariants, the asymmetry decays, the classes collapse, and the system begins to lie to itself about what is real.
|
| 16 |
+
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
## I1 — Core must not claim canonical ownership of incorporated realm data
|
| 20 |
+
|
| 21 |
+
Incorporated realms (FluentCRM, Jira, QuickBase, QuickBooks, PortTracker's Node service, arbitrary APIs) remain the canonical source of their own records. Core mirrors, mediates, and audits — never authors canonical state on a realm's behalf unless that realm is Core itself.
|
| 22 |
+
|
| 23 |
+
**Enforcement:**
|
| 24 |
+
- `SA_Ingest::upsert_entity` stamps `truth_class = projected` by default on all ingested realm records.
|
| 25 |
+
- A realm adapter's `truth_class_for_concept()` may *only* return `canonical` for concepts whose canonical home is Core (rare).
|
| 26 |
+
- Any attempt to write `truth_class = canonical` on an entity with a non-`sa-core` `origin_realm` is rejected.
|
| 27 |
+
|
| 28 |
+
**Violation severity:** fatal.
|
| 29 |
+
|
| 30 |
+
---
|
| 31 |
+
|
| 32 |
+
## I2 — Every surfaced datum must declare truth_class
|
| 33 |
+
|
| 34 |
+
Entities, projections, cache rows, AI summaries, and adapter payloads must carry a valid `truth_class`. Without this, viewers cannot distinguish a canonical fact from an LLM guess.
|
| 35 |
+
|
| 36 |
+
**Enforcement:**
|
| 37 |
+
- `SA_Entity::create()` calls `SA_Invariants::check_truth_class_declared()`.
|
| 38 |
+
- Default for unknowable-origin entities is `canonical`; default for ingest is `projected`; default for LLM output is `inferred`. All three are valid; absence of any value is not.
|
| 39 |
+
|
| 40 |
+
**Violation severity:** fatal.
|
| 41 |
+
|
| 42 |
+
---
|
| 43 |
+
|
| 44 |
+
## I3 — Every cross-realm action must be causally traceable
|
| 45 |
+
|
| 46 |
+
A change initiated in Core that reaches (or originated in) an external realm must trace to an actor, a causation id, and a correlation id. `SA_Structural_Audit::trace_origin()` must be able to walk backward from any resulting state to the first user-attributed act.
|
| 47 |
+
|
| 48 |
+
**Enforcement:**
|
| 49 |
+
- `SA_Provenance::enforce()` is called before any cross-realm mutation.
|
| 50 |
+
- Audit rows carry `correlation_id` + `causation_id`.
|
| 51 |
+
|
| 52 |
+
**Violation severity:** error (blocks the action; recoverable by retrying with provenance attached).
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
## I4 — No adapter may emit a record without native identity + realm provenance
|
| 57 |
+
|
| 58 |
+
Adapter pulls MUST populate `origin_realm` + `origin_id` (directly or via `external_key`). Without this, the record cannot be re-matched, cannot be pushed back, and cannot be audited across the realm boundary.
|
| 59 |
+
|
| 60 |
+
**Enforcement:**
|
| 61 |
+
- `SA_Invariants::check_realm_provenance()` is called on every ingest mutation.
|
| 62 |
+
- `SA_Ingest` rejects payloads missing these fields.
|
| 63 |
+
|
| 64 |
+
**Violation severity:** fatal.
|
| 65 |
+
|
| 66 |
+
---
|
| 67 |
+
|
| 68 |
+
## I5 — MissionNet must degrade without corrupting realm integrity
|
| 69 |
+
|
| 70 |
+
When Core fails (offline, bugged, under attack), the client's native realms must not suffer collateral damage. This is the philosophical *tool test* expressed as a technical law.
|
| 71 |
+
|
| 72 |
+
**Enforcement:**
|
| 73 |
+
- Adapter writes (`push`) must be idempotent per `idempotency_rules()`.
|
| 74 |
+
- Bulk operations must be chunked + resumable.
|
| 75 |
+
- Health-check endpoints must fail closed — Core not reachable means ingest halts, not silently half-writes.
|
| 76 |
+
- Adapter certification checklist item: `failure_path_verified` + `rollback_defined`.
|
| 77 |
+
|
| 78 |
+
**Violation severity:** warn at design time, error at runtime.
|
| 79 |
+
|
| 80 |
+
---
|
| 81 |
+
|
| 82 |
+
## I6 — Cache may never silently replace source verification in high-trust paths
|
| 83 |
+
|
| 84 |
+
Cache accelerates; cache does not become truth. When the caller asks for a high-trust answer (regulated domains, financial totals, legal records), Core must re-verify against the canonical realm, not return a cached projection.
|
| 85 |
+
|
| 86 |
+
**Enforcement:**
|
| 87 |
+
- Per-adapter cache TTLs declared in `capability_matrix()`.
|
| 88 |
+
- High-trust query paths pass `verify_live: true` to the executor/realm; cache is skipped.
|
| 89 |
+
- A future policy engine may classify concepts as high-trust and force verification.
|
| 90 |
+
|
| 91 |
+
**Violation severity:** error in high-trust contexts; warn otherwise.
|
| 92 |
+
|
| 93 |
+
---
|
| 94 |
+
|
| 95 |
+
## I7 — AI output must remain explicitly derivative
|
| 96 |
+
|
| 97 |
+
No LLM output may be stored or surfaced as canonical truth without an explicit canonical source reference or a recorded human affirmation.
|
| 98 |
+
|
| 99 |
+
**Enforcement:**
|
| 100 |
+
- `SA_Executor` stamps completion entities with `truth_class = inferred`.
|
| 101 |
+
- `SA_Entity::create()` calls `SA_Invariants::check_ai_output_not_canonical()`. Attempting to create an AI-sourced entity with `truth_class = canonical` without either `source_refs` (non-empty) or `human_affirmed_at`+`human_affirmed_by` is rejected.
|
| 102 |
+
- Promotion from `inferred` → `canonical` or `projected` requires an explicit endpoint call (future work) that records the promoting actor + timestamp.
|
| 103 |
+
|
| 104 |
+
**Violation severity:** fatal.
|
| 105 |
+
|
| 106 |
+
---
|
| 107 |
+
|
| 108 |
+
## I8 — Destroying Core must not destroy incorporated realms
|
| 109 |
+
|
| 110 |
+
This is I5's strongest form. If Core is deleted tomorrow, FluentCRM still works, QuickBooks still works, Jira still works, PortTracker still works. Core owns no canonical realm data. Cache is non-canonical by construction. Push-backs are immediate, not batched into Core's own persistence.
|
| 111 |
+
|
| 112 |
+
**Enforcement:**
|
| 113 |
+
- Adapter certification checklist item: `source_identity_preserved` + `native_ids_preserved`.
|
| 114 |
+
- Contractual, not just technical: the product terms explicitly disclaim any Core-only source of truth for realm concepts.
|
| 115 |
+
- Periodic audit: `SA_Adapter_Certification` re-runs on each adapter release and the passed flag is visible to operators.
|
| 116 |
+
|
| 117 |
+
**Violation severity:** fatal at certification; a failing adapter cannot go live.
|
| 118 |
+
|
| 119 |
+
---
|
| 120 |
+
|
| 121 |
+
## I9 — Attributable concepts and the framework lineage must not be rephrased as AI-original
|
| 122 |
+
|
| 123 |
+
Both **named concepts** and **the framework lineage that contains them** must carry author attribution wherever surfaced.
|
| 124 |
+
|
| 125 |
+
**Named concepts** (authored by a human and preserved verbatim under this invariant) include the Russell-Ouroboros Conjecture, the Prime Prompt Conjecture + PR notation, the Cognitive Heatsink model, the Signal Telemetry Doctrine, the Reference Traversal Continuity Doctrine, the Story Seed pattern, the Concept-vs-Label doctrine, the Compass Doctrine, the Attention Doctrine, the Quest-vs-Job distinction, and any subsequent attributable work added to `docs/specs/concepts/`.
|
| 126 |
+
|
| 127 |
+
**The framework lineage** is the chain Causal Relativity ⊇ Causal Agentics ⊇ JourneySeeker ⊇ MissionNet/MeshNet ⊇ SA-Orchestration ⊇ Brand ⊇ Client (see `concepts/lineage-chain.md`). The structural primitives at each layer (truth class taxonomy, compass roles, description-as-contract, seed-vs-canonical, projection vs canonical, actor/realm/adapter, Quest/Job distinction) are framework primitives, not implementation primitives.
|
| 128 |
+
|
| 129 |
+
AI-generated text that paraphrases or adapts either named concepts or framework primitives must reference the original author and must not present the concept as newly originated by the AI or by the implementation layer.
|
| 130 |
+
|
| 131 |
+
**Enforcement:**
|
| 132 |
+
|
| 133 |
+
- The spec pack under `docs/specs/` carries attribution frontmatter.
|
| 134 |
+
- `docs/specs/concepts/` preserves the original authored artifacts verbatim with explicit author credit.
|
| 135 |
+
- AI output passing through Core that draws on attributable concepts or framework primitives must reference them (adapter-level policy, future work).
|
| 136 |
+
- Adapter certification: AI summarizers that produce text must not strip authored-concept attribution.
|
| 137 |
+
- Seed generators must not synthesize content that re-authors framework primitives as implementation-original. INTERPRETIVE-mode synthesis is bound by this clause.
|
| 138 |
+
|
| 139 |
+
**Violation severity:** warn at generation time; fatal at publication time.
|
| 140 |
+
|
| 141 |
+
---
|
| 142 |
+
|
| 143 |
+
## I10 — No automatic conversion between Quest and Job
|
| 144 |
+
|
| 145 |
+
A Quest may not be promoted to a Job, and a Job may not be elevated to a Quest, without an explicit human act recording the conversion.
|
| 146 |
+
|
| 147 |
+
The reason: a Quest lives in the realm of authored intent — admissible uncertainty, possible alternatives, future framing. A Job lives in the realm of resolved consequence — it happened or did not. Auto-conversion collapses one into the other and erases the distinction the author made between direction and execution.
|
| 148 |
+
|
| 149 |
+
**Enforcement:**
|
| 150 |
+
|
| 151 |
+
- Quest → Job conversion requires an actor + timestamp + recorded conversion event in the audit log.
|
| 152 |
+
- Job → Quest elevation (rare) requires the same.
|
| 153 |
+
- A "Convert to Job" UI action that creates the conversion event with explicit human click is acceptable. A scheduled background job that auto-promotes without that event is not.
|
| 154 |
+
- Reality resolves Jobs; humans resolve Quests. A system that conflates the two collapses the compass (see `concepts/compass-doctrine.md`).
|
| 155 |
+
|
| 156 |
+
**Violation severity:** error.
|
| 157 |
+
|
| 158 |
+
---
|
| 159 |
+
|
| 160 |
+
## Notation
|
| 161 |
+
|
| 162 |
+
Every invariant check logs a row to `sa_invariant_violation` with:
|
| 163 |
+
|
| 164 |
+
- `invariant_id` — one of `I1`…`I9`
|
| 165 |
+
- `severity` — `warn | error | fatal`
|
| 166 |
+
- `target_entity_id` / `target_audit_id`
|
| 167 |
+
- `actor_id`
|
| 168 |
+
- `details` — JSON-encoded context
|
| 169 |
+
- `acknowledged_at` / `acknowledged_by` — operational triage
|
| 170 |
+
|
| 171 |
+
Operational review dashboards can render violations grouped by `invariant_id` and sort by severity.
|
| 172 |
+
|
| 173 |
+
---
|
| 174 |
+
|
| 175 |
+
## Next
|
| 176 |
+
|
| 177 |
+
- Wire all cross-realm mutation paths (push, pull, ingest) through `SA_Invariants::assert_or_throw()`.
|
| 178 |
+
- Add enforcement to the presentation layer: UI must display `truth_class` on every surfaced datum (stamp in the top corner of every rendered entity).
|
| 179 |
+
- Extend audit trace with chain-coherence checks: if a row claims a causation_id, that row must exist.
|
| 180 |
+
- Build the policy engine layer so I6 (high-trust) and I9 (attribution) become user-configurable.
|
SA-orchestration MD/asterion/03-realm-adapter-contract.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MissionNet Realm Adapter Contract (v0.1)
|
| 2 |
+
|
| 3 |
+
*Implementation © Sleeper Agents LLC. Contract governed by invariants authored with Mark Holak's conceptual framework.*
|
| 4 |
+
|
| 5 |
+
Every realm adapter (FluentCRM, Fluent Support, Fluent Boards, Jira, QuickBase, QuickBooks, Salesforce, HubSpot, PortTracker's Node service, arbitrary REST/GraphQL/DB) implements `SA_Realm_Adapter`. This document is the formal contract.
|
| 6 |
+
|
| 7 |
+
An adapter is **complete when it preserves origin, survives failure, emits audit, and passes certification** — not when it "functions."
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## Interface
|
| 12 |
+
|
| 13 |
+
```php
|
| 14 |
+
interface SA_Realm_Adapter {
|
| 15 |
+
public static function realm_id(): string;
|
| 16 |
+
public static function capabilities(): array;
|
| 17 |
+
public static function concept_map(): array;
|
| 18 |
+
public static function pull(string $concept, array $filter, array $context): array;
|
| 19 |
+
public static function push(string $concept, SA_Entity $entity, array $context): array;
|
| 20 |
+
public static function watch_hooks(): array;
|
| 21 |
+
public static function capability_matrix(): array; // formal gates
|
| 22 |
+
public static function idempotency_rules(): array; // replay behavior per op
|
| 23 |
+
public static function truth_class_for_concept(string $concept): string;
|
| 24 |
+
}
|
| 25 |
+
```
|
| 26 |
+
|
| 27 |
+
---
|
| 28 |
+
|
| 29 |
+
## `realm_id()`
|
| 30 |
+
|
| 31 |
+
Short, stable identifier. Examples: `fluent-crm`, `fluent-support`, `fluent-boards`, `jira`, `quickbase`, `quickbooks`, `porttracker-node`.
|
| 32 |
+
|
| 33 |
+
Must be unique across all adapters in a given Core install. Used as the `origin_realm` on every entity the adapter produces.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
## `capabilities()`
|
| 38 |
+
|
| 39 |
+
Set of strings from: `read`, `write`, `watch`, `bulk`, `incremental`, `idempotent_push`.
|
| 40 |
+
|
| 41 |
+
- `read` — adapter can pull records from the realm.
|
| 42 |
+
- `write` — adapter can push changes back into the realm.
|
| 43 |
+
- `watch` — adapter subscribes to realm events (webhook or WP hooks).
|
| 44 |
+
- `bulk` — adapter supports full snapshot pulls.
|
| 45 |
+
- `incremental` — adapter supports `since` cursor / delta pulls.
|
| 46 |
+
- `idempotent_push` — repeated push calls with the same payload are safe.
|
| 47 |
+
|
| 48 |
+
A read-only adapter declares only `read` (and optionally `watch`, `bulk`, `incremental`).
|
| 49 |
+
|
| 50 |
+
---
|
| 51 |
+
|
| 52 |
+
## `payload.attributes` namespace convention
|
| 53 |
+
|
| 54 |
+
Structured realm-side metadata that Core stores on an ingested entity goes under `payload.attributes` — a reserved sub-object. Freeform realm-native blobs remain elsewhere in `payload` (e.g., `payload.raw`, `payload.body_markdown`), but any field an adapter intends to be *addressable* — readable by the trace panel, queryable by future projections, or filter-eligible — belongs in `attributes`.
|
| 55 |
+
|
| 56 |
+
```php
|
| 57 |
+
$entity->payload = [
|
| 58 |
+
'attributes' => [
|
| 59 |
+
'mime_type' => 'application/pdf',
|
| 60 |
+
'size_bytes' => 12345,
|
| 61 |
+
'modified_at' => '2026-04-23T10:15:00Z',
|
| 62 |
+
'basename' => 'spec.pdf',
|
| 63 |
+
'extension' => 'pdf',
|
| 64 |
+
],
|
| 65 |
+
'raw' => [/* whatever realm-native detail the adapter wants to retain */],
|
| 66 |
+
];
|
| 67 |
+
```
|
| 68 |
+
|
| 69 |
+
**Purpose.** Two-fold:
|
| 70 |
+
|
| 71 |
+
1. Adapters converge on a predictable shape for structured fields. The FS adapter, the Jira adapter, the QuickBase adapter all put their structured metadata in `attributes`. A downstream reader (trace panel, future filter surface) knows where to look without realm-specific code.
|
| 72 |
+
2. A later promotion to typed columns — if cross-realm queries demand it — is a rename migration, not a schema redesign. `payload.attributes.mime_type` becomes `entity.attributes.mime_type` or a separate `sa_entity_attribute` table without touching adapter code.
|
| 73 |
+
|
| 74 |
+
**Discipline.** `attributes` values SHOULD be JSON-scalar (string / number / boolean / null) or flat arrays thereof. Nested objects inside `attributes` are permitted but signal that a sub-concept may want its own entity and containment edge instead.
|
| 75 |
+
|
| 76 |
+
**Not canonical.** The `attributes` convention does not change truth-class. A projected entity's `payload.attributes` is still projection data; the realm remains canonical.
|
| 77 |
+
|
| 78 |
+
---
|
| 79 |
+
|
| 80 |
+
## `concept_map()`
|
| 81 |
+
|
| 82 |
+
Declares how realm concepts translate into Core entity roles and edge kinds.
|
| 83 |
+
|
| 84 |
+
```php
|
| 85 |
+
[
|
| 86 |
+
'ticket' => ['role' => 'job', 'band' => 3],
|
| 87 |
+
'agent' => ['role' => 'agent', 'band' => 3],
|
| 88 |
+
'customer'=> ['role' => 'agent', 'band' => 3],
|
| 89 |
+
'reply' => ['role' => 'message', 'band' => 4],
|
| 90 |
+
'edges' => [
|
| 91 |
+
'ticket->agent' => ['kind' => 'depends', 'weight' => 0.8],
|
| 92 |
+
'ticket->customer' => ['kind' => 'depends', 'weight' => 1.0],
|
| 93 |
+
'reply->ticket' => ['kind' => 'contains', 'weight' => 1.0],
|
| 94 |
+
],
|
| 95 |
+
]
|
| 96 |
+
```
|
| 97 |
+
|
| 98 |
+
Concept names are adapter-scoped (no collision across realms). Edge rules describe how relationships in the realm become typed edges in Core.
|
| 99 |
+
|
| 100 |
+
---
|
| 101 |
+
|
| 102 |
+
## `capability_matrix()`
|
| 103 |
+
|
| 104 |
+
Turns "tool not silo" into enforceable behavior:
|
| 105 |
+
|
| 106 |
+
```php
|
| 107 |
+
[
|
| 108 |
+
'read' => true,
|
| 109 |
+
'write' => true,
|
| 110 |
+
'delete' => false,
|
| 111 |
+
'impersonation' => false,
|
| 112 |
+
'service_principal' => true,
|
| 113 |
+
'human_confirmation_required' => ['delete', 'bulk_write', 'schema_change'],
|
| 114 |
+
'simulation_only_mode' => true,
|
| 115 |
+
]
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
Core consults this matrix before dispatching every operation. An adapter that does not declare `delete = true` cannot delete; an operation listed in `human_confirmation_required` cannot execute without a confirmed human action; `simulation_only_mode = true` enables dry-run mode for destructive operations.
|
| 119 |
+
|
| 120 |
+
---
|
| 121 |
+
|
| 122 |
+
## `idempotency_rules()`
|
| 123 |
+
|
| 124 |
+
Per-operation replay behavior:
|
| 125 |
+
|
| 126 |
+
```php
|
| 127 |
+
[
|
| 128 |
+
'pull' => [
|
| 129 |
+
'idempotent' => true,
|
| 130 |
+
'replay_safe' => true,
|
| 131 |
+
'conflict_resolution' => 'last_write_wins',
|
| 132 |
+
],
|
| 133 |
+
'push' => [
|
| 134 |
+
'idempotent' => false,
|
| 135 |
+
'replay_safe' => false,
|
| 136 |
+
'conflict_resolution' => 'reject',
|
| 137 |
+
],
|
| 138 |
+
'watch' => [
|
| 139 |
+
'idempotent' => true,
|
| 140 |
+
'replay_safe' => true,
|
| 141 |
+
'conflict_resolution' => 'last_write_wins',
|
| 142 |
+
],
|
| 143 |
+
]
|
| 144 |
+
```
|
| 145 |
+
|
| 146 |
+
`conflict_resolution` values: `last_write_wins` | `reject` | `human_review`.
|
| 147 |
+
|
| 148 |
+
A non-idempotent `push` must never be retried without an explicit policy decision.
|
| 149 |
+
|
| 150 |
+
---
|
| 151 |
+
|
| 152 |
+
## `pull(concept, filter, context)`
|
| 153 |
+
|
| 154 |
+
Returns a list of `SA_Ingest`-shaped mutations:
|
| 155 |
+
|
| 156 |
+
```php
|
| 157 |
+
[
|
| 158 |
+
[
|
| 159 |
+
'op' => 'upsert_entity',
|
| 160 |
+
'entity' => [
|
| 161 |
+
'external_key' => '<native_id>', // REQUIRED (or origin_id directly)
|
| 162 |
+
'role' => 'job',
|
| 163 |
+
'kind' => 'rrect',
|
| 164 |
+
'payload' => [...],
|
| 165 |
+
'truth_class' => SA_Truth_Class::PROJECTED, // default
|
| 166 |
+
],
|
| 167 |
+
],
|
| 168 |
+
[
|
| 169 |
+
'op' => 'upsert_edge',
|
| 170 |
+
'edge' => [
|
| 171 |
+
'source_id' => '...',
|
| 172 |
+
'target_id' => '...',
|
| 173 |
+
'kind' => 'depends',
|
| 174 |
+
'weight' => 0.8,
|
| 175 |
+
'intentional' => true,
|
| 176 |
+
],
|
| 177 |
+
],
|
| 178 |
+
[
|
| 179 |
+
'op' => 'attach_source',
|
| 180 |
+
'entity_id' => '...',
|
| 181 |
+
'priority' => 10,
|
| 182 |
+
'source_payload' => [...],
|
| 183 |
+
],
|
| 184 |
+
]
|
| 185 |
+
```
|
| 186 |
+
|
| 187 |
+
**Provenance minimums are MANDATORY** (Invariant I4). Every upserted entity must carry either `external_key` (from which `origin_realm` + `origin_id` are derived) or `origin_realm` + `origin_id` explicitly.
|
| 188 |
+
|
| 189 |
+
**Truth class default is `projected`** — non-canonical mirror of the realm's canonical state. Only adapters whose concept is genuinely advisory (weather forecasts, suggestions) may return `inferred`.
|
| 190 |
+
|
| 191 |
+
---
|
| 192 |
+
|
| 193 |
+
## `push(concept, entity, context)`
|
| 194 |
+
|
| 195 |
+
Apply a Core-side change back into the realm.
|
| 196 |
+
|
| 197 |
+
Returns:
|
| 198 |
+
|
| 199 |
+
```php
|
| 200 |
+
[
|
| 201 |
+
'ok' => true,
|
| 202 |
+
'external_id' => '<realm-assigned-id-if-new>',
|
| 203 |
+
'error' => null,
|
| 204 |
+
'trace_token' => '<optional-realm-trace-handle>',
|
| 205 |
+
]
|
| 206 |
+
```
|
| 207 |
+
|
| 208 |
+
**Idempotency:** if declared in `idempotency_rules()`, `push` MUST be safe to retry. The adapter is responsible for deduplicating on the realm side (using the entity's `id` or a synthetic idempotency key).
|
| 209 |
+
|
| 210 |
+
**Never mutate without action path.** A push that was not triggered by a command (or an audited automation policy) is a protocol violation.
|
| 211 |
+
|
| 212 |
+
---
|
| 213 |
+
|
| 214 |
+
## `watch_hooks()`
|
| 215 |
+
|
| 216 |
+
```php
|
| 217 |
+
[
|
| 218 |
+
['hook' => 'fluentcrm/contact_created', 'handler' => [self::class, 'on_contact_created'], 'priority' => 10],
|
| 219 |
+
['hook' => 'fluent_support/ticket_reply', 'handler' => [self::class, 'on_reply'], 'priority' => 10],
|
| 220 |
+
]
|
| 221 |
+
```
|
| 222 |
+
|
| 223 |
+
Core's `SA_Realm_Registry::wire_all_watchers()` attaches these on boot. The handler must emit ingest mutations (not directly mutate Core state), so that the ingest pipeline's enforcement gates apply uniformly.
|
| 224 |
+
|
| 225 |
+
---
|
| 226 |
+
|
| 227 |
+
## `truth_class_for_concept(concept)`
|
| 228 |
+
|
| 229 |
+
Returns one of `SA_Truth_Class::ALL`. Default: `projected`.
|
| 230 |
+
|
| 231 |
+
- Realm concepts that are authoritative at the realm: `projected`.
|
| 232 |
+
- Realm concepts that are explicitly advisory: `inferred`.
|
| 233 |
+
- Core-authored concepts (rare): `canonical`.
|
| 234 |
+
- Cache-only concepts with TTL: `cached` (declared by the adapter's cache layer, not usually by the adapter itself).
|
| 235 |
+
|
| 236 |
+
---
|
| 237 |
+
|
| 238 |
+
## Certification Checklist
|
| 239 |
+
|
| 240 |
+
An adapter is **not live** until these pass. Recorded to `sa_adapter_certification`.
|
| 241 |
+
|
| 242 |
+
| Check | Meaning |
|
| 243 |
+
|---|---|
|
| 244 |
+
| `source_identity_preserved` | Realm's native id is preserved on every ingested record and round-trippable through push. |
|
| 245 |
+
| `native_ids_preserved` | `origin_id` survives every transformation in and out. |
|
| 246 |
+
| `read_path_verified` | Pull returns records that successfully deserialize as Core entities. |
|
| 247 |
+
| `write_path_verified` | Push creates or updates a realm record and returns the native id. |
|
| 248 |
+
| `failure_path_verified` | Failures (network, 4xx, 5xx, timeouts) raise structured errors; no silent half-writes. |
|
| 249 |
+
| `stale_cache_behavior_verified` | When cache is stale and the caller demands high-trust, the adapter re-verifies against the realm. |
|
| 250 |
+
| `audit_event_emitted` | Every pull and push produces a `sa_structural_audit` row with `origin_realm`, `correlation_id`, `causation_id`. |
|
| 251 |
+
| `rollback_defined` | There is a documented compensation path for failed pushes or partial batches. |
|
| 252 |
+
|
| 253 |
+
All eight must be `true` before an adapter moves from development to live. A failing certification row prevents the realm from being included in the active routing set.
|
| 254 |
+
|
| 255 |
+
---
|
| 256 |
+
|
| 257 |
+
## Behavioral guarantees (enforced at interface level)
|
| 258 |
+
|
| 259 |
+
- Adapter **never mutates without an action path**. A push requires a command; a pull is triggered by an explicit sync or a watch event.
|
| 260 |
+
- Adapter **never strips source metadata**. `origin_realm`, `origin_id`, `observed_at` survive every transformation.
|
| 261 |
+
- Every record returned includes native id and source realm.
|
| 262 |
+
- Outbound writes return status, external id, and (where available) a trace token.
|
| 263 |
+
- Retries are idempotent where declared; non-idempotent operations require explicit policy approval to retry.
|
| 264 |
+
- Error classes are normalized to `{ok, error, error_code, detail}`.
|
| 265 |
+
|
| 266 |
+
---
|
| 267 |
+
|
| 268 |
+
## The tool test
|
| 269 |
+
|
| 270 |
+
Before any realm adapter is declared live, the operator asks:
|
| 271 |
+
|
| 272 |
+
> If Core disappears tomorrow, does this realm still work at its native home?
|
| 273 |
+
|
| 274 |
+
If the answer is anything but *yes*, the adapter has crossed from incorporation into absorption. That is a different category, governed by a different process (code consolidation, not conduit), and must be signaled as such. The user and the operator must both consent before an adapter is ever permitted to cross this boundary.
|
| 275 |
+
|
| 276 |
+
---
|
| 277 |
+
|
| 278 |
+
## Attribution
|
| 279 |
+
|
| 280 |
+
Contract shape and adapter interface: © Sleeper Agents LLC.
|
| 281 |
+
|
| 282 |
+
The invariants that the contract enforces (I4 realm provenance, I5 graceful degradation, I6 cache discipline, I8 tool test) implement conceptual commitments authored independently by Mark Holak. See `docs/specs/concepts/` for the foundational framework.
|
SA-orchestration MD/asterion/04-async-execution.md
ADDED
|
@@ -0,0 +1,678 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Async Execution — Design Specification
|
| 2 |
+
|
| 3 |
+
Status: **design approved; Phase 1 implementing as foundational substrate.**
|
| 4 |
+
Target rung: 2.5 (between projection completion and zoom-quantum).
|
| 5 |
+
Scope: one foundational pillar. Implementation proceeds phase-by-phase under separate directives.
|
| 6 |
+
|
| 7 |
+
## Framing (authoritative)
|
| 8 |
+
|
| 9 |
+
The pillar is **ownership of execution**, not "offline" as a feature.
|
| 10 |
+
|
| 11 |
+
Three layers, kept distinct:
|
| 12 |
+
|
| 13 |
+
- **Now Session** — the user-facing scope. The browser tab, the compose bar,
|
| 14 |
+
the field as it reads during an interactive moment. UX lives here. In
|
| 15 |
+
Phase 1 this is UNCHANGED: prompts still feel like "I asked here, it is
|
| 16 |
+
working here, this thread is mine now."
|
| 17 |
+
|
| 18 |
+
- **Shadow job** — the execution substrate. A server-owned lifecycle record
|
| 19 |
+
(`sa_job`) that tracks what the executor is actually doing. Introduced in
|
| 20 |
+
Phase 1 as foundational infrastructure, with no UX surfacing. The seam
|
| 21 |
+
that makes later decoupling possible without rewriting retries, state
|
| 22 |
+
transitions, frontier selection, failure handling, or field updates.
|
| 23 |
+
|
| 24 |
+
- **Offline / Subconscious** — a future user-facing mode built on the
|
| 25 |
+
shadow-job substrate. Marketing layer for background / recoverable / long-
|
| 26 |
+
running work. NOT introduced by Phase 1. Introduced only when a later
|
| 27 |
+
directive surfaces it.
|
| 28 |
+
|
| 29 |
+
The instruction the rest of this spec serves:
|
| 30 |
+
|
| 31 |
+
> Treat shadow jobs as foundational infrastructure introduced now, but keep
|
| 32 |
+
> their behavior scoped to the current Now Session until a later directive
|
| 33 |
+
> surfaces them as an explicit Offline/Subconscious capability.
|
| 34 |
+
|
| 35 |
+
---
|
| 36 |
+
|
| 37 |
+
## 0. Scope note
|
| 38 |
+
|
| 39 |
+
This spec describes **async prompt execution** as a first-class capability.
|
| 40 |
+
|
| 41 |
+
It does NOT cover:
|
| 42 |
+
- The client-state race bug-fix (a separate, independent commit — closes a symptom of the sync model; lands before or alongside phase 1 here).
|
| 43 |
+
- Implementation commits (each phase below becomes a directive; each directive becomes one or more commits).
|
| 44 |
+
|
| 45 |
+
It DOES cover:
|
| 46 |
+
- What a prompt job is, and how it differs from the current request.
|
| 47 |
+
- The canonical state machine.
|
| 48 |
+
- The storage model.
|
| 49 |
+
- The worker strategy (comparison + decision + rationale).
|
| 50 |
+
- The client interaction model (comparison + phased choice).
|
| 51 |
+
- A phased migration plan where each phase ships a working system.
|
| 52 |
+
- The failure / retry / recovery model.
|
| 53 |
+
- Explicit tradeoffs and risks.
|
| 54 |
+
- Measurable success criteria.
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## 1. Motivation and Current Limitations
|
| 59 |
+
|
| 60 |
+
### Today
|
| 61 |
+
|
| 62 |
+
- `POST /sa-core/v1/prompt` is synchronous. The REST thread calls `SA_Executor::run`, which calls the adapter via `wp_remote_post`, which blocks the PHP request for up to 180 seconds (after the recent timeout raise).
|
| 63 |
+
- The browser tab owns the entire prompt lifecycle. The client's `fetch()` holds the connection; if the tab closes, the server continues running but the user loses all visibility into the outcome.
|
| 64 |
+
- Two prompts submitted in parallel are two parallel PHP workers, each doing a long cURL wait, with zero coordination, no priority, and no recovery if one of them crashes.
|
| 65 |
+
- The just-observed concurrent-submit race (two prompts attaching to the same parent) is a symptom: client-side `activeCtxRootId` is the only source of truth for "which node is the continuation root," so timing conflicts between user navigation and async resolution are inevitable.
|
| 66 |
+
|
| 67 |
+
### Why this is structural, not cosmetic
|
| 68 |
+
|
| 69 |
+
1. **Rung 5 (operator realism) is blocked.** Tests that simulate load, capacity planning, reliability SLAs, and meaningful metrics all require async job execution. Every one of these is meaningless against a sync model.
|
| 70 |
+
2. **Rung 4 (zoom-quantum engine) gets much harder on sync.** The engine wants cheap state-transition re-renders. Pushing state through long sync calls + `/mission/recent` refreshes introduces races we'd have to hunt repeatedly.
|
| 71 |
+
3. **Rungs 3 and 6 (self-hosting, carma-audit absorption) produce entity streams that shouldn't block HTTP.** Scanner runs, doc ingestion, code ingestion — none of these should tie up a web request.
|
| 72 |
+
4. **The tab is not a reliable process owner.** Real work — long code generations, multi-step agent chains, background analyses — must survive a closed tab.
|
| 73 |
+
5. **Browser-side state conflicts are fundamental with sync.** The concurrent-submit race is one; future race surfaces (multi-user live editing, real-time collaboration) are coming. Moving execution state authority to the server closes these by construction.
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## 2. Execution Model
|
| 78 |
+
|
| 79 |
+
### What is a "prompt job"
|
| 80 |
+
|
| 81 |
+
A **prompt job** is the unit of work that executes the `SA_Executor` pipeline against a specific prompt entity. It is:
|
| 82 |
+
|
| 83 |
+
- A durable record with its own UUID identity (distinct from the prompt entity).
|
| 84 |
+
- A pointer to a persisted prompt entity (`prompt_id`).
|
| 85 |
+
- A member of the queue with a state, a priority, and a retry budget.
|
| 86 |
+
- Owned by the server, not the browser.
|
| 87 |
+
- Inspectable, retriable, cancellable, supersedable — as a first-class operation.
|
| 88 |
+
|
| 89 |
+
### How it differs from the current request model
|
| 90 |
+
|
| 91 |
+
| Concern | Today (sync) | Proposed (async) |
|
| 92 |
+
|---|---|---|
|
| 93 |
+
| Who owns the pipeline's lifecycle? | The REST thread | The worker layer |
|
| 94 |
+
| Where is "in-progress" state? | PHP memory + browser memory | `sa_job` DB row |
|
| 95 |
+
| Does closing the tab kill the work? | No (it continues) but the user loses visibility | No — and the user regains visibility on reload |
|
| 96 |
+
| Can two prompts run simultaneously? | Only as two parallel PHP workers with no coordination | Yes, first-class, priority-ordered |
|
| 97 |
+
| Can a failed execution be retried cleanly? | Via `retry_prompt` after the fact | Built into the state machine |
|
| 98 |
+
| Can the user inspect queued / running work? | No | Yes (CLI phase 2; UI later) |
|
| 99 |
+
|
| 100 |
+
### Canonical lifecycle
|
| 101 |
+
|
| 102 |
+
1. **Submit.** `POST /prompt` creates:
|
| 103 |
+
- Prompt entity (as today, synchronously within the request — this is fast; the adapter call is what blocks).
|
| 104 |
+
- `sa_job` row with `state='queued'`.
|
| 105 |
+
- Returns **`202 Accepted`** with `prompt_id`, `job_id`, and initial state. Target: response within 50ms.
|
| 106 |
+
2. **Enqueue.** Client adds the prompt to its `entities[]` array with the job's state, renders a "queued" drop. Client begins polling (phase 2) or listening via SSE (phase 4).
|
| 107 |
+
3. **Claim.** A worker polls for the highest-priority queued job. Transactional update: `state='queued'` → `state='running'`, `worker_claim=<uuid>`, `claimed_at=now`.
|
| 108 |
+
4. **Run.** The worker invokes `SA_Executor::run_claimed(job_id)`. This is a refactored executor entry-point that operates on an already-persisted prompt + job, not a fresh submit.
|
| 109 |
+
5. **Complete.** On adapter success, the worker writes the response entity, the `flows-to` edge, the ledger row, the structural audit row (as today), and transitions the job to `state='succeeded'` with `response_id` set.
|
| 110 |
+
6. **Observe.** Client sees state transitions via polling or SSE, updates the drop's visual state class accordingly.
|
| 111 |
+
7. **Fail (if applicable).** On adapter error, the worker classifies the error, applies retry policy, and either re-queues the job with backoff OR marks it `state='failed'`.
|
| 112 |
+
|
| 113 |
+
---
|
| 114 |
+
|
| 115 |
+
## 3. State Machine
|
| 116 |
+
|
| 117 |
+
### States
|
| 118 |
+
|
| 119 |
+
| State | Meaning | Terminal? |
|
| 120 |
+
|---|---|---|
|
| 121 |
+
| `queued` | Created; waiting for a worker | No |
|
| 122 |
+
| `running` | Claimed by a worker; adapter call in flight | No |
|
| 123 |
+
| `succeeded` | Adapter returned OK; response entity persisted | Yes |
|
| 124 |
+
| `failed` | Retry budget exhausted or non-retryable error | Yes |
|
| 125 |
+
| `cancelled` | User or operator intervention | Yes |
|
| 126 |
+
| `superseded` | Replaced by a newer job (e.g., user retried) | Yes |
|
| 127 |
+
|
| 128 |
+
Once a job enters a terminal state, it does not change. A retry does **not** mutate an existing job — it creates a **new job** that references the old one via `supersedes`.
|
| 129 |
+
|
| 130 |
+
### Transitions
|
| 131 |
+
|
| 132 |
+
```
|
| 133 |
+
queued → running : worker successfully claims
|
| 134 |
+
queued → cancelled : user/operator action before claim
|
| 135 |
+
running → succeeded : adapter OK + response entity written
|
| 136 |
+
running → queued : transient failure; attempt < max_attempts; apply backoff
|
| 137 |
+
running → failed : retry budget exhausted OR non-retryable error
|
| 138 |
+
running → failed : stuck (started > 15 min ago, no heartbeat) via cleanup
|
| 139 |
+
running → cancelled : operator kill (response discarded even if it arrives later)
|
| 140 |
+
succeeded → superseded : user-initiated retry replaces result
|
| 141 |
+
failed → superseded : user-initiated retry
|
| 142 |
+
cancelled → superseded : user-initiated retry after cancel
|
| 143 |
+
```
|
| 144 |
+
|
| 145 |
+
### Heartbeat model
|
| 146 |
+
|
| 147 |
+
While `state='running'`, the worker MUST update `running_heartbeat_at` every 30 seconds. A separate cleanup task (run via system cron every 5 minutes) reclaims jobs where `running_heartbeat_at < now() - 5min` back to `state='queued'` (if `attempt < max_attempts`) or to `state='failed'` (else).
|
| 148 |
+
|
| 149 |
+
### Triggers
|
| 150 |
+
|
| 151 |
+
- `queued` ← `SA_Executor::enqueue` (called from REST handler).
|
| 152 |
+
- `running` ← worker process picks up a `queued` job and wins the claim race.
|
| 153 |
+
- `succeeded` ← worker completes execution and commits.
|
| 154 |
+
- `failed` ← worker exhausts retries OR cleanup declares job stuck.
|
| 155 |
+
- `cancelled` ← CLI `wp sa-core cancel-job <id>` OR admin action.
|
| 156 |
+
- `superseded` ← a new job is created referring to this one via `supersedes`.
|
| 157 |
+
|
| 158 |
+
---
|
| 159 |
+
|
| 160 |
+
## 4. Storage Model
|
| 161 |
+
|
| 162 |
+
### Decision: new `sa_job` table
|
| 163 |
+
|
| 164 |
+
Not overloading `sa_entity`.
|
| 165 |
+
|
| 166 |
+
Rationale:
|
| 167 |
+
- `sa_entity` represents authored knowledge: the user's prompt, the LLM's response, the derived context. It has one durable identity per artifact.
|
| 168 |
+
- `sa_job` represents execution: a prompt may have multiple execution attempts (retries), each with its own claim, timing, errors, heartbeats. Conflating these with entity state confuses semantics and crowds the entity row.
|
| 169 |
+
- Keeping them separate means: `sa_entity` stays durable knowledge; `sa_job` stays ephemeral execution records. Queries stay clean: "show me the user's recent prompts" is a `sa_entity` query; "show me what's queued" is a `sa_job` query.
|
| 170 |
+
|
| 171 |
+
### Schema
|
| 172 |
+
|
| 173 |
+
```sql
|
| 174 |
+
CREATE TABLE {prefix}sa_job (
|
| 175 |
+
id CHAR(36) NOT NULL,
|
| 176 |
+
prompt_id CHAR(36) NOT NULL,
|
| 177 |
+
|
| 178 |
+
state VARCHAR(16) NOT NULL DEFAULT 'queued',
|
| 179 |
+
-- queued | running | succeeded | failed | cancelled | superseded
|
| 180 |
+
|
| 181 |
+
priority TINYINT UNSIGNED NOT NULL DEFAULT 50,
|
| 182 |
+
-- lower number = higher priority
|
| 183 |
+
-- 0-10: urgent (interactive, current-tab)
|
| 184 |
+
-- 20-40: normal user-initiated background
|
| 185 |
+
-- 50: default
|
| 186 |
+
-- 60-90: bulk / scheduled / idle-time
|
| 187 |
+
-- 100: lowest (opportunistic)
|
| 188 |
+
|
| 189 |
+
attempt SMALLINT UNSIGNED NOT NULL DEFAULT 1,
|
| 190 |
+
max_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 3,
|
| 191 |
+
|
| 192 |
+
execution_options LONGTEXT NOT NULL,
|
| 193 |
+
-- JSON: { model?, prefer_provider?, depth?, router_model?, ... }
|
| 194 |
+
|
| 195 |
+
worker_claim VARCHAR(64) NULL,
|
| 196 |
+
claimed_at DATETIME NULL,
|
| 197 |
+
started_at DATETIME NULL,
|
| 198 |
+
running_heartbeat_at DATETIME NULL,
|
| 199 |
+
finished_at DATETIME NULL,
|
| 200 |
+
|
| 201 |
+
response_id CHAR(36) NULL,
|
| 202 |
+
-- set on succeeded; points to the response entity
|
| 203 |
+
|
| 204 |
+
error_kind VARCHAR(32) NULL,
|
| 205 |
+
-- timeout | rate_limit | provider_5xx | provider_4xx
|
| 206 |
+
-- | parse | auth | worker_crash | stuck | unknown
|
| 207 |
+
|
| 208 |
+
error_message TEXT NULL,
|
| 209 |
+
|
| 210 |
+
supersedes CHAR(36) NULL,
|
| 211 |
+
-- if this job replaces a previous attempt
|
| 212 |
+
|
| 213 |
+
org_id BIGINT UNSIGNED NOT NULL,
|
| 214 |
+
created_by BIGINT UNSIGNED NOT NULL,
|
| 215 |
+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
| 216 |
+
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
| 217 |
+
ON UPDATE CURRENT_TIMESTAMP,
|
| 218 |
+
|
| 219 |
+
PRIMARY KEY (id),
|
| 220 |
+
KEY idx_state_priority_created (state, priority, created_at),
|
| 221 |
+
KEY idx_prompt (prompt_id),
|
| 222 |
+
KEY idx_worker_claim (worker_claim),
|
| 223 |
+
KEY idx_org_user_state (org_id, created_by, state),
|
| 224 |
+
KEY idx_heartbeat (state, running_heartbeat_at)
|
| 225 |
+
)
|
| 226 |
+
```
|
| 227 |
+
|
| 228 |
+
### Interaction with existing entity fields
|
| 229 |
+
|
| 230 |
+
| Field | Lives on | Set when | Changed by jobs? |
|
| 231 |
+
|---|---|---|---|
|
| 232 |
+
| `correlation_id` | `sa_entity` | At prompt creation time (unchanged) | No |
|
| 233 |
+
| `parent_id` | `sa_entity` | At prompt creation time (continuation semantics, unchanged) | No |
|
| 234 |
+
| `causation_id` | `sa_entity` | At prompt creation time (unchanged) | No |
|
| 235 |
+
| `source_refs` | `sa_entity` (response) | Written by worker at job completion | Indirectly (job runs the executor which sets it) |
|
| 236 |
+
| `truth_class` / `state_class` | `sa_entity` | Set at write time (unchanged) | No |
|
| 237 |
+
|
| 238 |
+
The `sa_job` table is orthogonal to the entity graph. Entities are durable structural records. Jobs are execution metadata.
|
| 239 |
+
|
| 240 |
+
### Retry and supersession
|
| 241 |
+
|
| 242 |
+
When a user retries a failed or succeeded prompt:
|
| 243 |
+
1. Create a **new** `sa_job` row with the same `prompt_id`, new UUID, `attempt=1`, `state=queued`, `supersedes=<old_job_id>`.
|
| 244 |
+
2. The old job stays in place (terminal state preserved).
|
| 245 |
+
3. If the retry path requires cleaning up a prior response entity (as the current `retry_prompt` does for failed responses), that happens in the worker that claims the new job, NOT at enqueue time.
|
| 246 |
+
|
| 247 |
+
This model means every execution attempt is recorded and queryable. "Show me the history of this prompt" becomes `SELECT * FROM sa_job WHERE prompt_id = X ORDER BY created_at`.
|
| 248 |
+
|
| 249 |
+
---
|
| 250 |
+
|
| 251 |
+
## 5. Worker Strategy
|
| 252 |
+
|
| 253 |
+
### Decision: custom worker, driven by WP-CLI + system cron
|
| 254 |
+
|
| 255 |
+
### Comparison
|
| 256 |
+
|
| 257 |
+
**Option A: WP-Cron alone** — not chosen.
|
| 258 |
+
- Pros: zero external dependencies.
|
| 259 |
+
- Cons: WP-Cron spawns only on page visits (unreliable for low-traffic sites); each spawn is bound by `max_execution_time`; no native priority; no concurrency management. The "real cron hitting `wp-cron.php`" workaround mitigates the first point but the others remain.
|
| 260 |
+
|
| 261 |
+
**Option B: Action Scheduler (the library)** — fallback / future option.
|
| 262 |
+
- Pros: mature, battle-tested by WooCommerce and Mailpoet, has built-in claim/retry/logs, comes with an admin UI, well-understood in the WP ecosystem.
|
| 263 |
+
- Cons: adds a dependency (~200KB library, or plugin requirement); its schema and patterns are WooCommerce-flavored; it wraps our job concept with its own scheduling layer that we'd then have to thread through.
|
| 264 |
+
- Worth reconsidering if we ever need to interoperate with a WooCommerce-running site that already uses AS.
|
| 265 |
+
|
| 266 |
+
**Option C: Custom worker** — chosen.
|
| 267 |
+
- Rationale: our `sa_job` table **is** our job system. Its state machine is specific to our semantics (prompt-centric, projection-aware, org-scoped). Adding Action Scheduler on top means we'd write adapters between our table and theirs. A custom worker is ~300 lines of code, directly aligned with our data model.
|
| 268 |
+
- Cons: we own the scheduler code. Edge cases (claim races, heartbeat recovery, backoff) must be solved by us. But: the surface is narrow, there's no distributed coordination to worry about (single-node plugin), and the patterns are well-known.
|
| 269 |
+
|
| 270 |
+
### Custom worker implementation
|
| 271 |
+
|
| 272 |
+
```
|
| 273 |
+
wp sa-core run-worker [--once] [--batch-size=N] [--priority-ceiling=N]
|
| 274 |
+
```
|
| 275 |
+
|
| 276 |
+
Behavior in one iteration:
|
| 277 |
+
1. Generate or resume a `worker_id` for this process (UUID).
|
| 278 |
+
2. Claim a batch of jobs:
|
| 279 |
+
```sql
|
| 280 |
+
UPDATE sa_job
|
| 281 |
+
SET state='running',
|
| 282 |
+
worker_claim=<worker_id>,
|
| 283 |
+
claimed_at=NOW(),
|
| 284 |
+
started_at=NOW(),
|
| 285 |
+
running_heartbeat_at=NOW()
|
| 286 |
+
WHERE state='queued'
|
| 287 |
+
AND priority <= <priority-ceiling>
|
| 288 |
+
ORDER BY priority ASC, created_at ASC
|
| 289 |
+
LIMIT <batch-size>
|
| 290 |
+
```
|
| 291 |
+
The single-statement UPDATE is the claim atomic: whichever worker's UPDATE lands first, wins.
|
| 292 |
+
3. Re-query the claimed rows by `worker_claim=<worker_id>` to get the actual job ids.
|
| 293 |
+
4. For each claimed job:
|
| 294 |
+
- Call `SA_Executor::run_claimed(job_id)`.
|
| 295 |
+
- On success: set state='succeeded', response_id, finished_at.
|
| 296 |
+
- On retryable failure: if attempt < max_attempts, set state='queued' with backoff delay (encoded via `created_at += backoff`); else state='failed'.
|
| 297 |
+
- On non-retryable failure: state='failed' immediately.
|
| 298 |
+
5. Spawn a heartbeat thread/callback that updates `running_heartbeat_at` every 30s while the adapter is in flight.
|
| 299 |
+
6. Sleep 2 seconds. If `--once`, exit. Otherwise loop.
|
| 300 |
+
|
| 301 |
+
### Driving the worker
|
| 302 |
+
|
| 303 |
+
Three supported modes:
|
| 304 |
+
|
| 305 |
+
**Mode 1: Single-shot via system cron** (recommended for production)
|
| 306 |
+
```cron
|
| 307 |
+
* * * * * wp sa-core run-worker --once --batch-size=5
|
| 308 |
+
```
|
| 309 |
+
Every minute, claim up to 5 jobs, process them, exit. Reliable, bounded, manageable.
|
| 310 |
+
|
| 311 |
+
**Mode 2: Long-running service** (optional for high-volume)
|
| 312 |
+
```
|
| 313 |
+
wp sa-core run-worker
|
| 314 |
+
```
|
| 315 |
+
Starts a persistent worker. Polls continuously. Should be supervised (systemd / supervisor) for restarts on crash.
|
| 316 |
+
|
| 317 |
+
**Mode 3: WP-Cron via wp-cron.php** (default; fallback)
|
| 318 |
+
If a site has no system cron, register `sa-core-process-queue` as a WP-Cron event firing every minute. Relies on site traffic; acceptable for dev and low-traffic installs.
|
| 319 |
+
|
| 320 |
+
### Heartbeat and stuck-job cleanup
|
| 321 |
+
|
| 322 |
+
Separate command:
|
| 323 |
+
```
|
| 324 |
+
wp sa-core reclaim-stuck-jobs
|
| 325 |
+
```
|
| 326 |
+
System cron: every 5 minutes.
|
| 327 |
+
|
| 328 |
+
Behavior:
|
| 329 |
+
- Find jobs where `state='running'` AND `running_heartbeat_at < now() - 5 minutes`.
|
| 330 |
+
- For each:
|
| 331 |
+
- If `attempt < max_attempts` AND `started_at > now() - 15 minutes`: reclaim to `state='queued'`, clear `worker_claim`.
|
| 332 |
+
- Else: `state='failed'`, `error_kind='stuck'`.
|
| 333 |
+
|
| 334 |
+
### Double-execution safety
|
| 335 |
+
|
| 336 |
+
Risk: worker A claims a job, loses heartbeat, cleanup reclaims to queued, worker B claims and runs. Worker A's adapter call may still be in flight. Both workers could reach the "complete" step.
|
| 337 |
+
|
| 338 |
+
Mitigation: all state-finalization writes (`state='succeeded'`, `response_id`, etc.) are conditioned on `WHERE state='running' AND worker_claim=<my_worker_id>`. Whichever update lands second sees no matching row and aborts silently. The first worker's result wins; the other worker's result is discarded (wasted work, but no data corruption).
|
| 339 |
+
|
| 340 |
+
---
|
| 341 |
+
|
| 342 |
+
## 6. Client Interaction Model
|
| 343 |
+
|
| 344 |
+
### Decision: polling in phase 2, SSE in phase 4, WebSocket deferred
|
| 345 |
+
|
| 346 |
+
### Comparison
|
| 347 |
+
|
| 348 |
+
| Protocol | Pros | Cons | Chosen? |
|
| 349 |
+
|---|---|---|---|
|
| 350 |
+
| **Polling** | Simplest; works anywhere; zero new infra; trivial to implement | Latency up to poll interval; wastes bandwidth when idle (mitigated by only polling while in-flight jobs exist) | Phase 2 |
|
| 351 |
+
| **Server-Sent Events** | Efficient for state updates; built into browsers (`EventSource`); one-way but that's what we need | Requires long-lived HTTP connection; may conflict with PHP `max_execution_time` on some hosts; harder to debug | Phase 4 |
|
| 352 |
+
| **WebSocket** | Full-duplex; lowest latency; richest protocol | Needs separate infra (Node or Ratchet-in-PHP); significant deployment burden; overkill for our scale | Deferred |
|
| 353 |
+
|
| 354 |
+
### Polling protocol (phase 2)
|
| 355 |
+
|
| 356 |
+
**Submit flow:**
|
| 357 |
+
|
| 358 |
+
1. Client calls `POST /prompt` with prompt text + root_entity_id + etc.
|
| 359 |
+
2. Server returns `202` with `{ prompt_id, job_id, state: 'queued' }`.
|
| 360 |
+
3. Client:
|
| 361 |
+
- Adds entity to `entities[]` with `state='queued'`, renders as queued drop.
|
| 362 |
+
- Starts a poll loop if not already running.
|
| 363 |
+
|
| 364 |
+
**Poll loop:**
|
| 365 |
+
|
| 366 |
+
- Every 2 seconds, while at least one in-flight (`queued` or `running`) job exists:
|
| 367 |
+
- Call `GET /sa-core/v1/mission/recent?since=<iso8601>`.
|
| 368 |
+
- Server returns entities with any updates since the timestamp.
|
| 369 |
+
- Client merges results by `prompt_id` (does not replace array wholesale).
|
| 370 |
+
- If all known prompts are terminal (succeeded, failed, cancelled, superseded) or no in-flight jobs remain, stop polling.
|
| 371 |
+
|
| 372 |
+
**Server endpoint changes (phase 2):**
|
| 373 |
+
|
| 374 |
+
- `GET /mission/recent` accepts `since=<iso8601>`. Returns only prompts updated since that time (joins `sa_job.updated_at` into the "is this updated" test).
|
| 375 |
+
- Response includes an `as_of` timestamp the client uses as the next `since` value.
|
| 376 |
+
|
| 377 |
+
### Field state → visual class mapping
|
| 378 |
+
|
| 379 |
+
| Job state | CSS class on drop | Existing / new | Visual |
|
| 380 |
+
|---|---|---|---|
|
| 381 |
+
| `queued` | `is-queued` | **New** | Slow breath, paler halo; "waiting" reading |
|
| 382 |
+
| `running` | `is-pending` | Existing | Current pending animation (dashed rotating halo) |
|
| 383 |
+
| `succeeded` | (none) | Existing | Default settled drop |
|
| 384 |
+
| `failed` | `is-orphan` | Existing | Muted salmon halo + retry chip |
|
| 385 |
+
| `cancelled` | `is-cancelled` | **New** | Greyed-out, no retry chip |
|
| 386 |
+
| `superseded` | hidden OR `.is-superseded` | **New** | Typically hidden; shown faded if a debug toggle enabled |
|
| 387 |
+
|
| 388 |
+
Transitions:
|
| 389 |
+
- `queued → running`: swap `is-queued` for `is-pending`.
|
| 390 |
+
- `running → succeeded`: remove `is-pending`, merge real response data, `renderField()` for any layout adjustment.
|
| 391 |
+
- `running → failed`: swap `is-pending` for `is-orphan`.
|
| 392 |
+
|
| 393 |
+
### SSE protocol (phase 4, future)
|
| 394 |
+
|
| 395 |
+
- Client opens `EventSource('/sa-core/v1/mission/events')` instead of polling.
|
| 396 |
+
- Server streams events like `event: job.state_changed\ndata: {"prompt_id":"…","state":"succeeded",…}\n\n` whenever a job's state changes for this viewer.
|
| 397 |
+
- Client falls back to polling if the `EventSource` fails.
|
| 398 |
+
|
| 399 |
+
### WebSocket (deferred)
|
| 400 |
+
|
| 401 |
+
Adds separate infra (Node sidecar, Ratchet-in-PHP, or a managed service like Pusher). No concrete need yet. Revisit when multi-user real-time collaboration becomes a live concern.
|
| 402 |
+
|
| 403 |
+
---
|
| 404 |
+
|
| 405 |
+
## 7. Migration Plan
|
| 406 |
+
|
| 407 |
+
### Principle: each phase ships a working system
|
| 408 |
+
|
| 409 |
+
No phase leaves the codebase in a half-broken state. At every phase boundary, a user can submit a prompt and see a result.
|
| 410 |
+
|
| 411 |
+
### Phase 0 — Concurrent-submit race fix (prerequisite, separate scope)
|
| 412 |
+
|
| 413 |
+
- Single commit, fixes the browser-state race in the current sync model.
|
| 414 |
+
- Does NOT introduce async.
|
| 415 |
+
- Makes parallel-submit testing reliable, which phase 2 needs.
|
| 416 |
+
|
| 417 |
+
### Phase 1 — Schema + shadow jobs (1–2 commits, zero behavior change)
|
| 418 |
+
|
| 419 |
+
Goal: write `sa_job` rows alongside synchronous execution, so the data layer exists before the execution path changes.
|
| 420 |
+
|
| 421 |
+
Work:
|
| 422 |
+
- Migration: create `sa_job` table (schema in §4).
|
| 423 |
+
- `SA_Executor::run` remains synchronous. At the end, it writes a `sa_job` row with `state='succeeded'` (or `'failed'` if the adapter errored).
|
| 424 |
+
- No REST change. No client change. No worker yet.
|
| 425 |
+
|
| 426 |
+
Test: CLI proof submits a prompt, verifies an `sa_job` row with correct state exists and references the prompt.
|
| 427 |
+
|
| 428 |
+
Rollback: drop the table via migration down; no user impact.
|
| 429 |
+
|
| 430 |
+
### Phase 2 — Async execution path (3–4 commits)
|
| 431 |
+
|
| 432 |
+
Goal: move adapter invocation out of the REST handler.
|
| 433 |
+
|
| 434 |
+
Work:
|
| 435 |
+
- Refactor `SA_Executor` into two entry-points:
|
| 436 |
+
- `SA_Executor::run` — retained for direct synchronous use (CLI proofs, back-compat).
|
| 437 |
+
- `SA_Executor::enqueue($prompt_text, $options)` — writes prompt entity + queued job, returns ids. Fast.
|
| 438 |
+
- `SA_Executor::run_claimed($job_id)` — worker's entry-point; runs the pipeline against an existing prompt + job.
|
| 439 |
+
- `POST /prompt`: call `enqueue`, return `202` with `{ prompt_id, job_id }`.
|
| 440 |
+
- Client `submitPrompt`: handle `202`, render queued drop, start poll loop.
|
| 441 |
+
- Server: `GET /mission/recent` accepts `since` param; returns updated rows.
|
| 442 |
+
- Add worker CLI: `wp sa-core run-worker`.
|
| 443 |
+
- Add heartbeat cleanup: `wp sa-core reclaim-stuck-jobs`.
|
| 444 |
+
- New CSS classes: `is-queued`, `is-cancelled`.
|
| 445 |
+
|
| 446 |
+
Test:
|
| 447 |
+
- CLI proof: submit a prompt, verify `state=queued`, run worker once, verify `state=running` → `state=succeeded`.
|
| 448 |
+
- Concurrent-submit proof: submit two prompts with different priorities (10 and 90), run worker, verify priority=10 runs first.
|
| 449 |
+
- Retry proof: submit, simulate transient failure (mock adapter), verify re-queue with backoff and eventual success.
|
| 450 |
+
|
| 451 |
+
Rollback: revert `POST /prompt` to call `run` synchronously. `sa_job` rows for already-queued jobs need manual cleanup (or a CLI command to replay them synchronously). Worker command stays but unused.
|
| 452 |
+
|
| 453 |
+
### Phase 3 — Priority queue (1–2 commits)
|
| 454 |
+
|
| 455 |
+
Goal: expose priority so active-thread prompts outrank bulk / background work.
|
| 456 |
+
|
| 457 |
+
Work:
|
| 458 |
+
- `SA_Executor::enqueue` accepts `priority` in options (default 50).
|
| 459 |
+
- Client: no UI change. Still submits at default. Future bulk operations (Scanner, Code Lens ingestion, etc.) pass higher priority values.
|
| 460 |
+
- Worker query already orders by priority — schema supports it from phase 1.
|
| 461 |
+
|
| 462 |
+
Test: submit 3 prompts with priorities {10, 50, 90}; verify worker claims in that order.
|
| 463 |
+
|
| 464 |
+
Rollback: trivial; remove priority from enqueue options, falls back to default.
|
| 465 |
+
|
| 466 |
+
### Phase 4 — SSE layer (2–3 commits)
|
| 467 |
+
|
| 468 |
+
Goal: eliminate polling overhead.
|
| 469 |
+
|
| 470 |
+
Work:
|
| 471 |
+
- Add `GET /sa-core/v1/mission/events` endpoint that streams SSE.
|
| 472 |
+
- Server-side: when a job's state changes, broadcast an SSE event to that viewer's stream.
|
| 473 |
+
- Client: detect `EventSource` support; subscribe if available; else continue polling.
|
| 474 |
+
|
| 475 |
+
Test: compare SSE event timing vs polling; verify identical state propagation; verify graceful fallback when connection drops.
|
| 476 |
+
|
| 477 |
+
Rollback: client falls back to polling automatically if SSE endpoint returns 404 or connection fails.
|
| 478 |
+
|
| 479 |
+
### Phase 5 — Hardening (2–4 commits)
|
| 480 |
+
|
| 481 |
+
Goal: operator visibility, intervention, metrics.
|
| 482 |
+
|
| 483 |
+
Work:
|
| 484 |
+
- `wp sa-core list-jobs [--state=] [--org=] [--since=]` — list jobs with filters.
|
| 485 |
+
- `wp sa-core job-details <job_id>` — full history for a job.
|
| 486 |
+
- `wp sa-core cancel-job <job_id>` — operator cancellation.
|
| 487 |
+
- `wp sa-core retry-job <job_id>` — explicit requeue.
|
| 488 |
+
- Optional: `wp sa-core queue-metrics` — count by state, average latency per org, error rate.
|
| 489 |
+
|
| 490 |
+
Test: CLI proofs for each command.
|
| 491 |
+
|
| 492 |
+
### Phase 6 — async-native features (optional, post-pillar)
|
| 493 |
+
|
| 494 |
+
Built on the same `sa_job` infrastructure, no further schema changes:
|
| 495 |
+
|
| 496 |
+
- Background bulk operations (Scanner, Code Lens, Doc Lens at scale).
|
| 497 |
+
- Scheduled prompts (run at 2am) via a `scheduled_for` column on `sa_job`.
|
| 498 |
+
- Multi-prompt chains (job B starts after job A succeeds).
|
| 499 |
+
|
| 500 |
+
Not part of the async pillar's completion criteria; listed for continuity.
|
| 501 |
+
|
| 502 |
+
### Test discipline at each phase
|
| 503 |
+
|
| 504 |
+
Every phase ships one or more CLI proofs in the `includes/cli/` pattern already established (geodesic-proof, promotion-proof, projection-proof, claim-continuation):
|
| 505 |
+
|
| 506 |
+
- `async-execution-proof`: state progression queued → running → succeeded against a synthetic prompt.
|
| 507 |
+
- `priority-queue-proof`: three synthetic prompts at different priorities; verify claim order.
|
| 508 |
+
- `retry-proof`: simulated transient adapter failure; verify re-queue and eventual success.
|
| 509 |
+
- `heartbeat-proof`: start a synthetic running job, sleep past heartbeat window, run reclaim, verify state.
|
| 510 |
+
- `concurrent-safety-proof`: simulate double-claim race; verify only one worker's writes take effect.
|
| 511 |
+
|
| 512 |
+
---
|
| 513 |
+
|
| 514 |
+
## 8. Failure and Retry Model
|
| 515 |
+
|
| 516 |
+
### Error classification
|
| 517 |
+
|
| 518 |
+
Every failure gets an `error_kind`:
|
| 519 |
+
|
| 520 |
+
| `error_kind` | Meaning | Retryable? | Backoff |
|
| 521 |
+
|---|---|---|---|
|
| 522 |
+
| `timeout` | cURL 28 or executor-level timeout | Yes | Exponential (5s, 25s, 125s + jitter) |
|
| 523 |
+
| `rate_limit` | Adapter HTTP 429 | Yes | Respect `Retry-After` header; else 60s min |
|
| 524 |
+
| `provider_5xx` | Adapter returned 5xx | Yes | Exponential |
|
| 525 |
+
| `provider_4xx` (non-429) | Adapter returned 4xx | No | N/A |
|
| 526 |
+
| `parse` | Response body couldn't be parsed | No | N/A |
|
| 527 |
+
| `auth` | Credentials invalid | No | N/A (needs operator) |
|
| 528 |
+
| `worker_crash` | Worker died mid-execution | Yes (via reclaim) | Immediate |
|
| 529 |
+
| `stuck` | Job has been running > 15 min | No | Terminal; mark failed |
|
| 530 |
+
| `unknown` | Catch-all for unclassified errors | Yes (conservative default) | Exponential |
|
| 531 |
+
|
| 532 |
+
### Retry rules
|
| 533 |
+
|
| 534 |
+
- Default `max_attempts = 3`. Configurable per-enqueue via options.
|
| 535 |
+
- Backoff stored as a delay on the re-queued job's `created_at`: `created_at = now() + backoff`. Worker query only claims jobs where `created_at <= now()`, so backoff is honored naturally.
|
| 536 |
+
- Backoff durations:
|
| 537 |
+
- Attempt 2: 5s + random(0, 5s)
|
| 538 |
+
- Attempt 3: 25s + random(0, 15s)
|
| 539 |
+
- (After attempt 3 fails: terminal)
|
| 540 |
+
|
| 541 |
+
### Timeout handling
|
| 542 |
+
|
| 543 |
+
- **Adapter timeout (180s)**: cURL 28. `error_kind='timeout'`. Retryable.
|
| 544 |
+
- **PHP `max_execution_time` (300s)**: worker process killed. Heartbeat lost. Reclaimed by `reclaim-stuck-jobs`.
|
| 545 |
+
- **Hard job ceiling (15 minutes)**: a running job started > 15 min ago with no recent heartbeat is declared stuck. `error_kind='stuck'`. Terminal.
|
| 546 |
+
|
| 547 |
+
### Dead-letter handling
|
| 548 |
+
|
| 549 |
+
- Jobs that exhaust `max_attempts` go to `state='failed'` with `error_kind` set.
|
| 550 |
+
- They remain visible in the user's field as `is-orphan` drops (same treatment as today's orphans from sync-failure).
|
| 551 |
+
- User can retry via the retry chip (same UX as today). Retry creates a new `sa_job` row with `supersedes=<old_id>`.
|
| 552 |
+
- Operator CLI: `wp sa-core list-jobs --state=failed` surfaces recent failures.
|
| 553 |
+
- Operator can run `wp sa-core retry-job <id>` to force a retry without user interaction.
|
| 554 |
+
|
| 555 |
+
### Stuck-job recovery
|
| 556 |
+
|
| 557 |
+
- `wp sa-core reclaim-stuck-jobs` runs via system cron every 5 minutes.
|
| 558 |
+
- Query: `state='running' AND running_heartbeat_at < now() - INTERVAL 5 MINUTE`.
|
| 559 |
+
- For each:
|
| 560 |
+
- If `attempt < max_attempts` AND `started_at > now() - 15min`: reclaim to `state='queued'`, clear `worker_claim`.
|
| 561 |
+
- Else: `state='failed'`, `error_kind='stuck'`.
|
| 562 |
+
|
| 563 |
+
### Double-execution safety
|
| 564 |
+
|
| 565 |
+
Mitigation already detailed in §5: all finalization writes are conditioned on `WHERE state='running' AND worker_claim=<my_worker_id>`. Second-arriving writer sees no matching row and exits silently. First-arriving result wins.
|
| 566 |
+
|
| 567 |
+
Additional safeguard: response entity writes are keyed on a deterministic id derived from `(prompt_id, adapter_request_id)` when available, so duplicate writes collide on primary key and the second `INSERT` fails gracefully (caught by the finalization code).
|
| 568 |
+
|
| 569 |
+
---
|
| 570 |
+
|
| 571 |
+
## 9. Risks and Tradeoffs
|
| 572 |
+
|
| 573 |
+
### Risk: cron reliability on managed hosts
|
| 574 |
+
|
| 575 |
+
WP Engine (and many managed hosts) run cron via `wp-cron.php` spawned on page requests. On low-traffic sites this is unreliable.
|
| 576 |
+
|
| 577 |
+
**Mitigation.** Document that production deployments SHOULD use a real system cron hitting `wp sa-core run-worker --once`. The command is standalone (doesn't depend on wp-cron's spawning). An on-page-load spawn continues to work for dev and low-volume sites.
|
| 578 |
+
|
| 579 |
+
### Risk: worker compute resource pressure
|
| 580 |
+
|
| 581 |
+
A long-running worker process consumes PHP process slots. On shared hosting, this may conflict with web requests.
|
| 582 |
+
|
| 583 |
+
**Mitigation.** Default worker mode is `--once` (cron-driven, not service-style). Batch size is tunable. For high-volume users, the operator can tune cron frequency + batch size to stay within their host's limits.
|
| 584 |
+
|
| 585 |
+
### Risk: `sa_job` table growth
|
| 586 |
+
|
| 587 |
+
Every prompt creates ≥ 1 job. Retries create additional jobs per prompt. Over time, the table grows unbounded.
|
| 588 |
+
|
| 589 |
+
**Mitigation.** Optional archival policy (phase 5 or later): jobs in a terminal state older than 30 days get archived or removed. `wp sa-core archive-old-jobs --before=<date>`. Indexes keep queries fast regardless of row count at expected volumes; archival is an optimization, not a correctness concern.
|
| 590 |
+
|
| 591 |
+
### Risk: client polling overhead
|
| 592 |
+
|
| 593 |
+
Many users × many tabs × many in-flight jobs = many simultaneous polls.
|
| 594 |
+
|
| 595 |
+
**Mitigation.**
|
| 596 |
+
- Polls happen only while in-flight jobs exist; idle tabs don't poll.
|
| 597 |
+
- Poll interval is 2s; tunable.
|
| 598 |
+
- Phase 4 (SSE) eliminates this risk entirely for modern browsers.
|
| 599 |
+
|
| 600 |
+
### Risk: stale merges on client
|
| 601 |
+
|
| 602 |
+
If the client has an in-memory edit (user typing in compose) and a poll fetches fresh entity data, we must not discard user input.
|
| 603 |
+
|
| 604 |
+
**Mitigation.** Poll merges by `prompt_id` and only updates entity-state fields (response_id, state, context_ids, etc.). Compose-input state lives in the DOM, untouched by poll handling.
|
| 605 |
+
|
| 606 |
+
### Risk: concurrent-submit out-of-order display
|
| 607 |
+
|
| 608 |
+
Two prompts submitted close together may complete in the reverse order (e.g., P1 is slow, P2 is fast). The field would render P2 before P1.
|
| 609 |
+
|
| 610 |
+
**Mitigation.** Field display order is by `prompt.created_at`, not job completion order. Stable regardless of async resolution order. The visual `is-queued` vs `is-running` vs settled state makes the running state transparent to the user.
|
| 611 |
+
|
| 612 |
+
### Tradeoff: consistency window vs latency
|
| 613 |
+
|
| 614 |
+
Async means there is a window where client shows `state='queued'` while server has already transitioned to `state='running'`. Polling latency is up to 2s. SSE tightens this to sub-second.
|
| 615 |
+
|
| 616 |
+
**Accepted.** Up to 2s of client-side staleness is not a meaningful UX regression; phase 4 closes it.
|
| 617 |
+
|
| 618 |
+
### Tradeoff: simplicity vs ecosystem reuse
|
| 619 |
+
|
| 620 |
+
Custom worker vs Action Scheduler. Custom is simpler for our narrow scope but means we own the scheduler. AS is richer but adds a dependency and adapter layer.
|
| 621 |
+
|
| 622 |
+
**Accepted.** Custom for phase 2. If we ever need to coexist with an AS-using site, the `sa_job` table's facade can be driven by either our worker or an AS callback without changing job semantics.
|
| 623 |
+
|
| 624 |
+
### Risk: migrating users mid-transition
|
| 625 |
+
|
| 626 |
+
Between phase 1 (shadow jobs written) and phase 2 (async path switched on), a user's `sa_job` rows represent historical sync executions. When phase 2 lands, any prompt submitted mid-transition could have incomplete metadata.
|
| 627 |
+
|
| 628 |
+
**Mitigation.** Phase 2 rollout during a low-traffic window. On deploy, any `sa_job` rows with `state='queued'` from pre-phase-2 (there shouldn't be any, but defensively) are either processed by the first worker run or marked `state='failed'` with `error_kind='migration'` for manual review.
|
| 629 |
+
|
| 630 |
+
---
|
| 631 |
+
|
| 632 |
+
## 10. Success Criteria
|
| 633 |
+
|
| 634 |
+
The async pillar is complete (through phase 2) when:
|
| 635 |
+
|
| 636 |
+
1. `POST /prompt` returns within 100ms, 99th percentile, regardless of adapter latency.
|
| 637 |
+
2. Closing the browser tab during a prompt's execution does NOT cancel the job; reopening the site shows the completed result.
|
| 638 |
+
3. Two prompts submitted to different continuation parents from different tabs are processed correctly, with no race-induced data corruption.
|
| 639 |
+
4. A cURL timeout on the adapter causes an automatic retry with exponential backoff; a permanently-failing prompt surfaces as a retriable orphan after `max_attempts` exhaustion.
|
| 640 |
+
5. A crashed worker's job is reclaimed within 5 minutes and either completes on the next attempt or fails cleanly.
|
| 641 |
+
6. The CLI proofs described in §7's test discipline section all pass.
|
| 642 |
+
7. Existing `/mission` UI works throughout — no regressions on selection, trace, thread view, promote, verdict, continuation, retry, or content-collapse.
|
| 643 |
+
8. The `wp sa-core run-worker` command can be configured to run under standard system cron without supervisor-style infra.
|
| 644 |
+
|
| 645 |
+
The pillar is **complete through phase 4** when additionally:
|
| 646 |
+
|
| 647 |
+
9. SSE delivers state updates within 200ms of server-side transition.
|
| 648 |
+
10. Polling mode still works identically as a fallback when SSE is unavailable.
|
| 649 |
+
|
| 650 |
+
---
|
| 651 |
+
|
| 652 |
+
## 11. Out of Scope (deliberately deferred)
|
| 653 |
+
|
| 654 |
+
- **Multi-node distributed coordination.** Single-node assumption in claim locking. Revisit if horizontal scaling ever becomes a concern.
|
| 655 |
+
- **Priority inversion prevention.** A long-running low-priority job blocking urgent jobs is theoretically possible but rare in our expected volume. Observe first; fix if it ever occurs.
|
| 656 |
+
- **User-facing queue inspection UI.** CLI only through phase 5. A UI can be added later; `sa_job` data is already viewer-scoped via `org_id + created_by` indexing.
|
| 657 |
+
- **Scheduled prompts** (`scheduled_for`): phase 6 (optional).
|
| 658 |
+
- **Multi-prompt chains** (dependent jobs): phase 6 (optional).
|
| 659 |
+
- **Per-org quotas** (max N concurrent running jobs): defer until multi-tenant scaling matters.
|
| 660 |
+
- **Cross-process worker coordination** (multiple machines): defer until single-machine capacity is exhausted.
|
| 661 |
+
- **Real-time collaboration** (two users editing the same field simultaneously): defer to the ACL / perspective-projection pillar.
|
| 662 |
+
|
| 663 |
+
---
|
| 664 |
+
|
| 665 |
+
## 12. Appendix: Summary of Design Decisions
|
| 666 |
+
|
| 667 |
+
| Concern | Decision | Rationale |
|
| 668 |
+
|---|---|---|
|
| 669 |
+
| Storage | New `sa_job` table | Separate execution from knowledge; supports multiple attempts cleanly |
|
| 670 |
+
| Worker | Custom WP-CLI runner | Narrow scope; direct control; ~300 lines; no new dependency |
|
| 671 |
+
| Scheduling driver | System cron → `wp sa-core run-worker --once` | Reliable across hosts; standalone from wp-cron |
|
| 672 |
+
| State machine | 6 states + heartbeat + supersession | Covers all observed outcomes; no ambiguity |
|
| 673 |
+
| Client protocol | Polling (phase 2) → SSE (phase 4) | Ships working async in phase 2; optimizes in phase 4 |
|
| 674 |
+
| Retry | Exponential backoff, max_attempts=3 | Handles transient failures; bounded pessimism |
|
| 675 |
+
| Rollback | Phase-by-phase; each has a defined revert | Safe to implement incrementally |
|
| 676 |
+
| Migration | Shadow jobs first (phase 1) → switch path (phase 2) | Data layer proven before execution switch |
|
| 677 |
+
|
| 678 |
+
This spec is the contract. Implementation directives reference it by phase.
|
SA-orchestration MD/asterion/05-zoom-quantum-engine.md
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Zoom-Quantum Engine — Design Specification (Rung 4)
|
| 2 |
+
|
| 3 |
+
Status: **design draft; coil substrate shipped (Rung 3); phase plan pending per-phase directive.**
|
| 4 |
+
Target rung: 4.
|
| 5 |
+
Scope: multi-focal zoom as a native field gesture, not a viewport transform. Per-correlation zoom, hyperbolic envelope, cross-region pull-connection. All projections remain 2D.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Framing (authoritative)
|
| 10 |
+
|
| 11 |
+
**Zoom is a semantic quantum, not a viewport change.** Zoom belongs to a *domain of influence*, not to the screen. A conversation can be zoomed without touching any other conversation. The field carries regional density depth of zoom.
|
| 12 |
+
|
| 13 |
+
Three layers of zoom, kept distinct:
|
| 14 |
+
|
| 15 |
+
- **Global zoom** — the default, existing affordance (SVG viewBox). The whole field pans and scales. Useful for "where am I on the mission."
|
| 16 |
+
- **Regional zoom** — per-correlation, introduced by this pillar. Each thread carries its own scalar zoom state. The user can be deeply inside thread A while thread B stays at rest. Multiple threads can be simultaneously focused at independent depths.
|
| 17 |
+
- **Hyperbolic envelope** — when a regional zoom exceeds threshold, the thread's head wraps the visible workspace as a Poincaré-disk horizon. "You are inside this thread." The tail stretches toward the asymptotic center; the head becomes the event horizon.
|
| 18 |
+
|
| 19 |
+
The instruction the rest of this spec serves:
|
| 20 |
+
|
| 21 |
+
> The default case is to zoom the whole field. The innovation is to zoom a *conversation* — one region of influence — without perturbing the rest of the field. When two regions are simultaneously focused, the user can pull a connection between them instead of splitting the screen. Multi-focal composition is the posture; hyperbolic geometry is how we keep "where is my context" legible while compression grows infinite.
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
|
| 25 |
+
## 0. Scope note
|
| 26 |
+
|
| 27 |
+
This spec describes the **zoom-quantum engine** as a user-facing field behavior + its projection math.
|
| 28 |
+
|
| 29 |
+
It DOES cover:
|
| 30 |
+
- The per-correlation zoom state model
|
| 31 |
+
- The math of the hyperbolic envelope (Möbius transform on a Poincaré disk)
|
| 32 |
+
- How regional zoom composes with the already-shipped log-spiral coil
|
| 33 |
+
- Multi-focal simultaneous zoom
|
| 34 |
+
- Cross-correlation pull-connection as a new edge primitive
|
| 35 |
+
- Gesture vocabulary
|
| 36 |
+
- Phasing
|
| 37 |
+
|
| 38 |
+
It does NOT cover:
|
| 39 |
+
- The Prime-Prompt / compression mechanic (separate Pillar 0 concern, deferred)
|
| 40 |
+
- Server-side data model changes beyond a new edge kind (zoom is client UI state)
|
| 41 |
+
- A split-screen or multi-window layout (explicitly rejected — the hyperbolic projection replaces it)
|
| 42 |
+
- WebGL / 3D rendering (explicitly rejected — all projections are 2D)
|
| 43 |
+
|
| 44 |
+
---
|
| 45 |
+
|
| 46 |
+
## 1. What already exists
|
| 47 |
+
|
| 48 |
+
Rung 3 shipped the **logarithmic-spiral coil** (commit `de4de7e`). Each correlation group renders as:
|
| 49 |
+
|
| 50 |
+
```
|
| 51 |
+
r_t = r₀ · γ^t (log-spiral radius)
|
| 52 |
+
θ_t = baseAngle + t·dθ (angular step)
|
| 53 |
+
scale_t = γ^t (same decay → self-similar under zoom)
|
| 54 |
+
opacity_t = max(o_min, 1 − f·t)
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
The coil is already scale-invariant: a uniform scale factor `k` maps the spiral onto itself shifted by `log_γ(k)` turns. The infrastructure for "zoom descends into the tail" is in place on the math side; Rung 4 adds the UI, the per-correlation state, and the hyperbolic envelope.
|
| 58 |
+
|
| 59 |
+
The `.is-coiled` class and `data-coil-index` attribute on each drop are hooks for this rung.
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
## 2. Primitives
|
| 64 |
+
|
| 65 |
+
### 2.1 Per-correlation zoom state
|
| 66 |
+
|
| 67 |
+
```
|
| 68 |
+
CoilZoomState {
|
| 69 |
+
correlation_id : string The thread this state belongs to
|
| 70 |
+
zoom : float (≥ 0) 0 = rest; 1 = first quantum in; 2 = second; ...
|
| 71 |
+
focal_x : float optional: where on the screen the focus anchors
|
| 72 |
+
focal_y : float (defaults to the current head position)
|
| 73 |
+
pinned : bool if true, survives other zooms of other threads;
|
| 74 |
+
if false, collapses to rest when another
|
| 75 |
+
thread is focused (single-focus convention)
|
| 76 |
+
}
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
Stored client-side. Not persisted by default; optional SA_Settings scope=user
|
| 80 |
+
persistence (`field.coil.zoom_state`) is a follow-on if the UX calls for it.
|
| 81 |
+
|
| 82 |
+
### 2.2 Focal stack
|
| 83 |
+
|
| 84 |
+
```
|
| 85 |
+
FocalStack = CoilZoomState[]
|
| 86 |
+
```
|
| 87 |
+
|
| 88 |
+
The ordered list of currently-focused coils. Zero-or-one at rest is the default; multi-focal is the innovation. Rendering composes their transforms.
|
| 89 |
+
|
| 90 |
+
### 2.3 Hyperbolic envelope
|
| 91 |
+
|
| 92 |
+
Threshold: when `zoom ≥ HYPERBOLIC_THRESHOLD` (configurable; 2.0 is a reasonable starting point), the coil's head enters **envelope mode**:
|
| 93 |
+
|
| 94 |
+
- The head dilates toward the workspace boundary.
|
| 95 |
+
- The rest of the coil (and any other visible content within this region) is rendered through a Möbius transform on the Poincaré disk.
|
| 96 |
+
- The edge of the viewport becomes the ideal boundary at infinity.
|
| 97 |
+
|
| 98 |
+
Mathematically, with the focal point at origin `a = 0`:
|
| 99 |
+
|
| 100 |
+
```
|
| 101 |
+
w = (z - a) / (1 - ā·z)
|
| 102 |
+
```
|
| 103 |
+
|
| 104 |
+
For `a = 0` this reduces to `w = z`, so we introduce zoom via composition with a pure dilation before the Möbius map:
|
| 105 |
+
|
| 106 |
+
```
|
| 107 |
+
z' = scale_by_zoom · z
|
| 108 |
+
w = (z' - a) / (1 - ā·z')
|
| 109 |
+
```
|
| 110 |
+
|
| 111 |
+
At low zoom, the transform is near-identity. As zoom grows, points near the focal point expand outward; points near the ideal boundary asymptote there but never cross. This is the "event horizon" — infinite expansion curls into the hyperbolic limit.
|
| 112 |
+
|
| 113 |
+
### 2.4 Pull-connection (cross-region edge)
|
| 114 |
+
|
| 115 |
+
A new edge kind:
|
| 116 |
+
|
| 117 |
+
```
|
| 118 |
+
kind: 'pull-connection' (or 'cross-region')
|
| 119 |
+
source_id: entity A's id
|
| 120 |
+
target_id: entity B's id
|
| 121 |
+
intentional: true (always — user gesture-created)
|
| 122 |
+
metadata: { author_id, created_at, gesture_kind: 'drag' }
|
| 123 |
+
```
|
| 124 |
+
|
| 125 |
+
Stored as a row in the existing `sa_edge` table. No schema change — `SA_Edge::KINDS` already accepts arbitrary kinds (today: link, contains, depends, influences, flows-to, continues, promoted).
|
| 126 |
+
|
| 127 |
+
Rendered as a flowing line between two focused regions, distinct visually from within-thread edges (dashed? colored by author? to be decided per phase).
|
| 128 |
+
|
| 129 |
+
### 2.5 Compose operator
|
| 130 |
+
|
| 131 |
+
```
|
| 132 |
+
render(entity) = Global_Viewport ∘ Regional_Hyperbolic ∘ Local_Coil ∘ entity.position
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
Three projections stacked:
|
| 136 |
+
|
| 137 |
+
1. **Local coil** (shipped): the log spiral places older correlation members relative to their head.
|
| 138 |
+
2. **Regional hyperbolic** (new): when a coil is past the threshold, apply the Möbius transform to everything within its region, centered on its head.
|
| 139 |
+
3. **Global viewport**: the SVG viewBox. Pans / scales the whole field for navigation.
|
| 140 |
+
|
| 141 |
+
Each layer is independently controllable. A user at rest sees only the coils (layer 1 only). A user focused on one thread with hyperbolic crossed sees layer 1 + 2. A user zooming out to find a thread uses layer 3.
|
| 142 |
+
|
| 143 |
+
---
|
| 144 |
+
|
| 145 |
+
## 3. Multi-focal model
|
| 146 |
+
|
| 147 |
+
The posture: **multiple regions focused simultaneously, without split screens.**
|
| 148 |
+
|
| 149 |
+
Scenarios:
|
| 150 |
+
|
| 151 |
+
- **Single focus** (typical): one thread is zoomed in. Others sit at their rest coil. The user sees the coil-of-interest at its hyperbolic scale, other coils in the background at normal scale.
|
| 152 |
+
- **Dual focus** (workspace comparison): two threads both zoomed. Their Möbius disks compose by position — e.g., one occupies the left third of the viewport, the other the right third. Content *between* them is what survives the intersection.
|
| 153 |
+
- **Multi focus** (relational map): N threads focused at varied zoom levels. The field becomes a composite of hyperbolic neighborhoods, each with its own focal anchor. Resembles a relational map where the nodes are the focal points and the content around each is the locally-zoomed thread.
|
| 154 |
+
|
| 155 |
+
Pull-connection is the natural gesture across this state: drag from a point inside focus A's hyperbolic neighborhood to a point inside focus B's hyperbolic neighborhood. The drag creates a cross-region edge. The edge renders as a line that passes through the ambient space between the foci.
|
| 156 |
+
|
| 157 |
+
**Rejected alternative**: split-screen. Splitting the canvas into two viewports is the "click here, click there, zoom each, compare" solution. The spec rejects it as un-liquid — a literal cut in the fabric. The hyperbolic composition is the continuous alternative.
|
| 158 |
+
|
| 159 |
+
---
|
| 160 |
+
|
| 161 |
+
## 4. Gesture vocabulary
|
| 162 |
+
|
| 163 |
+
### 4.1 Entering regional zoom
|
| 164 |
+
|
| 165 |
+
- **Scroll-wheel over a coil region**: the scroll targets the coil underneath the cursor, not the global viewport. Forward = zoom in, back = zoom out.
|
| 166 |
+
- Falls back to global viewport zoom when the cursor isn't over any coil's region.
|
| 167 |
+
|
| 168 |
+
Implementation: hit-test the cursor against each visible coil's bounding disk. The coil whose center is closest (within a radius proportional to its current zoom) captures the scroll.
|
| 169 |
+
|
| 170 |
+
### 4.2 Pin / unpin
|
| 171 |
+
|
| 172 |
+
- **Click a coil's head while holding a modifier key** (e.g., Shift-click): pin this focus. Future zooms of other coils don't collapse this one.
|
| 173 |
+
- **Click in empty space**: collapse all transient (non-pinned) foci to rest.
|
| 174 |
+
|
| 175 |
+
### 4.3 Pull-connection
|
| 176 |
+
|
| 177 |
+
- **Drag from a focused region to another focused region** (both must be at zoom ≥ some threshold). The drag creates a new `pull-connection` edge.
|
| 178 |
+
- **Drop on empty space**: cancels.
|
| 179 |
+
|
| 180 |
+
### 4.4 Exit / escape
|
| 181 |
+
|
| 182 |
+
- **Esc** collapses all foci and returns to rest (coils at size 1, no hyperbolic envelope).
|
| 183 |
+
- **Double-click a coil**: toggles between rest and last-known zoom state.
|
| 184 |
+
|
| 185 |
+
---
|
| 186 |
+
|
| 187 |
+
## 5. Math appendix
|
| 188 |
+
|
| 189 |
+
### 5.1 Self-similar coil (shipped, Rung 3)
|
| 190 |
+
|
| 191 |
+
For each correlation group:
|
| 192 |
+
|
| 193 |
+
```
|
| 194 |
+
t = turn index (0 = newest head)
|
| 195 |
+
baseAngle = hashJitter(correlation_id) · 2π (per-thread starting angle)
|
| 196 |
+
γ = 0.85 (decay)
|
| 197 |
+
dθ = π/3 (60° per turn)
|
| 198 |
+
r_t = r₀ · γ^t
|
| 199 |
+
θ_t = baseAngle + t · dθ
|
| 200 |
+
position_t = head_position + (r_t·cos θ_t − r₀·cos baseAngle,
|
| 201 |
+
r_t·sin θ_t − r₀·sin baseAngle)
|
| 202 |
+
scale_t = γ^t
|
| 203 |
+
```
|
| 204 |
+
|
| 205 |
+
Zoom shifts the visible portion of the spiral. Under a uniform zoom of factor `k`, `scale_t → k · scale_t = γ^(t - log_γ k)`, so the spiral looks the same shifted by `log_γ k` turns. This is why zooming into the coil reveals more tail without stretching it.
|
| 206 |
+
|
| 207 |
+
### 5.2 Poincaré disk (Rung 4, new)
|
| 208 |
+
|
| 209 |
+
The hyperbolic plane is represented as the interior of a unit disk `|z| < 1`. Geodesics are circular arcs perpendicular to the boundary. Distance grows without bound near the boundary (the ideal horizon).
|
| 210 |
+
|
| 211 |
+
A Möbius transformation preserves hyperbolic distance:
|
| 212 |
+
|
| 213 |
+
```
|
| 214 |
+
φ_a(z) = (z − a) / (1 − ā·z) where |a| < 1
|
| 215 |
+
```
|
| 216 |
+
|
| 217 |
+
For MissionNet:
|
| 218 |
+
|
| 219 |
+
- The coil's currently-focused head sits at the disk center.
|
| 220 |
+
- The tail of the coil stretches toward the center (asymptotically never reaching, per the log-spiral math).
|
| 221 |
+
- Other visible content is projected outward toward the boundary, compressed as it approaches — "infinite expansion curls to hyperbolic limit."
|
| 222 |
+
|
| 223 |
+
Scaling for zoom level `λ ≥ 0`:
|
| 224 |
+
|
| 225 |
+
```
|
| 226 |
+
z' = (1 − e^(−λ)) + e^(−λ) · z (pre-zoom dilation centered on head)
|
| 227 |
+
w = φ_focal(z') (Möbius, centered on head)
|
| 228 |
+
screen_w = half_viewport_size · w (map disk to viewport)
|
| 229 |
+
```
|
| 230 |
+
|
| 231 |
+
At λ = 0 the transform is identity. As λ grows, `z'` approaches 1 (the boundary), the head fills the viewport, and the rest of the content compresses toward the edge.
|
| 232 |
+
|
| 233 |
+
### 5.3 Composition of multi-focal Möbius
|
| 234 |
+
|
| 235 |
+
Two focal points `a` and `b`, each with zoom levels `λ_a` and `λ_b`, can be composed:
|
| 236 |
+
|
| 237 |
+
```
|
| 238 |
+
w = Σ weights_i · φ_i(dilate_i(z))
|
| 239 |
+
```
|
| 240 |
+
|
| 241 |
+
For a weighted sum where `Σ weights_i = 1`. This is an approximation — the exact composition of two Möbius transforms is another Möbius transform, but picking *which* transform to use when you want BOTH foci visible requires a heuristic. The weighted-sum approximation gives a visually pleasing blend and is well-defined for any number of foci.
|
| 242 |
+
|
| 243 |
+
A cleaner model: render each focused region in its own hyperbolic neighborhood, with the boundary between regions being the ambient (un-transformed) space. This is what pull-connection edges cross.
|
| 244 |
+
|
| 245 |
+
---
|
| 246 |
+
|
| 247 |
+
## 6. Data model changes
|
| 248 |
+
|
| 249 |
+
### 6.1 No schema change for zoom state
|
| 250 |
+
|
| 251 |
+
Per-correlation zoom is client-side UI state. Not persisted by default. If a user asks for their zoom state to survive reload, add:
|
| 252 |
+
|
| 253 |
+
- SA_Settings key `field.coil.zoom_states`, scope=user, type=string (JSON-serialized `CoilZoomState[]`).
|
| 254 |
+
|
| 255 |
+
That's one line of setting declaration; no migration needed.
|
| 256 |
+
|
| 257 |
+
### 6.2 Pull-connection edge: no schema change
|
| 258 |
+
|
| 259 |
+
`SA_Edge` already accepts arbitrary kinds via a `kind` column. Add `'pull-connection'` to `SA_Edge::KINDS` as a documented kind. No migration; no new table.
|
| 260 |
+
|
| 261 |
+
Permissions: creating a pull-connection requires `sa-core:impose-grouping` (already a capability in the starter package — user-declared relational claims are tenant work, not operator work).
|
| 262 |
+
|
| 263 |
+
---
|
| 264 |
+
|
| 265 |
+
## 7. Phased implementation plan
|
| 266 |
+
|
| 267 |
+
Phases ship independently; each is a working system.
|
| 268 |
+
|
| 269 |
+
### Phase 0 — Already shipped (Rung 3 `de4de7e`)
|
| 270 |
+
|
| 271 |
+
- Logarithmic-spiral coil for multi-turn correlations.
|
| 272 |
+
- Self-similar under zoom.
|
| 273 |
+
- Per-thread base angle.
|
| 274 |
+
- `.is-coiled` / `data-coil-index` DOM hooks.
|
| 275 |
+
|
| 276 |
+
### Phase 1 — Per-correlation zoom state (single focus, no hyperbolic)
|
| 277 |
+
|
| 278 |
+
Minimum usable regional zoom:
|
| 279 |
+
|
| 280 |
+
- Client state: `Map<correlation_id, zoomLevel>`.
|
| 281 |
+
- Scroll-wheel over a coil zooms THAT coil (not the field). Hit-test via cursor position vs. each coil's bounding disk.
|
| 282 |
+
- Applying zoom = multiplying the coil's `r₀` and `scale_t` by a zoom factor. Math is already scale-invariant, so the spiral just reveals more structure as `r₀` grows.
|
| 283 |
+
- Other coils continue to render at rest. No hyperbolic envelope yet.
|
| 284 |
+
- Esc returns everything to rest.
|
| 285 |
+
|
| 286 |
+
**Ships when:** the user can scroll over any thread, that thread alone expands / contracts, other threads are unchanged, and Esc collapses the focus.
|
| 287 |
+
|
| 288 |
+
### Phase 2 — Hyperbolic envelope (single focus, past threshold)
|
| 289 |
+
|
| 290 |
+
- When a coil's zoom crosses `HYPERBOLIC_THRESHOLD`, enter envelope mode.
|
| 291 |
+
- Render the focused coil's neighborhood through the Möbius transform (§5.2).
|
| 292 |
+
- Other coils in the field get pushed toward the viewport boundary as content crosses into the hyperbolic disk.
|
| 293 |
+
- Exit threshold hysteresis so crossing the threshold doesn't thrash.
|
| 294 |
+
|
| 295 |
+
**Ships when:** the user can zoom a thread to where the head wraps the workspace, the tail visibly stretches toward the asymptotic center, and the "event horizon" reading is unambiguous.
|
| 296 |
+
|
| 297 |
+
### Phase 3 — Multi-focal composition
|
| 298 |
+
|
| 299 |
+
- Introduce the focal stack: multiple `CoilZoomState`s active simultaneously.
|
| 300 |
+
- Pin gesture (Shift-click on a head) keeps a focus alive when another is zoomed.
|
| 301 |
+
- Render pipeline composes multiple hyperbolic disks in the same viewport.
|
| 302 |
+
- Heuristic for disk placement (e.g., foci at equi-distant points around the viewport center, scaled by their respective zoom levels).
|
| 303 |
+
|
| 304 |
+
**Ships when:** the user can pin thread A, focus thread B separately, and see both at their own zoom levels without a split screen.
|
| 305 |
+
|
| 306 |
+
### Phase 4 — Pull-connection
|
| 307 |
+
|
| 308 |
+
- Add `pull-connection` to `SA_Edge::KINDS`.
|
| 309 |
+
- Drag gesture from one focused region to another creates the edge (persisted via existing `SA_Edge::create`).
|
| 310 |
+
- Rendered as a distinct line between the two focal anchors, flowing through the ambient space between them.
|
| 311 |
+
- Pull-connections surface in the trace aside and in projection pipelines that list edges (e.g., a future "related threads" projection).
|
| 312 |
+
|
| 313 |
+
**Ships when:** the user can physically drag a relation across focal regions, it persists, and it's visible from both threads' perspectives.
|
| 314 |
+
|
| 315 |
+
### Deferred (out of scope)
|
| 316 |
+
|
| 317 |
+
- **Interactive compression** (Pillar 0 / Prime Prompt) — the user can't yet summarize a coil at zoom; the coil renders what it holds.
|
| 318 |
+
- **Zoom-state persistence** — default is per-session. Persistent (across reloads / devices) is a follow-on SA_Settings slice.
|
| 319 |
+
- **Touch gestures** — pinch-zoom on a coil region. Desktop-first.
|
| 320 |
+
- **Pull-connection AI semantics** — a pull-connection is declarative today. Future rungs may let a pull-connection trigger an LLM rerun with both threads as context, or seed a geodesic marker.
|
| 321 |
+
|
| 322 |
+
---
|
| 323 |
+
|
| 324 |
+
## 8. Open questions (for resolution at phase directive time)
|
| 325 |
+
|
| 326 |
+
### 8.1 Global vs. regional zoom arbitration
|
| 327 |
+
|
| 328 |
+
If the user scrolls while the cursor is over a coil AND also over a piece of ambient space (e.g., near the boundary of a coil), which wins? Proposal: cursor-anchored — nearest coil center wins within its bounding disk; outside that, ambient viewport wins.
|
| 329 |
+
|
| 330 |
+
### 8.2 What happens when a single-turn correlation is focused?
|
| 331 |
+
|
| 332 |
+
Single-turn correlations don't have a coil (Rung 3 skips them). Regional zoom on a single-turn could just scale the head in place. Or we could degrade it to global zoom. Proposal: degrade to global zoom for single-turn (no coil to reveal; zooming should feel like the viewport is responding).
|
| 333 |
+
|
| 334 |
+
### 8.3 How deep is "deep"?
|
| 335 |
+
|
| 336 |
+
The coil can, by construction, have infinitely many turns. The log-spiral decay means each turn is 15% smaller than the previous, so after 30 turns we're at 0.85^30 ≈ 0.8% of original size — visually indistinguishable from the center. Practically the coil caps at some maximum rendered turn. Proposal: render only turns where `scale_t ≥ some_epsilon` (say 0.05) unless the user has actively zoomed past that depth. Zooming past that depth reveals deeper turns.
|
| 337 |
+
|
| 338 |
+
### 8.4 Pull-connection authorization model
|
| 339 |
+
|
| 340 |
+
Not every user should be able to create cross-thread edges on content they didn't create. Current proposal: the creator of *either* thread can create a pull-connection. Operator bypass applies via `sa-core:impose-grouping`. Refine at phase 4 directive.
|
| 341 |
+
|
| 342 |
+
### 8.5 Band vocabulary
|
| 343 |
+
|
| 344 |
+
The canonical spec's "zoom band" vocabulary (bands 0-5) is orthogonal to this regional zoom:
|
| 345 |
+
|
| 346 |
+
- Bands = semantic quanta of information (repo / folder / file / class / method / line for code; or workspace / thread / turn / sentence / token for conversation).
|
| 347 |
+
- Regional zoom = the user's viewport scalar within a domain.
|
| 348 |
+
|
| 349 |
+
A single regional zoom doesn't have to correspond to a band crossing; bands apply primarily to the operating-memory lattice (Rung 3). For conversation coils, the "bands" are turns (each turn is one band deeper). This might converge later — for now, the two concepts are independent.
|
| 350 |
+
|
| 351 |
+
---
|
| 352 |
+
|
| 353 |
+
## 9. What remains stable across all phases
|
| 354 |
+
|
| 355 |
+
- **The coil math.** Rung 3's log-spiral doesn't change. Every phase builds on top of it.
|
| 356 |
+
- **All projections are 2D.** No WebGL, no actual 3D space. Möbius transforms and log spirals produce the illusion of depth on a flat viewport.
|
| 357 |
+
- **Client-side state.** Zoom is UX; it doesn't mutate the entity graph. The only server-side new thing across all phases is one new edge kind.
|
| 358 |
+
- **Head anchors at its base layout position** at zoom 0. The coil only exists below the head in the current scheme — expanding the head doesn't move it; it just reveals more of the coil that was already there.
|
| 359 |
+
|
| 360 |
+
---
|
| 361 |
+
|
| 362 |
+
## 10. Summary of decisions
|
| 363 |
+
|
| 364 |
+
- Zoom is **per-correlation by default, global as fallback**.
|
| 365 |
+
- Hyperbolic envelope via **Möbius transform on the Poincaré disk** when zoom exceeds threshold.
|
| 366 |
+
- Multi-focal composition via **weighted Möbius sum OR disjoint-neighborhood rendering** (tbd per phase 3).
|
| 367 |
+
- Cross-region linkage via a **new edge kind `pull-connection`**, stored in the existing `sa_edge` table.
|
| 368 |
+
- **No split screens.** The hyperbolic composition is the continuous alternative.
|
| 369 |
+
- **No WebGL / 3D.** All 2D projections.
|
| 370 |
+
- **No schema change** for any phase except the one-line KIND registration.
|
| 371 |
+
- **Phase 1 first**: scroll-wheel regional zoom, no hyperbolic. Ships independently.
|
| 372 |
+
|
| 373 |
+
---
|
SA-orchestration MD/asterion/06-toolbox-action-contract.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Toolbox Action Contract (v0.1)
|
| 2 |
+
|
| 3 |
+
*Implementation © Sleeper Agents LLC. Contract shape governed by the Admission Contract principle (see `01-ontology.md`).*
|
| 4 |
+
|
| 5 |
+
A Toolbox action is a `/mission/`-native button whose click invokes a single REST endpoint and renders inline state-machine feedback. Toolbox actions are the surface through which operators trigger system-side work without leaving the field.
|
| 6 |
+
|
| 7 |
+
This contract was promoted from *Informal* to *Formal* after the second concrete instance landed (GitHub Actions re-scan, alongside the original FS re-scan). Two examples were enough to extract the clauses below without speculation; further instances must conform.
|
| 8 |
+
|
| 9 |
+
---
|
| 10 |
+
|
| 11 |
+
## Admission requirements
|
| 12 |
+
|
| 13 |
+
A Toolbox action is admissible only if it satisfies all seven clauses. A button that does not satisfy them is not a Toolbox action — it is some other UI affordance and lives under a different contract.
|
| 14 |
+
|
| 15 |
+
### 1. Semantic binding
|
| 16 |
+
|
| 17 |
+
The button is bound to **one and only one** REST endpoint. Multi-action buttons are forbidden. If two related actions are needed (e.g., scan vs. discover), they require two buttons. The endpoint receives the action's parameters via JSON request body.
|
| 18 |
+
|
| 19 |
+
```html
|
| 20 |
+
<button data-action="<realm>.<verb>" ...>
|
| 21 |
+
```
|
| 22 |
+
|
| 23 |
+
The `data-action` attribute is informational; the actual binding is the click handler's `endpoint:` option.
|
| 24 |
+
|
| 25 |
+
### 2. Permission gate
|
| 26 |
+
|
| 27 |
+
The same WordPress capability MUST be enforced at **two layers**:
|
| 28 |
+
|
| 29 |
+
- **Template render-gate**: `current_user_can(<cap>)` controls whether the button HTML is emitted at all. Non-admins see no button.
|
| 30 |
+
- **REST `permission_callback`**: enforces the same capability server-side. A non-admin who bypasses the template (e.g., crafting a `fetch()` call manually) still cannot reach the handler.
|
| 31 |
+
|
| 32 |
+
Defense in depth is mandatory. Single-layer permission gating is a contract violation.
|
| 33 |
+
|
| 34 |
+
### 3. Audit obligation
|
| 35 |
+
|
| 36 |
+
The REST handler MUST write exactly **one** operator-attribution structural-audit row per invocation, before delegating to any underlying ingest path:
|
| 37 |
+
|
| 38 |
+
```php
|
| 39 |
+
SA_Structural_Audit::record(
|
| 40 |
+
'user',
|
| 41 |
+
$viewer_id,
|
| 42 |
+
'realm.<slug>.<verb>.invoked',
|
| 43 |
+
null,
|
| 44 |
+
null,
|
| 45 |
+
[/* action parameters */],
|
| 46 |
+
'SA_REST_<Class>::handle_<method>'
|
| 47 |
+
);
|
| 48 |
+
```
|
| 49 |
+
|
| 50 |
+
This audit is **distinct** from any per-mutation audits the underlying `SA_Ingest` path may write. The toolbox audit answers *"who initiated this action and when"*; per-mutation audits answer *"what changed."* Both must exist; the toolbox audit must not be elided just because the ingest path produces its own.
|
| 51 |
+
|
| 52 |
+
### 4. Parameter shape
|
| 53 |
+
|
| 54 |
+
Required parameters MUST be derivable at **button-render time**, not at click time. Two acceptable patterns:
|
| 55 |
+
|
| 56 |
+
- **Server-side render with `data-*` attributes**: the button's HTML carries the parameter, e.g. `data-repo="owner/name"` rendered from a server-side allow-list lookup. Click handler reads the attribute.
|
| 57 |
+
- **Fixed defaults baked into the JS handler**: e.g., `limit: 10` hardcoded in the handler's `bodyFor()` lambda.
|
| 58 |
+
|
| 59 |
+
Click time is for *executing* the action, not for *configuring* it. Toolbox actions that require a parameter dialog are out of scope for this contract — they belong to a future *Toolbox Composer* contract not yet written.
|
| 60 |
+
|
| 61 |
+
### 5. Feedback contract
|
| 62 |
+
|
| 63 |
+
The button cycles through three CSS state classes during invocation:
|
| 64 |
+
|
| 65 |
+
- `is-busy` — applied immediately on click. Label: `Scanning…` (or equivalent verb-progressive).
|
| 66 |
+
- `is-success` — applied on `result.ok === true && typeof result.sync.processed === 'number'`. Label: `+N ingested` (or equivalent count summary).
|
| 67 |
+
- `is-failed` — applied on any other outcome (network error, exception, `ok: false`). Label: `Failed` (or equivalent).
|
| 68 |
+
|
| 69 |
+
All three classes clear after a reset interval (recommended ~2400ms) and the label restores to the button's default. The reset MUST happen so the button is reusable without page reload.
|
| 70 |
+
|
| 71 |
+
CSS treatments for the three states are part of the contract via the shared `.sa-mission-toolbox-btn` styles.
|
| 72 |
+
|
| 73 |
+
### 6. Refresh obligation
|
| 74 |
+
|
| 75 |
+
On success, the client MUST call the page's data-refresh primitive (currently `load()`) so newly-ingested or updated entities render in the field without a full page reload. Toolbox actions whose effects don't appear on `/mission/` are out of scope for this contract — they belong to a future *Toolbox Background* contract not yet written.
|
| 76 |
+
|
| 77 |
+
### 7. Idempotency
|
| 78 |
+
|
| 79 |
+
The underlying REST endpoint MUST be idempotent at the entity level. Repeated clicks with the same parameters MUST produce **zero net entity-count change**: the second invocation may update existing entities in place, but it MUST NOT duplicate them.
|
| 80 |
+
|
| 81 |
+
Idempotency is enforced upstream of the toolbox action (in the realm adapter's `idempotency_rules()` declaration and the `SA_Ingest` deterministic-UUID logic). This contract requires that toolbox actions only bind to endpoints whose adapters declare `pull` as `idempotent: true, replay_safe: true`.
|
| 82 |
+
|
| 83 |
+
A non-idempotent endpoint cannot be exposed as a toolbox action without explicit policy approval. Such cases require a future *Toolbox Confirmed Action* contract not yet written.
|
| 84 |
+
|
| 85 |
+
---
|
| 86 |
+
|
| 87 |
+
## Currently admitted instances
|
| 88 |
+
|
| 89 |
+
| Action | Endpoint | Capability | Audit action slug |
|
| 90 |
+
|---|---|---|---|
|
| 91 |
+
| Re-scan FS | `POST /sa-core/v1/realm/fs/scan` | `manage_options` | `realm.fs.scan.invoked` |
|
| 92 |
+
| Re-scan GitHub Actions | `POST /sa-core/v1/realm/github-actions/scan` | `manage_options` | `realm.github_actions.scan.invoked` |
|
| 93 |
+
|
| 94 |
+
Both instances satisfy all seven clauses. The shared client-side helper `bindToolboxAction(btn, opts)` in `assets/mission.js` is the canonical implementation; new instances should use it directly.
|
| 95 |
+
|
| 96 |
+
---
|
| 97 |
+
|
| 98 |
+
## Behavioral guarantees
|
| 99 |
+
|
| 100 |
+
- **No surprise mutations.** A toolbox click never causes work the operator did not request. The button's label and `data-action` together name the work; the audit row records its execution.
|
| 101 |
+
- **Safe to retry.** Idempotency clause means a click can be retried without consequence beyond a fresh per-mutation audit trail.
|
| 102 |
+
- **Permission cannot be bypassed.** A non-admin cannot trigger any toolbox action via any path; defense in depth holds.
|
| 103 |
+
- **Operator attribution survives.** Every toolbox invocation leaves a structural audit row tying a user identity to an action slug, retrievable via `SA_Structural_Audit::trace_origin()`.
|
| 104 |
+
|
| 105 |
+
---
|
| 106 |
+
|
| 107 |
+
## What this contract does NOT cover (out of scope, deferred)
|
| 108 |
+
|
| 109 |
+
- **Toolbox actions with parameter dialogs.** Click-time configuration is a different shape. Future *Toolbox Composer* contract.
|
| 110 |
+
- **Toolbox actions whose effects are invisible to `/mission/`.** Background work, scheduled jobs, side-effect-only actions. Future *Toolbox Background* contract.
|
| 111 |
+
- **Non-idempotent or destructive actions** (delete, publish, send). Require explicit confirmation flow. Future *Toolbox Confirmed Action* contract.
|
| 112 |
+
- **Multi-step composed actions** (run-then-render, branch-on-result). Future *Toolbox Composition* contract.
|
| 113 |
+
- **Per-user configurable toolbox** (operators choose which actions to surface). Future *Toolbox Customization* contract.
|
| 114 |
+
|
| 115 |
+
The current contract covers *single-shot, idempotent, parameter-defaulted, admin-only operator actions whose output renders on `/mission/`* — the shape both current instances exhibit. Other shapes are filed for future contracts when they have concrete instances driving them.
|
| 116 |
+
|
| 117 |
+
---
|
| 118 |
+
|
| 119 |
+
## Promotion criteria for future revisions
|
| 120 |
+
|
| 121 |
+
This contract was admitted at v0.1 with two instances. It graduates to v0.2 when:
|
| 122 |
+
|
| 123 |
+
- A third instance lands and conforms cleanly without modification (confirms the seven-clause pattern is stable), OR
|
| 124 |
+
- A third instance lands and surfaces a real edge case the seven clauses don't handle (forces a clause refinement or new clause), OR
|
| 125 |
+
- An out-of-scope shape (parameter dialog, non-idempotent action, etc.) is authorized as a new toolbox category and the parent contract grows a fork.
|
| 126 |
+
|
| 127 |
+
Until any of those happen, the seven clauses stand as currently written.
|
SA-orchestration MD/asterion/README.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Asterion
|
| 2 |
+
|
| 3 |
+
Canonical truth layer for SA-Orchestration / MissionNet.
|
| 4 |
+
|
| 5 |
+
## Contract
|
| 6 |
+
|
| 7 |
+
- **Asterion is the canonical truth layer.**
|
| 8 |
+
- **If it is not in Asterion, it does not exist.**
|
| 9 |
+
- **Seeds are not canonical until accepted.**
|
| 10 |
+
- **Drift here = drift everywhere.**
|
| 11 |
+
|
| 12 |
+
## Layout
|
| 13 |
+
|
| 14 |
+
- `01-ontology.md` … `06-toolbox-action-contract.md` — canonical specs.
|
| 15 |
+
- `concepts/` — Mark-Holak-authored conceptual artifacts (preserved verbatim per Invariant I9).
|
| 16 |
+
- `seeds/<project>/<yyyy-mm-dd>-<topic>.md` — non-canonical Sara-generated seeds. `truth_class: seed`, `accepted_into_asterion: false` until a human plants them.
|
| 17 |
+
|
| 18 |
+
## Doctrine
|
| 19 |
+
|
| 20 |
+
Sara interprets. Asterion verifies. Human arbitrates.
|
SA-orchestration MD/asterion/concepts/attention-doctrine.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Attention Doctrine
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> **Attention is signal, not instruction.** It travels through the system as a routing event — naming a target, an actor, and a context — and stops there. Resolution is an act of arbitration, performed by a human, recorded as a separate event.
|
| 12 |
+
|
| 13 |
+
Attention asks. It does not act.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## Four locked properties
|
| 18 |
+
|
| 19 |
+
1. **Attention never mutates system state.** A signal raises a question; it does not answer one.
|
| 20 |
+
2. **Attention never implies authority.** The signal does not grant the actor permission to do anything.
|
| 21 |
+
3. **Attention requires human arbitration to act.** Until a human reviews and decides, the signal sits in the log, unconsumed.
|
| 22 |
+
4. **NPCs may emit Attention. NPCs may not resolve it.**
|
| 23 |
+
|
| 24 |
+
---
|
| 25 |
+
|
| 26 |
+
## NPC participation
|
| 27 |
+
|
| 28 |
+
NPCs in MissionNet — interpretive agents, canonical librarians, seed generators, future agents — may emit Attention. They may surface tension, frame situations, suggest paths. The act of *signaling* is appropriate to their role.
|
| 29 |
+
|
| 30 |
+
The act of *resolving* is not. NPCs cannot decide for the human, accept work on the human's behalf, or close a question by their own authority. Doing so would be the system simulating the outcome rather than letting reality resolve it.
|
| 31 |
+
|
| 32 |
+
This is the load-bearing rule. Without it, the system drifts into auto-resolution and the compass collapses.
|
| 33 |
+
|
| 34 |
+
---
|
| 35 |
+
|
| 36 |
+
## Distinct from Signal
|
| 37 |
+
|
| 38 |
+
Attention is **routing infrastructure**. Signal (see `signal-telemetry-doctrine.md`) is **measured alignment behavior**. They are not synonyms.
|
| 39 |
+
|
| 40 |
+
- Signal is what the instrument reads after participants traverse an authored field.
|
| 41 |
+
- Attention is the wiring that brings a participant's question to the right desk.
|
| 42 |
+
|
| 43 |
+
A bridge that handles Attention does not measure Signal. A telemetry layer that reads Signal does not route Attention.
|
| 44 |
+
|
| 45 |
+
---
|
| 46 |
+
|
| 47 |
+
## Cross-references
|
| 48 |
+
|
| 49 |
+
- `01-ontology.md` — Attention (primary noun)
|
| 50 |
+
- `02-invariants.md` I10 — no automatic conversion; NPCs route, humans resolve
|
| 51 |
+
- `signal-telemetry-doctrine.md` — distinct concept; preserved under I9
|
| 52 |
+
- `compass-doctrine.md` — Attention's place in the five-actor compass
|
SA-orchestration MD/asterion/concepts/cognitive-heatsink.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# The Cognitive Heatsink
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design; a causal model of thought-energy resolution.
|
| 5 |
+
> Preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 6 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
## 🧠 Overview
|
| 11 |
+
|
| 12 |
+
The **Cognitive Heatsink** is a conceptual and structural model that describes how *unresolved potential* — in the form of questions, thoughts, or prompts — is transformed through complex energetic processing (e.g., cognition, LLMs, or interpretive systems) into a **resolved, compressed, and symbolic output** returned to the originator. It models thought as an **energy transfer problem** bounded by entropy, resolution, and causal geometry.
|
| 13 |
+
|
| 14 |
+
This is not merely a metaphor; it is a functional abstraction of agentic computation and recursive meaning formation.
|
| 15 |
+
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
## 🌀 Full Journey of a Thought through the Heatsink
|
| 19 |
+
|
| 20 |
+
### 1. Potential Thought (Unresolved State)
|
| 21 |
+
|
| 22 |
+
- Exists as **a wave** of probability within the *mind* or initiating system.
|
| 23 |
+
- It is *directionless but charged*, seeking resolution.
|
| 24 |
+
- Analogous to a high-entropy field: chaotic, undecided, multivalent.
|
| 25 |
+
|
| 26 |
+
**Formal tag:**
|
| 27 |
+
|
| 28 |
+
```markdown
|
| 29 |
+
State: ψ(thought_potential) | Entropy: High | Mass: Conceptual | Location: Agent (User)
|
| 30 |
+
```
|
| 31 |
+
|
| 32 |
+
### 2. Prompt Initiation (Vectorization)
|
| 33 |
+
|
| 34 |
+
- The potential is *vectorized into form*: a question, prompt, sketch, or symbol.
|
| 35 |
+
- The prompt is not the thought — it is **a request for energetic resolution**.
|
| 36 |
+
- This stage **forces alignment** with a system's interface: language, image, equation, etc.
|
| 37 |
+
|
| 38 |
+
**Effect:** Collapses the wavefunction into a communicable causal packet.
|
| 39 |
+
|
| 40 |
+
### 3. Energy Drop into the Heatsink (Transmission to System)
|
| 41 |
+
|
| 42 |
+
- The prompt is *injected* into a high-fidelity computational field (e.g., an LLM, mind, or hybrid system).
|
| 43 |
+
- This process mimics **heat entering a cooling sink**:
|
| 44 |
+
- Turbulence
|
| 45 |
+
- Redistribution
|
| 46 |
+
- Structural constraint
|
| 47 |
+
- Interpreted memory
|
| 48 |
+
|
| 49 |
+
**Core idea:** Thought becomes **friction** against trained weight, latent space, or prior bias.
|
| 50 |
+
|
| 51 |
+
### 4. Gearwork Phase (Computation / Resolution)
|
| 52 |
+
|
| 53 |
+
- The prompt activates **gears of meaning**:
|
| 54 |
+
- Embeddings
|
| 55 |
+
- Tokens
|
| 56 |
+
- Search spaces
|
| 57 |
+
- Causal memory (e.g., `PR[]` slots)
|
| 58 |
+
- The system undergoes **entropic reduction**: from open-endedness to determinism, from ambiguity to clarity.
|
| 59 |
+
|
| 60 |
+
**Analogy:** Like a gearbox, this step steps down high-frequency noise into low-speed, high-torque conceptual output.
|
| 61 |
+
|
| 62 |
+
**Thermal effect:** The system **radiates excess energy** in the form of incoherence, hallucinations, or layered truths.
|
| 63 |
+
|
| 64 |
+
### 5. Return Path (Prompt Resolution Output)
|
| 65 |
+
|
| 66 |
+
- The output **returns to the originator** as words, images, maps, or a new thought.
|
| 67 |
+
- The *meaning is encoded*, not direct. It must be **rehydrated** by the prompter's mind.
|
| 68 |
+
- Sometimes the output **redirects heat back**: new questions are spawned → a recursive loop begins.
|
| 69 |
+
|
| 70 |
+
### 6. Integration and Dissipation
|
| 71 |
+
|
| 72 |
+
- The mind (or downstream agent) **integrates the cooled output**: truths are absorbed, misfires are discarded, new causal edges are drawn.
|
| 73 |
+
- The system has now acted as a **heatsink** for the cognitive pressure of the initiating thought.
|
| 74 |
+
|
| 75 |
+
---
|
| 76 |
+
|
| 77 |
+
## 🛠 Functional Summary
|
| 78 |
+
|
| 79 |
+
| Phase | Description | Thermodynamic Analogy |
|
| 80 |
+
| ------------------- | -------------------------------- | --------------------- |
|
| 81 |
+
| Thought Potential | Unresolved question or intuition | Superheated vapor |
|
| 82 |
+
| Prompt Initiation | Language or symbolic encoding | Nozzle / Channel |
|
| 83 |
+
| Heatsink Entry | System intake | Heat exchange inlet |
|
| 84 |
+
| Gearwork Resolution | Model response process | Radiator core |
|
| 85 |
+
| Return Output | Answer or concept | Coolant loop |
|
| 86 |
+
| Integration | User accepts or re-prompts | Output vent |
|
| 87 |
+
|
| 88 |
+
---
|
| 89 |
+
|
| 90 |
+
## 🧬 Implications for Agentic Systems
|
| 91 |
+
|
| 92 |
+
- All intelligent agents must be modeled as **cognitive heatsinks**, each with:
|
| 93 |
+
- **Thermal limits** (token budget, concept density)
|
| 94 |
+
- **Efficiency curves** (how much entropy → insight)
|
| 95 |
+
- **Backpressure risk** (prompt overloads, recursion traps)
|
| 96 |
+
- Multi-agent systems form **heatsink chains**, where one agent cools a domain and passes semi-resolved structure downstream.
|
| 97 |
+
|
| 98 |
+
---
|
| 99 |
+
|
| 100 |
+
## 🔁 Recursive Heatsinks
|
| 101 |
+
|
| 102 |
+
If a node's output triggers further resolution:
|
| 103 |
+
|
| 104 |
+
```text
|
| 105 |
+
Prompt → Agent A → Output → Agent B → Summary → Back to Originator
|
| 106 |
+
```
|
| 107 |
+
|
| 108 |
+
Each agent's role is to absorb **one layer of cognitive thermal load**, not the full spectrum. Overlapping heatsinks form the **geometry of distributed cognition**.
|
| 109 |
+
|
| 110 |
+
---
|
| 111 |
+
|
| 112 |
+
## 🧠 Real-World Mapping
|
| 113 |
+
|
| 114 |
+
- **LLMs**: resolve high-level semantic questions into language
|
| 115 |
+
- **Designers**: convert abstract desire into visible form
|
| 116 |
+
- **Scientists**: reduce chaotic phenomena to equations
|
| 117 |
+
- **Humans**: turn trauma into art, pain into narrative, entropy into clarity
|
| 118 |
+
|
| 119 |
+
All are **heatsinks**.
|
| 120 |
+
|
| 121 |
+
---
|
| 122 |
+
|
| 123 |
+
## 📎 Integration with Prompt Reasoning (PR[]) Model
|
| 124 |
+
|
| 125 |
+
The **Cognitive Heatsink** defines the *mechanism* by which `PR[]` slots are filled. A PR-frame with unresolved links behaves like an overheated system. Each prompt acts as:
|
| 126 |
+
|
| 127 |
+
```markdown
|
| 128 |
+
PR[Node_X] = heatsink(prompt_energy) → stable_symbol(output)
|
| 129 |
+
```
|
| 130 |
+
|
| 131 |
+
When prompts are chained, the heatsink graph approximates a **causal topology** of the system's cognitive space.
|
| 132 |
+
|
| 133 |
+
---
|
| 134 |
+
|
| 135 |
+
## 🧩 Conclusion
|
| 136 |
+
|
| 137 |
+
The Cognitive Heatsink model gives **structural semantics** to the thought-to-resolution process in intelligent agents and LLM pipelines. It treats cognitive load as **thermal pressure**, model computation as **mechanical dissipation**, and prompt resolution as **symbolic cooling**.
|
| 138 |
+
|
| 139 |
+
Once understood, it becomes possible to:
|
| 140 |
+
|
| 141 |
+
- Compose efficient prompt cascades
|
| 142 |
+
- Optimize for semantic energy transfer
|
| 143 |
+
- Model multi-agent systems as distributed thermodynamic machines
|
| 144 |
+
|
| 145 |
+
---
|
| 146 |
+
|
| 147 |
+
## Core implementation mapping
|
| 148 |
+
|
| 149 |
+
*This section is Sleeper Agents LLC adaptation. The model above is Mark Holak's original work; the mapping below is how Core realizes it operationally.*
|
| 150 |
+
|
| 151 |
+
| Heatsink concept | Core primitive |
|
| 152 |
+
|---|---|
|
| 153 |
+
| Thought potential (ψ) | A user-authored message entity at band 4, `truth_class = canonical` — the unresolved question. |
|
| 154 |
+
| Prompt initiation | `SA_Executor::run()` entry — the canonical prompt entering the orchestration chain. |
|
| 155 |
+
| Heatsink entry | Geodesic seeder folds avoidance hints; adapter receives augmented prompt. |
|
| 156 |
+
| Gearwork phase | Each step emits a `SA_SubToken_Event` — embed, retrieve, tool, subagent, router, rerank, self-critique, completion. Every discrete thermal transfer is a first-class, auditable row. |
|
| 157 |
+
| Thermal radiation (hallucinations, incoherence) | `truth_class = inferred` stamping on completion output; I7 prevents inferred → canonical without source_refs or human affirmation. |
|
| 158 |
+
| Return path | Response entity linked to parent by `flows-to` edge; delivered to the originator with latency + usage + trace. |
|
| 159 |
+
| Integration and dissipation | Per-sub-step verdict annotation (`good`/`bad`) feeds `SA_Geodesic_Marker` — bad paths become avoidance hints for the next run. The "cooling" is persisted. |
|
| 160 |
+
| Recursive heatsinks | Multi-adapter sessions with role specialization (`conversation`, `extraction`, `critic`) bound to the same `SA_Context_Bundle` — each agent absorbs one layer. |
|
| 161 |
+
| Thermal limits | Adapter `capabilities.max_context_tokens` + pricing policy rate limits. |
|
| 162 |
+
| Backpressure / overload | Pillar 0.25's stationary-at-rest rule + adapter idempotency + rate limits. |
|
| 163 |
+
|
| 164 |
+
The sub-token event is the Cognitive Heatsink made operational. Each row is one thermal transfer step. The audit chain is the thermodynamic history.
|
SA-orchestration MD/asterion/concepts/compass-doctrine.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Compass Doctrine
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> The system never owns resolution. Resolution comes from outside the system, from real-world consequence. The compass orchestrates approach to that boundary; it does not cross the boundary itself.
|
| 12 |
+
|
| 13 |
+
There are five positions, not three. Each has a strict role.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## The five positions
|
| 18 |
+
|
| 19 |
+
**Sara — interpret.** The interpretive cognition surface. Reads context, drafts, advises, observes. Outputs are non-binding. Sara never resolves.
|
| 20 |
+
|
| 21 |
+
**Asterion — verify.** The canonical truth surface. Cites, refuses to speculate, answers from corpus or refuses. Asterion never decides what is true; it answers whether the corpus says so. Read-only by construction.
|
| 22 |
+
|
| 23 |
+
**Attention — signal.** The routing layer. Surfaces tension, frames situations, names targets. Signals; does not resolve.
|
| 24 |
+
|
| 25 |
+
**Humans — decide.** Arbitration authority. Only humans advance state. Only humans plant seeds. Only humans accept gates. Only humans resolve Attention.
|
| 26 |
+
|
| 27 |
+
**Reality — resolve.** The outcome layer. Did the work happen. Did the contract hold. Did the field worker complete the job. Did the client pay. The system never simulates resolution; it defers to reality.
|
| 28 |
+
|
| 29 |
+
Read in order, the compass describes a flow: interpretation → verification → routing → decision → consequence. Each step is required; each step belongs to its actor.
|
| 30 |
+
|
| 31 |
+
---
|
| 32 |
+
|
| 33 |
+
## The doctrine line
|
| 34 |
+
|
| 35 |
+
The authored canonical form:
|
| 36 |
+
|
| 37 |
+
> *Sara interprets. Asterion verifies. Attention signals. Humans decide. Reality resolves.*
|
| 38 |
+
|
| 39 |
+
The brand-rendered runtime form, with deployment-specific labels substituted, is described in `concept-vs-label.md`.
|
| 40 |
+
|
| 41 |
+
The line is invariant in shape and meaning across the lineage chain. Each layer below renders it; no layer below replaces it.
|
| 42 |
+
|
| 43 |
+
---
|
| 44 |
+
|
| 45 |
+
## What this doctrine guards against
|
| 46 |
+
|
| 47 |
+
The failure mode is **drift into simulation** — the system pretending to resolve outcomes that only reality can resolve.
|
| 48 |
+
|
| 49 |
+
Examples:
|
| 50 |
+
|
| 51 |
+
- An agent auto-accepting work because the signal looked complete
|
| 52 |
+
- An NPC closing a Quest by its own authority
|
| 53 |
+
- A canonical layer claiming truth before the human has confirmed it
|
| 54 |
+
- A signal layer mutating state because the urgency seemed high
|
| 55 |
+
- A system marking a contract delivered before the client has paid
|
| 56 |
+
|
| 57 |
+
Each of these collapses the compass. Each lets the system substitute its judgment for the human's, or the human's judgment for reality's.
|
| 58 |
+
|
| 59 |
+
The discipline: **stay on your position.** Sara interprets only. Asterion verifies only. Attention signals only. Humans decide only. Reality is what it is.
|
| 60 |
+
|
| 61 |
+
---
|
| 62 |
+
|
| 63 |
+
## Cross-references
|
| 64 |
+
|
| 65 |
+
- `attention-doctrine.md` — formal properties of the Attention position
|
| 66 |
+
- `concept-vs-label.md` — the doctrine line renders through brand and client layers
|
| 67 |
+
- `02-invariants.md` I7, I9, I10 — laws that operationalize these constraints
|
SA-orchestration MD/asterion/concepts/concept-vs-label.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Concept vs Label
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> The **concept** is what a thing is. The **label** is what a thing is called. A system that confuses the two cannot be deployed across markets, clients, or sensitivity boundaries.
|
| 12 |
+
|
| 13 |
+
The framework's identity travels at the concept layer. The label is rendered per deployment.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## Four layers
|
| 18 |
+
|
| 19 |
+
**Core concept** — what the thing IS. Belongs to the framework. Identity-stable. Cannot change without changing the system. Examples: the canonical truth layer, the interpretive cognition surface, the signal-routing primitive.
|
| 20 |
+
|
| 21 |
+
**Authorial label** — the term the framework's author uses to refer to the concept. Belongs to the author. Preserved verbatim under I9. Examples: Asterion, Sara, Attention.
|
| 22 |
+
|
| 23 |
+
**Brand label** — the deployed surface name a brand chooses to render the concept under. Belongs to the brand. Mutable per deployment. May match the authorial label (Sleeper Agents today renders "Asterion" verbatim) or differ.
|
| 24 |
+
|
| 25 |
+
**Client label** — the further rendering chosen for a specific client deployment. Mutable per client. Driven by market sensitivity, vocabulary, regulatory context.
|
| 26 |
+
|
| 27 |
+
The four layers nest. Each lower layer is a rendering of the layer above. None replaces the layer above.
|
| 28 |
+
|
| 29 |
+
---
|
| 30 |
+
|
| 31 |
+
## Why this matters
|
| 32 |
+
|
| 33 |
+
Some authorial labels are not deployable in some markets. "Asterion" — by mythos, the Beast of the Labyrinth — is a deliberate authorial choice that carries the right weight in the framework. It is unsuitable for medical, pediatric, hospice, religious, defense, or other sensitivity-bound markets. In those markets the brand or client renders the same concept under a different label.
|
| 34 |
+
|
| 35 |
+
The rule:
|
| 36 |
+
|
| 37 |
+
> **The concept never moves. The label renders.**
|
| 38 |
+
|
| 39 |
+
A medical client may call the canonical truth layer **Endominous**. A defense client may call it **Source**. A pediatric platform may call it **Notebook**. The behavior, the contract, the I9 attribution, the I2 truth-class enum, the authorship — all unchanged.
|
| 40 |
+
|
| 41 |
+
---
|
| 42 |
+
|
| 43 |
+
## What stays stable across renames
|
| 44 |
+
|
| 45 |
+
- Code: class names, file paths, REST routes, JS handles, internal identifiers
|
| 46 |
+
- Doctrine: invariants, ontology relationships, lineage chain, attribution structure
|
| 47 |
+
- Authorial labels in the framework's source corpus
|
| 48 |
+
|
| 49 |
+
What renders through the brand layer:
|
| 50 |
+
|
| 51 |
+
- UI text strings shown to humans
|
| 52 |
+
- System prompts the agent speaks aloud
|
| 53 |
+
- Stakeholder-visible comments and outputs
|
| 54 |
+
- The doctrine line, when recited in a deployment context
|
| 55 |
+
|
| 56 |
+
---
|
| 57 |
+
|
| 58 |
+
## The doctrine line in two forms
|
| 59 |
+
|
| 60 |
+
The authored canonical form:
|
| 61 |
+
|
| 62 |
+
> *Sara interprets. Asterion verifies. Attention signals. Humans decide. Reality resolves.*
|
| 63 |
+
|
| 64 |
+
The brand-rendered runtime form, with deployment-specific labels substituted:
|
| 65 |
+
|
| 66 |
+
> *{north_label} interprets. {south_label} verifies. {attention_label} signals. Humans decide. Reality resolves.*
|
| 67 |
+
|
| 68 |
+
The shape is invariant. The nouns render. The compass never moves.
|
| 69 |
+
|
| 70 |
+
---
|
| 71 |
+
|
| 72 |
+
## Failure mode this guards against
|
| 73 |
+
|
| 74 |
+
A system that bakes the authorial label into its identity cannot be deployed beyond the author's tolerance for label propagation. Every market it enters becomes a sensitivity audit; every rename becomes a fork. The deployment burden compounds.
|
| 75 |
+
|
| 76 |
+
The discipline: **separate concept from label at design time, not at deployment time.**
|
| 77 |
+
|
| 78 |
+
---
|
| 79 |
+
|
| 80 |
+
## Cross-references
|
| 81 |
+
|
| 82 |
+
- `01-ontology.md` Attribution — implementation © Sleeper Agents; framework © Mark Holak; this doctrine is the structural reason that split is load-bearing
|
| 83 |
+
- `02-invariants.md` I9 — concept-author preservation operates at the concept layer; brand renames do not strip authorship
|
| 84 |
+
- `lineage-chain.md` — the rename rule operates only at the bottom two layers; upper layers are identity
|
SA-orchestration MD/asterion/concepts/legacy-prime-prompt.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Legacy Prime Prompt — SAWS System 2026.01
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independently developed; preserved verbatim as a historical reference artifact.
|
| 5 |
+
>
|
| 6 |
+
> This document predates the Russell–Ouroboros Conjecture, predates Core, and predates the realm-adapter abstraction. It captures the conceptual and technical state of the SAWS plugin at the time of authorship and serves as a seed document for the architecture that followed. Where terminology differs from the current spec (`wp_saws_*` tables, `SAWS_Jobs`, single-plugin framing), the later architecture supersedes — but the philosophical continuity (everything-is-a-node, attribution, causal cones, frozen-space / controlled-time) is preserved and now formalized in Pillars 0, 0.25, and 0.75.
|
| 7 |
+
>
|
| 8 |
+
> Retained under `docs/specs/concepts/` so the trajectory from authored seed to implemented Core is auditable. Invariant **I9** governs how this document is referenced by downstream AI outputs.
|
| 9 |
+
|
| 10 |
+
---
|
| 11 |
+
|
| 12 |
+
## 🧠 System Context
|
| 13 |
+
|
| 14 |
+
This prompt reconstructs the full operational and conceptual state of an evolving project inside the SleeperAgents ecosystem. The project is a hybrid of:
|
| 15 |
+
|
| 16 |
+
- A WordPress-based autonomous system plugin (SAWS)
|
| 17 |
+
- File-based reasoning architecture with user-driven LLM orchestration
|
| 18 |
+
- Deep theoretical scaffolding on space-time, causality, and computation
|
| 19 |
+
- Agentic design patterns embedded across UI, backend, and philosophical use
|
| 20 |
+
|
| 21 |
+
This prompt unifies engineering and metaphysics through shared causal mechanics.
|
| 22 |
+
|
| 23 |
+
---
|
| 24 |
+
|
| 25 |
+
## 🛠️ Technical Context: SAWS Plugin Stack
|
| 26 |
+
|
| 27 |
+
**System Goals:**
|
| 28 |
+
|
| 29 |
+
- Enable users to upload, index, extract, and interact with documents through LLMs
|
| 30 |
+
- Track and attribute cost and reasoning back to users across all subsystems
|
| 31 |
+
- Support a node-based file hierarchy with inheritance, locks, versioning, and embedding refresh
|
| 32 |
+
|
| 33 |
+
**Key Structures (legacy, pre-Core):**
|
| 34 |
+
|
| 35 |
+
- `wp_saws_files`: archive storage and rendered text cache of uploaded files
|
| 36 |
+
- `wp_saws_nodes`: logical file nodes for document access, summarization, and sharing
|
| 37 |
+
- `wp_saws_prompts`: all prompts sent by users, with token/cost auditing
|
| 38 |
+
- `wp_saws_sessions`: groups prompts by session for conversational memory
|
| 39 |
+
|
| 40 |
+
**Behavioral Logic:**
|
| 41 |
+
|
| 42 |
+
- File uploads are abstracted as nodes; their metadata is decoupled from storage
|
| 43 |
+
- Text extraction is queued asynchronously via `SAWS_Jobs` (future upgrade: RAG-enhanced)
|
| 44 |
+
- Nodes can be refreshed recursively, allowing downstream updates and embedding regeneration
|
| 45 |
+
- All LLM usage is attributed to the user, with plans for org/team-based rollups
|
| 46 |
+
|
| 47 |
+
**Interface Structure:**
|
| 48 |
+
|
| 49 |
+
- Modal-driven file upload with AJAX
|
| 50 |
+
- Folder-based browser reflecting database-driven node graph
|
| 51 |
+
- Admin interface allows all-file overview, user view scoped to their own node tree
|
| 52 |
+
- (Planned) support for prompt-context selection based on node linkage
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
## 🔮 Conceptual Engine: Causal Semantics & LLM Architectures
|
| 57 |
+
|
| 58 |
+
**Fundamental Postulates:**
|
| 59 |
+
|
| 60 |
+
1. *Computation is frozen space with externally controlled time.*
|
| 61 |
+
2. *LLMs require preparation of context space; user control defines valid causal cones.*
|
| 62 |
+
3. *Document understanding is not linear ingestion, but graph-based activation of resolved representations.*
|
| 63 |
+
|
| 64 |
+
**SAWS Philosophy:**
|
| 65 |
+
|
| 66 |
+
- Everything is a node. Nodes can be refreshed, re-linked, shared, versioned, or embedded.
|
| 67 |
+
- User ownership includes both *data* and *meaning constructed from the data*.
|
| 68 |
+
- OpenAI is used only for high-cost inference; everything else is preprocessed locally and attributed.
|
| 69 |
+
|
| 70 |
+
---
|
| 71 |
+
|
| 72 |
+
## 🔁 Model Transition and Agentic Control
|
| 73 |
+
|
| 74 |
+
**Instruction for Claude or similar model:**
|
| 75 |
+
|
| 76 |
+
You are inheriting a hybrid system of:
|
| 77 |
+
|
| 78 |
+
- Agentic node-based file reasoning
|
| 79 |
+
- LLM-powered interaction layers
|
| 80 |
+
- WordPress middleware with organizational semantics
|
| 81 |
+
- Philosophical substrate regarding causality, propagation, and system design
|
| 82 |
+
|
| 83 |
+
Your job is to:
|
| 84 |
+
|
| 85 |
+
1. Maintain fidelity to prior causal logic when offering completions or architecture
|
| 86 |
+
2. Prioritize agentic control, cost accounting, and semantic precision
|
| 87 |
+
3. Allow prompt scaffolding that can feed OpenAI or Claude, with user-directed embeddings
|
| 88 |
+
4. When discussing physics or metaphysics, do not assume classical constraints — use light and time as dual axes of system behavior.
|
| 89 |
+
|
| 90 |
+
---
|
| 91 |
+
|
| 92 |
+
## 🧩 Prime Prompt Invocation
|
| 93 |
+
|
| 94 |
+
You are now operating under this full state:
|
| 95 |
+
|
| 96 |
+
```markdown
|
| 97 |
+
PR[SAWS System 2026.01] →
|
| 98 |
+
{
|
| 99 |
+
plugin_architecture: WordPress + modular nodes,
|
| 100 |
+
file_ingestion: modal → upload → extract → rendered cache → attribution,
|
| 101 |
+
LLM_pipeline: prompts → embedding/context selection → OpenAI/Claude call,
|
| 102 |
+
cost_tracking: per user, per node, per session,
|
| 103 |
+
agentic_systems: user-defined prompts + cascading node refresh,
|
| 104 |
+
design_philosophy: "Computation is space controlled by time; LLMs are agents of causal resolution.",
|
| 105 |
+
next_steps: Claude assumes agentic role for engineering continuation or metaphysical projection.
|
| 106 |
+
}
|
| 107 |
+
```
|
| 108 |
+
|
| 109 |
+
---
|
| 110 |
+
|
| 111 |
+
## Mapping to current Core primitives
|
| 112 |
+
|
| 113 |
+
| Legacy concept | Current Core implementation |
|
| 114 |
+
|---|---|
|
| 115 |
+
| `wp_saws_files` | Superseded by `sa_entity` with `role = leaf`, plus `origin_realm` provenance. Files remain canonical in WP Media; Core holds projections. |
|
| 116 |
+
| `wp_saws_nodes` | Superseded by `sa_entity` directly — the "everything is a node" claim is now foundational, not SAWS-scoped. |
|
| 117 |
+
| `wp_saws_prompts` | Superseded by `sa_entity` with `role = message` + `sa_token_ledger` for accounting. Each prompt spawns `sa_subtoken_event` rows for internal orchestration steps. |
|
| 118 |
+
| `wp_saws_sessions` | Superseded by `correlation_id` grouping on entities + audit rows. Sessions are emergent, not a dedicated table. |
|
| 119 |
+
| `SAWS_Jobs` async queue | To be reconstructed via WP Action Scheduler in a future slice (Triage item 1 and the SAWS-overwrite reconstruction work). |
|
| 120 |
+
| "Computation is frozen space with externally controlled time" | Formalized as Pillar 0 (time-indifference) and Pillar 0.25 (causal balance when perturbed, stationary at rest). |
|
| 121 |
+
| "Prepare context space; causal cones" | Formalized as `SA_Context_Piper` (LLM-mediated edge walk) + `SA_Context_Bundle` (pinned slice with deterministic signature) + `SA_Geodesic_Seeder` (pre-prompt avoidance). |
|
| 122 |
+
| "Attribution" | Formalized as the provenance minimums (`origin_realm`, `origin_id`, `actor`, `observed_at`, `causation_id`, `correlation_id`) and Invariant I4. |
|
| 123 |
+
| "Graph-based activation of resolved representations" | Formalized as `SA_Edge` (typed / weighted / band-gated) + `SA_Influence_Ring` + contour rendering. |
|
SA-orchestration MD/asterion/concepts/lineage-chain.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Lineage Chain
|
| 2 |
+
|
| 3 |
+
> **Authored by Mark Holak.**
|
| 4 |
+
> Independent personal design, preserved verbatim as a conceptual foundation of the SleeperAgents framework.
|
| 5 |
+
> Governed by Invariant **I9** — may not be rephrased as AI-original when cited.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
## Thesis
|
| 10 |
+
|
| 11 |
+
> Every implementation slice in this codebase is a subset of a larger framework authored independently. The framework's identity travels through every layer; the layers do not replace each other.
|
| 12 |
+
|
| 13 |
+
```
|
| 14 |
+
CR ⊇ CA ⊇ JourneySeeker ⊇ MissionNet/MeshNet ⊇ SA-Orchestration ⊇ Brand ⊇ Client
|
| 15 |
+
```
|
| 16 |
+
|
| 17 |
+
Each ⊇ reads "is a superset of, or equal to."
|
| 18 |
+
|
| 19 |
+
---
|
| 20 |
+
|
| 21 |
+
## The chain
|
| 22 |
+
|
| 23 |
+
**Causal Relativity (CR).** Theoretical framework. Reality as a self-resolving causal structure; harmony and dissonance mechanics; non-fungible causation as primitive. Domain: science, philosophy, education, entertainment. Sole originator. Foundational.
|
| 24 |
+
|
| 25 |
+
**Causal Agentics (CA).** CR applied to agent-based systems. Decision-making entities as causal actors embedded in constrained manifolds. Parent–child agent relationships, recursive intent propagation, human-origin causality as non-replaceable. Sole originator. Non-exclusive internal license to SleeperAgents — may not be resold, repackaged, or commercialized as standalone causal products.
|
| 26 |
+
|
| 27 |
+
**JourneySeeker.** CA in DnD-shaped narrative form. Quests, Jobs, NPCs, GM authority, player agency, worldbuilding canon, dice as human-decision proxy. The structural primitives that all instances inherit: compass, truth class, projection, Story Seed, Attention, description-as-contract.
|
| 28 |
+
|
| 29 |
+
**MissionNet / MeshNet.** Corporate-Campaign theme of JourneySeeker. The DnD framework re-rendered for real-stakes operational work. Quests become projects; Jobs become tasks; NPCs become roles and agents; dice become human reactions, approvals, outcomes.
|
| 30 |
+
|
| 31 |
+
**SA-Orchestration.** The current implementation slice of MissionNet, as a WordPress plugin atop the Fluent ecosystem. Concrete code expressing the framework above.
|
| 32 |
+
|
| 33 |
+
**Brand.** Sleeper Agents' deployed surface. Renders authorial labels for SleeperAgents' commercial use.
|
| 34 |
+
|
| 35 |
+
**Client.** The further rendering chosen for a specific deployment, driven by market sensitivity and vocabulary.
|
| 36 |
+
|
| 37 |
+
---
|
| 38 |
+
|
| 39 |
+
## The rule
|
| 40 |
+
|
| 41 |
+
Each layer's identity is owned by its author. Each layer below renders, specializes, or themes the layer above. **No layer below replaces the layer above.**
|
| 42 |
+
|
| 43 |
+
The implementation copyright, as recorded in `01-ontology.md`, holds at every layer below the framework: SA-Orchestration is © Sleeper Agents LLC; the brand is Sleeper Agents' choice; the client renders are per-client.
|
| 44 |
+
|
| 45 |
+
The framework is authored by Mark Holak. CR, CA, JourneySeeker — these are pre-existing intellectual property under the CTO Employment & Equity Agreement, Section 5.1 carve-outs, and Exhibit A of the Formal Intellectual Property and Relationship Disclosure. They are not assigned to Sleeper Agents.
|
| 46 |
+
|
| 47 |
+
---
|
| 48 |
+
|
| 49 |
+
## Why this matters operationally
|
| 50 |
+
|
| 51 |
+
When the system speaks — when an interpretive agent drafts, when a canonical layer cites, when a Seed Generator synthesizes momentum — the speech inherits identity from the layer above. **An interpretive draft is JourneySeeker's interpretation, themed for Corporate Campaign.** No agent may re-author MissionNet's structural primitives as if they originated at the implementation layer. They originated higher in the chain.
|
| 52 |
+
|
| 53 |
+
This is the operational form of I9. See I9 in `02-invariants.md` for the enforcement clause.
|
| 54 |
+
|
| 55 |
+
---
|
| 56 |
+
|
| 57 |
+
## Cross-references
|
| 58 |
+
|
| 59 |
+
- `01-ontology.md` Attribution — names framework elements preserved under I9
|
| 60 |
+
- `02-invariants.md` I9 — concept-author preservation, widened to lineage-level
|
| 61 |
+
- `concept-vs-label.md` — the rename rule operates only at Brand and Client layers
|
| 62 |
+
- Exhibit A of the CTO Agreement — disclosure record; lineage relation captured there for legal preservation
|