# LOST-D — Skyhawk.org active work (passdown) **Canonical passdown for any AI executor (Claude or ChatGPT).** Read this file first in every session: `https://raw.githubusercontent.com/Skyhawk-Association/deterministic-ai-control-plane/main/projects/skyhawk/LOST-D.md` **Freshness:** the raw URL can lag a few minutes behind a push; right after a push, verify with git (clone or ls-remote). **Update rule:** every verified consequential step updates this file (last verified step, next step, open decisions) and pushes it in the same run as the change. The Drupal LOST-D page (node 2479) points here. **Public file. Never put here:** passwords, SSH/API keys, token links (upload, manage or verify tokens), member personal data (names, email or contact details of attendees or contributors), backup contents, database contents, server IP addresses. ## Governing references (read before acting) - Skyhawk Working Rules: `projects/skyhawk/RULES.md` in this repository (public URL `https://raw.githubusercontent.com/Skyhawk-Association/deterministic-ai-control-plane/main/projects/skyhawk/RULES.md`). Binding for every executor. - Environment Reference: `projects/skyhawk/ENVIRONMENT.md` in this repository (Drupal node 49461 points here). GitHub / Source Reconstruction Reference: `projects/skyhawk/GITHUB.md`. Termux SSH Notes: `projects/skyhawk/TERMUX.md`. Site Menu Reference: `projects/skyhawk/SITE_MENU.md`. (Their Drupal pages 49463, 49458 and 49457 point here.) - Squadron Template 49454, Squadron Roadmap 49453 and `skyhawk_site_fixes/data/squadron-template-contract.php`: superseded for new squadron work by Gene (2026-09-27). Ignore them except the lessons listed under Active slice. ## Executors - Claude and ChatGPT are both authorized executors, one at a time, as Gene chooses. The tunnel (one AI checking the other) happens only when Gene asks for it. Formal record: `authoritative/DACP_Application_Implementation_Authorization_0.7.md`. Gene authorized a controlled VPS administration path on 2026-09-30 for Skyhawk migration and ongoing administration, bounded by current DACP/Skyhawk authority, provider policy, least privilege, auditability, and full pipe qualification. ## HANDOVER 2026-10-05 ~15:45Z (Claude -> next executor) - BACKUPS: VPS cron 01:30 runs ~/bin/skyhawk-db-backup.sh (drush sql:dump via PHP shim, cache tables structure-only, verify, keep 14, log ~/backups/db/backup.log); first run OK 171M, 473 tables. Mac LaunchAgent com.m4.skyhawk.vps-db-backup (03:15) runs ~/Scripts/skyhawk_vps_db_backup.sh: pulls dumps to /Volumes/ArchiveSSD/skyhawk-vps-backups/db, verifies newest SHA-256, keeps 90 days; test run OK sha_match. - FILES BACKUP: a block was issued to create case-sensitive APFS volume SkyhawkBackup on ArchiveSSD and extend the same script to mirror the VPS drupalbeta tree to /Volumes/SkyhawkBackup/skyhawk-vps-files/current (changed/deleted files kept in _changed/ for 90 days if rsync supports --backup-dir), with the initial full copy started in the background. RESULT NOT YET VERIFIED: check `tail -2 /Volumes/ArchiveSSD/skyhawk-vps-backups/backup.log` for a "FILES OK" line. - Mac /etc/hosts SKYHAWK-INMOTION-TEST line removed (verified 0). - emconalfa.net: it is the A2 cPanel account's MAIN domain (all skyhawk domains are add-ons). No email use (no domain mailbox; default mailbox holds only 2 bounce notices). Zero references in the live skyhawk.org database. drupaltest.emconalfa.net = Drupal 8.9.20 snapshot, content frozen 2022-02-19, 46,895 nodes, superseded by the live site. Its database (darwus_drup360, 48M, verified 190 tables) is archived at /Volumes/ArchiveSSD/skyhawk-archive/drupaltest-emconalfa-20261005T151228Z/db.sql.gz with SHA256SUMS. Its 21 GB of files were NOT archived (Gene decision: duplicates of the live site). Only 2 titles are unique to it: "NAS Floyd Bennett Field" (Gene: possibly subsumed into the latest VMA-131 page) and "FAQ - Research- Contact"; bodies saved on the Mac at ~/Desktop/emconalfa-unique-pages.html. - RECURRING DEFECT: Mac zsh does not word-split variables; SSH options or word lists held in a variable fail. Write ssh options inline on each command. - NEXT: (1) verify the FILES OK line; (2) compare the Floyd Bennett page with the live VMA-131 content and decide whether to recreate it; (3) optional DKIM record (selector skyhawk2026) in the R4L skyhawk.org zone; (4) external uptime monitor; (5) remove A2 dependencies: a4skyhawk.org nameservers (ns1-4.a2hosting.com), a4skyhawk.us and emconalfa.net zones on mysecurecloudhost; then cancel A2; (6) on Gene's approval delete /home/n790725/drupalbeta/private.pre-move-20261005T145420Z and settings.php.pre-private-path-20261005T145420Z. ## DRUPAL MIGRATION LEFTOVERS FIXED 2026-10-05 ~14:54Z - Private files moved (same-filesystem rename, 192 files / 2.7 GB, count verified) from /home/n790725/drupalbeta/web/private to /home/n790725/drupalbeta/private (outside web root); symlink web/private -> ../private kept for compatibility; .htaccess present. Previous near-empty target set aside as /home/n790725/drupalbeta/private.pre-move-20261005T145420Z (removable on Gene's approval). - settings.php file_private_path changed from the old A2 path to /home/n790725/drupalbeta/private; backup settings.php.pre-private-path-20261005T145420Z; perms restored 444 (file) / 555 (sites/default). - ImageMagick: path_to_binaries /opt/alt/alt-ImageMagick/usr/bin/ (A2) -> /usr/bin/; imagemagick_version v7 -> v6 (VPS has ImageMagick 6.9.13). Real image resize test passed (toolkit imagemagick). skyhawk.org HTTPS 200 after change. - Remaining status-report error: see evidence report status-report-remaining-error (2026-10-05). Deprecated-module warnings (Ban, Layout Builder Expose All Field Blocks) are housekeeping, not migration leftovers. ## DNS RECOVERY VERIFIED 2026-10-05 ~14:45Z (supersedes the 09:34 EDT section below) - ROOT CAUSE OF CONFUSION: Gene's home network intercepts DNS. A query from the Mac to a non-existent server (192.0.2.53) returns a cached answer; from the VPS it times out. Every Mac-side dig "authoritative" result on Oct 4-5 was a cached recursive answer. RULE: run authoritative DNS checks from the VPS (ssh Inmotion), never from the Mac. - VERIFIED FROM THE VPS: ns1.r4l.com and ns2.r4l.com (both addresses) and ns1.mysecurecloudhost.com serve the VPS address for skyhawk.org, a4skyhawk.com, a4skyhawk.info, a4skyhawk.net, a4skyhawk.biz and usmcskyhawkers.org, with www CNAME to each domain's own apex. Register4Less support confirmed the same. Public caches (3H TTL) were expiring; skyhawk.org returns 200 and the alternates 301 to https://skyhawk.org/ via the VPS. - A2 cPanel zone files for the same six domains also hold the VPS address and www to own apex (serials 2026100500/01). - MAIL: the R4L reset had replaced skyhawk.org SPF. Repaired in the R4L skyhawk.org zone only (serial 1791211153): "v=spf1 a mx a:ns2.r4l.com ~all". Served by both R4L servers and visible at Google. Drupal test mail from the VPS delivered to Gene's inbox with no bounce. MX remains R4L defaults (email not migrated, by decision). - OPEN: DKIM selector skyhawk2026 TXT not published in the R4L zone (optional). a4skyhawk.org is still delegated to ns1-4.a2hosting.com; a4skyhawk.us and emconalfa.net to mysecurecloudhost: resolve before cancelling A2. Drupal private-file path and ImageMagick path still point at old A2 locations. Remove the Mac /etc/hosts SKYHAWK-INMOTION-TEST line. External uptime monitor and nightly backup from the VPS still to do. ## DNS RECOVERY STATE 2026-10-05 ~09:34 EDT - Register4Less reset-to-defaults replaced production web records with parking defaults on the R4L zones. Manual zone edits were then made. - Independent command-line verification at ~09:34 EDT: a4skyhawk.org is correct (A=173.231.242.84; www CNAME=a4skyhawk.org.) but is still delegated to ns1-ns4.mysecurecloudhost.com. - The other six changed production domains (skyhawk.org, a4skyhawk.com/.info/.net/.biz, usmcskyhawkers.org) are delegated to ns1/ns2.r4l.com but both public DNS and direct queries to ns1.r4l.com still return R4L parking defaults (A=142.4.204.181; www CNAME=vhost.r4l.com.). DNS recovery is therefore NOT yet verified complete. - The two intentionally untouched domains remain unchanged: a4skyhawk.us A=173.231.242.84 with www CNAME to apex on mysecurecloudhost; emconalfa.net A=65.181.120.151 with www CNAME to apex on mysecurecloudhost. - NEXT: wait only for evidence of R4L publication if the saved custom-zone values have not yet reached ns1/ns2.r4l.com; otherwise reopen the affected R4L zones and correct/publish them. Do not claim site recovery until direct authoritative R4L queries show the intended A/CNAME values and HTTPS passes. ## VERIFIED CUTOVER 2026-10-05 ~03:52Z - DNS ownership clarification: Register4Less is the registrar/control account, but the current registry delegation for skyhawk.org points to ns1-ns4.mysecurecloudhost.com, so the active authoritative zone is external to Register4Less's dormant custom zone. All seven production apex A records now resolve to the InMotion VPS; www remains CNAME to apex. - Drupal/InMotion: maintenance mode cleared; Apache backend, nginx front, and /user/login verified HTTP 200 before DNS cutover. - TLS: Let's Encrypt SAN certificate successfully issued and installed for all 14 production names (seven apex + www), valid through 2027-01-03. - HTTPS: skyhawk.org and www.skyhawk.org verified 200 externally; the six alternate domains and their www names verified 301 to https://skyhawk.org$request_uri. - Certificate SAN independently verified from the Mac against the live endpoint. - Current cutover status: production DNS and HTTPS are live on InMotion. - DNS continuity verification 2026-10-05: ns1.r4l.com/ns2.r4l.com already answer authoritatively for all seven production zones as secondaries, with the same SOA serial/MNAME as ns1.mysecurecloudhost.com. Command-line comparison of 204 observed owner/type RRsets between ns1.mysecurecloudhost.com and ns1.r4l.com found 0 mismatches. Therefore no manual record transcription is needed. R4L is presently serving synchronized secondary copies; because the SOA MNAME still points to ns1.mysecurecloudhost.com, do not cancel A2 until R4L is made the independent primary/authoritative owner and registry delegation is switched. - NEXT: use the Register4Less registrar boundary to convert/switch the seven domains from the current mysecurecloudhost delegation to R4L-owned DNS without editing individual records, then independently verify delegation, SOA ownership, all seven apex/www web outcomes, and mail-related records before retiring A2. Then complete new VPS backup/nightly backup setup. ## HANDOVER 2026-10-04 ~19:10Z (Claude -> next executor) - FULL CUTOVER PREPARED, NOT EXECUTED - TTLs: apex A records of skyhawk.org, a4skyhawk.org/.com/.info/.net/.biz, usmcskyhawkers.org set to 300 at 17:35Z via A2 uapi (DNS mass_edit_zone, verified). Cutover window opens 21:36Z. www records are CNAMEs to apex (leave). a4skyhawk.us already on VPS. emconalfa.net zone exists on A2: unknown, untouched. - Target behavior (from live A2): skyhawk.org and www serve the site (http and https). The other 6 domains plus www 301 to skyhawk.org; VPS will redirect to https://skyhawk.org$request_uri once cert exists. - Cert decision (Gene, option A): InMotion Let's Encrypt only. After DNS flip run acme.sh HTTP-01 for all 14 names via webroot /usr/local/apache/autossl_tmp (same pattern as a4skyhawk.us), install, add :443 vhosts, sleep before verify (reload race). Accept ~5-10 min https gap. - VPS nginx today: skyhawk.org-precutover.conf (:80) staged; no redirect vhosts; no certs for cutover names. Drupal trusted hosts already include skyhawk.org/www. - Mail gate CLOSED: VPS added to skyhawk.org SPF (ip4) via uapi; Drupal test mail delivered to Gene inbox. DKIM: OpenDKIM key selector skyhawk2026 installed on VPS; TXT record skyhawk2026._domainkey exists in A2 zone but A2 nameservers did not serve it (suspected negative caching). Deferred, not a gate. - DO NOT sync from the Mac nightly backup (~/ServerBackups/drupalbeta): it is the mi3-ts4 copy (darwus_test, schema 10600, max nid 49356). ArchiveSSD Skyhawk-A2-Backup (~40 GB) source/date unverified. - A2<->VPS SSH is blocked both ways. Proposed final-sync route (not yet run): from the Mac, ssh -A -R 22022:s19522.use2.stableserver.net:22 Inmotion, then on the VPS rsync from darwus@127.0.0.1 port 22022 into /home/n790725/drupalbeta, excluding .git, web/error_log, web/sites/default/settings*.php, files/css, files/js, files/php. Dry-run first. - OPEN GENE DECISION: final sync from current A2 (dump plus rsync) versus accept the VPS Oct 2 content as final. - Cutover sequence: A2 maintenance mode; fresh darwus_beta dump, import into n790725_skyhawk, updb plus cache rebuild with the PHP shim; rsync; compare 100 most recent nodes A2 vs VPS; flip 7 apex A records via uapi; LE cert plus :443; verify. - Evidence pipes: ~/bin/ai-report on the Mac and VPS (Git evidence/skyhawk). If the Mac reports PULL_FAIL, reset ~/dacp-repo to origin/main. Mac zsh: do not use variables as word lists; blocks must check their host. - Post-cutover backlog: DKIM DNS serving; VPS root alert mail bounces (DMARC); verify Register4Less DNS/registrar continuity before cancelling A2; external uptime monitor; new nightly backup from the VPS; drupalbeta_nightly_backup LaunchAgent stays disabled. - Drive checkpoint: DACP_CLAUDE_SESSION_20261004T191000Z_skyhawk-cutover-handover.md ## VPS migration continuity - 2026-10-04 - CONTAMINATION FOUND AND REVERSED: the Oct 4 handoff imported the Mac nightly dump, which came from the old mi3-ts4 copy (database darwus_test, MariaDB 10.5, schema 10600, max nid 49356), and rsynced its files over the verified Oct 2 mirror. The Mac nightly backup reaches the wrong host via darwus_backup_key; its LaunchAgent is disabled (com.m4.drupalbeta.backup.plist.disabled). Do not re-enable it unchanged. - VERIFIED RESTORE: InMotion n790725_skyhawk restored from the pre-import backup (Oct 2 A2 lineage): max nid 49781, system schema 11401, 0 pending updates, cache rebuild OK, HTTP 200. Report /home/n790725/ai-reports/20261004T153409Z-inmotion-restore-pre-import.txt. - OPEN FILES CONTAMINATION: versus the Oct 2 A2 public-files manifest, 101 config-sync YAML files (files/config_*/sync, web-denied 403 by design) are wrong-source versions and 66 non-generated extras exist. The VPS mirror has no .git. Resolve in the final A2 sync. - DRUSH ON VPS: Drush child processes resolve php through PATH (8.2.33). Run Drush with a temporary PATH shim where php links to /usr/local/bin/php84-skyhawk (pattern: /home/n790725/skyhawk-migration/run_updb.sh). - a4skyhawk.us LIVE ON VPS: A record moved to the VPS in A2 cPanel Zone Editor (zone nameservers are A2 mysecurecloudhost; mail and MX left on A2). nginx vhosts conf.d/vhosts/a4skyhawk.us.conf and a4skyhawk.us-ssl.conf; Let's Encrypt via /root/.acme.sh, expires 2027-01-02, renewal reloads nginx. HTTPS 200 verified; Gene visually accepted the site. - EVIDENCE PIPE QUALIFIED 2026-10-04: ~/bin/ai-report on the Mac (personal GitHub key, alias github-dacp) and on the VPS (repository deploy key, alias github-dacp via ssh.github.com port 443 because the VPS blocks outbound port 22). Both qualified by fresh-clone read-back and SHA-256 match. Usage: ( commands ) 2>&1 | ~/bin/ai-report "task"; Gene pastes only the AI_REPORT line. Organization deploy keys were enabled by Gene for this. - VPS reports directory: /home/n790725/ai-reports (skyhawk-migration/diagnostics is root-owned). - EXECUTION LOCATION: every block must verify its own host/user and refuse with a plain message if run in the wrong place. The Mac is on a wired home connection. - CUTOVER DECISIONS (Gene 2026-10-04): move the whole site, all seven domains; email is NOT migrated (existing aliases compromised; new secure email later, self-hosted mail not recommended); lower A and www TTLs to 300 before cutover; backups to be managed from the new server. - CUTOVER PREREQUISITES OPEN: Drupal outbound mail relay (SMTP with SPF/DKIM) needed before cutover; DNS hosting is on Register4Less and does not need migration from A2; A2 to VPS SSH times out and VPS to A2 is refused (VPS blocks outbound 22 locally), so the final sync route is currently via the Mac. - AVAILABILITY: one unexplained SSH hang from the Mac on 2026-10-04 while the site loaded over cellular; cause not identified. External uptime monitor recommended before production cutover. - NEXT: final sync from A2 s19522 (freeze, darwus_beta dump, delta files including config sync), 100-most-recent-node A2 versus VPS comparison, then DNS cutover. ## VPS migration continuity - 2026-09-30 - VERIFIED: Mac SSH alias `Inmotion` now resolves to the VPS migration account `n790725` using the existing Mac Ed25519 key. - VERIFIED: passwordless key authentication succeeds from the Mac with `ssh -a Inmotion`; remote identity returned host `vps142898.inmotionhosting.com`, user `n790725`, uid 1001. - TRANSIENT OUTAGE 2026-09-30: the VPS dropped Gene's live root SSH session and temporarily stopped accepting `ssh -a Inmotion`. Connectivity later returned and the `Inmotion` alias was usable again. Treat this as an availability event to track; do not infer configuration rollback from the disconnect alone. The dropped root session means subsequent root-only inspection again requires a human-authenticated root login unless/until a qualified elevated executor path is established. - FOLLOW-UP 2026-09-30: a report intended as root-only CWP selector inspection actually executed as `n790725` (uid 1001), so protected CWP selector backend files and `/scripts/phpfpm_rebuild_user_conf` remained unreadable. This proves only that the report command executed under `n790725`; it does NOT prove Gene's separate live root session disconnected. Gene confirms the root session remained continuously open after the one documented outage. Root-only selector ownership remains unresolved until the inspection is run from that verified root prompt. - SUPERSEDED 2026-10-02: root public-key login is now qualified from Gene's Envy. The existing Envy `~/.ssh/id_rsa.pub` was added to `/root/.ssh/authorized_keys`; `ssh -o BatchMode=yes -l root Inmotion` returned `ROOT_KEY_AUTH_OK`, user `root`, and host `vps142898.inmotionhosting.com`. The `Inmotion` SSH alias remains keyed to `~/.ssh/id_rsa`; use `-l root Inmotion` for elevated key-authenticated work and the default alias user `n790725` for routine migration access. - AUTH CONTEXT 2026-09-30: `n790725` was provisioned by InMotion and Gene did not create a password for it. Do not assume `sudo -i` is usable from this account. For root escalation, use the InMotion AMP root credential path (Request Root Access / Get My Root Password) and `su root` from the existing `n790725` shell; do not guess among stale root-password candidates. - VERIFIED ROOT CONTEXT 2026-09-30: Gene successfully elevated the live VPS shell with `su root`; `id` returned uid 0 / gid 0. Root-only CWP selector inspection can now proceed from that same interactive shell. Do not disclose or persist the root password. - Preserve Gene's already-open root session until elevated migration work no longer needs it. Routine migration access should use `ssh -a Inmotion`; escalate only when required. - VERIFIED REPAIR 2026-10-02: the PHP 8.4 CLI/Composer PCRE blocker is repaired without changing global PCRE2. Evidence showed `/usr/local` PCRE2 10.39 was built without JIT while PHP 8.4 was configured with external PCRE and `/usr/local` pkg-config paths; system PCRE2 is 10.32. A private PCRE2 10.39 build with JIT was installed at `/opt/skyhawk/pcre2-10.39-jit`, and `/usr/local/bin/php84-skyhawk` scopes `LD_LIBRARY_PATH` to that private library. Verified: PHP 8.4.24 starts, `preg_match()` returns 1, PCRE reports 10.39 / Unicode 14.0.0 / JIT enabled, and the wrapper works as `n790725`. Composer 2.10.3 was installed and `/usr/local/bin/composer84-skyhawk` verified as root and `n790725`. Drupal `composer.json` validates and `composer check-platform-reqs --lock --no-dev` passes all production requirements for Drupal core-recommended 11.4.8. Do not replace/remove global PCRE2; use the scoped Skyhawk wrappers for CLI/Composer. The separate per-account PHP-FPM 8.4 assignment owner remains unresolved pending supported CWP/provider guidance. - VERIFIED: the migrated public-files tree is present under the VPS migration workspace at about 22 GB. The account web root remains essentially empty apart from the CWP placeholder page. - VERIFIED: the current CWP-generated temporary vhost for account `n790725` points to `/home/n790725/public_html` and still routes PHP through the PHP 8.2 FPM socket. HTTPS is not yet listening on the VPS test IP, and `a4skyhawk.us` still resolves to the old host, so no DNS or public cutover has occurred. - VERIFIED 2026-09-30: root-only CWP inspection showed `/scripts/phpfpm_rebuild_user_conf` is an obsolete test script that exits immediately and must not be used. The active `php_selector3` / PHP-FPM selector implementation is ionCube-encoded, and the `root_cwp.user` table has no PHP-version field. The per-account PHP-version persistence owner remains unresolved; generated vhosts must not be edited by hand while that owner can still be discovered. - VERIFIED 2026-09-30: root inspection of CWP rebuild candidates found no maintained account-level vhost/PHP-FPM rebuild CLI in `/scripts`; `/scripts/phpfpm_rebuild_user_conf` remains unusable test code. The live temporary Apache vhost directly contains the PHP 8.2 socket path, and the PHP 8.4 per-user pool is still absent. The next owner search must trace the literal FPM `SetHandler` template/generator rather than guess at a rebuild command. - VERIFIED 2026-09-30: the `php_selector3` / `phpfpm_selector` path is the global PHP-FPM version compiler/manager, not the per-account PHP-version assignment owner. Access logs show the prior 8.4 action called `loader_ajax.php?ajax=phpfpm_selector&acc=compile_php_vesion`, followed by compile-status polling. That explains why PHP 8.4 was built successfully without creating `n790725`'s 8.4 pool or changing its vhost. - SUPPORT ESCALATION 2026-09-30: Gene created a verified InMotion Technical Support ticket under Technical Support / Other asking for the supported CWP7pro per-account PHP-FPM 8.4 assignment method, whether CWP should generate the account pool/socket/vhost automatically, whether a supported CLI/API exists, confirmation of the scoped PHP 8.4 PCRE2 `/lib64` workaround, and whether the CWP root-admin Terminal is a supported uid-0 administration path. Further reverse-engineering of the opaque selector is paused pending support guidance. - TARGET LAYOUT CLARIFICATION 2026-10-02: mirror A2's Drupal structure. A2 project root is `/home/darwus/drupalbeta` with docroot `/home/darwus/drupalbeta/web`, explicitly not under `public_html`. The InMotion target is `/home/n790725/drupalbeta` with docroot `/home/n790725/drupalbeta/web`, colocated beside `/home/n790725/public_html`. `public_html` is not the Drupal deployment target and must remain separate unless Gene explicitly changes this architecture. - VERIFIED MIRROR ASSEMBLY 2026-10-02: the verified non-public staged tree was assembled server-side into `/home/n790725/drupalbeta`. The target contains 47,216 files excluding `web/error_log`, totals about 4.3 GB, and a checksum-mode rsync dry-run from `/home/n790725/skyhawk-migration/drupal-staged-clean/` to `/home/n790725/drupalbeta/` with `web/error_log` excluded returned `DIFF_LINES=0` / `DRUPAL_MIRROR_CHECKSUM_IDENTICAL`. `public_html` remains separate and untouched. - VERIFIED PUBLIC FILES REPAIR 2026-10-02: A2 `web/sites/default/files` has 58,783 files. The old InMotion migration copy had 34,547 files: 34,202 matched A2, 24,480 were missing, 101 mismatched, and 244 were extra/stale. A case-sensitive APFS staging volume on ArchiveSSD was used to preserve three case-colliding Linux filename pairs. The 24,581 missing/different paths were transferred and independently SHA-256 verified against A2, the 34,547-file InMotion tree was used as a local seed in `/home/n790725/drupalbeta/web/sites/default/files`, the 24,581 verified repair paths were applied, and the 244 proven extras were removed from the new mirror only. Final A2/InMotion public-files manifests each contain 58,783 files and are byte-identical with SHA-256 `c05e6f78f78efcd511be333e84a190b1a0ab0f8da3fe7d44edbe69d437999e6f`. - VERIFIED COMPLETE FILESYSTEM MIRROR 2026-10-02: whole-tree manifests for A2 `/home/darwus/drupalbeta` and InMotion `/home/n790725/drupalbeta`, excluding `.git` and mutable `web/error_log`, had zero hash mismatches and zero InMotion-only files. A2 had exactly three additional files, all verification artifacts created after the migration (`web/downloads/full-tree-manifest-20261002.tsv`, `web/downloads/public-files-manifest-20261002.tsv`, and its `.sha256`). After excluding those three post-migration evidence files, both normalized manifests contain 105,999 files and are byte-identical with SHA-256 `170342c8a61ba3552bfe24af50bee3eb2aed449e0ae0adf9a3666c36c663a440`. The mirrored Drupal filesystem at `/home/n790725/drupalbeta` is therefore VERIFIED complete relative to the migration source scope. `public_html` remains separate and untouched. - DATABASE IMPORT ATTEMPT 2026-10-02: the verified A2 database dump imported successfully into target `n790725_skyhawk`; the import produced 473 InnoDB tables, the dedicated target database account could read all 473 tables, and target Drupal settings were updated inside the transaction. Final verification failed because `vendor/bin/drush` was incorrectly passed to the PHP wrapper even though it is a shell launcher. The rollback restored `settings.php` to the A2 credentials, but later evidence proved the rollback did NOT remove the created `n790725_skyhawk` database or `n790725_skyhawk@localhost` account despite printing rollback begin/end markers. A second run correctly stopped at its clean-target guard with `EXISTING_DB=1` and `EXISTING_USER=1`. Treat the imported database as retained pending root-side verification; do not reimport or drop it blindly. NEXT database action: inspect the retained DB/user, verify 473 InnoDB tables, reset the dedicated DB-user password to a fresh secret, update target settings, and execute Drush normally with a temporary `php` shim resolving to `/usr/local/bin/php84-skyhawk`. - DATABASE SETTINGS EDIT DEFECT 2026-10-02: the adoption attempt verified that retained target `n790725_skyhawk` exists with 473 InnoDB tables and that the dedicated DB user can read all 473 tables. PHP 8.4 and Drush 13.8.0 also execute correctly through the temporary PHP shim. The remaining failure was caused by settings-edit logic that replaced the first documented/sample `database` assignment near line 80 rather than the live `$databases['default']['default']` block near line 799. Drush therefore still reported A2 credentials (`darwus_blade` / `darwus_beta`) and the live DB query failed. Rollback restored the live settings block, but the accidental documentation-sample edit remains and must be cleaned up. NEXT: edit only the live database block, rotate the dedicated password again, verify Drush sees `n790725_skyhawk`, then clean the sample comment. - DATABASE GATE CLOSED 2026-10-02: retained target database `n790725_skyhawk` and user `n790725_skyhawk@localhost` were finalized without reimport. Root verification found DB/user present, 473 tables, all InnoDB. Target `settings.php` was backed up and staged; staged file passed PHP 8.4 lint before mutation. Dedicated DB-user password was rotated without printing, staged settings were installed atomically, dedicated login returned 473 tables, and machine-readable Drush verification under PHP 8.4.24 returned `db-name=n790725_skyhawk`, `db-username=n790725_skyhawk`, `db-hostname=localhost`, `db-port=3306`, `php-version=8.4.24`. Drupal SQL query returned 473. Final settings mode is `n790725:n790725 444`. Evidence: `/home/n790725/skyhawk-migration/diagnostics/database-finalize-20261002T160144Z.txt`. Treat the database migration gate as CLOSED. - PHP-FPM 8.4 RUNTIME GATE CLOSED 2026-10-02: the `php-fpm84` systemd override was corrected from `LD_LIBRARY_PATH=/lib64` to the proven private PCRE2/JIT path `/opt/skyhawk/pcre2-10.39-jit/lib`. Live verification after restart showed `ACTIVE=active`, `ENV=LD_LIBRARY_PATH=/opt/skyhawk/pcre2-10.39-jit/lib`, nonzero `MAINPID=461047`, and `/opt/alt/php-fpm84/usr/sbin/php-fpm -tt` reported the PHP-FPM 8.4 configuration test successful. Treat the PHP-FPM 8.4 base runtime as restart-safe. NEXT: create and verify the `n790725` PHP-FPM 8.4 user pool and socket before changing Apache/nginx. - PHP-FPM 8.4 ACCOUNT POOL GATE CLOSED 2026-10-02: `/opt/alt/php-fpm84/usr/etc/php-fpm.d/users/n790725.conf` was created from the proven PHP 8.2 account-pool structure with only versioned socket/log paths changed. PHP-FPM 8.4 config test passed before reload (`POOL_CONFIG_TEST_RC=0`), reload returned 0, service remained active, `/opt/alt/php-fpm84/usr/var/sockets/n790725.sock` exists with group `nobody` and mode `660`, and final config test returned 0. Evidence: `/home/n790725/skyhawk-migration/diagnostics/phpfpm84-user-pool-20261002T162921Z.txt`. Treat the account PHP-FPM 8.4 pool/socket gate as CLOSED. - NEXT: the mirrored Drupal filesystem/database and the `n790725` PHP-FPM 8.4 pool/socket are complete and verified. Remaining migration work is the vhost switch to `/home/n790725/drupalbeta/web` and the PHP 8.4 socket, followed by local HTTP verification and then HTTPS/test-host runtime verification. Do not infer the account web runtime has moved until Apache/nginx configuration, reloads, and local request evidence all pass. - VERIFIED TRANSFER 2026-10-02: the A2 non-public Drupal project tree was transferred through a case-preserving tar archive after Mac directory staging exposed case-colliding Linux paths (`CSS`/`css`) that cannot be represented exactly on the Mac filesystem. The verified archive SHA-256 is `d71e2d78b69e602802c5d59188e0c61019ea2041958bacdc55aea2a95ab8ccbe`; it was copied to InMotion and independently re-hashed there before extraction. A clean extraction now lives at `/home/n790725/skyhawk-migration/drupal-staged-clean`. Independent A2/InMotion manifests, excluding `.git`, the separately transferred `web/sites/default/files`, and mutable `web/error_log`, contain 47,216 files and are byte-identical with manifest SHA-256 `49ef8e152bdd7b0839bdecba106aaf314ca0cc834e648fe81b295b1c508649bb`. The sole pre-exclusion difference was `web/error_log`. Preserve the older partial `/home/n790725/skyhawk-migration/drupal-staged` until cleanup is explicitly authorized. - PUBLIC FILES GAP 2026-10-02: the existing InMotion `/home/n790725/skyhawk-migration/files` tree is incomplete: 34,547 files / about 22 GB versus A2 `web/sites/default/files` at 58,783 files / about 23 GB. Do not assemble this existing tree into the staged Drupal site or treat it as verified. A2 also contains three case-colliding filename pairs under `darwsafolders/A4-docs-natops/NATOPS/a4-specific-parts/`, so ordinary case-insensitive Mac directory staging is unsafe. NEXT: use a case-sensitive local staging surface on ArchiveSSD with resumable rsync, then transfer to a fresh InMotion public-files candidate and verify count/hash before assembly. ## Operating facts (non-secret) - VPS administration path: AUTHORIZED BUT NOT YET QUALIFIED. Do not rely on it until end-to-end request, execution, result read-back, and verification have passed for the assigned executor. Provider-policy compliance is a hard gate. - Project root `/home/darwus/drupalbeta`; Drush `/home/darwus/drupalbeta/vendor/bin/drush --root=/home/darwus/drupalbeta/web`. - Commands are pasted at the A2 prompt; wrap each block in a subshell `( ... )` so a failure never logs Gene out. A2 has no `/dev/fd`: no bash process substitution. A2 throttles rapid SSH connections: wait about 5 minutes if refused. - A2 is a shared hosting server: no AI gets direct access, ever. Gene runs every A2 command. - HOSTS (Gene 2026-09-30): production skyhawk.org is served by s19522.use2.stableserver.net (the Envy ssh alias A2). mi3-ts4.a2hosting.com is a SEPARATE A2 Hosting account holding an older copy of drupalbeta (max node 49356; no ai-report); the Mac reached it with darwus_backup_key on a non-standard port. NEVER target mi3-ts4 for Skyhawk work. First line of every A2 block should confirm the host (hostname must start s19522). - Files move by `scp` from Windows (host alias `A2`); Gene's working folder is `C:\Users\genea\dacp-work\vma131`. - A2 transport (Gene 2026-09-28): never chain scp and ssh on one line; copy and connect are separate commands, each with -o ConnectTimeout=20; keep A2 connections per step to a minimum (backups: A2 writes the checksum beside the dump, one scp brings both down, compare on Windows, delete in the next A2 block). A2 is fragile until the hosting move. - Large outputs: `( commands ) 2>&1 | ~/bin/ai-report "task"` pushes a secret-scanned report to evidence/skyhawk/ in this repository; paste only its one-line result. - skyhawk.org Git remote is private (`github-skyhawk` identity, account geneatwell). The same identity pushes this DACP repo (clone on A2: `/home/darwus/dacp-repo`). Organization deploy keys are disabled. - Composer only via `bin/skyhawk-composer` (require or update, then functional check, then `finish`). Its pending marker is git-ignored. - Never pipe or `tail` a command that asks a question (`skyhawk-composer finish`, anything without `-y`): the prompt is hidden and Enter answers No. - Configuration: site-wide `config:import` fails validation because of orphaned configuration from old modules and themes. Apply structure through the entity API, then `drush config:export -y`, then commit only the expected files. - Backups before structural database work: dump to `/home/darwus/skyhawk_backups`, download to the Envy (`Desktop\ChatGPT\pre_update__\database.sql.gz`), verify SHA-256, then delete the server copy. - Styling: one global stylesheet `skyhawk_site_fixes/css/skyhawk-global.css` and its semantic vocabulary (skyhawk-focus, -feature, -context, -note, -reference; modifiers -navy, -marine, -joint, -heritage; skyhawk-focus-label). ## Active slice: Squadron CMS, VMA-131 test build **Last verified step:** Reunion photo actions styling VERIFIED 2026-09-30. `field_reunion_photos_link` and `field_reunion_upload_link` remain on reunion_event node 49466 with their established routes (`/reunions/2026/photos` and `/form/reunion-2026-photo-upload`). The single maintained global stylesheet `skyhawk_site_fixes/css/skyhawk-global.css` was rewritten coherently so the photo-action rules live inside the existing Reunion V2 section rather than as a stray appended block. skyhawk.org commit `f50d215b0b7f706060361c2c01e2ff752ee0c7ec`; AI report `20260930T164313Z-reunion-photo-css-integrate`. Independent public verification confirmed both links, the `skyhawk-reunion-links` group, and the new rules in the CSS aggregate actually served by the Reunion page. OPEN: finish the brisk/airy Reunion landing-page presentation; download and verify backup pre_reunion_landing.sql.gz (+ .sha256) to the Envy, then delete from A2; photo upload failure symptom still not captured. **State** - Content type `squadron`: identity, snapshot, story, people, featured story, aircraft, remember and research fields, plus the 14 detailed-record sections. Legacy body kept but hidden. Tabbed edit form (Field Group). - Display: Field Group panels using the global semantic classes inside the wrapper group_sq_page (`skyhawk-squadron-cms`, styled by SQUADRON FAMILY (CMS) in skyhawk-global.css); kickers use `skyhawk-focus-label`; the featured title is an h3; hero photo field `field_sq_hero_image`; jump bar EVA `eva_jump`. - Media: vocabulary `unit_collections` (Voices, Research, Visual record, Final Inspection, and the rest). Document and image media carry Unit, Collection, Heading, Order and Description. One media record per placement, named "Title · Collection"; files are never copied. VMA-131 has 14 placements. - View `squadron_collection` has three EVA displays (Voices, Research, Visual record), filtered by the page's unit and placed inside their panels. Links open in a new window. - Test node **49779**, unpublished, at `/squadrons/vma-131-test`. The live VMA-131 page, node 49417 at `/article-unit/vma131`, is unchanged until Brian Putney signs off. `/squadrons/vma-131-preview` redirects 301 to it. - VMA-131 assets: 356 images in `sites/default/files/vma131-preview/images` (with `manifest.tsv`; 1 placeholder photo pending from Brian). Interim section pages are nodes 49770–49777. - Modules added: field_group 4.0, eva 3.1, views_field_view 1.0. Core 11.4.8, webform 6.3.1 (security updates applied 2026-09-27). **Lessons kept from the old template:** thumbnails open the original in a new window, with a way back to the squadron page; Gabby's Histories is linked with the unit preselected; no large aircraft-assignment tables on the landing page; the complete Commanding Officers list is collapsible on the landing page; scrape the target unit first; never clone another unit's content. **Next steps (in order)** 1. Done: shared contribute block and Gabby link (skyhawk.org 87737c5). 2. Done: Skyhawks Assigned off the landing display (skyhawk.org 7ab995a). 3. Brian’s collections. DECIDED by Gene 2026-09-27: (a) collection sections as taxonomy terms (unit, collection, heading, order, Brian’s text as rich text), with document and photo placements pointing at their section; (b) Brian’s text sits at the top of each section (exact text/file interleaving not kept; explain to Brian). Then: backup (Rules), vocabulary and fields, sections and document placements, photo placements, collection View with test pages at /squadrons/vma-131-test/. About 220 documents, 356 photos, 60 sections. Progress: 3.1 done (skyhawk.org 0bec5cb); 3.2, 3.3 and 3.4 done: test collection pages at /squadrons-test/vma-131/{squadron-home, final-inspection, diamondback-stories, usmc-stories, us-military-stories, tails-of-aviation, aircraft-photos, squadron-mates, archives}. Explore menu and back links done (2421be1). at cutover the paths become /squadrons// and the interim nodes 49770-49777 retire. 3a. Done and visually accepted by Gene 2026-09-27 (skyhawk.org 7eafd3d): SQUADRON FAMILY (CMS) section in skyhawk-global.css, scoped to the outer Field Group wrapper group_sq_page (class skyhawk-squadron-cms): hero over the unit photo (new field field_sq_hero_image, Identity tab) with the unit patch small, navy snapshot band, jump bar (EVA eva_jump on squadron_actions, links only to bands with content), alternating section bands, gold kickers, two-column image and text, Explore as cards. Node 49779: hero shows the unit patch only; station and group patches are in the record. squadron.css stays legacy-only for the three old pages. 3b. Done 2026-09-27: designated reviewer account is active with CO role; Drupal access checks returned YES for node 49779 and related review nodes. The main CMS test node remains unpublished. 3c. Done 2026-09-27: review email sent with instructions to log in and review /squadrons/vma-131-test and its collection pages. Status: AWAITING REVIEWER RESPONSE. Brian's sign-off remains the gate for cutover. 4. Unit identity on the `skyhawk_units` term. PRINCIPLE (Gene 2026-09-28): the unit taxonomy is hidden metadata for automatic lists, filters, preselection and tagging; pages stand on their own content; designations are internal. VALUES WRITTEN 2026-09-28 (see last verified step); next: the class mechanism (decision open), then show identity on squadron pages. Read-only mapping/derivation completed 2026-09-27 for 213 sources, then Gene resolved all 15 exception rows. Final broad affiliation map: 137 U.S. Navy, 49 U.S. Marine Corps, 18 Foreign Military, 7 Civilian, 1 Joint Navy/Marine compendium, plus `/node/49222` as a reference-only source covering various civilian and non-U.S. operators. Specific clarifications include: A-4LLC -> Sky Resources; Discover Air -> Top Aces; FAGU -> Navy; NAF Willow Grove page -> Marine unit compendium at a Joint Reserve Base; HU-2 page -> evenly split Navy/Marine; NAS Chase Field -> Navy trainer facility; NAS Quonset Point -> Navy facility with Navy aircraft. Foreign rows remain further derived to specific service/operator where supported by the menu/page label (10 operators, 2 evaluation pages, 6 proposal pages). Remaining review rows: 0. Stable unit identity remains separate from menu placement and historical designation/lineage. Rollback gate verified 2026-09-28: `pre_unit_taxonomy_20260928T010141Z.sql.gz` is on the Envy and its SHA-256 exactly matches the A2 copy. Dump-growth analysis shows current serialized table-data sections at about 986 MB; `watchdog` is about 366 MB, while the rapid same-day growth is dominated by Drupal cache tables. The structure script was corrected so the new `field_unit_kind` is optional until terms are populated, then staged to A2 through the authorized file-transfer route with matching local/remote SHA-256. No Drupal mutation had been verified at the time of this record; next is A2 lint, live-owner precheck, entity-API structure apply, postcheck and config export. RESOLVED 2026-09-28: structure applied and committed (4003276). Mapping in Git 2026-09-28: projects/skyhawk/data/unit-taxonomy-reviewed-213.tsv (source of truth; derived-213 kept for provenance). Next: page-to-term match report, then backup, then term values. Former gate text: re-inspect the live A2/Drupal `skyhawk_units` structure and the A2 `skyhawk.org` Git working tree. Canonical Git does not independently prove that the preceding no-mutation statement still matches current live server state. Treat live mutation/config state as UNRESOLVED until read back; do not assume the structure is either applied or unapplied. 5. Parity check against node 49417, then Gene's review, Brian's sign-off and cutover. 6. Documentation: the Environment Reference's Squadron CMS section (a draft exists, shelved until 131 is done). **Open decisions (Gene):** choose the canonical Windows evidence folder; unit-identity tint CLOSED (Marines scarlet and gold, all others blue and gold; e844788); history: colours DECIDED by Gene 2026-09-28: U.S. Navy = blue and gold; U.S. Marine Corps = scarlet and gold; tint is an optional use of the hidden unit taxonomy; joint-use stations later); approve orphaned-configuration cleanup; delete node 49778; fix the journal PDF URI error in the logs. ## Active slice: Reunion system ### Reunion photo links — CLOSED 2026-09-30 - CLOSED: the 2026 Reunion page now exposes the two requested photo actions in a sensible grouped location: `View Reunion Photos` -> `/reunions/2026/photos` and `Upload Reunion Photos` -> `/form/reunion-2026-photo-upload`. - Independent public verification returned HTTP 200 for both destinations. The gallery is the live `reunion_2026_photos` View and the upload destination is the live `reunion_2026_photo_upload` Webform. - Independent managed-file smoke testing successfully uploaded a synthetic PNG through the public Webform and Drupal returned temporary FID 62444 with no form/upload error. The test stopped before final submission, so no junk public Media was created. - Existing accepted multi-photo Webform/Media bridge evidence remains valid. No current upload-path failure is reproduced. - Do not reopen this placement/upload objective without new contradictory evidence from a real contributor failure or a broken public endpoint. **Source continuity:** Gene authorized project-chat reconstruction on 2026-09-28. Relevant prior project chat: `Reunion Page Setup`. The durable statements below are cross-checked against current `skyhawk.org` source/config on `origin/main`; chat history is continuity evidence, not authority. **Verified working 2026 photo path** - Webform `reunion_2026_photo_upload` is open and accepts up to 20 images per submission. Contributor identity/person, public credit, rights consent and optional batch caption are shared across the batch. - `skyhawk_gallery` marker `SKYHAWK_REUNION_WEBFORM_MEDIA_BRIDGE_V1` converts every submitted FID into exactly one `skyhawk_contributed_photo` Media entity and is idempotent by `field_media_image.target_id`. - Current bridge binds the 2026 Reunion Event directly to node 49466. Media carries Reunion Event, Reunion Person, public credit, caption and rights consent. - Acceptance already proved one six-photo submission persisted all six FIDs and mapped them one-to-one to Media, followed by a fresh successful multi-photo submission. This architecture is accepted reusable Reunion infrastructure; before reuse for another Reunion, resolve the event context instead of cloning the hard-coded 2026 event ID. - Public gallery View `reunion_2026_photos` is at `/reunions/2026/photos`, 30 items/page, newest first, filtered to published contributed-photo Media for Event 49466. Detail View `reunion_2026_photo_detail` serves `/reunions/2026/photos/{mid}`. - Do not replace this working Webform/Media bridge with the older token-upload path merely because token-era Reunion classes/routes remain in the codebase. **Historical production provenance (sanitized)** - A read-only production baseline captured 2026-09-14 exists privately on the Envy/Drive as `derived/reunion_2026_production_baseline_20260914T025036Z.json` with matching SHA-256 sidecar. The raw file is NOT suitable for public Git because it contains credentials and member-level data. - That baseline proves the Reunion system was already materially in production by 2026-09-14: 2 `reunion_event` nodes, 150 `reunion_person` nodes, 150 `reunion_attendance` nodes, 7 contributed-photo Media records, and 7 submissions to `reunion_2026_photo_upload` at capture time. Treat those counts as historical evidence only, not current counts. - The same baseline showed enabled menu entry points for Reunions, Submit a Reunion, My Reunion Events, Request a Reunion, 2026 Reunion, Reunion Photos and Upload Photos. This establishes that the newer Ready Room/request surfaces were not merely dead source files by that date, while still requiring current live reinspection before mutation. - Event 49466 was already the published 2026 Reunion hub with registration/hotel links, Reunion documents, photo-gallery/upload links and durable post-event wording; its 2026 photo/gallery role therefore predates the later multi-photo bridge acceptance. **Current Reunion-management direction** - Authenticated Ready Room routes exist at `/ready-room/reunions`, `/ready-room/reunion/{node}`, `/ready-room/reunion/{node}/newsletter` and `/ready-room/reunions/request`. - Gene decision 2026-09-28: each Reunion has at most two human participants in the authority model: (1) one accountable current Skyhawk Association member, represented by the `reunion_event` owner UID, and (2) at most one optional Worker Bee who may or may not be a member and is authorized only for that one Reunion. There is no permanent third continuity-contact participant. - The accountable member may do all work personally or appoint/revoke the Worker Bee. The Worker Bee never becomes the accountable owner merely by doing the work. If the accountable member later becomes unavailable, normal Association/Drupal administration may reassign ownership to another verified member. - LIVE 2026-09-28, skyhawk.org `cc8b5c4`: `ReunionReadyRoomController` now enforces scoped Reunion management as current `authorized_user` owner UID OR the one assigned `field_reunion_worker` UID. Owner eligibility remains member-gated; a Worker Bee may be a nonmember. No global reunion-event edit permission or administrator bypass was added. - KISS field model: keep owner identity in Drupal's existing node author/UID; add only one optional single-value user-reference field for the Worker Bee. Do not add a duplicate owner field. - `ReunionRequestForm` marker `SKYHAWK_REUNION_SOURCE_INTAKE_V1` is the newer self-service intake direction: an active authenticated member may upload one source document or paste source text; Drupal preserves the source, creates an unpublished `reunion_event` draft owned by that account, records source provenance/hash in the revision log, verifies persistence, creates no token and activates no authority. - Durable authority is account-based, not token-based. The Worker Bee should be a normal Drupal identity whose email control is verified using Drupal core account creation/one-time-login behavior; assignment to one Reunion grants the scoped management authority. Token/verification links may establish identity during transition but are not durable Reunion authority. - Transitional membership rule, Gene decision 2026-09-28: the Secretary's current membership roster remains the eventual authoritative source for current Association membership, but its delayed availability does not block Reunion implementation. Pending reconciliation against that roster, the existing Drupal user population is accepted as the current dues-paying member baseline because Drupal accounts have historically been issued only to dues-paying members. `authorized_user` is the intended Drupal member-authorization marker to normalize against that existing population. This is a temporary operational proxy, not a replacement for the Secretary's roster. New nonmember Worker Bee accounts must not receive `authorized_user` merely because they can authenticate. - DONE 2026-09-28, skyhawk.org `cc8b5c4`: the built-in Drupal `Authenticated User` role was reduced to the verified universal logged-in baseline, member-only capabilities were moved/ensured on `authorized_user`, and the accepted pre-Worker-Bee active account population was normalized to `authorized_user`. Institutional powers remain on the narrower existing officer/admin roles. Existing `Reunion Staff` is not used for Worker Bee authority. - LIVE CUTOVER 2026-09-28, skyhawk.org `cc8b5c4`: the optional single-value user-reference `field_reunion_worker` now exists on `reunion_event`, remains hidden from the generic node edit form, and the owner-only Worker Bee assignment route/source is deployed. A2 PHP lint, cache rebuild, role/field/member-gate verification, Git commit/push, remote SHA read-back, and committed runtime verification all passed. No Worker Bee account has yet been created or assigned; end-to-end assignment/revocation/replacement acceptance remains pending. Evidence: `evidence/skyhawk/20260928-reunion-member-worker-cutover.txt`. - SOURCE CORRECTION 2026-09-29, skyhawk.org `f9a54901e0257581dc0fcb63c4b03485e52288de`: `ReunionWorkerForm` now verifies Drupal 11.4 `_user_mail_notify('register_admin_created', ...)` using its actual boolean return contract instead of incorrectly treating the return value as a mail-result array. A2 lint, commit/push and remote read-back completed successfully. Prior mail-path failure classifications generated from the bad array assumption are invalid as transport evidence and must not be used to claim mail failure. - WORKER EMAIL-CONTROL ACCEPTANCE 2026-09-29: the controlled test Worker Bee received Drupal account-created mail and successfully used a one-time-login link after CLI mail generation was run with the explicit production URI `https://skyhawk.org`. Earlier CLI-generated links used Drush's default request host and were unusable. Authentication mechanics are therefore proven through mailbox control and successful login for the test account. A separate UX defect remains: Drupal's stock login/one-time-link error/help messaging is too technical and unhelpful for ordinary members and Worker Bees, so authentication UX should be improved without replacing Drupal core authentication. - AUTH UX VOICE DECISION 2026-09-29: login, password-reset, one-time-link, and related authentication guidance should use clear plain language with light A-4 / Naval Aviation humor appropriate to the Skyhawk Association. Humor must never obscure the corrective action. Example approved direction for a normal login failure: “We couldn't sign you in with those credentials, but we did sign you up for the midnight watch. Check the creds or use ‘Reset your password’ below.” - AUTH UX IMPLEMENTED 2026-09-29, skyhawk.org `d8c843ba6e6c6d7d691f0bcb617462b05485ef70`: `skyhawk_site_fixes` now provides presentation-only Naval Aviation authentication guidance for normal login, password reset, and one-time-login flows while leaving Drupal core authentication, flood control, tokens, password handling, privacy behavior, and account state untouched. Installed-core ownership inspection passed before mutation; PHP lint, cache rebuild, runtime read-back of the custom messages/form text, Git commit/push, remote SHA read-back, and final lint/cache rebuild all passed. Human browser acceptance of the actual wrong-credentials, password-reset, and expired/used-link surfaces remains the next UX gate. - AUTH UX ACCEPTANCE STATUS 2026-09-29: OPEN / NOT ACCEPTED. Browser testing proved a fresh `/user/login` does not show failure guidance before submission, while a failed login does show the custom Paddles-oriented failure text. Gene rejected the current combined/layout presentation as still wrong. Desired failed-login presentation is two distinct pieces: `Paddles sent you around. Watch the ball next time around!` plus `We couldn't sign you in with those credentials. Check the creds or use Reset your password.` where `Reset your password` is the link and ends the sentence; do not append `below`. Preserve Drupal's single generic authentication-failure semantics so unknown-user and wrong-password cases remain indistinguishable. Subsequent attempts to split the presentation were not verified/accepted; one heredoc attempt was aborted with Ctrl-C before execution, so do not infer its mutation state. Repeated manual failure testing triggered Drupal flood control after more than five attempts, producing the stock `Login failed` temporary-block page; Gene considers that page bland but explicitly does not want this slice widened tonight. Before any further edit, inspect live `skyhawk_site_fixes.module`, live Git HEAD/status, and actual browser behavior. Keep core authentication, flood control, privacy/account-enumeration protection, tokens, and password handling untouched. - AUTH UX MESSAGE MAP (Gene 2026-09-29; code skyhawk.org 54f67f1; BROWSER ACCEPTANCE PENDING): /user/login before submit = Password field description "Passwords are case-sensitive. Caps Lock has ruined more approaches than anyone cares to admit." (kept). After a failed login (unknown user and wrong password stay indistinguishable) = red error "Push Tanker, watch the ball on your next approach." plus separate plain guidance "We couldn't sign you in with those credentials. Check the creds or use [Reset your password]." (link ends the sentence; no "below"). Also live: user_pass help ("Need new credentials?..."), user_pass_reset help ("First time aboard?...", button "Check in"), expired-link rewording ("That launch window has closed..."). Flood page out of scope. Login UX remains the active unfinished slice. - 403/404 UX ACCEPTED 2026-09-29: Drupal-owned Basic pages are live and wired through `system.site` as the real 403 and 404 handlers at `/access-denied` and `/page-not-found`. Gene edited the page text and added photos in Drupal, then browser-tested the actual error routes and accepted both as good to go. These pages are now normal Drupal content and should be maintained through Drupal rather than custom PHP. - LOGIN UX ROOT CAUSE 2026-09-29: skyhawk.org commit `9c51f8aa39d9c311b999c6ee24712a105993bd65` is NOT browser-accepted. It successfully removed the Username field-level error styling, but `#disable_inline_form_errors = TRUE` caused Drupal core's parent `FormErrorHandler` to send the remaining form error to Messenger; Bootstrap Barrio is explicitly configured with `bootstrap_barrio_messages_widget: toasts`, so the desired `Push Tanker...` text appeared as the upper-right `Error message` toast. This was a control-application/ownership failure: the prior patch targeted Inline Form Errors without resolving the full render owner chain. Verified route now is `UserLoginForm validation -> form_error_handler -> Messenger -> bootstrap_barrio status messages -> Toasts`. Next repair must preserve a form error so submission remains blocked, keep it off Username, render the red headline plus plain recovery guidance inside the form, and suppress only that exact failed-login Messenger message from the status-message output on `user.login`. Do not globally change Barrio's toast setting or disturb other site messages. - `ReunionNewsletterUpdateForm` marker `SKYHAWK_REUNION_READY_ROOM_UPDATE_V1` is presently an acceptance fixture limited to Event 49464 and its authenticated owner. It preserves newsletter history, verifies private-to-public copy/hash/persistence and HTTP retrieval, and explicitly labels the general current-member gate as deferred. Do not generalize that fixture by assumption. - Older token-era routes/forms still exist: `/community/event-submission/{token}`, `/reunion/verify/{token}`, `/reunion/manage/{token}` and the token admin. They are transitional only and are to be retired in toto after the account-based owner/Worker-Bee path is proven. **Reunion next steps** 1. DONE 2026-09-28 (report 20260928T155448Z-reunion-live-reinspection): all 9 Reunion main-menu links enabled (Reunions, Submit a Reunion /node/49349, My Reunion Events, Request a Reunion, 2026 Reunion, Reunion Photos, Upload Photos, Ready Room x2). Events: 49466 published (2026 hub), 49464 unpublished; 150 persons, 150 attendance. Photo webform open, 29 submissions, 57 contributed-photo media. Ready Room routes 403 for anonymous (correct). 2. DONE 2026-09-28: scalable Reunion front door applied and independently read back from public /reunions. Node 49769 now leads with the general Reunion identity and planning actions. Drupal View reunion_index supplies Current & Upcoming and Reunion Archive blocks. Optional `field_registration_link` is an outbound organizer/provider link; Skyhawk.org is not the registration processor. Follow-up title/date defects are resolved (evidence/skyhawk/20260928-reunion-view-display-fix.txt; skyhawk.org 736bce1). 3. DONE 2026-09-28: legacy token compatibility restored and independently verified (evidence/skyhawk/20260928-reunion-legacy-token-compatibility.txt; skyhawk.org d5c9688). The actual stored historical upload token returns HTTP 200; invalid upload and manage tokens return 404; invalid verify token returns 302. No token value is recorded. Token-format assumptions are removed; exact `hash_equals()` comparison to Drupal state is retained. Legacy token machinery remains transitional only pending account-based owner/Worker-Bee replacement. 4. DONE 2026-09-28: live role/account audit completed, real admin authority was preserved, the built-in `Authenticated User` role was reduced to the safe baseline, and the accepted pre-Worker-Bee active population was normalized to `authorized_user` in skyhawk.org `cc8b5c4`. 5. DONE THROUGH LIVE CUTOVER 2026-09-28: skyhawk.org `cc8b5c4` deployed the safe Authenticated baseline, member normalization, `field_reunion_worker`, current-member owner gate, owner-or-worker Ready Room access, and owner-only Worker Bee assignment surface. End-to-end Worker Bee account/assignment/revocation/replacement/one-Reunion acceptance remains the next gate. 6. APPLIED 2026-09-28: the Secretary's membership roster remains the eventual authoritative membership source and reconciliation is deferred until supplied. The accepted pre-Worker-Bee Drupal account population has now been normalized to the transitional `authorized_user` member-authorization role. New nonmember Worker Bee accounts must remain outside `authorized_user`. 7. Use Drupal core administrator-created-account / one-time-login email flow to establish Worker Bee account/email control; do not invent a second authentication mechanism. Source correction `f9a5490` fixed the Worker Bee form's bad `_user_mail_notify()` return-value verification; determine the actual state of the already-created test Worker Bee account/mail before sending any further account-created notification. 8. Prove owner and Worker Bee end-to-end, including replacement/revocation and one-event-only access. Then retire token routes, token admin, token fields/storage, token controllers/forms/classes, and the remaining node-body link to the token path in one controlled removal. 9. Preserve the accepted 2026 multi-photo Webform/Media architecture. Generalize only the hard-coded Event 49466 binding when a real second-Reunion use case requires it. 10. Keep Reunion work separate from VMA-131/Squadron CMS review; neither is a prerequisite for the other. **Half-done:** the safe Authenticated baseline, transitional member normalization, scoped Worker Bee field, member-only accountable-owner gate and owner-or-worker Ready Room source are now live and committed. Remaining Reunion activation work is end-to-end Worker Bee account/assignment/revocation/replacement/one-Reunion acceptance, followed by controlled retirement of the superseded Reunion token machinery. Secretary-roster reconciliation remains deferred and is not an activation blocker. The 2026 photo upload remains accepted working infrastructure. ## Previous LOST-D (Drupal node 2479, verbatim at migration, 2026-09-27T14:26Z) ``` LOST-D Current implementation slice: Journal modernization. Raven-derived article metadata is already live as 534 skyhawk_association_journal_inde records covering Summer 2004 through Winter 2019. Active work is to create maintainable procedures for future Journal uploads and separately complete article metadata for Journals from 1995 through the second Journal of 2004. For the Raven-indexed historical period, do not rediscover or overwrite existing title, author, issue, year, journal number, page, category, record, or PDF-access metadata merely because a Journal PDF is processed again. The existing Drupal article-index records are the baseline unless a reviewed correction is accepted. Skyhawk Working Rules - authoritative human/AI operating contract. Intentionally not required in the Blade navigation menu. Generic Intake System - current state and specification for reusable file intake. Drupal Environment Reference - durable environment facts when germane. How LOST-D Is Used LOST-D contains active human-facing work and navigation. Project references contain current project truth. The Rules govern how work is performed. Completed or superseded debugging history does not remain in the active list merely because it once consumed oxygen. Legacy LOST-D content The material below is preserved from the prior LOST-D page for historical context. Its presence here does not make completed, obsolete, or superseded items active work. h1 { color: blue; font-size: 40px; margin: 0px; text-align: center; } h6 { color: #1275d1; font-size: 20px; margin: 0px; background: #f5f33c; text-align: center; } Items with dashes through text indicate total or partial completion. Convert site to Composer Compliance Perform all Updates via Composer-Frequent and ongoing. Create Menu entry for Gabby's Histories. Clean data from Gabby's gigantic spreadsheet to reduce errors. Uploaded! Create Menu entry for Journal Index. Clean data from Raven's Excel file for upload to site to reduce errors and create proper data format for uploading to site. Create new procedures for uploading future Journals to website and share with Hide. Association Photos. Protect photos with lettering and watermarking. Align photos so they don't look like raggedy-assed Marines. I agree with Jigger on this one. Solicit member recommendations for both. In progress. Learn Atom Editor-Ongoing Forever. Disable second database and Views Database Connector to increase performance of the site. Create new page for YouTube Videos. Create new user fields to allow for all members to input their info and approve or disapprove of receiving emails from other dues paying members. Create a page for new members to register online. This will have a verification associated with it to reduce robots from spamming the site. Use Board Members as Guinea Pigs to test methods in order to reduce member confusion once this new information is uploaded and will then require member verification. Create pages to allow logged in members to directly email other members without divulging the email of the person receiving the e-mail. Rearrange all Staff member communications to eliminate e-mail trolling. Need somebody to revisit all Journals from 1995 until the second Journal in 2004 and create a spreadsheet with Authors, Article names, etc to be included here. Create this page. Update when necessary to add member recommendations. Your Desire Here? Items with dashes through text indicate total or partial completion. GitHub / Composer Infrastructure Closeout The private Skyhawk-Association/skyhawk.org GitHub repository contains the accepted Skyhawk reconstruction architecture. The A2 SSH identity is proven against the repository and local main is verified against remote origin/main. The live Drupal configuration is authoritative and has been exported to the tracked configuration sync tree with zero active-vs-sync drift. Normal mutating dependency maintenance uses /home/darwus/drupalbeta/bin/skyhawk-composer. The interactive user-level Composer guard warns before direct update, require, remove, or install and defaults to No. The Composer wrapper uses explicit proven PHP, Composer, Drush, Drupal-root, Git and project-root paths and does not depend on shell aliases or current directory. Mutating Composer maintenance is not complete until functional acceptance, zero Drupal configuration drift, safety validation, Git commit/push, and exact local/remote parity. This infrastructure workstream is closed. Reopen only if new evidence proves a defect or a future maintenance requirement changes. ``` - SUPPORT CHECK 2026-10-02: Gmail search found no substantive InMotion support response newer than Ryan's 2026-09-30 message offering to create a deeper-investigation ticket. No supported per-account CWP PHP-FPM/vhost assignment method has been supplied by the provider. Controlled local ownership is therefore proceeding from verified server state with backups, config tests, reload verification, and rollback capability. - VHOST HTTP TEST DIAGNOSIS 2026-10-02: Apache/nginx vhost switch to `/home/n790725/drupalbeta/web` and PHP-FPM 8.4 is active and both configs reloaded successfully. Initial 403 was caused by `drupalbeta`/`web` traversal group mismatch; both now mirror CWP's `n790725:nobody 750` model. After that repair, direct Apache returned `HTTP 400` with `X-Powered-By: PHP/8.4.24` and body `The provided host name is not valid for this server.` Settings inspection proved `$settings['trusted_host_patterns']` allows the production Skyhawk domains but not `1790723478a62e50832643ebc3.temporary.link`. NEXT: add only the temporary hostname to trusted hosts, lint settings, then verify Apache and nginx requests. - TRUSTED-HOST EDIT DEFECT 2026-10-02: the temporary hostname was inserted into the commented documentation example near line 701 rather than the live `$settings['trusted_host_patterns']` array near line 724. PHP lint passed because the bad insertion remained valid commented/example text, but Drupal continued returning `400 The provided host name is not valid for this server.` NEXT: remove the stray example insertion, add `^1790723478a62e50832643ebc3\.temporary\.link$` to the live trusted-host array only, lint, then retest direct Apache and nginx. - TRUSTED-HOST EDIT ROOT CAUSE 2026-10-02: repeated failed edits were caused by two separate control defects: (1) earlier regexes matched Drupal's commented documentation example because they were not anchored to a real PHP assignment; (2) cleanup literals used over-escaped backslashes, so the stray line in the example was never removed. A disposable-copy test on the exact current `settings.php` proved a simpler line-oriented method: remove every line containing the temporary host token, locate the one exact live line `$settings['trusted_host_patterns'] = [`, and insert one canonical pattern line immediately after it. Diff showed only the intended deletion from the example and insertion into the live array. - HTTP RUNTIME GATE CLOSED 2026-10-02: temporary-host trusted-host repair succeeded using the proven line-oriented editor. Independent report read-back showed `LIVE_ASSIGNMENT_COUNT=1`, `TEMP_HOST_COUNT=1`, `TEMP_HOST_LINE=725`, `EDIT_RC=0`, `TOTAL_TEMP_HOST_OCCURRENCES=1`, `PHP_LINT_RC=0`, direct Apache `APACHE_HTTP_STATUS=200`, nginx front `FRONT_HTTP_STATUS=200`, login `LOGIN_HTTP_STATUS=200`, and `DRUPAL_LOGIN_BODY_RECOGNIZED=YES`. Evidence: `/home/n790725/skyhawk-migration/diagnostics/trusted-host-line-repair-20261002T192322Z.txt`. Treat nginx -> Apache -> PHP-FPM 8.4 -> Drupal -> migrated MariaDB over direct VPS HTTP routing as VERIFIED. - TEMPORARY-HOST ROUTE RE-PLUMB 2026-10-02: the InMotion temporary hostname `1790723478a62e50832643ebc3.temporary.link` resolves publicly to `173.247.245.156`, while the target VPS owns `173.231.242.84`. Unique HTTP and HTTPS requests through the public temporary hostname did not appear in any local nginx/Apache log on the VPS. A direct request to `173.231.242.84` with the temporary hostname supplied as the Host header reached nginx -> Apache -> PHP-FPM 8.4 -> Drupal successfully and returned Drupal HTTP 200. The public temporary-host endpoint is therefore not a valid test route for this VPS. Evidence: `evidence/skyhawk/20261003T011614Z-temporary-host-route-trace-v2.txt`, `evidence/skyhawk/20261003T011404Z-https-upstream-owner-diagnostic.txt`. - HTTPS RUNTIME GATE CLOSED 2026-10-02: `vps142898.inmotionhosting.com` resolves directly to the target VPS `173.231.242.84`. Its existing Let's Encrypt certificate and private key were verified to match, nginx SSL support and firewall TCP/443 access were present, and port 443 was initially unbound. A narrow nginx TLS vhost was created at `/etc/nginx/conf.d/vhosts/vps142898.inmotionhosting.com-ssl.conf`, bound to `173.231.242.84:443`, using the existing certificate under `/root/.acme.sh/cwp_certs/vps142898.inmotionhosting.com/`. Because Drupal does not trust the VPS hostname directly, this test vhost preserves the externally validated TLS hostname while proxying the already-trusted temporary hostname to Apache/Drupal. Independent Windows HTTPS verification without certificate bypass returned HTTP 200 for both `/` and `/user/login`, with `X-Powered-By: PHP/8.4.24`, `X-Generator: Drupal 11`, and Drupal login content recognized. Evidence: `evidence/skyhawk/20261003T012035Z-vps-hostname-tls-readiness.txt`, `evidence/skyhawk/20261003T012151Z-vps-https-bind-and-verify.txt`. Treat external HTTPS -> nginx -> Apache -> PHP-FPM 8.4 -> Drupal -> migrated MariaDB runtime as VERIFIED. NEXT: production DNS/cutover planning is the remaining boundary; do not change production DNS until Gene explicitly selects the cutover point. - PRODUCTION HTTP VHOST STAGED 2026-10-02: An explicit pre-cutover nginx HTTP vhost for skyhawk.org and www.skyhawk.org is installed on the InMotion VPS at /etc/nginx/conf.d/vhosts/skyhawk.org-precutover.conf. It preserves the production Host header to Apache/Drupal, provides the ACME HTTP challenge route, and was verified with HTTP 200 for the front page, www, and /user/login. ACME challenge routing was independently exercised through nginx. Production DNS remained unchanged and still points away from the VPS. Evidence: evidence/skyhawk/20261003T014434Z-production-http-vhost-stage.txt. NEXT: after the A2 full-account backup completes, inspect its Mailman state; production DNS remains a Gene-controlled cutover boundary. - CUTOVER EXECUTION 2026-10-04 ~21:56Z: final frozen real-A2 dump `cutover-darwus_beta-20261004T211918Z.sql.gz.gz` is staged on InMotion and its source hash had already been verified on ArchiveSSD. A fresh pre-cutover rollback dump of `n790725_skyhawk` was created on InMotion at `/home/n790725/skyhawk-migration/pre-cutover-n790725_skyhawk-20261004T215602Z.sql.gz`; gzip integrity passed, SHA-256 `ba7a3641125deeaa1f7f52b521c183e067132afe0f76e3e150396c96ff584239`, size 98,504,944 bytes. The required download of that rollback to ArchiveSSD has NOT completed: direct Mac scp disconnected and rsync/ssh then timed out; the alternate Envy scp route also failed. No database replacement was attempted after this gate failed. Current InMotion database remains `n790725_skyhawk` with 47,358 nodes / max nid 49781, 0 pending Drupal updates, maintenance 0. NEXT: when SSH transport to InMotion recovers, download and hash-verify the rollback on ArchiveSSD, then import the already-staged frozen A2 dump and continue the cutover. Do not recreate the rollback or re-upload the final A2 dump unless new evidence requires it.