项目级、声明式、失败关闭的内容发布器。它不内置行业、批次、任务或 attempt 名称;生产与测试均通过同一个严格 JSON 配置和同一个 CLI 入口运行。
python -m shared_content_publisher --config <batch-config.json> --validate-only
python -m shared_content_publisher --config <batch-config.json>
python -m shared_content_publisher --config <batch-config.json> --read-direct-current
python -m shared_content_publisher.postcommit_archive --config <archive-config.json>
python -m shared_content_publisher.postcommit_archive --rollback-config <authorized-rollback-config.json>
核心边界:
canonical_audit_id 与 review_handoff_id 是不同字段和不同 ID 域;release preimage 只使用 canonical audit。PID+UUID 进程实例身份。SHARED_CONTENT_PUBLISHER_ATTEMPT_EVENT_CHAIN_V1 规范化事件链的 SHA-256、行数、起止 UTC 和逐阶段进程身份;正常提交、幂等重放、回滚与恢复均复用同一验证入口,任一列漂移均不得返回 IDEMPOTENT_COMMITTED。当前成果索引.md;result Markdown 保持为指向 cases 的薄入口,不引入 JSON pointer 或消费者迁移。当既有消费者直接读取稳定 Markdown/CSV 路径、不能迁移到 release 目录时,V3 配置可选择 DIRECT_STABLE_PATH_SET_V1:
candidate.rows[].formal_relative_path 就是唯一稳定目的地;除唯一 cases 当前成果索引.md 激活点外,只允许落在该行业的 核心文档/、manifest/ 或 ana-data/result/<industry>/。expected.destination_prior 同时冻结每个目的地的已有文件身份或 ABSENT 状态;已有和缺失成员可以在同一事务中发布。expected.prior.mode=ABSENT_GENESIS_V1:prior.rows 必须为空,cases/result current、current state 与全部声明目的地必须实测 ABSENT;发布后仍复用同一锁、恢复锚、事件链、回滚与幂等验证,不以 genesis 名义绕开正式闭环。commit_plan.json 明确绑定逐文件顺序,cases current 永远是最后且唯一激活点。read_direct_current_snapshot(),或使用 --read-direct-current 做只读闭环证明。读前要求 publisher lock absent 并冻结 cases current index/current manifest 双身份;读完整目标集后再次要求 lock absent 且双身份不变。锁存在返回 RETRY_PUBLISH_IN_PROGRESS,identity/exact-set 漂移返回 STOP_NOT_CURRENT,均不返回 payload 或 current 标记。PREPARED、VERIFIED、首个稳定目的地前和每个稳定目的地提交后的 durable prefix 均由一个恢复验证器管理。同 config 新进程先绑定 snapshot、receipt、staging、全部 17 列 event chain 与每个目的地 prior/candidate 真值,再精确恢复 prior 并返回可严格重放的 ROLLED_BACK;合法未完成前缀不再返回 TERMINAL_REPEAT_BLOCKED。fsync、关闭、回读,再以 no-overwrite 原子目录改名一次发布。原子改名前的可归属残片在 formal prior/ledger 不变时由同 config 安全退役并重建;finalized member、extra 或 official anchor 的篡改返回明确 RECOVERY_REQUIRED,不得盲删或继续发布。MARKDOWN_CURRENT_INDEX_REPLACE_V1 / V2 schema 保持兼容,不改变其 release-directory 行为。机器可读 schema:
batch_config.schema.json:V2 release-directory 策略;batch_config.direct_stable_path_set.schema.json:V3 direct stable-path 策略。postcommit_archive.schema.json:发布成功后的旧目录原子归档及恢复回执。postcommit_archive.rollback.schema.json:仅在独立 AUTH- 与 AUDIT- 绑定后恢复 legacy 原路径。正式 current 已由 DIRECT_STABLE_PATH_SET_V1 提交并完成精确回读后,可用独立的postcommit_archive 协调器把一个完整旧目录原子改名到同卷审计包:
COMMITTED 状态,并逐行验证旧路径映射、旧树和新正式树;RECOVERY_REQUIRED,不得把不确定状态声明为已归档;ARCHIVED,同配置完整回放为 IDEMPOTENT_ARCHIVED。归档回放会从冻结的 publisher config 复核完整正式集合(包括所有 core、manifest-self、
cases/result 两入口),并复算 17 列事件链及 lock absence,不只验证 legacy map 覆盖的
目标。若整体迁移随后获得独立回退授权,必须另建严格 rollback config;协调器先绑定原
archive config/terminal、完整正式集合、归档树和授权身份,建立独立回退回执锚后,才可
以一次 no-overwrite 原子改名恢复 legacy 原路径。回退成功与同配置重放分别返回LEGACY_RESTORED 和 IDEMPOTENT_LEGACY_RESTORED,原 archive config 不得再次归档。
即使进程在 rollback 目录原子改名后、terminal 发布前中断,重启也必须先重新验证
archive anchor、648 项正式集合、17 列事件链、lock、canonical 645 项及恢复后的 legacy
645 项;任一漂移只返回 RECOVERY_REQUIRED,不得补写或重放成功终态。
正式批次配置由项目管理员在实现审核通过后另行生成,本实现不包含任何真实批次配置。