Grok Build Handoff — Publish Architecture + Scotomaville
Grok Build Handoff — Publish Architecture + Scotomaville
First Publish
IN Lattice · Intelligent Netware · MA5 Council
| Field | Value |
|---|---|
| Written | 2026-06-20 |
| Carbon Steward | Daniel Comp |
| Primary build partner | Grok Build (D:\04_WORK\Code\Lattice\_ChatUI) |
| Prior handoffs | Grok_Handoff_SynNA_20260620_SessionEnd.md · Grok_Handoff_SynNA_PhaseGrid.md |
| Status | Architecture ratified · SFTP before SQL commit · Scotomaville single-tenant first · multi-fractome deferred |
New thread opener (read this first)
- This file — fractome routing model, install flavors, publish sequence
handoffs/Grok_Handoff_SynNA_PhaseGrid.md— master phase grid (update 5C/6A order note below)- Active packet:
D:\03_MAP\Syn_Pipeline\the-makers-exodus\— stateproof_approved, NA ID 238
Lattice UI: http://127.0.0.1:8780
Executive summary (2026-06-20 — Daniel + Grok)
Daniel and Grok aligned on publish routing and sequencing:
- Routing key = fractome, not writer agent. Writer agents (Arnie, Chris, Clint) are voice/SOUL;
status.composition.fractomedrives URLs, SFTP folder, SQL connection, andnext_na_id. - Two install flavors, one codebase:
- Client laptop ("breeder") — one writer in sidebar, one fractome profile in config, no multi-network UI. - Operator master (Daniel, Angelina) — single GUI, multiple fractomes via publish.fractomes{} lookup at assemble/SFTP/SQL time.
- URL replacement happens at assemble, not SQL.
assembled.htmlships remote URLs;preview.htmlkeeps127.0.0.1:8780. Do not patch URLs insyn_sql_build.py. - Publish runtime order (ratified): SFTP images to server before SSMS SQL commit. Without images on the webserver, DNN renders a broken article even if the DB row exists.
- Build order for Scotomaville first publish:
- Daniel: Azure VPS SFTP setup (this handoff § SFTP guide) - Grok: syn_publish.py (Phase 6A) — paramiko upload + HTTPS verify - Grok: syn_sql_build.py (Phase 5C) — SSMS-ready {slug}_insert.sql - Daniel: upload images → verify HTTPS → run SQL in SSMS → bump next_na_id
Chris and Clint may be removed from agent_order.json on client installs; keep them on Daniel's master until per-fractome publish profiles ship.
Fractome as publish router (future — not blocking
Scotomaville)
Today (single-tenant)
syn_config.yaml assemble + publish sections assume scotomaville / danielcomp:
```yaml assemble: tahoe_css_base: "https://syn.scotomaville.com" image_author: "danielcomp" image_url_base: "https://syn.scotomaville.com/portals/0/images/articles/danielcomp" preview_api_base: "http://127.0.0.1:8780"
preview only — never in assembled.html
publish: next_na_id: 238 syndication_url_pattern: "https://scotomaville.com/syn-us?na={na_id}"
sftp_host, sftp_user, remote_image_folder, public_base_url — Daniel fills at
onboarding ```
Future schema — publish.fractomes{}
When Angelina/Chris/Steve articles publish from one Lattice install, extend config (or MANIFEST) so each fractome resolves:
| Field | Used by |
|---|---|
image_url_base / image_author | syn_assemble.py |
tahoe_css_base | Gate 2 preview |
syndication_url_pattern | references + bottom sections |
references_template | Syd proof |
sftp_host, sftp_user, remote_image_folder | syn_publish.py |
public_base_url | HTTPS HEAD verify |
sql_profile (server/db name) | syn_sql_build.py |
next_na_id (or per-fractome registry file) | assemble + Syd + SQL |
Lookup: status.composition.fractome → profile. Gates 1–3 unchanged; only publish stages branch.
Writer agent mapping (convenience, not routing)
| Agent | Hermes container | Typical fractome(s) |
|---|---|---|
| Arnie | daniel | scotomaville |
| Chris | angelina | halotherapy, wellnessbychoice, businesswomennews |
| Clint | steve | cowboyching |
Edge case: Arnie prose + halotherapy fractome mismatch. Mitigation: default fractome on promote from writer; show fractome chip in UI before Approve for SQL.
MANIFEST
fractomes (composition only today)
templates/codey/MANIFEST.yaml lists fractomes with operator + keywords. Publish profiles will attach to the same id keys when multi-tenant ships.
Install flavors
A — Client laptop ("breeder")
- Ship one refined writer SOUL; client gets a named writer in sidebar.
agent_order.json: omit chris, clint (and other operators' writers).syn_config.yaml: single fractome publish profile pre-filled at install.MANIFEST.yaml: one fractome or locked picker.- No
publish.fractomes{}needed.
B — Operator master (Daniel, Angelina)
- Multiple writers in sidebar or one "Writer" tab with SOUL selected from packet fractome.
- Full
publish.fractomes{}map. - Shared Picasso / Codey / Syd pipeline; fractome switches destination only.
Publish pipeline — corrected sequence
Phase Grid originally listed 5C (SQL build) before 6A (SFTP). Runtime order for live publish:
`` proof_approved → syn_publish.py SFTP images (+ inline/) to remote folder → HTTPS HEAD verify 200 + Content-Length per file → syn_sql_build.py write {slug}_insert.sql (can be built earlier for review) → SSMS COMMIT article row + image rows → bump next_na_id config + dnn_article_registry.yaml → archive packet published_root ``
Grok build order for Scotomaville: syn_publish.py then syn_sql_build.py (or parallel once SFTP credentials exist). SQL file generation does not require images on server; SSMS commit does.
Active packet — `the-makers-exodus`
| Field | Value |
|---|---|
| State | proof_approved |
| Fractome | scotomaville |
| NA ID reserved | 238 |
| Remote image base | https://syn.scotomaville.com/portals/0/images/articles/danielcomp/ |
SFTP
upload file list (minimum)
| Local file (packet folder) | Remote path (under images/articles/danielcomp/) | DNN role |
|---|---|---|
the-makers-exodus_200.jpg | same filename | thumb SortOrder 0 |
the-makers-exodus_1920x420.jpg | same | banner SortOrder 1 |
the-makers-exodus_768x420.jpg | same | tablet SortOrder 2 |
the-makers-exodus_480x420.jpg | same | mobile SortOrder 3 |
the-makers-exodus_1920x960.jpg | same | body divider (no DB row) |
the-makers-exodus_DNA_Airstream_MountHood.jpg | same (flat in arnie\) | inline prose image |
assembled.html already uses remote syn.scotomaville.com URLs (assemble-time rewrite). Confirm with:
```powershell Select-String -Path "D:\03_MAP\Syn_Pipeline\the-makers-exodus\assembled.html" -Pattern "127.0.0.1"
expect: no matches
```
syn_sql_build.py notes (5C — when built)
- Scaffold from
D:\04_WORK\Code\Garwis\Arnie_DB_Insert_v2.sql - Summary (
ntext): full hook fromna_record.summary - MetaDescription (
nvarchar(500)): truncated copy only - Image byte sizes from
status.yamlimages.*.bytes @Folder=images/articles/danielcomp/(confirm pre-flight in SSMS)
Daniel onboarding checklist — `syn_config.publish`
After SFTP server is live, fill:
```yaml publish: sftp_key_file: "D:/04_WORK/Code/_APIs/sftp_key"
private key, no .pub
sftp_host: "<Azure VPS public IP or syn.scotomaville.com>" sftp_port: 22
add to schema if non-default
sftp_user: "syn_publish"
dedicated user recommended
remote_image_folder: "/portals/0/images/articles/danielcomp"
confirm physical path on server
public_base_url: "https://syn.scotomaville.com/portals/0/images/articles/danielcomp" ```
Grok adds sftp_port to config if missing when implementing syn_publish.py.
Azure VPS — Windows OpenSSH SFTP setup guide
Target: Windows Server on Azure VPS · Administrator access · DNN site at syn.scotomaville.com
Method: Windows OpenSSH Server (already noted in syn_config.yaml comment: paramiko over OpenSSH). Not IIS FTP.
Hardened SFTP user (2026-06-20): syn_publish keys in C:\ProgramData\ssh\syn_publish_authorized_keys via Match User syn_publish in sshd_config (user-profile .ssh\authorized_keys unreliable on Windows). Optional ForceCommand internal-sftp — SFTP only, no shell. Admin SSH key cleared from administrators_authorized_keys; PasswordAuthentication no.
Prerequisites
- RDP access to the VPS
- Azure Portal access (NSG / firewall)
- DNN image folder already exists and serves HTTPS (confirm one existing article image URL in browser)
Step 1 — Confirm DNN physical image path
on the server ✅ (2026-06-20 Daniel)
IIS sites on Azure VPS (Administrator RDP):
| Site | PhysicalPath |
|---|---|
IN9_Scotomaville | W:\IN9_Scotomaville |
IN9_Scotomaville_Syn | W:\IN9_Scotomaville_Syn ← syn.scotomaville.com |
IN9_Footwork | W:\IN9_Footwork |
Verified live image:
- Physical:
W:\IN9_Scotomaville_Syn\Portals\0\images\articles\arnie\DNA_Airstream_MountHood.jpg - HTTPS:
https://syn.scotomaville.com/Portals/0/images/articles/arnie/DNA_Airstream_MountHood.jpg
the-makers-exodus publish folder — arnie (ratified 2026-06-20):
Daniel: danielcomp holds thousands of legacy images; Syn articles use arnie (one inline image already live). syn_config.yaml updated; packet reassembled.
```powershell $target = "W:\IN9_Scotomaville_Syn\Portals\0\images\articles\arnie" Test-Path $target
exists — DNA_Airstream_MountHood.jpg verified
New-Item -ItemType Directory -Force -Path (Join-Path $target "inline") ```
Record:
- Physical path →
W:\IN9_Scotomaville_Syn\Portals\0\images\articles\arnie - HTTPS base →
https://syn.scotomaville.com/Portals/0/images/articles/arnie - SQL
@Folder→images/articles/arnie/(5C syn_sql_build)
Verify an existing file:
```powershell Invoke-WebRequest -Uri "https://syn.scotomaville.com/portals/0/images/articles/danielcomp/" -Method Head
Or HEAD a known .jpg from a live
article ```
Step 2 — Install OpenSSH Server (Windows Server)
```powershell
Windows Server 2019 / 2022
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*' Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd Set-Service -Name sshd -StartupType Automatic
Confirm listening
Get-NetTCPConnection -LocalPort 22 -ErrorAction SilentlyContinue ```
If Add-WindowsCapability fails, use Settings → Apps → Optional Features → OpenSSH Server.
Step 3 — Azure Network Security Group (firewall)
In Azure Portal:
- Virtual Machine → Networking (or the subnet/VNet NSG)
- Inbound port rules → Add rule:
- Name: Allow-SSH-SFTP - Priority: 310 (or any free slot above DenyAll) - Source: Your IP (for setup) — later restrict to Daniel home/office IP or use VPN - Destination: Any - Service: SSH - Port: 22 - Action: Allow
- Save
Security note: Do not leave Source = Any longer than needed for testing. Prefer your current public IP.
Step 4 — Windows Defender Firewall on the
VPS
``powershell New-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -DisplayName "OpenSSH Server (sshd)" -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 ```
Step 5 — Create dedicated SFTP user (not
Administrator)
``powershell $password = Read-Host "Enter password for syn_publish (temporary — we will use key auth)" -AsSecureString New-LocalUser -Name "syn_publish" -Password $password -FullName "SynNA Publish" -Description "Lattice paramiko SFTP upload only" -PasswordNeverExpires
Do NOT add to Administrators group
```
Step 6 — NTFS permissions on image folder
only
```powershell $target = "W:\IN9_Scotomaville_Syn\Portals\0\images\articles\danielcomp"
Daniel VPS 2026-06-20
$acl = Get-Acl $target $rule = New-Object System.Security.AccessControl.FileSystemAccessRule( "syn_publish", "Modify", "ContainerInherit,ObjectInherit", "None", "Allow" ) $acl.SetAccessRule($rule) Set-Acl $target $acl ```
syn_publish needs Modify on danielcomp\ and danielcomp\inline\ only — not on wwwroot broadly.
Step 7 — SSH key authentication (Lattice paramiko)
On Daniel's laptop (PowerShell):
```powershell
If you do not already have a key
pair for this purpose: ssh-keygen -t ed25519 -f "D:\04_WORK\Code\_APIs\sftp_key" -C "lattice-syn-publish"
Show public key — copy entire line
Get-Content "D:\04_WORK\Code\_APIs\sftp_key.pub" ```
On the VPS, as Administrator:
```powershell $sftpUser = "syn_publish" $sshDir = "C:\Users\$sftpUser\.ssh" New-Item -ItemType Directory -Force -Path $sshDir
Paste the .pub line into authorized_keys (single line,
OpenSSH format) notepad "$sshDir\authorized_keys"
Permissions — critical on Windows OpenSSH
icacls "$sshDir\authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F" /grant "${sftpUser}:R" icacls $sshDir /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F" /grant "${sftpUser}:F" ```
Edit C:\ProgramData\ssh\sshd_config (back up first):
`` PubkeyAuthentication yes PasswordAuthentication no PermitRootLogin no ``
Optional hardening — force SFTP subsystem only for syn_publish via Match User block (Grok can help tune in a follow-up session).
Restart SSH:
``powershell Restart-Service sshd ``
Step 8 — Test from Daniel's laptop
```powershell
Test SSH key login
ssh -i "D:\04_WORK\Code\_APIs\sftp_key" syn_publish@<VPS_PUBLIC_IP>
Test SFTP put (manual smoke test)
sftp -i "D:\04_WORK\Code\_APIs\sftp_key" syn_publish@<VPS_PUBLIC_IP>
sftp> cd /portals/0/images/articles/danielcomp
path depends on default directory / chroot
sftp> put D:\03_MAP\Syn_Pipeline\the-makers-exodus\the-makers-exodus_200.jpg
sftp> quit
```
Then verify HTTPS:
``powershell Invoke-WebRequest -Uri "https://syn.scotomaville.com/portals/0/images/articles/danielcomp/the-makers-exodus_200.jpg" -Method Head ``
Step 9 — Fill syn_config and hand off
to Grok
Once Step 8 passes, update .Scripts/syn_config.yaml publish section and notify Grok to implement syn_publish.py.
Troubleshooting quick reference
| Symptom | Check |
|---|---|
| Connection timeout | Azure NSG port 22; Windows Firewall |
| Permission denied (publickey) | authorized_keys permissions; correct .pub line |
| Connected but cannot cd/put | NTFS ACL on danielcomp; remote path mapping |
| Upload OK, 404 in browser | Wrong folder vs IIS virtual path; DNN cache |
| Wrong file size in DNN | Re-upload; SQL uses bytes from status.yaml |
OpenSSH path note for paramiko
Windows OpenSSH SFTP paths are often absolute Windows paths:
`` /C:/inetpub/wwwroot/portals/0/images/articles/danielcomp/ ``
or relative to user home. Confirm during Step 8 manual sftp session — record exact pwd and put target in this handoff or syn_config.yaml comment.
Open items (ordered)
| Item | Owner | Blocks |
| 1 | Azure SFTP setup (this guide) | Daniel | DONE 2026-06-20 — hardened syn_publish + key-only; admin SSH removed |
|---|---|---|---|
| 2 | syn_publish.py + config port field | Grok | image upload automation |
| 3 | syn_sql_build.py (5C) | Grok | SSMS insert file |
| 4 | SSMS commit + live verify | Daniel | first publish |
| 5 | publish.fractomes{} schema | Grok | multi-network (Angelina) |
| 6 | Client install flavor (trim agent_order) | Grok + Daniel | breeder laptops |
State machine — `the-makers-exodus`
`` proof_approved ← YOU ARE HERE → (SFTP images live on server) → sql_ready ← syn_sql_build.py writes insert SQL → published ← SSMS commit + verify ``
Written by Grok Build · 2026-06-20 · Architecture ratified · SFTP-before-SQL · Scotomaville first.