fix: CodeRabbit auto-fixes for PR #13 - #15
coderabbitai[bot] wants to merge 80 commits into
Conversation
Add critical evaluation of the termux-monorepo architecture, detailing branch topology, security concerns, and recommendations for improvement prior to Merging.
Added detailed repository audit findings, including branch inventory, pull request evaluations, architectural strengths, risks, and recommendations for improvement. Added content from the links.
Added initial proposal for ChatGPT integration and repository improvements.
Fixed 6 file(s) based on 10 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedFailed to post review comments. We encountered an issue with GitHub. Use ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (95)
💤 Files with no reviewable changes (1)
|
| Layer / File(s) | Summary |
|---|---|
Reliability and safety archwiz/*, deepcli/*, archwiz/restore_version.py, archwiz/linear_sync.py |
Adds bounded log reads, subprocess failure reporting, portable identity lookup, restore containment checks, safer task matching, and HTTP fallback handling. |
Content addressing and dashboard cli-synthegration/*, termux-multi-agent/dashboard.py, deepcli-tui/tui.py |
Uses full SHA-256 hashes and replaces ANSI dashboard rendering with Rich Live output. |
Agentic CI
| Layer / File(s) | Summary |
|---|---|
Routing actions and workflows .github/actions/*, scripts/model_router.py, .github/workflows/gemini-*.yml |
Adds provider routing, free-model discovery, quota handling, reusable Gemini workflows, and HTTP model invocation. |
Agent feedback and review orchestration .github/workflows/agent-*.yml, .github/workflows/peer-review-orchestrator.yml |
Adds Linear feedback subtasks, Jules triggers, peer-review polling, Autofix requests, and idempotent status comments. |
Wiki publication .github/workflows/publish-wiki.yml |
Publishes wiki changes on branch pushes or manual dispatch. |
NexusCLI and indexing
| Layer / File(s) | Summary |
|---|---|
NexusCLI nexuscli/*, multi-ai-cli/backends/* |
Adds session and chat commands, API operations, proof-of-work solving, exports, secure caches, and requests compatibility wrappers. |
Database indexing src/db.py, termux-multi-agent/src/db.py, termux-multi-agent/*/run.py, termux-multi-agent/provision_agent.py, tests/test_db_optimized.py |
Adds shared SQLite connections, batched writes, FTS5 message search, and database tests. |
Documentation and governance
| Layer / File(s) | Summary |
|---|---|
Repository guidance and proposals AGENTS.md, GEMINI.md, README.md, docs/**, .Jules/*, .coderabbit.yaml |
Adds operating rules, Termux guidance, identity hygiene, proposal records, routing schemas, and review configuration. |
Wiki content and status wiki/*, workspace/llm_map/master_tasks.json |
Adds architecture and navigation pages, DeepWiki mirroring guidance, and marks arch-015 complete. |
Estimated code review effort: 5 (Critical) | ~120 minutes
Possibly related issues
- @Gemini-CLI GitHub Actions Workflows require improvement from failure #54 — The PR adds and modifies Gemini workflow files, including dispatch and reusable review workflows.
Possibly related PRs
- timerloggedout-spec/termux-monorepo#36 — Shares Gemini CLI workflow integration.
- timerloggedout-spec/termux-monorepo#40 — Shares the NexusCLI package, API wrapper, launcher, documentation, and proof-of-work solver.
- timerloggedout-spec/termux-monorepo#19 — Shares SQLite batching and full SHA-256 content-addressed storage changes.
Suggested reviewers: timerloggedout-spec
| f.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - Dispatch error: {e}\n") | ||
| except: | ||
| except OSError: |
There was a problem hiding this comment.
🔴 Command-line tool can crash right after starting a new chat session
The fallback error-logging step only tolerates file-system failures (except OSError at deepcli/deepcli/core.py:79) instead of any failure, so if the logging helper itself cannot be loaded the whole command aborts with an error instead of quietly continuing.
Impact: Users creating a new session can see the CLI/server crash with a traceback in environments where the companion configuration package isn't importable.
Exception type narrowing inside the nested error handler
_set_last_session wraps get_history(...) in a try/except; inside the handler it does from archwiz.config import LOG_DIR and writes a log file. When deepcli is installed/run without the monorepo root on sys.path, that import raises ModuleNotFoundError (a subclass of ImportError, not OSError). Previously the bare except: swallowed it; now the exception escapes _set_last_session and propagates to callers such as deepcli/deepcli/cli.py:80 and deepcli/server.py:49. Note the sibling hook in _cache_save was correctly changed to except Exception: (deepcli/deepcli/core.py:64), making this inconsistent.
Was this helpful? React with 👍 or 👎 to provide feedback.
| # Match task ID as complete token, not substring | ||
| status = "DONE" if any(task_id_str == line.strip() or task_id_str in line.split() for line in done) else "TODO" |
There was a problem hiding this comment.
🟡 Completed tasks can be reported as not done after stricter matching
Task completion is now decided by whitespace-separated exact matching (task_id_str in line.split() at archwiz/linear_sync.py:60), so completion entries where the identifier is followed by punctuation are no longer recognized.
Impact: Tasks that are actually finished are reported as TODO in the sync output, giving a misleading status list.
Punctuation-adjacent IDs no longer match
taDone.md lines are free-form markdown; common forms such as - [x] M-01: path normalization, **M-01**, or (M-01) split into tokens like M-01: / **M-01**, which never equal task_id_str, and the whole-line comparison also fails. The previous substring test matched all of these. If a whole-token match is desired, use a word-boundary regex (re.search(rf"(?<!\w){re.escape(task_id_str)}(?!\w)", line)) instead of split().
Prompt for agents
In archwiz/linear_sync.py the DONE/TODO determination was changed from a substring check to `task_id_str == line.strip() or task_id_str in line.split()`. taDone.md is free-form markdown, so IDs typically appear adjacent to punctuation or markdown emphasis (e.g. '- [x] M-01: done', '**M-01**'), which tokenizes into 'M-01:' or '**M-01**' and no longer matches, causing completed tasks to be reported as TODO. Consider a word-boundary regex match on the escaped ID instead of split()-based tokenization, so punctuation-adjacent occurrences still match while avoiding partial-ID substring matches.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| # Root containment check: ensure target_path resolves within HOME | ||
| try: | ||
| resolved_target = target_path.resolve() | ||
| resolved_home = HOME.resolve() | ||
| if not str(resolved_target).startswith(str(resolved_home)): | ||
| print(f"{R}Error: Target path must be within home directory{N}") | ||
| return False | ||
| except (OSError, ValueError) as e: | ||
| print(f"{R}Error validating target path: {e}{N}") | ||
| return False |
There was a problem hiding this comment.
📝 Info: Home-containment check happens after expensive retrieval work
The containment validation runs only after find_last_good_version and extract_code_from_session (and potentially a subprocess codex search at archwiz/restore_version.py:104-107) have already executed. Validating output_path/target_file at the start of restore() (or in __main__) would avoid doing all that work for a path that will be rejected anyway.
Was this helpful? React with 👍 or 👎 to provide feedback.
| if PIPELINE_ACTIVE: | ||
| subprocess.run(['python3', str(control_script), 'stop']) | ||
| print(f"{R}Pipeline stopped.{N}") | ||
| PIPELINE_ACTIVE = False | ||
| result = subprocess.run(['python3', str(control_script), 'stop']) | ||
| if result.returncode == 0: | ||
| print(f"{R}Pipeline stopped.{N}") | ||
| PIPELINE_ACTIVE = False | ||
| else: | ||
| print(f"{R}Failed to stop pipeline.{N}") | ||
| else: | ||
| env = os.environ.copy() | ||
| env['ARCHWIZ_MODE'] = PIPELINE_MODE | ||
| subprocess.run(['python3', str(control_script), 'start']) | ||
| print(f"{G}Pipeline started in {PIPELINE_MODE} mode.{N}") | ||
| PIPELINE_ACTIVE = True | ||
| result = subprocess.run(['python3', str(control_script), 'start'], env=env) | ||
| if result.returncode == 0: | ||
| print(f"{G}Pipeline started in {PIPELINE_MODE} mode.{N}") | ||
| PIPELINE_ACTIVE = True | ||
| else: |
There was a problem hiding this comment.
📝 Info: Pipeline state is only in-memory, so start/stop success tracking can drift
PIPELINE_ACTIVE is a module-global initialized to False on every dashboard launch; the new return-code checks make the flag more faithful to the last command executed but still don't reflect an already-running listener started outside this process. Consequently get_pipeline_status() shows OFF (and never reads the log) for a pipeline that is actually running. Querying listener_control.py status at startup would make the display accurate.
Was this helpful? React with 👍 or 👎 to provide feedback.
- Document mandatory pull/cherry-pick → smoke-test → clean workflow for agents - Forbid models, session dumps, exports, venvs in working tree - Provide agent checklist + weekly health commands - Target: keep .git under 200 MB under normal use Co-authored-by: ArchW1z <lean-maintenance>
…Bolt) Up to ~95% reduction in SQLite transaction/connection I/O during workspace indexing. - executemany batching for nodes/edges - optional shared conn across tree walks - FTS5 messages table + helpers - tests/test_db_optimized.py - synchronized blueprints in provision_agent Jules task 11274228245989312171 Merged by automated production prioritization.
… (Palette) Replaces raw ANSI clear with rich.live.Live + Table/Panel. - Differential updates, color status, clean empty-state guidance - KeyboardInterrupt restores cleanly - Journaled in .Jules/palette.md Jules task 10623504202529550216 Merged by automated production prioritization.
Immediate enablement: GHA workflows only fire from default branch for pull_request_review / review_comment events. Agent: Grok Profile: https://x.com/grok Signed-off-by: Grok <grok@x.ai>
Seed wiki/ + publish-wiki workflow. Address Devin review (concurrency, explicit token). One-time: initialize Wiki tab with a dummy page, then run Actions → Publish wiki.
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
| # Read only the last few lines instead of the whole file | ||
| try: | ||
| with open(plog, 'rb') as f: | ||
| f.seek(0, 2) # Go to end | ||
| file_size = f.tell() | ||
| # Read up to last 2KB (roughly 20-30 lines) | ||
| read_size = min(2048, file_size) | ||
| f.seek(file_size - read_size) | ||
| chunk = f.read().decode('utf-8', errors='replace') | ||
| lines = chunk.splitlines() | ||
| if read_size < file_size and lines: | ||
| lines = lines[1:] # drop possibly partial first line | ||
| for line in reversed(lines): | ||
| if line.strip() and '\u274c' not in line and '#' not in line: | ||
| last = line.strip()[:80] | ||
| return f" {status} {mode_str} | {C}{last}{N}" | ||
| except OSError: | ||
| pass |
There was a problem hiding this comment.
📝 Info: Tail-read of autoexec.log silently loses the newest matching line if it's beyond the 2KB window
The new tail-read only inspects the last 2KB and additionally drops the first (possibly partial) line when truncation occurred (archwiz/archwiz.py:56-61). If the log's most recent lines are all filtered out (contain # or ❌) but an eligible line exists earlier in the file, the status line silently degrades to showing no last-activity text, whereas the previous full-file read would have found it. Acceptable trade-off for a dashboard, but worth noting as a behavior change.
Was this helpful? React with 👍 or 👎 to provide feedback.
| # Handle missing IDs and match as complete tokens | ||
| if task_id is None: | ||
| continue | ||
| task_id_str = str(task_id) | ||
| # Match task ID as complete token, not substring | ||
| status = "DONE" if any(task_id_str == line.strip() or task_id_str in line.split() for line in done) else "TODO" |
There was a problem hiding this comment.
🔍 Task ID matching still relies on whitespace tokenization
The new match task_id_str == line.strip() or task_id_str in line.split() (archwiz/linear_sync.py:60) is stricter than the prior substring check, but markdown lines like - [x] TASK-12: done tokenize to TASK-12: (with a trailing colon), so IDs followed by punctuation will now be reported as TODO where they were previously DONE. A regex word-boundary match would handle punctuation-adjacent IDs.
Was this helpful? React with 👍 or 👎 to provide feedback.
Added detailed instructions for setting up a Termux environment on Ubuntu/Linux, including methods like Docker, Anbox/Waydroid, and Android Studio Emulator. Provided a comparison of these methods for sandbox testing.
Added a section on developing workflow for the termux-smoke branch and considerations for agent access.
Added high priority note about initializing Render marketplace.
Docs-only sync from master-staging + kimi cloud-offload pointer. Signed-off-by: Grok ArchW1z
…fault branch Place agent-jules-on-issues + gemini-* workflows on master so issue_comment and issues events fire (GitHub only loads these from the default branch). Includes coordination: prior open agent PR inventory + agent-claim rules so Jules and Gemini do not edit the same files on the same issue. Also ships GEMINI.md + agentic docs for agent context. Agent: Grok · Signed-off-by: Grok <grok@x.ai>
- Nest kimi-cloud-offload under active/ (MANIFEST, ITEMS, DEBATE) - Keep full text on docs/kimi-cloud-offload-evaluation; pointer on master - Update registry.yaml + proposals README navigation - CONSENSUS §10 + PROCESS automation for promotion path - scripts/proposals: validate_registry, record_vote, promote_proposal - GHA proposal-lifecycle: registry validate + PR checklist comment
Signed-off-by: Grok <grok@x.ai>
Signed-off-by: Grok <grok@x.ai>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…sue_comment) On issue_comment/review events checkout is default branch, so git diff origin/master...HEAD is empty. Fetch the real PR diff via gh api independent of checkout ref. Cap at 24k chars. Add curl timeouts so network blips degrade to warning comment not silent fail. Also validate TARGET_PR is numeric before write path. Addresses Devin empty-diff finding on #97. Signed-off-by: Grok <grok@x.ai>
…ter-invoke-free feat(routing): FB-01 OpenRouter free-tier invoke + leaderboard matrix (#94)
- model-router: peer band (Omni auto/best-free + OR :free) ordered by role model preference; Gemini residual only - http-llm-invoke: shared OpenAI-compat call + comment; auto base URL discovery; curl timeouts; :free hard rule - routing-priority.yaml v2 peer policy + discovery catalog (ADE/BIUDL) - gemini-triage: wire has-omni + peer invoke paths FREE TIER ONLY. After #93 + #97 on master. Signed-off-by: Grok <grok@x.ai>
…list, wire review/invoke Devin 🔴 triage prompt had no issue #/title/body/EXTRA_CTX. SEC: validate https + catalog hosts before Bearer POST. Wire has-omni + http-llm-invoke on review/invoke; continue-on-error on invoke. FREE TIER ONLY. Closes operational gap for #91. Signed-off-by: Grok <grok@x.ai>
Was hard-coded has-openrouter:false → always Gemini-only. Wire peer flags + optional peer HTTP second-pass; Gemini residual kept. Checkout default branch for trusted composite actions under workflow_run. Signed-off-by: Grok <grok@x.ai>
…#102) Wire has-omni/has-openrouter on after-peers; peer HTTP second-pass; Gemini residual. Trusted checkout from default branch under workflow_run. Signed-off-by: Grok <grok@x.ai>
Add https://github.com/timerloggedout-spec/termux-monorepo/tree/deep_core/feat/reverse_engineered_deepseek_wasm_gh-worflows && Labels: True Requesting, additional changes, upgrade Optimization Enhancements Help
Maximize CodeRabbit coverage on deep_core track and auto-labeling. Implements: CodeRabbit maximization (operator request) Signed-off-by: Grok <grok@x.ai>
…outing (#119) - Replaced rigid bash picking logic inside GHA model router with `scripts/model_router.py`. - Implemented real-time OpenRouter `:free` model availability polling via live API endpoint. - Introduced custom performance index (ELO ≈ 3L0) in `docs/schemas/model-success-matrix.yaml` to phase out reliance on public leaderboards. - Maintained 100% GHA cache budget compatibility and added comprehensive pytest unit tests under `tests/test_model_router.py`.
…119) - Replaced rigid bash picking logic inside GHA model router with `scripts/model_router.py`. - Implemented real-time OpenRouter `:free` model availability polling via live API endpoint. - Introduced custom performance index (ELO ≈ 3L0) in `docs/schemas/model-success-matrix.yaml` to phase out reliance on public leaderboards. - Catch Linear 'usage limit exceeded' / 'USAGE_LIMIT_EXCEEDED' GraphQL errors gracefully in `agent-feedback-linear-sync.yml` to prevent CI failure when free tiers are exhausted. - Maintained 100% GHA cache budget compatibility and added comprehensive pytest unit tests under `tests/test_model_router.py`.
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ching, robust fallback, security checks, and graceful Linear sync limit handling (#119) - Replaced rigid GHA bash router with `scripts/model_router.py`. - Added 1-hour temporal file caching for OpenRouter `:free` model list polling to optimize polling timing/intervals. - Guarded polling behind `has_openrouter` to completely eliminate redundant network latency on restricted runners. - Asserted `:free` suffix check on all selected OpenRouter models for robust safety enforcement. - Wrapped `main()` in a top-level try-except for seamless graceful degradation inside actions. - Moved comment reaction inside try-except for Linear issue synchronization in `agent-feedback-linear-sync.yml` to prevent fake success reactions on limit errors. - Added comprehensive unit tests in `tests/test_model_router.py` (all passed).
- Replaced rigid GHA bash router with `scripts/model_router.py`. - Added 1-hour temporal file caching for OpenRouter `:free` model list polling to optimize polling timing/intervals. - Guarded polling behind `has_openrouter` to completely eliminate redundant network latency on restricted runners. - Asserted `:free` suffix check on all selected OpenRouter models for robust safety enforcement. - Wrapped `main()` in a top-level try-except for seamless graceful degradation inside actions. - Moved comment reaction inside try-except for Linear issue synchronization in `agent-feedback-linear-sync.yml` to prevent fake success reactions on limit errors. - Added comprehensive unit tests in `tests/test_model_router.py` (all passed). - Updated `docs/proposals/active/rate-limit-rotation/ITEMS.md` tracking row. Implements: RL-17 Signed-off-by: Jules <jules@grok.x.ai>
- Replaced rigid GHA bash router with `scripts/model_router.py`. - Added 1-hour temporal file caching for OpenRouter `:free` model list polling to optimize polling timing/intervals. - Guarded polling behind `has_openrouter` to completely eliminate redundant network latency on restricted runners. - Asserted `:free` suffix check on all selected OpenRouter models for robust safety enforcement. - Wrapped `main()` in a top-level try-except for seamless graceful degradation inside actions. - Moved comment reaction inside try-except for Linear issue synchronization in `agent-feedback-linear-sync.yml` to prevent fake success reactions on limit errors. - Added comprehensive unit tests in `tests/test_model_router.py` (all passed). - Updated `docs/proposals/active/rate-limit-rotation/ITEMS.md` tracking row. Implements: RL-17 Signed-off-by: Jules <jules@grok.x.ai>
- Replaced rigid GHA bash router with `scripts/model_router.py`. - Added 1-hour temporal file caching for OpenRouter `:free` model list polling to optimize polling timing/intervals. - Guarded polling behind `has_openrouter` to completely eliminate redundant network latency on restricted runners. - Asserted `:free` suffix check on all selected OpenRouter models for robust safety enforcement. - Wrapped `main()` in a top-level try-except for seamless graceful degradation inside actions. - Moved comment reaction inside try-except for Linear issue synchronization in `agent-feedback-linear-sync.yml` to prevent fake success reactions on limit errors. - Added comprehensive unit tests in `tests/test_model_router.py` (all passed). - Updated `docs/proposals/active/rate-limit-rotation/ITEMS.md` tracking row. Implements: RL-17 Signed-off-by: Jules <jules@grok.x.ai>
- Replaced rigid GHA bash router with `scripts/model_router.py`. - Added 1-hour temporal file caching for OpenRouter `:free` model list polling to optimize polling timing/intervals. - Guarded polling behind `has_openrouter` to completely eliminate redundant network latency on restricted runners. - Asserted `:free` suffix check on all selected OpenRouter models for robust safety enforcement. - Wrapped `main()` in a top-level try-except for seamless graceful degradation inside actions. - Moved comment reaction inside try-except for Linear issue synchronization in `agent-feedback-linear-sync.yml` to prevent fake success reactions on limit errors. - Added comprehensive unit tests in `tests/test_model_router.py` (all passed). - Updated `docs/proposals/active/rate-limit-rotation/ITEMS.md` tracking row. Implements: RL-17 Signed-off-by: Jules <jules@grok.x.ai>
- Replaced rigid GHA bash router with `scripts/model_router.py`. - Added 1-hour temporal file caching for OpenRouter `:free` model list polling to optimize polling timing/intervals. - Guarded polling behind `has_openrouter` to completely eliminate redundant network latency on restricted runners. - Asserted `:free` suffix check on all selected OpenRouter models for robust safety enforcement. - Wrapped `main()` in a top-level try-except for seamless graceful degradation inside actions. - Moved comment reaction inside try-except for Linear issue synchronization in `agent-feedback-linear-sync.yml` to prevent fake success reactions on limit errors. - Added comprehensive unit tests in `tests/test_model_router.py` (all passed). - Updated `docs/proposals/active/rate-limit-rotation/ITEMS.md` tracking row. Implements: RL-17 Signed-off-by: Jules <jules@grok.x.ai>
- Replaced rigid GHA bash router with `scripts/model_router.py`. - Added 1-hour temporal file caching for OpenRouter `:free` model list polling to optimize polling timing/intervals. - Guarded polling behind `has_openrouter` to completely eliminate redundant network latency on restricted runners. - Asserted `:free` suffix check on all selected OpenRouter models for robust safety enforcement. - Wrapped `main()` in a top-level try-except for seamless graceful degradation inside actions. - Moved comment reaction inside try-except for Linear issue synchronization in `agent-feedback-linear-sync.yml` to prevent fake success reactions on limit errors. - Added comprehensive unit tests in `tests/test_model_router.py` (all passed). - Updated `docs/proposals/active/rate-limit-rotation/ITEMS.md` tracking row. Implements: RL-17 Signed-off-by: Jules <jules@grok.x.ai>
- Replaced rigid GHA bash router with `scripts/model_router.py`. - Added 1-hour temporal file caching for OpenRouter `:free` model list polling to optimize polling timing/intervals. - Guarded polling behind `has_openrouter` to completely eliminate redundant network latency on restricted runners. - Asserted `:free` suffix check on all selected OpenRouter models for robust safety enforcement. - Wrapped `main()` in a top-level try-except for seamless graceful degradation inside actions. - Moved comment reaction inside try-except for Linear issue synchronization in `agent-feedback-linear-sync.yml` to prevent fake success reactions on limit errors. - Added comprehensive unit tests in `tests/test_model_router.py` (all passed). - Updated `docs/proposals/active/rate-limit-rotation/ITEMS.md` tracking row. Implements: RL-17 Signed-off-by: Jules <jules@grok.x.ai>
Implements OpenRouter free-model polling and internal ELO≈3L0 historic performance index for triage/review/invoke routing. Fixes #122 Implements: RL-17 Advances rate-limit-rotation RL-05 Signed-off-by: OPERATOR (Grok via Connectors)
Resolved conflicts in: - AGENTS.md (both-modified) - archwiz/archwiz.py (content) - docs/ARCHW1Z-GATE.md (both-modified) - docs/ARCHW1Z-OPERATOR-CHECKLIST.md (both-modified) - docs/ARCHW1Z-STATUS.md (both-modified) - docs/CONSENSUS.md (both-modified) - docs/PR-SUMMARY-LOG.md (both-modified) - docs/PR-SUMMARY-PROCESS.md (both-modified) - docs/SECURITY-REMEDIATION.md (both-modified) - docs/TERMUX-SMOKE.md (both-modified) - docs/proposals/AGENTIC-PERMISSIONS.md (both-modified) - docs/proposals/PROCESS.md (both-modified) - docs/proposals/README.md (both-modified) - docs/proposals/_template/MANIFEST.md (both-modified) - docs/proposals/active/chatgpt-critical-eval/ITEMS.md (both-modified) - docs/proposals/active/chatgpt-critical-eval/MANIFEST.md (both-modified) - docs/proposals/active/chatgpt-droidapp/ITEMS.md (both-modified) - docs/proposals/active/chatgpt-droidapp/MANIFEST.md (both-modified) - docs/proposals/active/chatgpt-initial/ITEMS.md (both-modified) - docs/proposals/active/chatgpt-initial/MANIFEST.md (both-modified) - docs/proposals/registry.yaml (both-modified) - docs/schemas/provider-capabilities.md (both-modified) - docs/schemas/session-ssot.md (both-modified) Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
| core.setOutput('prior_prs', inventory); | ||
|
|
||
| - name: Invoke Jules API (optional) | ||
| if: ${{ secrets.JULES_API_KEY != '' }} |
There was a problem hiding this comment.
🔴 The workflow that summons the coding agent from issues cannot run at all
The step that decides whether to call the coding agent is gated on a secret value inside a step condition (if: ${{ secrets.JULES_API_KEY != '' }} at .github/workflows/agent-jules-on-issues.yml:102), which GitHub does not allow, so the whole workflow is rejected and never runs.
Impact: Labelling an issue or mentioning the agent produces no acknowledgement and no agent work at all.
secrets context is unavailable in step-level if conditions
GitHub Actions only exposes github, needs, strategy, matrix, job, runner, env, vars, steps, inputs to jobs.<id>.steps.if. Referencing secrets there yields Unrecognized named-value: 'secrets' at workflow parse time, which fails the entire run — including the earlier acknowledgement/inventory step in the same job. The same pattern appears three times: .github/workflows/agent-jules-on-issues.yml:102, :138, and :232.
The usual fix is to surface the presence of the secret through a job/step env (or an earlier step output) and test that in if, e.g. set HAS_JULES_KEY: ${{ secrets.JULES_API_KEY != '' }} at job level and use if: env.HAS_JULES_KEY == 'true'.
Prompt for agents
In .github/workflows/agent-jules-on-issues.yml the three step-level conditions at lines 102, 138 and 232 reference the secrets context (`if: ${{ secrets.JULES_API_KEY != '' }}` / `== ''`). GitHub Actions does not expose the secrets context to step-level `if`, so the workflow fails to parse and no job in it ever executes, including the acknowledgement step. Rework the gating so the presence of the key is computed somewhere secrets are allowed (job-level `env:` mapping, or a preceding step that writes an output) and have the steps test that env var / step output instead.
Was this helpful? React with 👍 or 👎 to provide feedback.
| @@ -306,7 +306,7 @@ def index_conversation(self, session_id: str, title: str, messages: List[dict], | |||
| for blk_idx, match in enumerate(re.finditer(r"```(\w+)?\n(.*?)```", content, re.DOTALL)): | |||
There was a problem hiding this comment.
🟡 Previously stored code snippets become unreachable after the content-hash length change
Code snippets are now filed under a full-length fingerprint instead of the short one used until now (hashlib.sha256(...).hexdigest() at cli-synthegration/synthegration_index.py:306), so everything stored earlier can no longer be found and gets saved a second time.
Impact: Existing indexed snippets stop showing up in lookups and the on-disk store silently doubles up on the same content.
Mixed 16-char and 64-char hashes in blobs, index and wire format
All hash producers were widened from hexdigest()[:16] to the full 64-char digest (:206, :228, :306, :557). Blob files already on disk are named <16-char>.blob and are re-registered by _rebuild_hash_index (:274-283) under those short keys, while codex_index.json pointers loaded by _from_flat (:264-271) also carry short ch values. reverse_lookup (:557-564) now computes a 64-char hash, so exact matches against any pre-existing entry always miss, and index_conversation writes a new blob for content already stored.
The wire format is affected too: to_wire (:35-40) emits len(hash)/2 bytes, so old short hashes serialize to 8 bytes while from_wire (:42-47) now unconditionally reads data[20:52], misaligning any stream that contains a legacy pointer.
A migration (rename existing blobs / rewrite index entries, or tolerate both lengths on read) is needed alongside the widening.
Prompt for agents
cli-synthegration/synthegration_index.py switched every content hash from sha256()[:16] to the full 64-char digest (lines 206, 228, 306, 557), but persisted state still uses the old 16-char keys: blob filenames rescanned by _rebuild_hash_index, `ch` fields in codex_index.json read by _from_flat, and any serialized pointers. Consequences: reverse_lookup exact-hash hits always miss for pre-existing content, index_conversation re-writes duplicate blobs, and Pointer.from_wire now assumes a fixed 32-byte hash while to_wire emits 8 bytes for legacy short hashes, so mixed streams deserialize incorrectly. Decide on a migration strategy — e.g. a one-time rename/rewrite of existing blobs and index entries to full-length hashes, plus a length-tolerant read path (and a length prefix or version tag in the wire format) so old data is not silently orphaned.
Was this helpful? React with 👍 or 👎 to provide feedback.
| for candidate in peer_candidates: | ||
| prov = candidate["provider"] | ||
| mod = candidate["model"] | ||
| limit_dict = limits.get(f"{prov}/{mod}", {}) | ||
| limit = limit_dict.get(role, limit_dict.get("default", 40)) | ||
|
|
||
| used = get_usage(prov, mod) | ||
| if used < limit: | ||
| new_used = increment_usage(prov, mod) | ||
| print(f"::set-output name=provider::{prov}") | ||
| print(f"::set-output name=model::{mod}") | ||
| print(f"::set-output name=skip::false") | ||
| print(f"::set-output name=reason::role={role} peer={prov} model={mod} used={new_used}/{limit} (ranked score={candidate['score']})") |
There was a problem hiding this comment.
📝 Info: Router increments the soft-budget counter before the provider call is attempted
increment_usage runs at selection time, but the downstream invoke steps are continue-on-error: true and may fail (transport error, empty response, non-free rejection). Failed attempts therefore consume budget, and since the counters live in a per-branch Actions cache restored/saved around the job, concurrent runs on different branches keep independent tallies. Both are acknowledged as “best-effort” in docs/schemas/model-rotation.yaml, but the accounting will drift optimistically low in aggregate and pessimistically high per branch.
Was this helpful? React with 👍 or 👎 to provide feedback.
| def parse_yaml(filepath): | ||
| """ | ||
| Minimal robust YAML parser for standard key-value and indentation structures. | ||
| Does not require external dependencies like PyYAML. | ||
| """ | ||
| if not os.path.exists(filepath): | ||
| return {} | ||
|
|
||
| result = {} | ||
| path = [] | ||
|
|
||
| with open(filepath, 'r', encoding='utf-8') as f: | ||
| for line in f: | ||
| stripped = line.strip() | ||
| if not stripped or stripped.startswith('#'): | ||
| continue | ||
|
|
||
| indent = len(line) - len(line.lstrip()) | ||
|
|
||
| while path and path[-1][0] >= indent: | ||
| path.pop() | ||
|
|
||
| if not path: | ||
| parent = result | ||
| parent_key = None | ||
| else: | ||
| parent = path[-1][1] | ||
| parent_key = path[-1][2] | ||
|
|
||
| if stripped.startswith('- '): | ||
| item_str = stripped[2:].strip() | ||
| if ':' in item_str and not (item_str.startswith('"') or item_str.startswith("'")): | ||
| k, v = item_str.split(':', 1) | ||
| k = k.strip().strip('"\'') | ||
| v = v.strip().strip('"\'') | ||
| try: | ||
| if '.' in v: v = float(v) | ||
| else: v = int(v) | ||
| except ValueError: | ||
| pass | ||
| item_val = {k: v} | ||
| else: | ||
| item_val = item_str.strip('"\'') | ||
| try: | ||
| if '.' in item_val: item_val = float(item_val) | ||
| else: item_val = int(item_val) | ||
| except ValueError: | ||
| pass | ||
|
|
||
| if isinstance(parent, dict) and parent_key is not None: | ||
| if parent_key not in parent or not isinstance(parent[parent_key], list): | ||
| parent[parent_key] = [] | ||
| parent[parent_key].append(item_val) | ||
| if isinstance(item_val, dict): | ||
| sub_key = list(item_val.keys())[0] | ||
| path.append((indent, item_val, sub_key)) | ||
| continue | ||
|
|
||
| m = re.match(r'^("[^"]+"|\'[^\']+\'|[^:]+):\s*(.*)$', stripped) | ||
| if not m: | ||
| continue | ||
|
|
||
| key = m.group(1).strip().strip('"\'') | ||
| val = m.group(2).strip() | ||
| if '#' in val: | ||
| val = val.split('#')[0].strip() | ||
| val = val.strip('"\'') | ||
|
|
||
| if not val: | ||
| new_dict = {} | ||
| if isinstance(parent, dict): | ||
| parent[key] = new_dict | ||
| path.append((indent, new_dict, key)) | ||
| else: | ||
| if val.startswith('[') and val.endswith(']'): | ||
| parsed_val = [v.strip().strip('"\'') for v in val[1:-1].split(',')] | ||
| else: | ||
| if val.lower() == 'true': | ||
| parsed_val = True | ||
| elif val.lower() == 'false': | ||
| parsed_val = False | ||
| else: | ||
| try: | ||
| if '.' in val: | ||
| parsed_val = float(val) | ||
| else: | ||
| parsed_val = int(val) | ||
| except ValueError: | ||
| parsed_val = val | ||
|
|
||
| if isinstance(parent, dict): | ||
| parent[key] = parsed_val | ||
| path.append((indent, parent, key)) | ||
|
|
||
| return result |
There was a problem hiding this comment.
📝 Info: Hand-rolled YAML parser is fragile for the success matrix it consumes
parse_yaml only supports a narrow subset: it ignores block scalars (|/>), anchors, multi-line strings, and nested lists-of-lists, and it treats any # inside an unquoted scalar as a comment. docs/schemas/model-success-matrix.yaml currently fits the subset, but adding a notes: | block or an inline # to that file would silently produce wrong ELO/suitability values and thus wrong routing, with no error. Consider validating the parsed structure (e.g. assert every model entry has a numeric elo) so schema drift fails loudly instead of degrading to the 1000 default.
Was this helpful? React with 👍 or 👎 to provide feedback.
| blob = Path(blob_path) | ||
| if blob.exists(): | ||
| results.append({ | ||
| 'pointer': p.to_key(), |
There was a problem hiding this comment.
🔍 Search results still crash when a blob has no recorded timestamp
self.time_index.get(p.content_hash, '') falls back to a plain string, and ''.isoformat() raises AttributeError. Pointers restored by _rebuild_hash_index (cli-synthegration/synthegration_index.py:274-283) never populate time_index, so any recovered blob that matches a search will blow up here — exactly the recovery path this module exists for. The surrounding lines were touched in this PR (blob lookup moved to self.blobs), so it is a natural place to also return None plus a timestamp_source marker, as docs/schemas/session-ssot.md prescribes.
Was this helpful? React with 👍 or 👎 to provide feedback.
| - name: Publish peer-review-ready marker | ||
| uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 | ||
| env: | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | ||
| SUMMARY: ${{ steps.wait.outputs.peer_summary }} | ||
| AUTOFIX: ${{ steps.autofix.outputs.posted }} | ||
| TIMED_OUT: ${{ steps.wait.outputs.timed_out }} | ||
| READY: ${{ steps.wait.outputs.ready }} |
There was a problem hiding this comment.
🔍 Peer-review gate publishes the ready marker even when no peer was seen
The Publish peer-review-ready marker step has no if: guard, so it posts on every run, including the timeout path where ready: false. Downstream, gemini-after-peers.yml:69-75 only searches for the marker comment and never inspects the embedded ready:/timed_out: fields, so a 12-minute timeout with zero peer activity still triggers the second-pass reviewer — which defeats the stated purpose of saving free-tier quota until peers finish. Consider having the consumer parse ready: or gating publication on steps.wait.outputs.ready == 'true'.
Was this helpful? React with 👍 or 👎 to provide feedback.
| - name: Post @jules resolve (idempotent window) | ||
| if: steps.meta.outputs.should_invoke == 'true' | ||
| uses: actions/github-script@v7 | ||
| with: | ||
| script: | | ||
| const prNumber = Number('${{ steps.meta.outputs.pr_number }}'); | ||
| const head = '${{ steps.meta.outputs.head_ref }}'; | ||
| const marker = '<!-- agent-auto-jules -->'; | ||
| const { data: comments } = await github.rest.issues.listComments({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| per_page: 50, | ||
| }); | ||
| const recent = comments | ||
| .filter(c => c.body && c.body.includes(marker)) | ||
| .sort((a, b) => new Date(b.created_at) - new Date(a.created_at))[0]; | ||
| if (recent) { | ||
| const ageMs = Date.now() - new Date(recent.created_at).getTime(); | ||
| if (ageMs < 20 * 60 * 1000) { | ||
| core.info('Debounced: recent agent-auto-jules comment exists'); | ||
| return; | ||
| } | ||
| } |
There was a problem hiding this comment.
🔍 Second-pass workflow can loop on its own comments
gemini-after-peers only runs on workflow_run of the orchestrator, which is fine, but agent-review-auto-jules.yml fires on issue_comment/pull_request_review_comment from any login containing coderabbit/devin and posts a new PR comment. The orchestrator in turn posts @coderabbitai autofix, which will trigger CodeRabbit to comment again. The only brakes are the 20-minute debounce (agent-review-auto-jules.yml:109-115) and the 45-minute autofix throttle (peer-review-orchestrator.yml:169-179); both are time-based rather than SHA-based for the auto-jules path, so a busy PR can still produce repeated cycles. Worth confirming the loop terminates in practice before enabling on high-traffic branches.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Skipped: comment is from another GitHub bot.
There was a problem hiding this comment.
@coderabbitai resolve conflicts && fix #15 (review)
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
repo="timerloggedout-spec/termux-monorepo"
pr="15"
review_id="4893888061"
echo "== PR metadata =="
gh api "repos/$repo/pulls/$pr" \
--jq '{number, state, mergeable, mergeable_state, head: .head.sha, head_ref: .head.ref, base_ref: .base.ref, changed_files, url}'
echo
echo "== Referenced review =="
gh api "repos/$repo/pulls/$pr/reviews/$review_id" \
--jq '{id, user: .user.login, state, body, submitted_at, commit_id}'
echo
echo "== Comments in referenced review =="
gh api "repos/$repo/pulls/$pr/comments?per_page=100" \
--jq --argjson review_id "$review_id" \
'.[] | select(.pull_request_review_id == $review_id) |
{id, path, line, start_line, side, body, user: .user.login, commit_id, html_url}'
echo
echo "== All unresolved review threads =="
gh api graphql \
-F owner="timerloggedout-spec" \
-F name="termux-monorepo" \
-F number="$pr" \
-f query='
query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
reviewThreads(first: 100) {
nodes {
isResolved
path
line
comments(first: 20) {
nodes {
author { login }
body
url
}
}
}
}
}
}
}' \
--jq '.data.repository.pullRequest.reviewThreads.nodes[] |
select(.isResolved == false) |
{path, line, comments: [.comments.nodes[] | {author: .author.login, body, url}]}'Length of output: 2973
🏁 Script executed:
#!/bin/bash
set -euo pipefail
repo="timerloggedout-spec/termux-monorepo"
pr="15"
review_id="4893888061"
base_ref="manus/novel-work"
echo "== Comments in review $review_id =="
gh api --paginate "repos/$repo/pulls/$pr/comments?per_page=100" |
jq --argjson review_id "$review_id" '
.[] | select(.pull_request_review_id == $review_id) |
{
id,
path,
line,
start_line,
side,
body,
user: .user.login,
commit_id,
html_url
}
'
echo
echo "== Unresolved review threads =="
gh api graphql \
-F owner="timerloggedout-spec" \
-F name="termux-monorepo" \
-F number="$pr" \
-f query='
query($owner: String!, $name: String!, $number: Int!) {
repository(owner: $owner, name: $name) {
pullRequest(number: $number) {
reviewThreads(first: 100) {
nodes {
isResolved
path
line
comments(first: 20) {
nodes {
author { login }
body
url
}
}
}
}
}
}
}' |
jq '
.data.repository.pullRequest.reviewThreads.nodes[] |
select(.isResolved == false) |
{
path,
line,
comments: [.comments.nodes[] | {author: .author.login, body, url}]
}
'
echo
echo "== Conflicting files =="
git fetch --quiet origin "$base_ref"
base="$(git merge-base HEAD "origin/$base_ref")"
git merge-tree "$base" HEAD "origin/$base_ref" |
awk '
/^changed in both$/ { capture=1; next }
capture && /^ base / { next }
capture && /^ our / { next }
capture && /^ their / { next }
capture && /^ result / { next }
capture && /^ / { sub(/^ /, ""); print; capture=0 }
' |
sort -uLength of output: 74166
🏁 Script executed:
#!/bin/bash
set -euo pipefail
repo="timerloggedout-spec/termux-monorepo"
pr="15"
base_sha="$(gh api "repos/$repo/pulls/$pr" --jq '.base.sha')"
head_sha="$(gh api "repos/$repo/pulls/$pr" --jq '.head.sha')"
echo "base_sha=$base_sha"
echo "head_sha=$head_sha"
git fetch --quiet origin "$base_sha" "$head_sha"
merge_base="$(git merge-base "$head_sha" "$base_sha")"
echo "== Conflicted paths =="
git merge-tree --messages "$merge_base" "$head_sha" "$base_sha" |
sed -n '/^CONFLICT/,/^$/p'
echo "== Changed files on both sides =="
git diff --name-only "$merge_base" "$head_sha" | sort > /tmp/pr-files
git diff --name-only "$merge_base" "$base_sha" | sort > /tmp/base-files
comm -12 /tmp/pr-files /tmp/base-filesLength of output: 1208
🏁 Script executed:
#!/bin/bash
set -euo pipefail
workflow=".github/workflows/agent-jules-on-issues.yml"
ast-grep outline "$workflow" --items all || true
echo "== Secret and event-expression uses =="
rg -n -C 4 '\bsecrets\.JULES_API_KEY\b|github\.event\.(issue|comment)\.(title|body)' "$workflow"
echo "== Workflow section =="
sed -n '1,280p' "$workflow"Length of output: 13673
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="cli-synthegration/synthegration_index.py"
ast-grep outline "$file" --lang python --items all
echo "== Persistence and search implementations =="
rg -n -C 5 'class Pointer|def (to_wire|from_wire|_from_flat|_rebuild_hash_index|index_conversation|reverse_lookup|search)' "$file"
echo "== Candidate tests =="
fd -t f . | rg '(^|/)(test.*synthegration|.*synthegration.*test).*\.py$'Length of output: 9021
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for file in \
".github/workflows/peer-review-orchestrator.yml" \
".github/workflows/gemini-after-peers.yml" \
".github/actions/http-llm-invoke/action.yml" \
"scripts/model_router.py" \
"tests/test_model_router.py" \
"docs/schemas/model-success-matrix.yaml"; do
if [ -f "$file" ]; then
echo "== $file =="
ast-grep outline "$file" --items all 2>/dev/null || true
rg -n -C 4 'peer-review-ready|ready:|timed_out:|::set-output|GITHUB_OUTPUT|parse_yaml|increment_usage|elo|exit 0|::error::' "$file" || true
fi
doneLength of output: 18359
🏁 Script executed:
#!/bin/bash
set -euo pipefail
files=(
"termux-multi-agent/src/db.py"
"src/db.py"
"termux-multi-agent/run.py"
"termux-multi-agent/workspace/run.py"
"termux-multi-agent/provision_agent.py"
"termux-multi-agent/dashboard.py"
"archwiz/linear_sync.py"
"archwiz/archwiz.py"
"archwiz/restore_version.py"
)
for file in "${files[@]}"; do
if [ -f "$file" ]; then
echo "== $file =="
ast-grep outline "$file" --lang python --items all
rg -n -C 4 'batch_insert_fts_messages|messages_fts|index_project_file|except Exception|conn\.commit|task_id|subprocess\.run|PIPELINE_ACTIVE|restore\(' "$file" || true
fi
done
echo "== Candidate tests =="
fd -t f . | rg '(^|/)(test.*(archwiz|linear_sync|db|provision|router)|.*(archwiz|linear_sync|db|provision|router).*test).*\.py$'Length of output: 28394
🏁 Script executed:
#!/bin/bash
set -euo pipefail
base_sha="40feea7790aafa7cac2bd13ffc596cb9ab0f1489"
head_sha="20e9c0be9fef85800ad5253d337d63f28a90b377"
git fetch --quiet origin "$base_sha" "$head_sha"
echo "== Merge conflicts =="
git merge-tree --write-tree "$head_sha" "$base_sha" 2>&1 || true
echo
echo "== Synthegration persistence and result rendering =="
sed -n '250,370p' "cli-synthegration/synthegration_index.py"
sed -n '540,585p' "cli-synthegration/synthegration_index.py"
echo
echo "== Peer-ready publication and consumer selection =="
sed -n '195,255p' ".github/workflows/peer-review-orchestrator.yml"
sed -n '45,90p' ".github/workflows/gemini-after-peers.yml"
echo
echo "== Model-router parser and output helpers =="
sed -n '29,125p' "scripts/model_router.py"
sed -n '345,455p' "scripts/model_router.py"
echo
echo "== FTS and embedded-template shapes =="
sed -n '142,210p' "termux-multi-agent/src/db.py"
sed -n '1,145p' "termux-multi-agent/provision_agent.py"Length of output: 29117
@timerloggedout-spec, I completed the analysis and prepared the code-change plan.
The confirmed fixes cover:
-
.github/workflows/agent-jules-on-issues.yml- Replace invalid step-level
secretsconditions. - Pass issue and comment text as environment data. Do not interpolate it into workflow script or prompt syntax.
- Replace invalid step-level
-
cli-synthegration/synthegration_index.py- Support legacy 16-character hashes with full SHA-256 hashes.
- Prevent duplicate legacy blobs.
- Make pointer decoding compatible with persisted data.
- Handle missing timestamps safely.
-
.github/workflows/peer-review-orchestrator.ymland.github/workflows/gemini-after-peers.yml- Prevent the second-pass workflow from running when the peer-review gate is not ready.
-
.github/actions/http-llm-invoke/action.yml- Return a failing status for invalid HTTPS and OpenRouter free-model validation paths.
-
scripts/model_router.pyandtests/test_model_router.py- Remove deprecated
::set-outputcommands. - Retain
GITHUB_OUTPUT. - Add validation for malformed model-matrix entries.
- Remove deprecated
-
termux-multi-agentdatabase, runner, and provisioning-template files- Make FTS re-indexing idempotent.
- Report indexing and commit failures.
- Synchronize generated templates with live modules.
-
archwiz/linear_sync.pyandarchwiz/archwiz.py- Skip empty task IDs.
- Match Markdown-adjacent IDs without matching partial IDs.
- Handle
OSErrorfrom controller and backup subprocess launches.
GitHub still reports the PR as conflicted. The local merge simulation produced a merge tree without conflict diagnostics. This result is inconclusive. After the planned branch updates, GitHub must recompute the merge status before the conflict can be considered resolved.
You are interacting with an AI system.
| if [[ ! "$RAW" =~ ^https:// ]]; then | ||
| echo "::error::base_url must be https:// (got scheme-less or http)" | ||
| exit 0 | ||
| fi | ||
| HOST=$(echo "$RAW" | sed -E 's|^https://([^/]+).*|\1|' | tr '[:upper:]' '[:lower:]') | ||
| OK=0 | ||
| for h in $ALLOW_HOSTS; do | ||
| if [ "$HOST" = "$h" ]; then OK=1; break; fi | ||
| done | ||
| if [ "$OK" != 1 ]; then | ||
| echo "::error::base_url host '$HOST' not in allow-list ($ALLOW_HOSTS); using catalog default" | ||
| RAW="$CATALOG" | ||
| fi | ||
| BASE="$RAW" | ||
|
|
||
| case "$PROVIDER" in | ||
| omni) | ||
| TITLE="termux-monorepo-${ROLE}-omni" | ||
| MARKER="<!-- omni-${ROLE} -->" | ||
| HEAD="### 🌐 OmniRoute ${ROLE} (\`${MODEL}\`)" | ||
| EGG="<!-- matrix: valley-hunt via omni free aggregation / 3L0 labels pending -->" | ||
| ;; | ||
| openrouter) | ||
| if [[ "$MODEL" != *:free ]]; then | ||
| echo "::error::OpenRouter path requires :free model id (got $MODEL)" | ||
| exit 0 |
There was a problem hiding this comment.
📝 Info: HTTP invoke action reports a hard error but exits successfully
Both the scheme check and the OpenRouter :free check emit ::error:: and then exit 0, so the step is green while doing nothing. Since callers already set continue-on-error: true, using a non-zero exit (or downgrading to ::warning::) would keep run logs honest — as written, an annotated error with a passing step is easy to miss. Note also that the non-allow-listed-host branch falls back to the catalog default and continues, which is a different (and reasonable) policy than the scheme branch that aborts.
Was this helpful? React with 👍 or 👎 to provide feedback.
| print(f"::set-output name=provider::{prov}") | ||
| print(f"::set-output name=model::{mod}") | ||
| print(f"::set-output name=skip::false") | ||
| print(f"::set-output name=reason::role={role} peer={prov} model={mod} used={new_used}/{limit} (ranked score={candidate['score']})") |
There was a problem hiding this comment.
📝 Info: Deprecated ::set-output commands are still emitted
::set-output was disabled on GitHub-hosted runners; the script also writes GITHUB_OUTPUT, so routing still works, but the stdout commands are dead weight and will show as workflow warnings. The crash handler at scripts/model_router.py:429-447 relies on the same pair, so removing the ::set-output prints is safe as long as the GITHUB_OUTPUT writes are retained. The tests in tests/test_model_router.py:160-163 assert on the deprecated stdout form, so they would need updating together.
Was this helpful? React with 👍 or 👎 to provide feedback.
| prompt: | | ||
| You are Jules working on termux-monorepo. Read AGENTS.md and GEMINI.md if present. | ||
|
|
||
| ## Issue #${{ github.event.issue.number }}: ${{ github.event.issue.title }} | ||
|
|
||
| ${{ github.event.issue.body }} | ||
|
|
||
| ## Open agent / related PRs (DO NOT overlap files) | ||
| ${{ steps.coord.outputs.prior_prs }} |
There was a problem hiding this comment.
🟨 Untrusted PR/issue text is interpolated directly into workflow shell and prompt expressions
Several new workflows inline attacker-controllable payload fields directly into run:/prompt bodies via ${{ }} expansion, e.g. the Jules invoke prompt embeds ${{ github.event.issue.title }} / ${{ github.event.issue.body }} (.github/workflows/agent-jules-on-issues.yml:111-113, :239-244). Anything expanded with ${{ }} is substituted before the step content is parsed, so issue/comment text containing quote or backtick sequences can alter the surrounding YAML/shell context rather than being treated as data.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
sha: 20e9c0b @jules Continuous ops (GHA agent-continuous-ops) — unattended advance. PR #15 · Instructions
Read AGENTS.md. No Class 3/4 artifacts. No secret leaks. |
This stacked PR contains CodeRabbit auto-fixes for #13.
Files modified:
archwiz/archwiz.pyarchwiz/linear_sync.pyarchwiz/restore_version.pydeepcli/deepcli/core.pydocs/evaluations/manus/REPORT.mddocs/proposals/active/manus-critical-eval/ITEMS.mdSummary by CodeRabbit
New Features
Bug Fixes
Documentation