# Daily Queue Selector v0.1.0

Workflow code is MIT licensed: see [LICENSE](n8n-daily-queue-selector-LICENSE.txt) and [scope notice](n8n-daily-queue-selector-NOTICE.md). The premium commercial licence remains separate and unchanged.

## Important n8n import settings limitation

In the tested n8n file-import flow, the new workflow retained default UTC and default execution-saving settings instead of applying the export settings. The JSON declares Africa/Luanda and no execution-data saving, but **do not assume those settings survive import**. Open the new workflow settings, review and explicitly configure timezone and your execution-data retention policy before using private inputs. All live tests used fictional data. Code results are independent of the workflow timezone because the selector validates its explicit Luanda input. No settings round-trip audit is claimed.

## What it does

Manual, inactive, credential-free n8n template selecting at most one eligible queue item. No model calls, network, scheduling, reservation, approval or publication. Every result has `generation_allowed: false` and `reservation_required: true`. Supplied approval flags are unauthenticated records, never permission or proof.

## Contract and deterministic order

Input: `now` explicit-timezone ISO timestamp with seconds (optional 1–3 fractional digits), `timezone: Africa/Luanda`, `max_items: 1`, and `items` (0–1000 objects). Supported calendar years: 2000–2099. Offsets must be known, no greater than ±14:00; `-00:00` is rejected. Luanda is UTC+01:00 within this bounded range, so selection uses its editorial date, not the UTC date.

Each item requires `content_id` (1–100 ASCII letters/digits/dot/underscore/hyphen, first character alphanumeric), `status`, integer `priority` (0–1000000), valid `planned_date` (YYYY-MM-DD), booleans `topic_approved`, `sources_ready`, `images_ready`, and `reserved_by` (null or a nonempty string up to 200 characters). Duplicate IDs and malformed records reject the entire input. All specified queue lifecycle statuses are recognized; only `ready_for_brief` is eligible. Dates on or before the editorial date are eligible.

Smaller priority numbers rank first, then earliest planned date, then case-sensitive ASCII content ID. The input is never mutated. Output includes one selected ID or `no_work`, Luanda date, eligible count, and reasons for every excluded item. Valid blocked records produce `no_work`; malformed inputs throw and must not be routed around as approval.

## Manual demonstration and recovery

1. Import `workflow.json` into a new inactive workflow. Inspect its three nodes. The fake `demo-A` should win over `demo-B` and `demo-C`
2. Change every item's `topic_approved` to false. Execute: expect `no_work`, `topic_not_approved`, and generation still disabled
3. Restore the booleans and execute: `demo-A` returns
4. Change `now` to `2026-09-29T22:59:59Z`: all September 30 items are future. At `2026-09-29T23:00:00Z`, Luanda is already September 30 and the eligible candidate returns

A fresh isolated import in the n8n workspace passed the valid, all-unapproved negative, and canonical-restored cases on 30 September 2026. Node-level tests and embedded-Code parity also pass. The n8n export-download UI did not complete, so no post-save runtime-export audit is claimed. Exact evidence and hashes are recorded in `docs/queue-budget-candidates-2026-09-30.json`.

## Production integration is separate

This module provides no mutual exclusion or durable state. Two executions can select the same ID. A future dispatcher must atomically reserve a unique content ID and period in trusted durable storage, fail closed if reservation fails, persist request ID/attempt/date/reason, then atomically reserve budget before any paid call. A get followed by an upsert is not atomic. Unknown execution outcomes retain reservations until reconciled; never automatically release them and retry paid work.

Do not pass the production queue directly without a reviewed explicit adapter that maps actual state, dates, priorities and readiness evidence to this contract. Never fill missing approval/readiness flags with true. The fictional input grants no approval to a real editorial item. The proposed 17:00 Luanda schedule is deliberately absent.

Run: `node --test automation/editorial/daily-queue.test.cjs automation/editorial/queue-budget-packages.test.cjs`.

### Explicit editorial-queue adapter

`automation/editorial/editorial-queue-adapter.cjs` is a separate read-only bridge for the approved schema-version-1 batch document at `content/briefs/2026-09-29/queue.json` (reviewed at commit `1700cbe2c3ea62ece672e9fbececef903b96f2da`). It maps `id` to `content_id`, `approved` with exact `approval_scope: topic_and_briefing_plan` to topic approval, and `research_ready` to source readiness. It preserves priority and image readiness. Pending-evidence topics map to `topic_proposed`; already reviewed text maps to `brief_awaiting_review`; unknown states reject.

The batch document has no item planned dates or reservation snapshot. The caller must explicitly supply `planned_dates_by_id` and `reservations_by_id` for every ID plus `now`; the adapter never invents dates or assumes an absent reservation is null. If `execution_enabled` is false, every mapped status is blocked. The reviewed batch therefore cannot select work. `approval_required: false` and `final_article_approved` do not override these gates. Use the returned `selector_input` only after validating the caller's external snapshots; the adapter report is advisory and cannot authenticate those snapshots or reserve anything.

Maintainers: regenerate deterministic exports and the allowlisted download route with `node automation/editorial/build-queue-budget-workflows.cjs`, then rerun tests and the production build. Public release approved on 30 September 2026; this does not activate a production workflow or authorize paid generation.

Runtime version evidence: the pre-restart About version was not captured. An initial template-link parameter suggested 2.39.6, but is not authoritative. About n8n after the workspace restart explicitly showed 2.41.4. WF11 and WF12 initial/insufficient cases ran before that restart; WF12 exact-balance, missing-bound and recovery cases ran afterwards. Both workflows retained restored canonical fake inputs after reload and stayed unpublished.
