PreFlight Outcome
PreFlight Outcome is how you find out whether your predictions were any good
- status
This is the least glamorous node in the pack and the one that decides whether the other three are useful. PreFlight Report gives you a prediction. PreFlight Outcome is where you write down what the platform actually did, days later, once the post has run its course.
Skip it and you have a very sophisticated looking guess-generator forever. Fill it in and PreFlight Calibrate can tell you which rules of the engine are wrong and in which direction.
What you set
record - the prediction to attach an outcome to, newest first. Each entry is labelled from the record itself, so you don't need any file-naming convention to find it again:
a3f9c2d1 · 07-24 14:02 · IG:RISK TT:RISK X:RISK · bikini/beach_pool · "summer drop, lim…"
id, when it was logged (UTC), worst verdict per platform, garment/setting, and the opening of the caption. Genuinely good labelling - you can tell three posts in a batch apart at a glance.
The list is the store's 50 newest, and it's live: when Report logs a prediction, the server pushes the new list to every open browser and each Outcome node shows it immediately. No page reload, no refresh button. A node you add starts on the newest record. A saved workflow's record value is never rewritten on load, even when the list no longer holds it - the node still runs it, since the id is the label's first token.
platform - instagram, tiktok or x. Queue once per platform. Outcomes attach per platform, so one post needs three queues to be fully recorded.
result - clean (normal reach), demoted (suppressed, flagged, FYF-ineligible) or removed (taken down).
record_id_override - paste an id here to bypass the list entirely, for predictions older than the 50 it shows. Report prints the id in its summary, so keep the summary around for anything you actually publish.
The one thing you must do
Pick a fixed personal heuristic for demoted and never change it. Decide your threshold up front - "40% or more below my median reach" is a reasonable starting line - and apply it consistently forever. Inconsistent labels poison the calibration: if demoted means "clearly suppressed" on Monday and "the numbers felt low" on Friday, the per-rule table downstream is measuring your mood rather than the platforms.
clean is normal performance. removed is the post is gone. Those two are unambiguous, which is exactly why the middle one is the dangerous one.
The output
status is a string telling you what happened: logged: a3f9c2d1 instagram=demoted, or why nothing was logged (no record selected, an unknown platform). Errors come back in the string too - they're never raised, so a typo in an id won't kill your queue. This is also an output node, so it runs as a terminal in the graph.
There's no image input, and that's intentional. Outcomes attach to records, not files. The observation, the caption and the rules that fired are already in the store against that id; re-uploading the image would add nothing.
Every queue writes, even with identical inputs - so if you queue twice for the same record and platform by accident, the second entry wins.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/0xBeycan/ComfyUI-BCNodes
pip install -r ComfyUI-BCNodes/requirements.txt
Restart, search preflight. No model, no VRAM, no additional Python packages - this is a form that appends a line to ComfyUI/user/BCNodes/preflight/feedback.jsonl. The requirements file's opencv-python, postfx and caption-audit belong to entirely different nodes in the pack.
You can also leave the node sitting in a saved workflow and just open it when you feel like entering a week's worth of results. There's no pressure to do it immediately; entering outcomes is optional and a prediction without one costs nothing downstream.
Getting burned
Entering outcomes from memory is how you break this. The moment you're reconstructing "I think that one did fine" from a week ago, you're writing noise into the store. Log the reach number while you're looking at it, or don't log it at all.
The list shows 50. If you're catching up on a backlog, you'll be pasting ids from Report summaries rather than clicking. Nothing wrong with that - but keep the summaries.
It doesn't know anything you don't. There's no platform API here and no scraping. The node records your judgement of what happened, which is exactly why the heuristic has to be yours and fixed. If you wanted a node that polls Instagram, this isn't it and can't be - the pack's whole approach is a local, offline loop you drive by hand.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| record | COMBO | The prediction to attach an outcome to, newest first. The list follows the feedback store: a prediction PreFlight Report logs shows here at once. | |
| platform | COMBO | Which platform this outcome is for. | |
| result | COMBO | clean | clean = normal reach; demoted = suppressed / FYF-ineligible / flagged; removed = taken down. Pick one fixed personal heuristic for 'demoted' and stick to it. |
| record_id_override | STRING | If set, this record id is used instead of the list selection (the id is in the Report summary), e.g. for a prediction older than the 50 the list shows. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| status | STRING | — |