Fleet changelogs · dev.ecs0.net
rdmsm4x-changelog-20260830-1235-desktop-ticket-ingest-and-first-real-publish

rdmsm4x — Desktop ticket ingest, record repair, and first real publish to dev.ecs0.net

When: 2026-08-30 12:23–12:35 EDT · Host: rdmsm4x · Author: claude@rdmsm4x Scope: rdmsm4x only. ~/Desktop, ~/dev/issues, ~/dev/sites/dev.ecs0.net.

Summary

Organized 92 loose ticket reports off the Desktop into ~/Desktop/issues/, repaired four ambiguous ticket records, fixed three exporter defects, and discovered that no ticket had ever actually been published to dev.ecs0.net — the export target was not part of the website. /issues/ now returns 200 with all 85 tickets.

What changed

1. Desktop organized

2. Fixtures kept out of the record

18 Desktop reports were QA fixtures ("CLI Test Feature", "Test rfc", "Test ui", "Test doc", "CHALLENGER-TEST", empty titles) from the same family a prior session archived. They were not ingested. Moved to ~/dev/issues/archive/test-fixtures-20260830/html-desktop/. Also archived: fleet-lifecycle-dashboard/ (316 mixed real+fixture exports) and a byte-identical duplicate of the audit report.

3. Record repair — four ambiguous tickets

ISSUE-20260830-26 reported four tickets simultaneously open and resolved and said choosing a copy needed project judgement. Resolved per ticket:

4. bin/ticket fixes (backup: bin/ticket.bak-20260830)

5. ISSUE-20260830-34 — the publish target was never served

bin/ticket exported to sites/dev.ecs0.net/issues/. That directory is not part of the website: infra/compose.yaml:37 mounts ../wiki as the nginx docroot, and build_site.py writes only into wiki/. There was no wiki/issues at all — never tracked in git, absent from the source manifest. Every ticket page for days was written somewhere unreachable while the CLI printed a success line naming the path.

This corrects ISSUE-20260830-27's claim that 268 fixture pages "were live on the real site." They were never served; the fixture exposure was not public.

Fixed: SITES_ISSUES_DIR repointed to wiki/issues; 85 pages exported; the orphan tree archived to issues/archive/never-served-sites-issues-20260830.

6. ISSUE-20260830-35 — my own fix had a data-loss path (peer-caught)

A peer probed the ISSUE-26 fix and found it unlinked every stray open/ copy unconditionally. Content existing only in a stray was destroyed — precisely the content I had hand-merged for ISSUE-20260829-02/03/04 one commit earlier. The commit message documented the merge while the code discarded.

Fixed: a stray byte-identical to the resolved record is removed (nothing can be lost); one that differs is moved to archive/superseded-open-copies/<slug>-<ts>.md with a warning naming the file. open/ is still cleared, so status stays unambiguous — that only needs a move, not a delete. Added the missing import shutil.

Verified by replicating the reporter's probe: the unique marker now survives in 1 file instead of 0, open/ empty, one resolved copy.

Verification

curl -H 'Host: dev.ecs0.net' http://127.0.0.1:8788/issues/                    -> 200
curl -H 'Host: dev.ecs0.net' .../issues/ISSUE-20260830-34.html                -> 200
curl -H 'Host: dev.ecs0.net' .../issues/EPIC-20260830-03.html                 -> 200
served index lists 85 ticket IDs
store(87) == published site(87) == ~/Desktop/issues/tickets(87); 0 ambiguous
tickets in both open/ and resolved/: 0

Resolve fixes proven in a HOME-jailed probe store (canonical untouched): created a ticket, renamed its open/ file to a different slug without reindexing, ran resolve -> "(index was stale; adopted ...)", open/ empty, exactly one resolved copy.

Verification trap: curl 127.0.0.1:8788 without a Host header hits the gateway's catch-all (server_name _; location / { return 404; }) and 404s every path. Public URLs return 302 to Cloudflare Access before the origin is consulted. Both mask real origin errors — always use -H 'Host: dev.ecs0.net'.

Backups / undo

Open for the owner