Content Promotion Workflow
Created: 2026-06-20
Purpose
Move useful ideas from metadata-only survey exports toward public UAI Explorer catalog entries without exposing raw device files.
This workflow starts from sanitized survey exports and stops before catalog publication unless an operator approves specific redacted artifacts.
No-Change Boundaries
- Do not put raw source paths in public docs.
- Do not copy raw survey folders into CT
126or production CT121. - Do not publish sanitized export rows directly as catalog content.
- Do not run whole-device embeddings on raw device material.
- Do not infer approval from a survey score, topic, or filename.
Build A Promotion Packet
From the repo root:
python tools\build_content_promotion_packet.py `
--export-dir sanitized-exports\macbook-air\2026-06-20 `
--export-dir sanitized-exports\nuc-ipex\2026-06-20 `
--export-dir sanitized-exports\zenbook\2026-06-20 `
--out-md docs\review\content-promotion-packet-2026-06-20.md `
--out-json docs\review\content-promotion-packet-2026-06-20.json `
--max-per-topic 5
The packet includes survey refs, private lookup row numbers, topics, lanes, tags, and review actions. It must not include raw file aliases, raw hashes, absolute paths, source paths, or raw content.
Private Selection
The operator uses the packet to look up approved rows inside the private raw survey inventory. The selected-redaction file must stay in a private lane and use the selection shape shown in the packet.
Required private fields:
source_path: relative to the private source root.raw_inventory_row: survey row used for lineage.source_manifest_alias: device/date alias.title,project,kind,required_tags, andsummary.
Redaction
Run:
python tools\redact_selected_artifacts.py `
--source-root <private-redaction-root> `
--selection <private-selection.json> `
--out <private-redacted-output>
Review outputs:
manifest.jsonredaction-report.jsoncatalog-import.jsonartifacts/*.md
Generated outputs remain public_publishable=false until an operator approves
them for catalog import.
Approval Gate
After reviewing redacted artifacts, create a private approval JSON. The approval file must not include raw paths, raw aliases, hashes, or raw content.
Example shape:
{
"approval_alias": "operator-approved-batch",
"entries": [
{
"slug": "approved-redacted-artifact",
"approved": true,
"human_visible": true,
"ai_visible": false,
"required_tags": ["docs", "uai"],
"summary": "Operator-reviewed sanitized summary.",
"freshness": "current"
}
]
}
Prepare an import-ready catalog file:
python tools\prepare_catalog_import.py `
--export-dir <private-redacted-output> `
--approval <private-approval.json> `
--out <private-redacted-output>\catalog-import-approved.json
The worker refuses:
- raw source fields in the approval file,
- missing or escaping artifact paths,
- artifact paths outside
artifacts/*.md, - unredacted secret-shaped values in reviewed artifacts,
- approved entries with no human or AI visibility,
- approved entries with no required tags.
Stage Approved Catalog Package
After catalog-import-approved.json exists, stage only those approved
sanitized artifacts into a catalog data root. This step rewrites source_path
values from the private redacted export directory into the public-safe catalog
root path expected by UAI Explorer.
python tools\stage_approved_catalog.py `
--export-dir <private-redacted-output> `
--approved-import <private-redacted-output>\catalog-import-approved.json `
--catalog-root <catalog-data-root> `
--stage-prefix approved-catalog `
--out <private-redacted-output>\catalog-import-staged.json
The worker refuses:
- blocked stage prefixes such as
raw-survey-zoneorsanitized-exports, - staged paths that escape the catalog root,
- approved imports that are not public-publishable,
- approved entries without operator approval, visibility, or tags,
- artifacts that do not declare the approved sanitized hash,
- unredacted secret-shaped values in staged artifacts.
Publication Gate
Before database import:
- Check no unredacted secret-shaped values remain.
- Confirm source lineage and freshness state.
- Confirm required tags and audience.
- Confirm human/AI visibility flags.
- Confirm
tools\prepare_catalog_import.pyproducedcatalog-import-approved.json. - Confirm
tools\stage_approved_catalog.pyproducedcatalog-import-staged.jsonand staged artifacts under the catalog data root. - Confirm production cutover or catalog-import authority exists.
Dry-run the staged import first:
python tools\import_staged_catalog.py `
--staged-import <private-redacted-output>\catalog-import-staged.json `
--data-root <catalog-data-root> `
--db <uai-explorer.sqlite3> `
--out <private-redacted-output>\catalog-import-dry-run.json
Apply only after authority is explicit:
python tools\import_staged_catalog.py `
--staged-import <private-redacted-output>\catalog-import-staged.json `
--data-root <catalog-data-root> `
--db <uai-explorer.sqlite3> `
--out <private-redacted-output>\catalog-import-result.json `
--apply `
--on-conflict fail
The importer refuses:
- missing Explorer catalog tables,
- raw-data flags,
- blocked source paths such as
raw-survey-zone,sanitized-exports,uploads,private, ordata, - staged paths that escape the catalog data root,
- missing staged artifacts,
- staged hash mismatches,
- artifacts that do not declare the approved sanitized hash,
- approved entries without operator approval, visibility, or tags,
- slug conflicts unless
--on-conflict skipor--on-conflict updateis explicitly chosen.