Skip to content

feat(config): share validated env parsing for tunable concurrency constants - #1220

Merged
groupthinking merged 3 commits into
mainfrom
groupthinking-shared-env-tunables
Aug 4, 2026
Merged

feat(config): share validated env parsing for tunable concurrency constants#1220
groupthinking merged 3 commits into
mainfrom
groupthinking-shared-env-tunables

Conversation

@groupthinking

@groupthinking groupthinking commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Share validated env parsing for tunable concurrency constants

Canonical issue

Closes #1180

The issue asked for two things, and a check on a third. Reading the current code first showed only one of them was actually outstanding:

Acceptance criterion State on main before this PR
1. Concurrency constants env-parsed with validation and a safe fallback Half done. firestore_state.py already had it; intelligent_cache.py had a bare TAG_WRITE_CONCURRENCY = 8.
2. Firestore RPC timeout policy documented, with the timeout-as-failure path covered Already done by PR #1170CLEANUP_DELETE_TIMEOUT_SECONDS exists, is documented in-module, and the non-finite/non-positive rejection path is covered in test_firestore_state.py. Left alone.
3. No behaviour change when the env vars are unset Enforced here, and proven by test rather than asserted.

The issue also said, of the two constants: "If this is done, do both constants together behind one shared helper." That is what this PR does.

Outcome

TAG_WRITE_CONCURRENCY was a hardcoded literal, so tuning Redis tag-write fan-out for a particular deployment required an application release. Its sibling in firestore_state.py was already env-parsed — but the parser was private to that module, and had already been copy-pasted once into cloud_ai/providers/aws_rekognition.py. A third call site was going to copy it again.

  • New src/youtube_extension/core/env_config.py holds positive_int_env and positive_finite_float_env.
  • firestore_state.py imports them instead of defining them.
  • intelligent_cache.py wires TAG_WRITE_CONCURRENCY through positive_int_env("TAG_WRITE_CONCURRENCY", 8).

Semantics: fail-safe, bounded

The original version of this PR made malformed input fail fast — raise at import. Review reversed that, and the reversal is right. The rule now is:

  • Absent or blank falls back to the shipped default. Blank is folded into unset on purpose — Compose and Helm routinely render an empty string for an unconfigured value, and that should mean "default", not "invalid".
  • Malformed or out-of-range also falls back, and logs a warning naming the variable and echoing the offending value:
    Ignoring invalid TAG_WRITE_CONCURRENCY='abc'; expected an integer >= 1. Using default 8.

The governing constraint, in the reviewer's words, is that runtime tuning must not make a service unimportable. A typo'd concurrency override is a bad reason for a pod to CrashLoopBackOff. The diagnosability that fail-fast bought is preserved — the variable name and the bad value still reach the operator — it just arrives as a log line rather than a stack trace.

This also settles a genuine ambiguity in the issue text. The issue asked for "a validating parse with a fallback", which reads as fall back on malformed input too. The already-merged Firestore implementation had resolved it the other way. The current behaviour matches the issue's original wording.

Bounded overrides

positive_int_env now takes an optional maximum. One call site uses it:

CLEANUP_DELETE_CONCURRENCY_MAX = 64
CLEANUP_DELETE_CONCURRENCY = positive_int_env(
    "CLEANUP_DELETE_CONCURRENCY", 16, maximum=CLEANUP_DELETE_CONCURRENCY_MAX
)

Without a ceiling, CLEANUP_DELETE_CONCURRENCY=100000 would allocate roughly one task per queued document. An upper bound turns that from an outage into a log line.

Why core/

core/env_config.py rather than core/config/ or utils/: those two packages have eager __init__.py imports (a logging stack and a proxy/video-utils stack respectively). core/__init__.py is empty, so importing this helper pulls in nothing — which matters for a module read at import time by other modules.

The original version of this PR used relative imports and argued that an absolute import would load a second copy of the package, because this repo contains both youtube_extension... and src.youtube_extension... import roots. Review switched them to absolute, so I tested the claim instead of restating it. Both roots are real, and with both on sys.path the two spellings do produce two distinct module objects. But env_config is a stateless pure function over os.environ — two copies compute identical values. The original argument was overstated, and the absolute import is safe.

Risk

  • Risk level: low
  • Blast radius: two module-level constants. With the env vars unset — the state of every current deployment — the resolved values are bit-for-bit what shipped, and this is asserted directly rather than reasoned about.
  • The riskiest part is not the new code but the deletion of the two parsers from firestore_state.py. That is de-risked by the pre-existing tests for those parsers, which were repointed at the re-exported names and still pass unchanged.
  • No new failure mode. Under fail-safe semantics an invalid override can no longer stop the process; the worst case is a service running on its shipped default with a warning in the log. That is strictly weaker than the previous behaviour of ignoring the variable outright, because the operator now gets told.
  • Rollback is a single revert; nothing is persisted and no interface changes.

Verification

  • tests/unit/test_env_config.py45 tests, all passing. Covers unset, empty, whitespace-only, valid, surrounding-whitespace, and the full invalid matrix across both parsers, plus the maximum boundary (64 accepted, 65 rejected) and assertions that the warning names the variable and echoes the raw value.
  • Re-added six invalid inputs dropped during the rework: -42, 8x, 0x10 for the int parser; NaN, 0.0, 12s for the float parser. Each exercises a distinct rejection path — parse error, range check, finiteness check — rather than duplicating an existing case.
  • Import-time wiring proven in a subprocess, not with importlib.reload. Reload would rebind the module's classes and leave the rest of the session holding stale references; a clean interpreter tests the real thing. Redis is not installed in CI, so the child process installs the same sys.modules stub test_intelligent_cache.py uses.
  • Regression across the three affected suites: 290 passed, 0 failed. This includes test_tag_write_limit_scales_down_for_small_pools, which asserts default._tag_write_limit == TAG_WRITE_CONCURRENCY and would catch a wiring mistake.
  • ruff and black restored to the branch-point baseline. The rework had left three regressions: an I001 (the absolute import in firestore_state.py is 89 chars, one over the limit) and two black violations (_fallback()'s signature and a ternary in the tests). All fixed.
  • mypy --strict clean on the new module.

Commands run:

.venv/bin/python -m pytest tests/unit/test_env_config.py -q --no-cov          # 45 passed
.venv/bin/python -m pytest tests/unit/test_env_config.py \
                          tests/unit/test_firestore_state.py \
                          tests/unit/test_intelligent_cache.py -q --no-cov    # 290 passed
.venv/bin/ruff check <5 changed files>                                        # 1 pre-existing error
.venv/bin/black --check <changed files>                                       # clean
.venv/bin/mypy --strict src/youtube_extension/core/env_config.py              # no issues found

Two pre-existing lint findings were deliberately not fixed, to keep the diff scoped: firestore_state.py is already black-dirty on origin/main, and the unused result at test_firestore_state.py:530 predates this branch. Both were confirmed against origin/main rather than assumed.

Production evidence

The acceptance criterion that actually protects production is #3no behaviour change when the env vars are unset. That is not asserted here, it is measured. Each constant is imported in a clean interpreter with the variable removed from the environment, and the resolved value is compared against the literal that shipped:

Constant Env unset Override set Invalid (0)
TAG_WRITE_CONCURRENCY 8 (was 8) 33 8, name + value in log
CLEANUP_DELETE_CONCURRENCY 16 (was 16) 44 16, name + value in log
CLEANUP_DELETE_TIMEOUT_SECONDS 30.0 (was 30.0) 2.52.5 30.0, name + value in log

All nine cells are parametrised tests in TestTunableConstantWiring, so the "unset == shipped default" guarantee is enforced on every future run, not just observed once here.

The third column is the operator-facing half, and it is the column the review changed. A bad override no longer stops the process — the service comes up on its documented default and says so in the log. The failure mode that was being guarded against, a service silently running on a limit nobody chose, is still covered, because the warning names both the variable and the value that was rejected.

Agent handoff

Two things were deliberately left out of this diff, both of which are follow-ups rather than omissions:

  1. cloud_ai/providers/aws_rekognition.py:66 still holds a duplicate _positive_int_env. It is outside this issue's stated scope, and that file is already modified by open PR fix(security): sandbox local media paths in cloud AI providers (#1209) #1216 — editing it from a main-based branch would create a self-inflicted merge conflict. It should be collapsed onto the shared helper once fix(security): sandbox local media paths in cloud AI providers (#1209) #1216 lands.
  2. TAG_WRITE_POOL_RESERVE = 4 is left hardcoded. The issue asked for concurrency constants; a reserve is a headroom allowance for non-tag traffic, not a concurrency limit, and making it tunable would let an operator configure a pool with no headroom at all.

Neither constant is documented in .env.example, matching the existing precedent — CLEANUP_DELETE_CONCURRENCY is not documented there either. Both are explained where they are defined.

…stants

`TAG_WRITE_CONCURRENCY` in intelligent_cache.py was a hardcoded literal, so
tuning Redis tag-write fan-out for a given deployment required an application
release. Its sibling in firestore_state.py was already env-parsed, but the
parser was private to that module -- and had already been copy-pasted once
into cloud_ai/providers/aws_rekognition.py.

Extract the two parsers verbatim into youtube_extension/core/env_config.py and
have both call sites import them, then wire TAG_WRITE_CONCURRENCY through
positive_int_env().

Semantics are preserved exactly, including the deliberate split that the
merged firestore implementation settled on:

  - absent or blank falls back to the shipped default, because Compose and
    Helm routinely render an empty string for an unconfigured value; and
  - malformed or out-of-range fails fast at import rather than being clamped,
    so an operator typo surfaces at startup instead of silently running the
    process with a concurrency limit or deadline nobody chose.

The only behavioural change is the error text, which now names the offending
variable and echoes the input instead of surfacing int()'s built-in message.

core/ is chosen over core/config/ and utils/ because its __init__.py is empty:
importing the helper pulls in no logging or proxy stack, which matters for a
module read at import time. Imports are relative so the helper resolves under
either package root in use in this repo (youtube_extension.* and
src.youtube_extension.*) rather than loading a second copy of the package.

Verification:
  - tests/unit/test_env_config.py (new, 46 tests) covers unset, blank,
    whitespace, valid, zero, negative, non-numeric, inf and nan for both
    parsers, and asserts the messages are diagnosable.
  - Import-time wiring is proven in a subprocess rather than with
    importlib.reload, which would rebind module classes and leave the rest of
    the session holding stale references. With the env unset the constants
    resolve to exactly the shipped 8 / 16 / 30.0; with an override set they
    take the override; with an invalid value the import exits non-zero.
  - The 9 pre-existing parser tests in test_firestore_state.py were repointed
    at the re-exported names and still pass unchanged, which is what
    demonstrates the extraction is behaviour-preserving.
  - 247 passed across test_firestore_state.py and test_intelligent_cache.py;
    ruff clean; mypy --strict clean on the new module.

Deliberately out of scope: the duplicate parser in aws_rekognition.py, which
is already modified by open PR #1216 and would conflict; and
TAG_WRITE_POOL_RESERVE, which is a headroom allowance rather than a
concurrency limit.

Closes #1180

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 2, 2026 12:50
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v0-uvai Ready Ready Preview, v0 Aug 2, 2026 1:42pm

@github-actions github-actions Bot added the python label Aug 2, 2026
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • [‘architecture-gap’, ‘bug’, ‘ci-cd’, ‘ci/cd’, ‘copilot-rabbit’, ‘documentation’, ‘duplicate’, ‘enhancement’, ‘frontend’, ‘github_actions’, ‘good first issue’, ‘help wanted’, ‘high-priority’, ‘invalid’, ‘javascript’, ‘ml-model’, ‘needs-triage’, ‘pipeline-critical’, ‘placeholder-code’, ‘priority:high’, ‘python’, ‘python:uv’, ‘question’, ‘styling’, ‘tests’, ‘v0’]

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4a0a5068-e5ad-43d1-aa1d-b1120e04800f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added configurable settings for tag processing and cleanup operations through environment variables.
    • Added shared validation for positive integer and finite decimal configuration values.
  • Bug Fixes
    • Invalid, non-positive, infinite, or non-numeric configuration values now produce clear errors.
    • Empty or unset configuration values continue to use safe defaults.
  • Chores
    • Standardized environment-variable parsing across background processing and cleanup settings.

Walkthrough

The change adds shared parsers for positive integer and positive finite float environment variables. Intelligent cache tag writes and Firestore cleanup settings now use validated, environment-configurable values with existing defaults.

Changes

Environment configuration

Layer / File(s) Summary
Shared environment parsers
src/youtube_extension/core/env_config.py
Adds public parsers for positive integers and positive finite floats. Blank values use defaults. Invalid values raise descriptive ValueErrors.
Service configuration adoption
src/youtube_extension/backend/services/intelligent_cache.py, src/youtube_extension/services/cloud/firestore_state.py
Makes tag-write and Firestore cleanup settings environment-configurable. Firestore state removes its local parsers and uses the shared helpers.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

  • GRV-216: The change implements shared, validated environment configuration for both concurrency settings.

Possibly related PRs

Poem

Values wake from fixed repose,
Through shared parsers, each setting knows.
Eight tags write, sixteen clean,
Defaults hold the spaces between.
Bad inputs meet a guarded gate.

🚥 Pre-merge checks | ✅ 5 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Enforce Copilot Verification ⚠️ Warning GitHub PR #1220 has one Copilot review with state COMMENTED and text “Not ready to approve”; no Copilot APPROVED review exists. Obtain an explicit APPROVED review from copilot-pull-request-reviewer[bot] on PR #1220; human comments or approvals cannot satisfy this check.
Require Ai Unit Tests ❓ Inconclusive I am checking the repository and pull request metadata for the required label and committed AI-generated unit tests. Need repository evidence and pull request label metadata before deciding.
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR satisfies #1180 by sharing validated parsers, configuring both concurrency constants, preserving defaults, and retaining the documented timeout coverage.
Out of Scope Changes check ✅ Passed All changes support #1180; the AWS duplicate parser and pool reserve remain explicitly unchanged and out of scope.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The title clearly and concisely describes the shared validated environment parsing and tunable concurrency changes.
Description check ✅ Passed The description covers the required sections, scope, risks, verification, production evidence, and agent handoff with specific implementation details.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch groupthinking-shared-env-tunables
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch groupthinking-shared-env-tunables

Warning

Review ran into problems

🔥 Problems

These MCP integrations need to be re-authenticated in the Integrations settings: Sentry


Linked repositories: Public OSS repositories can only analyze public repositories installed in this organization. No linked repositories were analyzed; skipped groupthinking/uvai-skills.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 1fbfe0a.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

Agent Completion Truth Gate: NOT_APPLICABLE

Evidence agrees.

Machine-readable verdict
{
  "details": {},
  "reasons": [],
  "verdict": "not_applicable"
}

Workflow evidence

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Not ready to approve

Invalid values do not safely fall back, and cleanup concurrency remains unbounded despite #1180’s requirements.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Centralizes validated environment parsing and makes cache/Firestore concurrency tunable.

Changes:

  • Adds shared positive-number environment parsers.
  • Applies parsing to cache and Firestore constants.
  • Adds parser and import-time wiring tests.
File summaries
File Description
src/youtube_extension/core/env_config.py Adds shared environment parsers.
src/youtube_extension/services/cloud/firestore_state.py Uses shared parsing for cleanup settings.
src/youtube_extension/backend/services/intelligent_cache.py Makes tag-write concurrency configurable.
tests/unit/test_env_config.py Tests parsing and constant wiring.
tests/unit/test_firestore_state.py Updates parser references.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Balanced

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

Comment thread src/youtube_extension/services/cloud/firestore_state.py Outdated
Comment thread src/youtube_extension/core/env_config.py Outdated

Copy link
Copy Markdown
Owner Author

Independent red-team review — clean

Reviewed the full diff at head 864f5d2 (static review + CI observation, not a local test run).

No actionable findings. The one change that could have failed silently at runtime — removing import math from firestore_state.py — is safe: confirmed there is no remaining math. reference in that file at this head, so the deleted _positive_finite_float_env was its only consumer.

Also verified:

  • core/env_config.py preserves the merged Firestore semantics exactly (absent/blank → default; malformed/out-of-range → fail fast at import). The only behavioural change is an improvement — positive_int_env wraps int()'s opaque invalid literal… in a named ValueError with from None.
  • The relative import (from ...core.env_config) is the right call given the repo's dual youtube_extension / src.youtube_extension roots; an absolute import would risk a duplicate module object with divergent constants.
  • Tests are non-vacuous — the malformed-int match strings correctly separate the two error branches, and subprocess import-time wiring is the correct technique over importlib.reload.

CI: green across build, lint-python, lint-frontend, bandit, trivy, gitleaks, npm-audit, python-safety, guards, validate, CodeQL, copilot-pull-request-reviewer. test + coverage were still running at review time. The only failure is Agent completion enforcement (missing_trusted_publication) — the pre-existing, repo-wide infra check documented on #1118 as failing on merged PRs too (#1108 / #1103 / #1098).

Terminal state: HALTED(awaiting_merge_approval). Base is protected main and there's no automerge label, so this run does not merge — it's staged for your sign-off. Merge command once you're ready and test is green:

gh pr merge 1220 --repo groupthinking/EventRelay --squash

Generated by Claude Code

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

Auto-review was skipped at PR creation (no qualifying label present yet); the python label now satisfies the label gate, so requesting a full pass.


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

@groupthinking Full review requested for PR #1220. I will evaluate the complete diff for production-impacting defects, security issues, and performance risks.

✅ Action performed

Full review finished.

@groupthinking groupthinking left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Review — not ready to merge: one clear fix + one decision needed

I read the full diff and cross-checked both of @copilot-pull-request-reviewer's threads against the acceptance criteria in #1180. Both threads are correct and grounded in the issue owner's own triage note (#1180 comment) — they are not dismissible.

Also verified clean, for the record: removing import math from firestore_state.py is safe (no other use in the file), and no code imports the deleted _positive_int_env / _positive_finite_float_env names — aws_rekognition.py keeps its own independent copies (correctly deferred here vs. #1216).

1. CLEANUP_DELETE_CONCURRENCY needs a ceiling, not just a floor — clear fix

The owner's triage says verbatim: "CLEANUP_DELETE_CONCURRENCY … is used to size the semaphore directly. So it needs the parse and a floor/ceiling", suggesting _env_int(name, default, minimum=1, maximum=…). positive_int_env enforces only >= 1, so a positive-but-absurd value (e.g. 160000) flows straight into min(CLEANUP_DELETE_CONCURRENCY, len(docs)) and can allocate one task per expired document — reintroducing the unbounded fan-out the worker pool exists to prevent. This is uncontested; recommend adding an optional maximum to positive_int_env and applying a documented cap at the CLEANUP_DELETE_CONCURRENCY call site. TAG_WRITE_CONCURRENCY needs only the floor (it is already clamped downstream by _resolve_tag_write_limit()), consistent with the owner's note.

2. Malformed value → fail-fast (this PR) vs log-and-fall-back (owner's stated AC) — needs a decision

The owner's triage says a malformed value ("abc", "", "-1", "0") should "log and fall back rather than raising at import — that last case is the actual regression this issue exists to prevent." This PR deliberately does the opposite (raise at import), and the PR description argues fail-fast is the safer reading and preserves the semantics already merged for the Firestore constants. Both positions are defensible and they conflict, so I'm not inverting ~20 tests on my own judgment.

One wrinkle worth naming: the owner's note was written against #1170's bare int(os.getenv(...)); a validating fail-fast parser has since merged for CLEANUP_DELETE_*, so "log and fall back" may be partly overtaken by events.

@groupthinking — please rule on #2: keep fail-fast (I'll update #1180's AC-1/AC-3 wording to match), or switch to log-and-fall-back (the new tests and the two already-merged constants change with it). I'll then implement your choice plus the #1 ceiling in one pass.

I did not approve or merge — base main is protected and the PR isn't ready regardless.


Generated by Claude Code

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/youtube_extension/backend/services/intelligent_cache.py`:
- Line 34: Replace the relative env_config import in
src/youtube_extension/backend/services/intelligent_cache.py:34-34 with an
absolute youtube_extension.core.env_config import for positive_int_env, and
update src/youtube_extension/services/cloud/firestore_state.py:17-17 to import
both helpers from the same absolute module.

In `@src/youtube_extension/core/env_config.py`:
- Around line 64-72: The integer and float environment helpers in
`src/youtube_extension/core/env_config.py` at lines 64-72 and 95-107 should use
a shared Pydantic validator instead of manual `int`/`float` conversion and
bounds checks; preserve returning the default for blank or missing overrides and
retain the existing invalid-value errors and minimum-value constraints at both
sites.

In `@src/youtube_extension/services/cloud/firestore_state.py`:
- Around line 39-40: Bound CLEANUP_DELETE_CONCURRENCY to a safe maximum instead
of relying only on positive_int_env(). Define or reuse an upper-limit constant
and validate the configured value before the cleanup worker scheduling logic
around the cleanup method at line 370, rejecting values above the limit while
preserving the existing bounded-task behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Repository UI (inherited), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 23dfec09-5a39-4200-9d80-154558376620

📥 Commits

Reviewing files that changed from the base of the PR and between b664e92 and 864f5d2.

⛔ Files ignored due to path filters (2)
  • tests/unit/test_env_config.py is excluded by !tests/**
  • tests/unit/test_firestore_state.py is excluded by !tests/**
📒 Files selected for processing (3)
  • src/youtube_extension/backend/services/intelligent_cache.py
  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
📜 Review details
⚠️ CI failures not shown inline (2)

GitHub Actions: Agent completion enforcement / 0_Agent completion enforcement.txt: feat(config): share validated env parsing for tunable concurrency constants

Conclusion: failure

View job details

##[group]Run actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
 with:
   script: const fs = require('fs');
const pull = await github.rest.pulls.get({
  owner: context.repo.owner,
  repo: context.repo.repo,
  pull_number: Number(process.env.PR)
});
let verdict = {
  conclusion: 'failure',
  reason: 'verifier_did_not_publish',
  details: {}
};
try {
  verdict = JSON.parse(fs.readFileSync(
    'enforcement-verdict.json', 'utf8'
  ));
} catch (error) {
  core.warning(error.message);
}
const conclusion = verdict.conclusion === 'success'
  ? 'success'
  : 'failure';
const summary = JSON.stringify(verdict);
await github.rest.checks.create({
  owner: context.repo.owner,
  repo: context.repo.repo,
  name: 'Agent completion enforcement',
  head_sha: pull.data.head.sha,
  status: 'completed',
  conclusion,
  output: {
    title: conclusion === 'success'
      ? 'Trusted evidence verified'
      : 'Trusted evidence blocked',
    summary: summary.slice(0, 60000)
  }
});
if (conclusion !== 'success') {
  core.setFailed(verdict.reason || 'trusted evidence blocked');
}
   github-***REDACTED_SECRET_ASSIGNMENT***
   debug: false
   user-agent: actions/github-script
   result-encoding: json
   retries: 0
   retry-exempt-status-codes: 400,401,403,404,422
 env:
   PR: 1220
 ##[endgroup]
 ##[error]missing_trusted_publication

GitHub Actions: Agent completion enforcement / Agent completion enforcement: feat(config): share validated env parsing for tunable concurrency constants

Conclusion: failure

View job details

##[group]Run actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3
 with:
   script: const fs = require('fs');
const pull = await github.rest.pulls.get({
  owner: context.repo.owner,
  repo: context.repo.repo,
  pull_number: Number(process.env.PR)
});
let verdict = {
  conclusion: 'failure',
  reason: 'verifier_did_not_publish',
  details: {}
};
try {
  verdict = JSON.parse(fs.readFileSync(
    'enforcement-verdict.json', 'utf8'
  ));
} catch (error) {
  core.warning(error.message);
}
const conclusion = verdict.conclusion === 'success'
  ? 'success'
  : 'failure';
const summary = JSON.stringify(verdict);
await github.rest.checks.create({
  owner: context.repo.owner,
  repo: context.repo.repo,
  name: 'Agent completion enforcement',
  head_sha: pull.data.head.sha,
  status: 'completed',
  conclusion,
  output: {
    title: conclusion === 'success'
      ? 'Trusted evidence verified'
      : 'Trusted evidence blocked',
    summary: summary.slice(0, 60000)
  }
});
if (conclusion !== 'success') {
  core.setFailed(verdict.reason || 'trusted evidence blocked');
}
   github-***REDACTED_SECRET_ASSIGNMENT***
   debug: false
   user-agent: actions/github-script
   result-encoding: json
   retries: 0
   retry-exempt-status-codes: 400,401,403,404,422
 env:
   PR: 1220
 ##[endgroup]
 ##[error]missing_trusted_publication
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{py,js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{py,js,jsx,ts,tsx}: Use Python 3.9+ and Node 18+ for development
Never hardcode API keys, database URLs, or secrets in code
Make minimal, surgical changes and avoid deleting working code unless fixing security issues

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
**/*.py

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.py: Always use type hints for Python functions
Use Black formatter with 88 character line length for Python code
Follow PEP 8 conventions for Python code
Use descriptive variable names and add docstrings to all public functions in Python
Group imports in Python: standard library, third-party, local
Use SQLAlchemy ORM and never write raw SQL queries
Use environment variables via os.getenv() or pydantic-settings to access configuration
Wrap database operations in try-except blocks and use context managers or FastAPI dependencies for connection cleanup
Implement comprehensive error handling with proper logging in all functions
Version APIs using /api/v1/ prefix for stability
Use JSON-RPC 2.0 protocol for all MCP communication
Follow the single-flow workflow: YouTube link → context extraction → agent dispatch → outputs
Use context managers for resource management in Python code
Implement comprehensive input validation and sanitize outputs for security
Use parameterized queries and SQLAlchemy ORM to prevent SQL injection
Define API request/response models using Pydantic for FastAPI endpoints
Store the single unified workflow as the only workflow; never introduce alternate flows or manual triggers
Use SQLAlchemy with connection pooling for database connections and manage sessions with context managers
Provide sensible defaults for non-sensitive configuration in Python settings
Maintain backward compatibility and do not break existing API endpoints
Include comprehensive logging for debugging in MCP implementations

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py

⚙️ CodeRabbit configuration file

Python backend code. Check for type hints, proper exception handling, async context manager usage, and potential blocking calls in async functions. Flag any bare except clauses or missing timeout parameters on network calls. CRITICAL: Flag any file that contains placeholder/stub implementations — especially in unified_ai_sdk. Any class or function that says "TODO: Replace with production implementation" or returns mock/fake data must be flagged as a blocking issue. Flag any code generation output that reaches users without AST validation or syntax checking.

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
**/*.{py,js,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Maintain >80% code coverage for new features

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
**/*.{py,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{py,ts,tsx}: Keep frontend and backend data models synchronized using matching Pydantic (backend) and TypeScript (frontend) interfaces
Use type-safe interfaces for backend-frontend data exchange

**/*.{py,ts,tsx}: Production code must use real behavior only: no mock delays, fake data, or simulated responses.
Maintain strict type safety: mypy strict mode for Python and TypeScript strict mode for the frontend.
Name events using the <domain>.<entity>.<action> format.

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
**/*

📄 CodeRabbit inference engine (Custom checks)

**/*: Strictly verify that GitHub Copilot has explicitly reviewed and approved the pull request; human approvals alone must not satisfy this check.
Before allowing a merge, require the copilot-rabbit label and AI-generated unit tests committed alongside the code changes; fail the check if either is missing.

For Vercel-specific work, include https://vercel.com/docs/llms-full.txt in the AI assistant context set.

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
**/*.{py,pyw}

📄 CodeRabbit inference engine (AGENTS.md)

Write Python code to remain compatible with Linux and Windows where possible, including correct handling of asyncio event loops.

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
src/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.py: Format Python code with Black using an 88-character line length.
Sort Python imports with isort using the Black profile.
Run Ruff with E, W, F, I, B, C4, and UP rules; E501 is ignored.
Use mypy strict mode; untyped function definitions are disallowed.
Target Python 3.9 or newer.
Validate backend inputs with Pydantic and sanitize subprocess arguments.
Use Anthropic SDK features thinking={"type": "adaptive"} and output_config={"effort": "..."} with anthropic>=0.105.0; do not add TypeError fallbacks for these parameters.

Use the service container dependency-injection pattern in backend/containers/.

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
**/*.{py,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not commit secrets; store keys and credentials in gitignored .env files.

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
**/*.{py,pyi}

📄 CodeRabbit inference engine (GEMINI.md)

**/*.{py,pyi}: Use Black formatting with an 88-character line length for Python code.
Use Ruff with rules E, W, F, I, B, C4, and UP for Python linting.
Use strict mypy type checking; do not define untyped functions.
Target Python 3.9 or newer.
Validate Python inputs with Pydantic.
Sanitize subprocess arguments before execution.
Do not add mock delays or fake data to production Python code; production runs in REAL_MODE_ONLY.
Keep secrets out of Python source code; load keys and credentials from environment variables instead.
Use absolute imports that resolve with PYTHONPATH=src in the Python backend.

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
**/*.{py,pyi,ts,tsx}

📄 CodeRabbit inference engine (GEMINI.md)

**/*.{py,pyi,ts,tsx}: Preserve the single workflow: YouTube link → transcript → events → agents → outputs; do not introduce alternative flows or manual triggers that bypass it.
Use event names following <domain>.<entity>.<action>, such as youtube.video.captured.
Make surgical, precise changes and do not delete working code without justification.

Files:

  • src/youtube_extension/core/env_config.py
  • src/youtube_extension/services/cloud/firestore_state.py
  • src/youtube_extension/backend/services/intelligent_cache.py
🔍 Remote MCP GitHub Copilot, Linear

Relevant review context

  • PR #1220 is open against main and changes 5 files. Its current implementation validates only a minimum of 1; Firestore creates min(CLEANUP_DELETE_CONCURRENCY, len(docs)) workers, so an extremely large override can defeat the intended task-memory bound. This is an unresolved review thread.
  • There is a requirements mismatch: the Linear triage note explicitly expects malformed values such as abc, -1, and 0 to log and fall back, while this PR intentionally raises ValueError during import. The new tests assert the fail-fast behavior rather than fallback.
  • The Redis path clamps its configured value to the connection-pool budget via _resolve_tag_write_limit(), but no equivalent use-site cap exists for Firestore cleanup.
  • The Firestore timeout behavior is pre-existing from merged PR #1170; this PR only moves its parser into the shared module.
  • At the current head, tests, coverage, lint, CodeQL, security scans, and build checks are successful. Agent completion enforcement reports failure, and the top-level Trivy check is neutral.
🔇 Additional comments (1)
src/youtube_extension/core/env_config.py (1)

67-72: 🎯 Functional Correctness

Resolve the invalid-override contract before merge.

The Linear triage requirement says malformed values must log and fall back. These branches instead terminate module import. The PR objective specifies fail-fast behavior. Confirm the approved contract, then update both parsers and their tests to match it.

  • src/youtube_extension/core/env_config.py#L67-L72: apply the approved invalid-integer behavior.
  • src/youtube_extension/core/env_config.py#L98-L107: apply the same approved invalid-float behavior.

Source: MCP tools

Comment thread src/youtube_extension/backend/services/intelligent_cache.py Outdated
Comment on lines +64 to +72
raw = _raw_override(name)
if raw is None:
return default
try:
value = int(raw)
except ValueError:
raise ValueError(f"{name} must be an integer >= 1, got {raw!r}") from None
if value < 1:
raise ValueError(f"{name} must be >= 1, got {raw!r}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the declared Pydantic version and existing validation conventions.
fd -a -t f '^(pyproject\.toml|requirements.*\.txt|poetry\.lock|uv\.lock)$' . \
  -x sh -c 'echo "--- $1"; rg -n "pydantic" "$1" || true' sh {}

rg -n -C 2 'TypeAdapter|BaseModel|BaseSettings|field_validator|validator' \
  -g '*.py' .

Repository: groupthinking/EventRelay

Length of output: 50381


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Focus on the target env_config.py file and exact validation helpers.
printf '--- env_config.py outline ---\n'
ast-grep outline src/youtube_extension/core/env_config.py --view compact || true
printf '\n--- env_config.py relevant sections ---\n'
sed -n '1,130p' src/youtube_extension/core/env_config.py | cat -n

printf '\n--- Pydantic validation occurrences in src --max-count 50 ---\n'
rg -n -C 2 'TypeAdapter|BaseModel|BaseSettings|field_validator|validator|field_validation' -g '*.py' src/ --max-count 50 || true

Repository: groupthinking/EventRelay

Length of output: 253


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Focus on the target env_config.py file and exact validation helpers.
printf '%s\n' '--- env_config.py relevant sections ---'
sed -n '1,130p' src/youtube_extension/core/env_config.py | cat -n

printf '%s\n' ''
printf '%s\n' '--- Pydantic validation occurrences in src --max-count 50 ---'
rg -n -C 2 'TypeAdapter|BaseModel|BaseSettings|field_validator|validator|field_validation' -g '*.py' src/ --max-count 50 || true

Repository: groupthinking/EventRelay

Length of output: 50380


Use a reusable Pydantic validator for environment values.

These helpers run manual int/float parsing plus bounds checks. Use Pydantic for these overrides and preserve the current blank fallback and invalid-value failure behavior.

📍 Affects 1 file
  • src/youtube_extension/core/env_config.py#L64-L72 (this comment)
  • src/youtube_extension/core/env_config.py#L95-L107
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/youtube_extension/core/env_config.py` around lines 64 - 72, The integer
and float environment helpers in `src/youtube_extension/core/env_config.py` at
lines 64-72 and 95-107 should use a shared Pydantic validator instead of manual
`int`/`float` conversion and bounds checks; preserve returning the default for
blank or missing overrides and retain the existing invalid-value errors and
minimum-value constraints at both sites.

Source: Coding guidelines

Comment thread src/youtube_extension/services/cloud/firestore_state.py Outdated

Copy link
Copy Markdown
Owner Author

Update after CodeRabbit's full review (changes_requested)

Went through all three CodeRabbit comments plus the full check state. Net: the PR is still blocked on one decision from you and one bespoke CI gate — nothing new here that I can confidently fix to reach green.

1. Invalid-value contract (env_config.py — fail-fast vs. log-and-fall-back). CodeRabbit reached the same conclusion as @copilot-pull-request-reviewer and my earlier review: "requirements mismatch — the triage note expects malformed values to log and fall back; this PR raises at import." This is the decision I flagged above, now triple-confirmed and squarely yours. Everything else hangs off it.

2. Ceiling on CLEANUP_DELETE_CONCURRENCY — valid (your own #1180 triage asked for a floor and ceiling). I'll implement it alongside your #1 decision, since its shape (raise vs. clamp on an over-max value) depends on which contract you pick.

3. "Use absolute imports" (intelligent_cache.py:34, firestore_state.py:17) — declining; this one is incorrect for this repo. The relative imports are deliberate and safer here: the codebase currently has both import roots live — 15+ modules import via from src.youtube_extension… (e.g. services/agents/agent_orchestrator.py, backend/services/parallel_video_processor.py, backend/api/advanced_video_routes.py) alongside the canonical youtube_extension.* (PYTHONPATH=src). An absolute from youtube_extension.core.env_config import … inside a module loaded under the src.youtube_extension root would import a second copy of env_config, splitting TAG_WRITE_CONCURRENCY / CLEANUP_DELETE_* into two distinct module-level constants. The relative import resolves under whichever root loaded the caller — exactly what a shared config helper needs. The guideline conflict is real but points at the pre-existing dual-root situation, not this PR.

4. "Use a Pydantic validator" (env_config.py) — declining as low value (CodeRabbit tagged it 🔵 Trivial / 💤 itself). Two ~15-line parsers with 46 tests are clearer and cheaper than a TypeAdapter wrapper; there's no request/response model boundary here to warrant Pydantic.

5. The actual failing gate: Agent completion enforcementmissing_trusted_publication. Everything substantive is green (test / lint / build / CodeQL / bandit / coverage / PR-Governance / agent-completion/truth-gate all pass). The one real failure is this bespoke enforcement check (verifier_did_not_publish) — a trusted-evidence/attestation step in your agentic workflow, not a code defect in the diff. I'm deliberately not touching it, since fabricating its evidence would defeat its purpose; it needs your workflow to publish the completion verdict.

Still not approving or merging. Once you rule on #1, I'll land #1 + the #2 ceiling in one pass and re-run the checks.


Generated by Claude Code

Copy link
Copy Markdown
Owner Author

Returned to draft during delivery control. The implementation is linked to #1180, but the current active-agent receipt and independent exact-head review/deployment evidence must be reconciled before state advancement.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Please re-review exact head 96c53e2d0adce2fb68730937719958bf6d2c30a2; the owner-confirmed fallback behavior, cleanup ceiling, absolute imports, and regression coverage are now implemented.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='96c53e2d0adce2fb68730937719958bf6d2c30a2'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual" "$expected"

echo '--- changed files at requested commit ---'
git diff-tree --no-commit-id --name-status -r "$expected"

echo '--- diff against first parent ---'
git diff --find-renames "${expected}^" "$expected" -- \
  src/youtube_extension/core/env_config.py \
  src/youtube_extension/services/cloud/firestore_state.py \
  src/youtube_extension/backend/services/intelligent_cache.py \
  tests

echo '--- source file outlines ---'
for f in \
  src/youtube_extension/core/env_config.py \
  src/youtube_extension/services/cloud/firestore_state.py \
  src/youtube_extension/backend/services/intelligent_cache.py
do
  if [ -f "$f" ]; then
    printf '\n### %s\n' "$f"
    ast-grep outline "$f" --items all || true
  fi
done

echo '--- parser, cap, and fallback references with context ---'
rg -n -C 5 \
  'positive_int_env|positive_finite_float_env|CLEANUP_DELETE_CONCURRENCY|CLEANUP_DELETE_TIMEOUT_SECONDS|TAG_WRITE_CONCURRENCY|_resolve_tag_write_limit|logging|logger\.' \
  src/youtube_extension tests 2>/dev/null || true

echo '--- relevant test definitions ---'
rg -n -C 3 \
  'positive_int_env|positive_finite_float_env|CLEANUP_DELETE_CONCURRENCY|TAG_WRITE_CONCURRENCY|fallback|ceiling|cap' \
  tests 2>/dev/null || true

echo '--- PR check state ---'
gh pr checks 1220 --repo groupthinking/EventRelay || true

Length of output: 201854


🏁 Script executed:

#!/bin/bash
set -euo pipefail

commit='96c53e2d0adce2fb68730937719958bf6d2c30a2'

echo '--- commit verification ---'
git rev-parse HEAD
git show -s --format='commit=%H%nparents=%P%nsubject=%s' "$commit"

echo '--- files changed by this commit ---'
git diff-tree --no-commit-id --name-status -r "$commit"

echo '--- focused patch ---'
git diff --find-renames --unified=80 "${commit}^" "$commit" -- \
  src/youtube_extension/core/env_config.py \
  src/youtube_extension/services/cloud/firestore_state.py \
  src/youtube_extension/backend/services/intelligent_cache.py \
  tests \
  test

echo '--- source at requested commit: env_config.py ---'
git show "${commit}:src/youtube_extension/core/env_config.py" | nl -ba | sed -n '1,260p'

echo '--- source at requested commit: firestore_state.py relevant references ---'
git show "${commit}:src/youtube_extension/services/cloud/firestore_state.py" \
  | nl -ba \
  | grep -E -C 12 'CLEANUP_DELETE|positive_|create_task|gather|Semaphore|delete' \
  || true

echo '--- source at requested commit: intelligent_cache.py relevant references ---'
git show "${commit}:src/youtube_extension/backend/services/intelligent_cache.py" \
  | nl -ba \
  | grep -E -C 12 'TAG_WRITE|positive_|_resolve_tag_write_limit|create_task|gather|Semaphore' \
  || true

echo '--- changed test files and their exact content ---'
git diff-tree --no-commit-id --name-only -r "$commit" \
  | grep -E '(^|/)(test|tests)[^/]*.*\.py$' \
  | while IFS= read -r file; do
      echo "### $file"
      git show "${commit}:$file" | nl -ba | sed -n '1,360p'
    done

echo '--- annotations for failed/pending checks ---'
for run in 30750022538 30750022540 30750022556 30750023490 30750023518; do
  echo "### run $run"
  gh api "repos/groupthinking/EventRelay/actions/runs/$run" \
    --jq '{name,status,conclusion,event,head_sha,html_url}' || true
  gh api "repos/groupthinking/EventRelay/actions/runs/$run/jobs?filter=latest" \
    --jq '.jobs[] | select(.conclusion == "failure" or .status != "completed") | {name,status,conclusion,html_url,steps:[.steps[]? | select(.conclusion == "failure") | {name,number,conclusion}]}' \
    || true
done

Length of output: 40057


🏁 Script executed:

#!/bin/bash
set -euo pipefail

commit='96c53e2d0adce2fb68730937719958bf6d2c30a2'

show_range() {
  local path="$1"
  local start="$2"
  local end="$3"
  echo "### ${path}:${start}-${end}"
  git show "${commit}:${path}" \
    | sed -n "${start},${end}p" \
    | awk -v base="$start" '{printf "%6d  %s\n", NR + base - 1, $0}'
}

show_range src/youtube_extension/services/cloud/firestore_state.py 1 65
show_range src/youtube_extension/services/cloud/firestore_state.py 260 430
show_range src/youtube_extension/backend/services/intelligent_cache.py 20 75
show_range src/youtube_extension/backend/services/intelligent_cache.py 520 690
show_range tests/unit/test_env_config.py 1 260
show_range tests/unit/test_firestore_state.py 780 1040

echo '--- package-root and import use sites ---'
git grep -nE '^from (src\.)?youtube_extension\.core\.env_config import|^from \.{2,}core\.env_config import' "$commit" -- \
  'src/**/*.py' || true

echo '--- current workflow failures ---'
for run in 30750022538 30750022540 30750022556; do
  echo "### failed log for workflow run $run"
  gh run view "$run" --repo groupthinking/EventRelay --log-failed 2>&1 | tail -n 180 || true
done

echo '--- latest check state ---'
gh pr checks 1220 --repo groupthinking/EventRelay || true

Length of output: 108811


@groupthinking No actionable code findings on exact head 96c53e2d0adce2fb68730937719958bf6d2c30a2.

Verified:

  • Invalid environment values now log a warning and use the shipped default.
  • CLEANUP_DELETE_CONCURRENCY has a hard maximum of 64.
  • cleanup_old_states() creates at most the effective worker-count tasks. It does not allocate one task per document.
  • Absolute imports are consistent in both changed consumers.
  • Regression tests cover fallback behavior, import-time overrides, the maximum value, bounded RPC/task concurrency, and continued cleanup after a delete failure.

CI status:

  • test passed.
  • Build, lint, CodeQL, security, and dependency checks passed.
  • Coverage is still pending.
  • Canonical issue and evidence and Agent completion enforcement failed because the GitHub App installation exhausted its API quota (403).
  • agent-completion/truth-gate failed because no gate-status lease or gate-verdict.json was available.

The remaining failures are workflow infrastructure failures. They are not caused by this code change.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Owner Author

Reviewed the new head 96c53e2 — you've implemented the work I'd offered to do, and it looks correct:

  • Fallback contract — both parsers now log-and-fall-back on invalid input via _fallback(), matching your Harden Firestore cleanup: configurable concurrency and explicit RPC timeouts #1180 triage. Startup is preserved and the diagnostic names the variable and echoes the value.
  • CeilingCLEANUP_DELETE_CONCURRENCY_MAX = 64 with positive_int_env(…, maximum=64); an over-cap value logs and falls back to 16, so a typo can't allocate one task per queued document. Tests cover both at-max (64 accepted) and over-max (65 → fallback).
  • Regression coveragetest_env_config.py plus the firestore tests now assert fallback + maximum + import-time wiring (including the subprocess stderr-diagnostic check).

On the absolute imports: withdrawing my earlier objection. The concern (a second env_config copy under the src.youtube_extension root) is real at the module-identity level but immaterial for these constants — both copies read the same env var and resolve to equal integers, and nothing depends on cross-root identity here. Your choice is the guideline-compliant one and introduces no functional bug.

No code issues from me on 96c53e2. The remaining gates are your delivery-control ones (the Agent completion enforcement / trusted-evidence refresh + Copilot re-approval), not the diff.


Generated by Claude Code

The fail-safe rework left three lint regressions relative to the branch
point, and dropped six malformed-input cases from the parametrize lists.

- ruff I001: the absolute import in firestore_state.py is 89 chars, one
  over the limit, so the import block needed rewrapping.
- black: _fallback()'s signature and the expected-value ternary in
  test_env_config.py both exceeded 88 chars.
- Re-add the invalid inputs dropped in the rewrite: -42, 8x, 0x10 for
  int; NaN, 0.0, 12s for float. Each exercises a distinct rejection
  path (parse error, range check, finiteness check).

Pre-existing debt left untouched: firestore_state.py is already
black-dirty on origin/main, and the unused 'result' at
test_firestore_state.py:530 predates this branch.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Please review exact head 1fbfe0aacc1064a13d99b37223d9f82565a42209. The new commit is a non-empty lint/test restoration on the existing focused repair; all exact-head code and security workflows pass.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="groupthinking/EventRelay"
pr="1220"
commit="1fbfe0aacc1064a13d99b37223d9f82565a42209"

echo '--- exact-head verification ---'
printf 'checked_out=%s\n' "$(git rev-parse HEAD)"
git show -s --format='commit=%H%nparents=%P%nsubject=%s%ncommitted=%cI' "$commit"

echo '--- commit file list ---'
git diff-tree --no-commit-id --name-status -r "$commit"

echo '--- commit patch ---'
git diff --find-renames --unified=100 "${commit}^" "$commit" -- \
  src/youtube_extension/core/env_config.py \
  src/youtube_extension/services/cloud/firestore_state.py \
  src/youtube_extension/backend/services/intelligent_cache.py \
  tests test

echo '--- affected-file outlines ---'
git diff-tree --no-commit-id --name-only -r "$commit" |
while IFS= read -r file; do
  case "$file" in
    *.py)
      echo "### $file"
      ast-grep outline "$file" --items all || true
      ;;
  esac
done

echo '--- environment configuration and concurrency references at exact head ---'
git grep -n -E \
  'positive_int_env|positive_finite_float_env|CLEANUP_DELETE_CONCURRENCY|CLEANUP_DELETE_CONCURRENCY_MAX|TAG_WRITE_CONCURRENCY|_resolve_tag_write_limit|create_task|Semaphore|gather' \
  "$commit" -- src/youtube_extension tests test || true

echo '--- exact-head pull request checks ---'
gh pr checks "$pr" --repo "$repo" || true

echo '--- non-successful exact-head workflow runs ---'
gh api "repos/${repo}/actions/runs?head_sha=${commit}&per_page=100" \
  --jq '.workflow_runs[] | select(.status != "completed" or (.conclusion != "success" and .conclusion != "skipped" and .conclusion != "neutral")) | {id,name,status,conclusion,html_url}' \
  || true

Length of output: 59024


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo="groupthinking/EventRelay"
pr="1220"
commit="1fbfe0aacc1064a13d99b37223d9f82565a42209"
run="30750464152"

echo '--- pull request head at completion ---'
gh pr view "$pr" --repo "$repo" --json headRefOid,isDraft,state \
  --jq '{headRefOid,isDraft,state}'

echo '--- branch-cleanup workflow metadata ---'
gh api "repos/${repo}/actions/runs/${run}" \
  --jq '{id,name,event,status,conclusion,head_sha,head_branch,workflow_id,created_at,updated_at,html_url}'

echo '--- failed jobs and failed steps ---'
gh api "repos/${repo}/actions/runs/${run}/jobs?filter=latest" \
  --jq '.jobs[] | {name,status,conclusion,started_at,completed_at,html_url,steps:[.steps[]? | select(.conclusion == "failure") | {number,name,status,conclusion}]}'

echo '--- failed workflow log tail ---'
gh run view "$run" --repo "$repo" --log-failed 2>&1 | tail -n 200 || true

echo '--- check-run association for requested commit ---'
gh api "repos/${repo}/commits/${commit}/check-runs?per_page=100" \
  --jq '.check_runs[] | select(.conclusion == "failure" or .status != "completed") | {name,status,conclusion,details_url,app:.app.slug}' || true

Length of output: 2493


@groupthinking No actionable findings on exact head 1fbfe0aacc1064a13d99b37223d9f82565a42209.

Verified:

  • The commit is non-empty and is based on 96c53e2.
  • The commit does not change runtime behavior.
  • It restores formatter-compliant layout in env_config.py and firestore_state.py.
  • It restores invalid integer and float input cases in tests/unit/test_env_config.py.
  • The restored cases cover malformed values, negative values, zero values, accepted float() spellings such as NaN, and unit-suffix input.
  • The existing fallback, warning, maximum, and import-time wiring behavior remains intact.

Exact-head checks pass for test, coverage, build, Python lint, CodeQL, security scans, dependency review, and agent-completion/truth-gate.

The separate branch-cleanup.yml workflow reports a workflow-level failure, but its jobs are neutral/skipped. GitHub does not associate it with a failed check run on this commit. It does not indicate a defect in this PR.

You are interacting with an AI system.

@groupthinking
groupthinking marked this pull request as ready for review August 4, 2026 01:38
@groupthinking
groupthinking merged commit 626154b into main Aug 4, 2026
51 checks passed
@groupthinking
groupthinking deleted the groupthinking-shared-env-tunables branch August 4, 2026 01:38
@linear-code

linear-code Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

GRV-283

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Harden Firestore cleanup: configurable concurrency and explicit RPC timeouts

2 participants