Skip to content

fix(sn39): bind public status publications fail closed - #431

Merged
wallscaler merged 4 commits into
mainfrom
codex/sn39-sanitized-status-stream
Aug 2, 2026
Merged

wallscaler merged 4 commits into
mainfrom
codex/sn39-sanitized-status-stream

Conversation

@wallscaler

@wallscaler wallscaler commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

What this changes

Publishes a sanitized SN39 status stream without letting interrupted, mismatched, or concurrent writes preserve a stale public PASS.

  • writes a durable PENDING fence before each raw event,
  • binds the fence to the exact sanitized COMMITTED event,
  • refuses same-category substitutes and commits which precede their fence,
  • restricts public stage values to a fixed allowlist,
  • leaves the public generation PENDING if the source stream changes during publication,
  • keeps operator paths, credentials, hotkeys, and private diagnostics out of the public view.

Review and test evidence

Rebased onto current Cathedral main 76f59db, after PR #430 merged.

  • exact affected workflow family: 506 passed, 1 unrelated pre-existing skip,
  • focused status suites: 41 passed,
  • Ruff check and format: PASS,
  • git diff check: PASS,
  • independent adversarial review: PASS.

Boundary

This is implemented, locally tested, independently reviewed, and pushed. It is not deployed or live-host proven. Issue #3 should remain open until the deployed publisher and public endpoint are independently verified.

@wallscaler
wallscaler requested a review from ai-hpc August 2, 2026 08:34
Keep the complete validator journal private and project only a fixed operational allowlist into the group-readable status file. Bind the config, release launcher, systemd units, publisher, CLI, and regression tests to the same split so arbitrary event fields cannot reach the public stream.
Keep raw validator journals private during upgrade and publish only typed, event-specific operational fields. Fence raw/status transitions durably so interrupted or malformed publication cannot preserve a stale PASS, and document the stopped-writer migration and rollback boundary.
Publish a fail-closed PENDING marker before both event views and a digest-bound COMMITTED marker after them so interrupted refreshes cannot retain a stale PASS. Close fence metadata to reviewed categories, validate private-event commits, and keep the status regressions in required launch CI.
Bind each durable PENDING fence to the exact sanitized committed event, restrict public stage values to the reviewed enum, and leave a public generation pending when the source changes during publication. Add adversarial regressions for category substitution, reordered commits, stage leakage, and concurrent source updates.
@wallscaler
wallscaler force-pushed the codex/sn39-sanitized-status-stream branch from ff46a29 to 9cfb137 Compare August 2, 2026 08:35
@wallscaler
wallscaler merged commit 4679d5e into main Aug 2, 2026
8 checks passed
@wallscaler
wallscaler deleted the codex/sn39-sanitized-status-stream branch August 2, 2026 08:37

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff46a2959f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

("\n".join(human_lines) + ("\n" if human_lines else "")).encode("utf-8"),
human_log,
)
if current_source_snapshot() != source_snapshot:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Close the source-change race before committing

If the validator appends a PENDING fence after this snapshot comparison but before the COMMITTED status.json replacement, the publisher commits the older generation and can expose the preceding PASS until the 60-second timer runs again. This is exactly the concurrent-write window the new protocol is intended to fail closed; the final commit needs synchronization with the writer or a post-commit check that restores PENDING when the source changed.

Useful? React with 👍 / 👎.

# Remove a PENDING fence only when its exact COMMITTED partner is present.
# An unmatched fence is itself public evidence that the raw/status
# transition was interrupted and must remain visible as NOT_PROVEN.
events: deque[dict[str, Any]] = deque(maxlen=MAX_EVENTS)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve unmatched fences beyond the display limit

When an interrupted transition is followed by more than MAX_EVENTS allowlisted rows without a restart, this bounded deque evicts the unmatched PENDING fence. build_status() then no longer sees publication_pending, so a later successful weight or provenance event can restore PASS even though the interrupted transition was never resolved; preserve unresolved fences separately from the bounded event display.

Useful? React with 👍 / 👎.

Comment on lines +1047 to +1049
"status": authority_status
if authority_fresh and publication_pending is None
else "NOT_PROVEN",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear burn_share while a source fence is pending

When the source contains an unmatched STATUS_PUBLICATION_PENDING after a fresh 90/10 submission, this guard correctly changes authority status to NOT_PROVEN, but the adjacent burn_share calculation still emits the stale value "0.10". Unlike an interrupted outer file publication, this source state is subsequently published with publication.phase=COMMITTED, so _status_publication_view() does not clear the value; apply the pending-fence condition to burn_share as well.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant