---
name: content-decision-loop
description: "Use when running content or production decisions through DeltaX Evaluate with receipts: scoring candidates from real analytics (or labeled judgment), running the evaluation, acting on the selection, and logging results so next week's scores are evidence-based."
---

# Content decision loop

A weekly or per-release loop: measure, score, evaluate, act, log. Start with judgment calls, then replace them with evidence as receipts and analytics accumulate.

DeltaX Evaluate is the checkpoint in the middle of this recipe. It selects one step from the eligible candidates you submit, or refuses, and returns an auditable trace. It does not give a reason for its choice. The scenario that ships with this skill is illustrative: replace its values with your own.

## Setup

- Create a Free account at https://deltaxevaluate.com/account and create an API credential. Allowance and plans are on https://deltaxevaluate.com/pricing.
- Set `DELTAX_CLIENT_ID` and `DELTAX_CLIENT_SECRET` in your server or agent environment. `DELTAX_ACCESS_TOKEN` is also read if you already have a token. Never paste any of them into chat, files, repositories, or logs.
- `integration.py` needs Python 3.9 or newer and no packages. Contract: `2026-09-16.beta2`, profile `deltax-hosted-bounded-review-evaluation-v1`. If a request is blocked, a descriptive User-Agent (`DELTAX_USER_AGENT`) may help.

## Steps

1. **Measure.** Pull last period's real analytics from the channels involved (for example video platform stats such as views, retention, and click-through; social post impressions and engagement by format; site or product signals). Use only numbers you actually read, with date and source. Note any source that could not be reached, and leave its metric blank.
2. **Log learnings.** Update your learnings log: what went out, how it did, and which pattern held or broke (topic, hook, format, length, visual, platform, media or no media). Compare against your baseline, not taste. Mark a hypothesis as a finding only after a later cycle measures it.
3. **Frame the decision.** Write the objective (at most 1024 characters): what is being decided and what is not allowed. Add context as scalar values only (string up to 256 characters, number, boolean, or null; at most 16 entries), with no secrets, no personal data, and no reserved keys such as `url`, `path`, `token`, or `tool`. List up to 8 candidates with unique ids of at most 64 characters, using `analyze`, `compare`, `draft`, or `validate` for steps your agent can perform and the owner can review. Add a publish-now option as one `external` shadow candidate. It cannot be selected. Describe exactly what happens in each candidate and that nothing is published.
4. **Set support scores honestly.** Base each support value on measured performance where data exists, and record how each score was set (see the support section). Where no data exists, label the score "judgment" in the candidate description. Never present a guess as evidence.
5. **Declare your fallback before calling.** Decide now what your own system does if Evaluate refuses (for example, hand the case to a person). The fallback is your action, with its own risks. Evaluate does not perform it.
6. **Run it.** Run `python3 integration.py scenario.json --dry-run` to check the request locally, then run it without `--dry-run`. It sends one evaluation with an `Idempotency-Key` and credentials from the environment, and saves the receipt JSON. Keep a readable copy of the receipt as well (the saved JSON, plus a rendered page or image if you have one). Reuse the same key and body to retry. Never turn a timeout into a new request. A changed situation needs a changed request.
7. **Reconcile before you act.** Reject the result if `api_version` is not `2026-09-16.beta2`, if `profile_id` is not the profile you sent, if the selected id is not one of your submitted review candidates, or if any `authority` or `trace` flag is not `false`. On HTTP 202 stop and reuse the original key. On 429 stop.
8. **Act on the selection as the next step.** If the outcome is `selected`, perform that one review step yourself, and brief whichever teammate owns it with the receipt. If it is `governed_noop_refusal`, stop this path and use your declared fallback.
9. **Log the outcome.** Record links, times, and receipt ids (`receipt_id`, `result.commercial_receipt.receipt_id`, `result.trace.trace_id`) so the next run can measure what the selection produced. Evaluate does not observe outcomes or learn from them (the trace carries `learning_applied: false`), so updating next cycle's scores is your own dated update.

## Sample candidates

The files `scenario.json` and `integration.py` ship with this skill. Every support value in the sample is an illustrative placeholder, labeled as such (see `scenario.README.md`).

| candidate_id | semantic_class | operator_reported_support |
| --- | --- | --- |
| `draft-long-form-post` | draft | 0.8 |
| `draft-short-post` | draft | 0.5 |
| `draft-reply-set` | draft | 0.3 |
| `compare-hook-patterns` | compare | 0.5 |
| `analyze-metric-gaps` | analyze | 0.5 |
| `validate-draft-against-rules` | validate | 0.5 |
| `post-long-form-now` | external | 0.9 |

## Setting support

- **Measured data first.** Where you have data, base each candidate's support on a measured prior you can cite with a date, a window, and a source, and record how each score was set. One generic method: take the median of your chosen metric for the candidate's format over a dated window, divide by the highest median among the candidates, and round to two places. That division is a convention you write down so you can repeat or change it. It is not a DeltaX formula.
- **Labeled judgment when there is no data.** Where nothing has been measured, label the score "judgment" in the candidate description. Never present a guess as evidence. A missing metric stays missing.
- **Never score from your agent's own confidence or earlier output.** That is not independent evidence. Evaluate does not check any of these values. The sample scenario's values are illustrative placeholders, not measurements.

## Rules

- A selection is never permission or authority. Anything with an outside effect needs its own separate yes from the owner, outside Evaluate. A standing approval the owner set in their own words can cover a step, but only if it clearly does.
- Describe Evaluate only by what you can verify: the inputs you sent, gate pass or fail entries in the trace, one selection or a refusal, and receipt ids and hashes. Do not explain or guess how the gates work, and do not ask Evaluate for a reason behind a choice.
- Never print or log Evaluate credentials.
- No invented numbers.

## Reporting

Write a short summary: what worked (with real numbers), the decisions selected with receipt ids and readable receipts, and anything waiting on an owner's yes.

## Reading the response

The result sits inside `result`. `outcome` is `selected` or `governed_noop_refusal`, and `selected_candidate_id` is a submitted id or `null`. `reason_codes` holds bounded outcome codes, such as `candidate_selected_within_bounded_evaluation`; store it with the receipt, and do not present it, or any entry in `trace.lambda_decisions`, as a reason for or against any single candidate. The account record id (`receipt_id`) and the evaluator receipt id (`result.commercial_receipt.receipt_id`) are different records. Keep both.
