# Open issues

Refreshed 2026-09-21 after the four-layer overhaul. Ordered by how much each one blocks.

## 1. Nothing has published yet — the learning loop still has no real samples

Layers 1-3 run end to end (topics → renders → gate → drafts), but a draft can only be
created on a publisher that has a key AND a connected channel, and neither backend has a
channel yet:

- **Postiz** (instagram / youtube / tiktok): DNS A record for `postiz.funy.click`, `certbot`,
  the three developer apps in `postiz/.env`, then connect channels — only you can do these.
- **Zernio** (pinterest): create the account, connect Pinterest, paste the key + board id in
  the Settings tab.

The **Postiz API key is already in place**: `pipeline/config.json` → `apiKey` (64 chars), verified
2026-09-21 — `GET /api/public/v1/integrations` answers `200 []`. Only the channels are missing.
The Zernio key does not exist yet (no account).

Until then `publish.mjs` records `failed` posts rows ("not connected"); once a channel is
live, `node pipeline/publish.mjs --retry` re-sends them. `autoresearch.mjs` keeps reporting
`still collecting` — `--allow-score-basis` is still the loop grading its own homework, off by default.

## ⚠ The web UI has no login

`https://funy.click/socialmedia/` and `http://165.232.141.92/socialmedia/` are open to
anyone: the Settings tab writes API keys into the config files, the Queue tab approves
drafts, Research/Auto-loop spend credits and CPU. Add HTTP basic auth before sharing the URL:
`htpasswd -c /etc/apache2/.htpasswd-socialmedia <user>` and in
`/etc/apache2/conf-available/socialmedia.conf`'s `<Directory …/web>`:
`AuthType Basic` · `AuthName "Social poster"` · `AuthUserFile /etc/apache2/.htpasswd-socialmedia` · `Require valid-user`,
then `systemctl reload apache2`. (Keys never reach the browser — settings.php only returns set/unset booleans — but the write path is open.)

## 2. Layer 1 runs on the free path — no Keywords Everywhere, treg or Jev key

- Without **Keywords Everywhere** topics have no volume / CPC / competition.
- Without **Jev** the score is a heuristic (`jev_labels.basis = "heuristic"`) and the L3 gate
  always says `confirm` (everything needs a human).
- **treg** needs the token AND `treg.sources` (Settings tab). The Semrush ids are known
  (`semrush.google.keywords.ideas`, `semrush.google.keywords.volume`, `semrush.google.domain.*`)
  but their exact param names (`keyword` vs `phrase`, `database`) must be confirmed with
  `treg catalog get <id>` once the key exists; SERP payloads are handed to Jev unparsed.

## 3. Publisher endpoints verified against docs, not against a live account

- Postiz `PUT /posts/{id}/status` and `GET /analytics/post/{id}` are in the current public
  docs; the running image is from 2026-06-22. If they 404 with a real key:
  `cd postiz && docker compose pull && docker compose up -d`.
- Zernio draft → scheduled is `PUT /v1/posts/{id} {isDraft:false, scheduledFor}` per the
  OpenAPI spec; the first real approve confirms it. `POST /v1/posts` returns one post `_id`
  shared by every platform in the request (only pinterest is routed there, so 1:1 today).
- Postiz post analytics come back as label/series; `postStats()` reads a monotonic series as
  cumulative and sums anything else — check against the dashboard once one post has data.

## 4. Apify token is an unreplaced placeholder

`scraper/config.json` → `apify.token` is the literal `PASTE_…`. Blocks Instagram / TikTok /
Pinterest / LinkedIn research sources and the caption bodies for `niches/dark-motivational/`
exemplars. `isSet` (`scraper/scrape.mjs`) already rejects `PASTE_*`.

## 5. `youtubeApiKey` is empty

`metrics.mjs` still snapshots YouTube posts through Postiz analytics, but the free Data API
cross-check and research engagement ratios stay off until the key is set.

## 6. `hermes` is unidentified

Named in the intended learning path, appears nowhere in the repo. If it is a model: a
one-line `model` change (the LLM layer is provider-agnostic). If it is a retrieval layer for
exemplars: a separate build. Needs a decision.

## 7. `scrape.mjs` cannot scrape Instagram profiles

`APIFY_INPUT.instagram` is hashtag-search only; account-driven curation needs
`directUrls` + `resultsType: "posts"` (settable via `apify.inputs.instagram` in config, no
code change).

## 8. Niche pack content is a placeholder

`niches/dark-motivational/niche.json` has example pillars/seeds/cadence. Real pillars and
seeds are what make Layer 1 produce anything worth rendering; `dailyTopicCap` is the paid-call ceiling per run.

## Closed

- ~~HyperFrames CLI version drift~~ — one pin in `pipeline/hf.mjs` (0.8.58) shared by `poster.mjs` and `hyperframes/evaluate.mjs`.
- ~~metrics.mjs is YouTube-only~~ — Layer 4 pulls every platform's numbers from its publisher.
- ~~Remotion / HyperFrames dual stack~~ — HyperFrames only; `video/` deleted.
