Skip to content

Add concrete weekly producer artifact - #35

Closed
Pigbibi wants to merge 2 commits into
mainfrom
feat/pert-weekly-concrete-artifact-pr-pa
Closed

Add concrete weekly producer artifact#35
Pigbibi wants to merge 2 commits into
mainfrom
feat/pert-weekly-concrete-artifact-pr-pa

Conversation

@Pigbibi

@Pigbibi Pigbibi commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the concrete producer-side political-event-weekly-v1 artifact for the RSS source pipeline.

  • Switches the scheduled run to Monday 12:15 UTC for the immediately completed UTC ISO week.
  • Requires explicit period_start/as_of for manual runs and fails closed on reruns (run_attempt != 1).
  • Builds and validates exactly five dedicated artifact files:
    period_lock.json, political_events.csv, political_watchlist.csv,
    political_event_weekly.json, and weekly_manifest.json.
  • Binds exact bytes, lengths, SHA-256 digests, CSV headers/row counts, period/time fields, producer/workflow/run evidence, source snapshot, feed counters, and 30-day retention.
  • Rejects partial/failed/stale/missing feed status and all readback/tamper/file-set mismatches before dedicated upload.

This is producer-side only. QAR consumer integration, Pages/publisher, monthly, legacy/compatibility/migration, identity/store/registry, and production permissions are out of scope.

Validation

  • python3 -m pytest -q — 127 passed
  • uv sync --locked --extra test && uv run pytest -q — 127 passed
  • python3 -m compileall -q src scripts tests — passed
  • actionlint .github/workflows/rss_source_pipeline.yml — passed
  • git diff --check — passed
  • ruff — unavailable in the local environment
  • Local CLI build/readback — exact five files validated successfully

Contract gate

The dedicated artifact is only emitted after the pure builder/readback validator succeeds. Existing broad rss-source-pipeline upload remains separate and does not include the dedicated artifact directory.

Co-Authored-By: Codex <noreply@openai.com>
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

🤖 Codex PR Review

🚫 Merge blocked: 2 serious issue(s) found in high-risk files

🚫 Blocking Issues

These issues must be fixed before this PR can be merged:

1. 🟠 [HIGH] Logic in .github/workflows/rss_source_pipeline.yml

The new Build completed weekly producer artifact step now runs before Upload RSS source artifact, so any weekly-artifact failure (for example incomplete feed status, manual input mistakes, or schema mismatch) aborts the job before the existing rss-source-pipeline artifact is uploaded. That is a real compatibility break: the workflow used to preserve the broad source artifact for debugging even when downstream logic failed, but this PR suppresses it whenever the new gate trips. (line 120)

Suggestion: Move the Upload RSS source artifact step before the weekly build, or put it in a separate if: always()/separate job path so dedicated weekly-artifact failures do not block the legacy source artifact upload.

2. 🟠 [HIGH] Logic in .github/workflows/rss_source_pipeline.yml

For manual runs, period_start/as_of are only validated inside the late weekly-artifact step, after feed fetching/extraction and after the optional Publish live CSV outputs to repository step. A manual run with missing or malformed period inputs can therefore still update data/live/* and push a commit before the workflow finally rejects the run, which violates the intended fail-closed behavior for invalid manual requests. (line 142)

Suggestion: Add an early guard step that validates manual period_start/as_of before any fetch or publish side effects, or make those inputs effectively required for workflow_dispatch and stop the job before the publication step when they are absent/invalid.

ℹ️ Other Findings

1. 🟡 [MEDIUM] Reliability in .github/workflows/rss_source_pipeline.yml

Scheduled runs derive the target week from date -u +%F at execution time, and completed_week_period() only accepts Mondays. If GitHub starts the Monday 12:15 UTC cron late enough that the runner date is already Tuesday 00:00 UTC or later, the run fails with scheduled_period_invalid instead of producing the immediately completed week artifact. (line 140)

Suggestion: Compute the scheduled week from an immutable scheduled reference rather than the runner wall clock, or relax scheduled-mode week selection to choose the most recently completed UTC ISO week from any execution date.


Review by Codex PR Review bot • PR

@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: d828439af7

ℹ️ 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".

raise _invalid("weekly_artifact_invalid") from None
files: dict[str, bytes] = {
PERIOD_LOCK_NAME: period_lock,
EVENTS_NAME: source_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.

P1 Badge Reject out-of-period events before binding the week

For scheduled/manual builds where the fetched RSS output contains items outside period_start through as_of, this copies the entire upstream source_events.csv into political_events.csv. The workflow passes the raw extract_source_mentions output directly, and _csv_snapshot only checks shape, so a Monday run can publish current-Monday or older feed entries while the manifest declares the previous complete ISO week. This can corrupt downstream weekly analyses; filter or reject rows whose event_date is outside the locked period before hashing and writing the artifact.

Useful? React with 👍 / 👎.

raise _invalid(code) from None
if not rows or tuple(rows[0]) != expected_header:
raise _invalid(f"{code}_header")
if len(rows) < 2 or any(len(row) != len(expected_header) for row in rows[1:]):

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 Allow valid zero-event weeks

When RSS fetching succeeds but no fetched item matches any aliases, extract_source_mentions writes a header-only source_events.csv; this check treats that valid no-event snapshot as events_csv_invalid_rows, so the weekly artifact fails to upload for otherwise complete weeks with zero political events. The manifest already records row counts, so the events CSV should be allowed to have zero data rows while still enforcing the header.

Useful? React with 👍 / 👎.

test -n "${PERIOD_START}" && test -n "${AS_OF}"
ARGS+=(--period-start "${PERIOD_START}" --as-of "${AS_OF}" --run-mode manual)
fi
python scripts/build_weekly_artifact.py "${ARGS[@]}"

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 Keep live RSS publication independent of artifact completeness

When any configured feed fails, the fetch step still succeeds because this workflow invokes it with --continue-on-feed-error, but build_weekly_artifact rejects the resulting nonzero failed_feed_count; since this new step runs before Publish live CSV outputs, the job exits here and stops the existing live CSV commit and RSS artifact upload as well. This changes the documented RSS behavior from publishing partial-but-marked live outputs to publishing nothing whenever one feed is down, so isolate the dedicated weekly artifact failure from the legacy live-output path.

Useful? React with 👍 / 👎.

value["failed_feed_count"],
value.get("stale_feed_count", 0),
value.get("missing_feed_count", 0),
True,

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 Honor explicit incomplete feed status

If the producer status file marks the snapshot as incomplete with complete: false while the numeric counters are otherwise zero-failure, this hardcodes complete back to True and publishes a manifest claiming the feeds were complete. That bypasses the fail-closed feed-health signal already modeled by WeeklyFeedStatus, so pass through and validate the incoming complete value instead of overwriting it.

Useful? React with 👍 / 👎.

Co-Authored-By: Codex <noreply@openai.com>

@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: 33fe72d291

ℹ️ 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".

test -n "${PERIOD_START}" && test -n "${AS_OF}"
ARGS+=(--period-start "${PERIOD_START}" --as-of "${AS_OF}" --run-mode manual)
fi
python scripts/build_weekly_artifact.py "${ARGS[@]}"

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 Upload the RSS source artifact before the weekly gate

In the current ordering I checked, the weekly builder still runs before Upload RSS source artifact; when any feed fails, the fetch step continues because of --continue-on-feed-error, but build_weekly_artifact rejects the incomplete status and this command exits before the legacy rss-source-pipeline artifact is uploaded for operators to inspect. Fresh evidence versus the prior comment is that live publication was moved earlier, but the RSS source artifact upload remains behind the weekly failure boundary.

Useful? React with 👍 / 👎.

--output-dir data/output/political-event-weekly-v1
)
if [ "${GITHUB_EVENT_NAME}" = "schedule" ]; then
ARGS+=(--scheduled-today "$(date -u +%F)" --run-mode scheduled)

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 Tolerate delayed scheduled starts when locking the week

If the Monday cron run is queued long enough to start after 00:00 UTC on Tuesday, this passes Tuesday's wall-clock date to completed_week_period, whose helper rejects any non-Monday with scheduled_period_invalid; the scheduled run would then produce no weekly artifact even though the intended completed ISO week is still unambiguous. Compute the previous completed week from the actual start date without requiring it to still be Monday, or pass an explicit scheduled period.

Useful? React with 👍 / 👎.

source_snapshot_digest,
source_provenance,
(
SourceSnapshotArtifact(EVENTS_NAME, _sha256(period_events), event_rows),

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 Keep lock artifact hashes on the raw snapshot

When source_events contains any rows outside the locked week, source_snapshot_digest is computed from the unfiltered CSV, but this source_artifacts entry records the SHA and row count from period_events after filtering. That makes period_lock.json describe two different snapshots, so later retry or consumer code that uses lock.source_artifacts to verify the original source snapshot will compare against the wrong bytes; keep the lock metadata on the raw source snapshot and leave filtered output metadata to the weekly contract/manifest.

Useful? React with 👍 / 👎.

@Pigbibi

Pigbibi commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

PERMANENT_FREEZE/CLOSE_RESLICE: closure exhausted; preserve branch, commits, review threads, checks, and tests as evidence. No further code action in this PR.

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