Skip to content

feat: harden async tools, streaming, auth, and v0.0.10 release - #24

Merged
robotlearning123 merged 16 commits into
mainfrom
audit/release-v0.0.10-20260709
Jul 10, 2026
Merged

feat: harden async tools, streaming, auth, and v0.0.10 release#24
robotlearning123 merged 16 commits into
mainfrom
audit/release-v0.0.10-20260709

Conversation

@robotlearning123

@robotlearning123 robotlearning123 commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • move blocking REST, auth, Sentinel, and streaming boundaries off the event loop and fail closed on incomplete tool/DR streams
  • validate identifiers, redact persisted matching data, serialize instruction updates, and harden private runner artifacts
  • make Codex/Claude installation portable and transactional, including quoted TOML tables, CODEX_HOME, pipx interpreter migration, and Windows package smoke coverage
  • harden CI/release gates, pin Actions, verify exact artifact hashes against PyPI, and prepare version 0.0.10

Verification

  • SKIP_LIVE=1 python -m pytest -q318 passed, 9 skipped
  • python -m ruff check gpt2agent tests scripts
  • python scripts/verify_release.py
  • python -m compileall -q gpt2agent tests scripts
  • ShellCheck across all tracked shell scripts
  • parsed every workflow YAML file
  • project-resolved pip-audit --strict .no known vulnerabilities
  • Bandit — 0 medium/high (15 low heuristic findings)
  • clean git archive HEAD build and Twine check
  • clean wheel install, pip check, CLI/module/resource/skill smoke
  • clean sdist install and parser fixture suite — 18 passed
  • PyPI absence gate for 0.0.10
  • exact rehearsal hashes:
    • wheel: d019af67cc267210865d86b2fd73789b764f5e28a8e4d899039364390d3798a5
    • sdist: 8e2622ec1a3addddef4b0ff8409649e693e3eed2a8a95705bf237c5662551dfb

Closes #22

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@robotlearning123, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 66233a5f-04a9-46e5-9876-956eb3074a66

📥 Commits

Reviewing files that changed from the base of the PR and between 0439e05 and cd67d83.

📒 Files selected for processing (1)
  • tests/test_audit_2026_07_09_package.py
📝 Walkthrough

Walkthrough

The release updates version metadata to 0.0.10, adds release and artifact verification, converts REST tools to asynchronous handlers, and hardens authentication, installation, SSE/Deep Research processing, private artifacts, CI, documentation, and regression coverage.

Changes

Release 0.0.10 and validation

Layer / File(s) Summary
Release metadata and CI gates
.claude-plugin/plugin.json, pyproject.toml, server.json, scripts/*, .github/workflows/*
Version consistency checks, PyPI artifact hashing, pinned actions, Windows smoke tests, annotated-tag validation, and build verification are added.
Packaging and installer behavior
install.sh, gpt2agent/__main__.py, MANIFEST.in, .gitignore
Package execution, source distribution contents, pipx replacement, source selection, and diagnostic dump exclusions are updated.

Runtime hardening

Layer / File(s) Summary
Authentication and installation flows
gpt2agent/auth.py, backend.py, install.py, setup.py, _vendored/turnstile.py
Token shapes are validated, Codex paths honor CODEX_HOME, token reloads are synchronized, TOML edits are parsed, skill installation is transactional, plan detection fails closed, and Turnstile timing is per-call.
SSE and Deep Research completion
gpt2agent/sse.py, gpt2agent/skills/deep-research/bin/*
Incomplete streams, clarification follow-ups, connector failures, widget provenance, polling timeouts, private artifacts, and terminal status reporting are handled explicitly.
Asynchronous REST tools and privacy checks
gpt2agent/tools/*
REST handlers use asyncio.to_thread, path IDs are validated, memory matching redacts before comparison, and custom-instruction updates serialize read-modify-write operations.

Sequence Diagram(s)

sequenceDiagram
  participant MCPTool
  participant AsyncBackend
  participant BackendClient
  participant ChatGPTAPI
  MCPTool->>AsyncBackend: await REST tool request
  AsyncBackend->>BackendClient: execute synchronous request in thread
  BackendClient->>ChatGPTAPI: HTTP request
  ChatGPTAPI-->>BackendClient: response
  BackendClient-->>AsyncBackend: response payload
  AsyncBackend-->>MCPTool: tool result
Loading

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description omits the required What & why section, Type selection, and checklist items from the template. Add the template sections and fill in the Type and checklist entries, including changelog, tests, secrets, and one-concern-only confirmation.
Out of Scope Changes check ⚠️ Warning The PR includes many unrelated auth, streaming, install, CI, release, docs, and packaging changes beyond issue #22's REST-tool async conversion. Split the unrelated hardening, release, packaging, and documentation work into separate PRs, leaving only the async REST tool conversion and matching tests here.
Docstring Coverage ⚠️ Warning Docstring coverage is 52.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the PR's main themes of async tool hardening and release/version updates.
Linked Issues check ✅ Passed The REST tools were converted to async handlers and backed by async helpers that use asyncio.to_thread, and tests were updated accordingly.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch audit/release-v0.0.10-20260709

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.

@robotlearning123
robotlearning123 merged commit cda7e6b into main Jul 10, 2026
13 checks passed
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Caution

Review failed

An error occurred during the review process. Please try again later.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch audit/release-v0.0.10-20260709

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
gpt2agent/sentinel.py (1)

75-86: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

POW failure path never trips here

_pow.solve_pow() returns a non-empty stub token even when it doesn’t solve the challenge, so if not proof can never fire. A required POW miss still gets an invalid token instead of failing closed. Make the solver return None/raise on failure, or surface the solved flag so this branch can reject it.

🤖 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 `@gpt2agent/sentinel.py` around lines 75 - 86, Ensure required POW failures are
rejected in the POW handling branch of the sentinel request flow: update
_pow.solve_pow to return None or raise when it cannot solve the challenge, or
expose a solved-status result and check it alongside proof before assigning
out["proof"]. Remove reliance on a non-empty stub token so unsolved challenges
raise the existing failure error.
🧹 Nitpick comments (1)
gpt2agent/sse.py (1)

85-101: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Consider O_NOFOLLOW for the raw-dump file, for consistency with other output-hardening in this PR.

_raw_dump now tightens permissions to 0o600 (good), but the os.open call doesn't pass os.O_NOFOLLOW. The bundled deep-research runner hardens its own output files against symlink attacks (see test_bundled_runner_refuses_symlinked_output_artifact), so this debug dump path (which can contain full conversation content) is inconsistent with that pattern. Risk is low since GPT2AGENT_RAW_DUMP is a developer-set debug env var, but worth aligning for defense-in-depth.

🔒 Suggested hardening
-        fd = os.open(out, os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o600)
+        flags = os.O_WRONLY | os.O_CREAT | os.O_APPEND
+        if hasattr(os, "O_NOFOLLOW"):
+            flags |= os.O_NOFOLLOW
+        fd = os.open(out, flags, 0o600)
🤖 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 `@gpt2agent/sse.py` around lines 85 - 101, Harden _raw_dump’s file creation
against symlink traversal by adding os.O_NOFOLLOW to the flags passed to
os.open, matching the output-file security pattern used elsewhere; preserve
compatibility by conditionally including the flag when available and continue
handling resulting OS errors through the existing exception path.
🤖 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 @.github/workflows/ci.yml:
- Line 21: Set persist-credentials: false on every actions/checkout step in the
workflow, including the four checkout entries identified in the diff. Preserve
the existing pinned action revisions and add the option under each checkout
configuration.

---

Outside diff comments:
In `@gpt2agent/sentinel.py`:
- Around line 75-86: Ensure required POW failures are rejected in the POW
handling branch of the sentinel request flow: update _pow.solve_pow to return
None or raise when it cannot solve the challenge, or expose a solved-status
result and check it alongside proof before assigning out["proof"]. Remove
reliance on a non-empty stub token so unsolved challenges raise the existing
failure error.

---

Nitpick comments:
In `@gpt2agent/sse.py`:
- Around line 85-101: Harden _raw_dump’s file creation against symlink traversal
by adding os.O_NOFOLLOW to the flags passed to os.open, matching the output-file
security pattern used elsewhere; preserve compatibility by conditionally
including the flag when available and continue handling resulting OS errors
through the existing exception path.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: b88d1565-9053-48f8-94e1-6fa7fc59e16d

📥 Commits

Reviewing files that changed from the base of the PR and between 49199d2 and 0439e05.

📒 Files selected for processing (64)
  • .claude-plugin/plugin.json
  • .github/dependabot.yml
  • .github/pull_request_template.md
  • .github/workflows/ci.yml
  • .github/workflows/release.yml
  • .gitignore
  • CHANGELOG.md
  • CONTRIBUTING.md
  • MANIFEST.in
  • QA_REPORT.html
  • README.md
  • artifacts/verify/heavy-dr-citations-20260603.md
  • docs/clients.md
  • docs/configuration.md
  • docs/faq.md
  • docs/how-it-works.md
  • docs/quickstart.md
  • docs/troubleshooting.md
  • gpt2agent/__init__.py
  • gpt2agent/__main__.py
  • gpt2agent/_vendored/turnstile.py
  • gpt2agent/auth.py
  • gpt2agent/backend.py
  • gpt2agent/install.py
  • gpt2agent/sentinel.py
  • gpt2agent/setup.py
  • gpt2agent/skills/deep-research/SKILL.md
  • gpt2agent/skills/deep-research/bin/deep_research.py
  • gpt2agent/skills/deep-research/bin/quota.sh
  • gpt2agent/skills/deep-research/bin/run.sh
  • gpt2agent/skills/gpt2agent/SKILL.md
  • gpt2agent/skills/gpt2agent/tools-reference.md
  • gpt2agent/sse.py
  • gpt2agent/tools/_backend.py
  • gpt2agent/tools/_ids.py
  • gpt2agent/tools/_redact.py
  • gpt2agent/tools/account.py
  • gpt2agent/tools/apps.py
  • gpt2agent/tools/codex.py
  • gpt2agent/tools/conversations.py
  • gpt2agent/tools/gpts.py
  • gpt2agent/tools/images.py
  • gpt2agent/tools/instructions.py
  • gpt2agent/tools/memory.py
  • gpt2agent/tools/writes.py
  • install.sh
  • pyproject.toml
  • scripts/verify_pypi_artifacts.py
  • scripts/verify_release.py
  • server.json
  • tests/fixtures/heavy_dr_widget_state.json
  • tests/test_audit_2026_06_26.py
  • tests/test_audit_2026_07_02.py
  • tests/test_audit_2026_07_09_auth.py
  • tests/test_audit_2026_07_09_package.py
  • tests/test_audit_2026_07_09_streaming.py
  • tests/test_audit_2026_07_09_tools.py
  • tests/test_dr_clarification.py
  • tests/test_heavy_dr_parser.py
  • tests/test_install.py
  • tests/test_none_guards.py
  • tests/test_release_metadata.py
  • tests/test_security_hardening.py
  • tests/test_tools.py

Comment thread .github/workflows/ci.yml
name: Python quality + release metadata
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.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.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Set persist-credentials: false on all actions/checkout steps.

By default, actions/checkout persists the GitHub token in .git/config, making it accessible to any subsequent step. While the current workflow steps are trusted, adding persist-credentials: false is a trivial hardening measure that prevents credential leakage if a future step is added or a dependency is compromised.

🔒️ Proposed fix (apply to all four checkout steps)
       - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
+        with:
+          persist-credentials: false

Also applies to: 49-49, 79-79, 100-100

🧰 Tools
🪛 zizmor (1.26.1)

[warning] 21-21: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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 @.github/workflows/ci.yml at line 21, Set persist-credentials: false on every
actions/checkout step in the workflow, including the four checkout entries
identified in the diff. Preserve the existing pinned action revisions and add
the option under each checkout configuration.

Source: Linters/SAST tools

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.

Convert sync REST tools to async def + asyncio.to_thread

1 participant