S4 (a1): the media engine — VOICE templates, /desk, Ghost drafts
4a VOICE v1.1 committed (board start); lint is EXECUTABLE — banned list + no-exclamation law enforced in the engine (throws in test, drops in prod) and locked by tests. Curly-apostrophe variants covered. 4b mediaEngine: deterministic templates (MORNING WIRE, SIGNAL, STREAK WATCH, THE SETTLE, RECEIPTS, ARCHETYPE WATCH, LINE DISPATCH) filled ONLY from snapshot/ledger/streaks JSON. Record percentages never render under n>=20 (counts + 'Record building' below). Stark layer = curated committed library (content/stark-lines.json), day-rotated selection — selected, never generated. 4c /desk (founder-only: requireAuth + DESK_OWNERS email allowlist, deny-by-default): all formats as text + <=280-char pre-segmented tweets with per-tweet copy buttons + char counts, wire/numbers-only variants, DATA BRIEF block (structured day numbers) with copy-for-claude.ai. ntfy ping after the day's first snapshot: 'Desk pack ready'. 4d ghostPublisher: DRAFTS ONLY (status:'draft' test-locked), env-gated no-op, HS256 JWT via node crypto (zero new deps). POST /api/internal/ghost/drafts saves slate preview + settle drafts. Nothing anywhere auto-posts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -180,6 +180,25 @@ router.post('/outcomes/all', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/internal/ghost/drafts (Session 63 / A1-S4d) — assemble today's
|
||||
* desk pack and save the slate-preview + settle drafts to Ghost. DRAFTS
|
||||
* ONLY; Kev publishes from the Ghost admin. Env-gated no-op without Ghost.
|
||||
*/
|
||||
router.post('/ghost/drafts', async (req, res) => {
|
||||
try {
|
||||
const { assembleDeskPack } = require('../services/deskService');
|
||||
const ghost = require('../services/ghostPublisher');
|
||||
const pack = await assembleDeskPack();
|
||||
const result = await ghost.saveDailyDrafts(pack);
|
||||
return res.json({ ok: result.ok, result });
|
||||
} catch (err) {
|
||||
const message = err && err.message ? err.message : String(err);
|
||||
console.error('[internal/ghost/drafts] failed:', message);
|
||||
return res.status(500).json({ ok: false, error: message });
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* POST /api/internal/refresh/all (Session 60, Phase 2.5) — manual intraday
|
||||
* odds-only refresh: STEAM/VALUE movement, public revisions, closing
|
||||
|
||||
Reference in New Issue
Block a user