Commit Graph

77 Commits

Author SHA1 Message Date
can1357 55f5ebec49 chore: reformat 2026-07-15 00:08:50 +02:00
can1357 465f463ada fix(python/robomp): ensured omp run directory remained writable for all slots
- Added entrypoint setup for `/srv/agent-home/.omp/run` to enforce `omp` group ownership, group-write access, and setgid permissions so any sandbox slot can create or enter daemon state directories.
- Updated worker startup to skip generic home normalization on `.omp/run` and added a root-only run-dir preparation pass that reasserts `omp` ownership and writable, setgid permissions before launching subprocesses.
2026-07-14 17:56:37 +02:00
can1357 d469064d1a fix: handle stale tests 2026-07-11 07:54:19 +02:00
can1357 d435385ab1 feat: introduced max reasoning effort tier across model and rpc systems
- Introduced `Max` as a first-class reasoning effort tier across all packages, including AI providers, coding agent configurations, and RPC protocols.
- Refactored model effort ladders to use wire-exact mappings and removed legacy effort aliasing (e.g., `max-to-xhigh` mapping).
- Updated model registry and provider configurations to support `Max` tier routing, color themes, and UI icon associations.
- Expanded test suites to provide end-to-end coverage for the new reasoning tier, including updated compatibility and fallback scenarios.
2026-07-10 13:39:42 +02:00
can1357 b3c7646b4c feat(python/robomp): enforced commit message repair failures
- Make commit message repair mandatory once broken escapes are detected.
- Implement a failure handler that halts execution and provides manual correction instructions when git operations fail during the rewrite process.
- Ensure that partial states are avoided by refusing the push instead of allowing it with uncorrected messages.
2026-07-02 22:58:03 +02:00
can1357 22e9224ae8 feat(robomp): integrated linting amends and commit message sanitization
- Updated `_run_pre_publish_bun_fix` to amend `bun run fix` output into HEAD instead of creating standalone `style:` commits.
- Added `_repair_commit_message_escapes` to detect and rewrite commit messages containing shell-literal `\n` sequences into real newlines.
- Enforced safety checks during `bun run fix` to ensure HEAD is mutable and locally authored before amending.
- Improved documentation in prompts and README regarding commit message formatting and formatter workflow changes.
2026-07-02 22:55:07 +02:00
metaphorics 16600e89ab fix(robomp): harden sandbox cleanup, git-probe, and worktree-add paths
A diff-scoped review of the event-loop-hang fixes surfaced gaps in the new
timeout/error-handling code and its tests. All at/above the medium floor,
each mutation-verified.

- remove_workspace: prune on any nonzero `git worktree remove` (not just a
  present checkout) and RAISE on a failed prune, so a killed remove that
  leaves a dangling pool registration is cleared or retried instead of
  recording success over stale metadata. Gate git ops on the pool being a
  real clone (ensure_clone mkdir's the dir before cloning, so a failed first
  clone leaves a non-git dir where `git worktree prune` would error), and
  only speculatively prune a missing checkout when ws_root still exists.
- _worktree_add: new helper wrapping the three worktree-add sites; on a
  failed add (incl. the new 124 timeout) it removes the partial checkout and
  prunes the pool before re-raising, so the event retry starts clean. Raises
  a failed prune chained from the add error.
- _reset_origin_url: a timed-out (124) `git remote get-url origin` probe is
  indeterminate; raise before fetch instead of silently skipping the rewrite,
  so a legacy credentialed origin cannot persist and be reused.
- tests: assert the subprocess timeout is passed in the _safe_run/_run
  timeout fakes; add a real-`git worktree prune` integration test; make the
  cancel-drain test deterministic (loop-turn pump, no wall-clock sleep) and
  cover the repeated-cancel branch; add regressions for the prune-failure,
  checkout-gone-on-entry, non-git-pool, and repeat-close cleanup paths.

Op: correct
Restores: spec:pool-cleanup-clears-or-retries-dangling-registration
Restores: spec:indeterminate-git-probes-raise-not-silently-proceed
2026-07-02 13:04:19 +09:00
metaphorics dfaa41f6b3 fix(robomp): prune pool metadata on any failed worktree remove
`remove_workspace` guarded its rmtree+prune fallback on `repo_dir.exists()`.
But a `git worktree remove` that is killed (incl. a 124 timeout) mid-operation
can delete the checkout *before* it clears the pool's worktree registration.
In that window `repo_dir` is already gone, so the exists() guard skipped the
prune and left dangling metadata — the next `git worktree add` for the same
path then failed with "missing but already registered worktree".

Guard the fallback on the remove command's return code instead; prune runs on
any nonzero exit regardless of whether the checkout was already deleted. Added
a regression test for the remove-deleted-checkout-then-died case, which the
existing test (checkout survives) never covered.

Op: correct
Restores: spec:failed-worktree-remove-must-prune-dangling-pool-metadata
2026-07-02 10:24:06 +09:00
metaphorics b7bcc0bbf0 fix(robomp): address PR #4184 review nits
- log the worker thread's exception when a workspace op raises during
  caller cancellation, so a persistently failing setup surfaces instead
  of being buried behind CancelledError.
- raise on a timed-out (124) git symbolic-ref probe in the repo-exists
  path, matching the rev-parse probes, instead of silently accepting the
  caller-supplied branch.
- assert the subprocess timeout is passed in the two _chown_workspace
  test fakes so a refactor cannot silently drop the bound.

Op: correct
Restores: spec:indeterminate-git-probes-raise-not-silently-proceed
2026-07-02 09:58:14 +09:00
metaphorics 6d16c19a04 fix(robomp): run sandbox setup/teardown off the event loop safely
Workspace setup/teardown (git clone/fetch, worktree add/remove, chown)
ran synchronously on the asyncio dispatcher loop, so one stalled
subprocess froze the entire process.

- Offload every ensure_workspace/remove_workspace call to a worker thread
  via a new _run_workspace_op helper that drains the thread to completion
  on cancellation, so a cancelled event cannot reap/release a slot the
  setup thread still owns.
- Serialize same-repo setup with a per-repo threading.RLock while letting
  distinct repos run concurrently.
- Bound the direct git/chown subprocesses with a 120s timeout
  (returncode 124); treat a timed-out branch probe as an error rather
  than "branch absent" to avoid silently rebasing a follow-up onto the
  default branch and losing the PR's commits.
- When a timed-out worktree remove leaves the checkout behind, rmtree it
  and run `git worktree prune` so the pool's dangling registration cannot
  trip a later worktree add for the same path.

Adds regression tests for event-loop liveness, cancellation-safe offload,
per-repo lock serialization, subprocess timeout mapping, the branch-probe
timeout guard, and worktree-prune after a failed remove.

Op: correct
Restores: spec:dispatcher-event-loop-never-blocks-on-workspace-io
2026-07-02 08:10:37 +09:00
can1357 958a923a42 feat(python/robomp): implemented retry logic for transient network errors
- Added exponential backoff retry mechanisms to `GitHubClient` and `GitHubProxyClient` request methods.
- Included handlers for `httpx.ConnectError` and `httpx.TimeoutException` to improve resilience against transient network failures.
2026-06-24 17:22:42 +02:00
can1357 93f8548f6a security(git): hardened git operations by neutralizing malicious local config
- Constrained git configuration for smart-HTTP requests by explicitly overriding proxy, sslVerify, and credential helpers across all relevant path suffixes.
- Prevented potential credential capture by disabling repo-configured credential helpers that could otherwise execute malicious commands during authentication challenges.
- Hardened git operations against attacker-injected proxies by exhaustively blanking configuration keys for all identifiable git request endpoints.
- Excluded sslCAInfo/sslCAPath from overrides to prevent premature TLS negotiation failure while maintaining security via mandatory proxy neutralization.
2026-06-24 15:30:29 +02:00
can1357 7bcbbc7d1a security(proxy): prevented malicious refspec injection via input validation
- Added `_require_fetch_ref` validator to enforce strict alphanumeric character sets and disallow special git characters (e.g., `:`, `--`, `..`, `*`).
- Integrated validation into `git_fetch_ref_endpoint` to block malicious refspec inputs before git execution.
- Added test cases in `test_proxy_server.py` to verify rejection of attempted shell and refspec injections.
2026-06-24 15:30:29 +02:00
can1357 02d4de9453 test(git): validated git configuration hardening against security bypasses
- Added test suite to verify git configuration overrides for auth tokens.
- Validated that repo-local git configurations cannot override security-critical settings such as proxy, sslVerify, and credential helpers.
- Confirmed that smart-HTTP path-specific overrides are correctly applied to prevent proxy-based MITM attacks.
- Ensured system CA locations remain untouched to prevent disruption of TLS verification.
2026-06-24 15:30:29 +02:00
can1357 1344be8ae7 fix(python/robomp): restricted URLs starting with a hyphen in proxy server
- Added a check to reject remote URLs that begin with a hyphen to prevent command-line option injection.
- Updated the test suite to verify that option-shaped URLs are correctly blocked.
2026-06-23 20:26:44 +02:00
can1357 c58f72d943 chore: update changelogs 2026-06-23 20:22:31 +02:00
can1357 c752aee69d security(python-robomp): implemented git remote validation and credential hardening
- Sanitized git subprocess environment variables to prevent leakage of parent authentication tokens.
- Enforced strict HTTPS protocol restrictions and source validation for all git repositories.
- Implemented secure remote URL handling to neutralize malicious push URLs and prevent credential exfiltration.
- Applied scoped token injection during git operations to restrict token exposure to intended targets.
2026-06-23 20:19:14 +02:00
runbgp bc41b2ed3e fix(robomp): refused token-bearing git ops to attacker-controlled origins
- Extracted `_pat_safe_remote` and rejected HTTP(S) origins with embedded credentials or mismatched host/repo.
- Guarded `clone` via `_assert_clone_url_safe` on the caller-supplied `clone_url` (pool has no `origin` yet).
- Asserted origin safety before `fetch`, `fetch_ref`, and `fetch_pr_head` inject the PAT header.
- Appended POSIX `--` separator in `omp_local` so prompts starting with `-` aren't parsed as flags.
- Added proxy tests covering attacker-origin fetch rejection and unsafe `clone_url` refusal.

Co-authored-by: can1357 <me@can.ac>
2026-06-23 19:57:15 +02:00
can1357 69d0ac4dd3 fix(python/robomp): updated mention regex to correctly reject suffixes
- Updated the mention extraction regex to prevent partial matching when a suffix follows the `[bot]` identifier.
- Added a regression test to ensure that invalid extended suffixes are correctly rejected.
2026-06-21 19:26:42 +02:00
can1357 24a0c8428a feat(python/robomp): implemented has_authorized_impl_event in the
- Implement `has_authorized_impl_event` in the database to retrieve historical authorization state.
- Update `_enforce_impl_authorization` to permit actions if prior events on the issue provided implementation authorization.
- Normalize maintainer logins by stripping `[bot]` suffixes and allow match-regex to ignore them.
2026-06-21 19:18:37 +02:00
can1357 4b2e4085e0 feat(robomp): improved authorization and login normalization
- Implemented case-insensitive normalization for bot logins to handle mention handles and `[bot]` suffixes consistently.
- Added support for `ROBOMP_MAINTAINER_LOGINS` to allow authorized non-owner users to execute implementations.
- Refined authorization logic to distinguish between personal repository owners and organizational accounts.
- Updated documentation and added comprehensive tests to verify authorization handling across tasks, workers, and directive processing.
2026-06-21 19:14:13 +02:00
can1357 4b9f7cd8fa feat(python/robomp): allowed personal repository owners to authorize implementations
- Updated configuration to strip the '@' prefix from bot login names.
- Granted personal repository owners authorization to trigger implementations regardless of their GitHub author association.
2026-06-21 19:05:31 +02:00
can1357 5a99705797 feat(python/robomp): added authorizes_impl support to task directive processing
- Included authorizes_impl field when attaching threads to directives.
- Added a test case to ensure the author authorization flag is preserved during directive hydration.
2026-06-21 18:51:24 +02:00
Can Bölük 6723c1baf6 Merge pull request #2926 from lyc-aon/feat/robomp-lifecycle-cards
Replace Robomp status tables with lifecycle cards
2026-06-20 23:43:06 +02:00
can1357 1d35e8624f fix(python/robomp): updated pull request event trigger criteria
- Added the labeled action to the pull_request event, ensuring that workers process pull requests when labels are updated.
2026-06-20 21:38:53 +02:00
can1357 89e9ce8647 feat(python/robomp): bootstrapped node_modules in bare worktrees
- Added `ensure_workspace_dependencies` to automate `bun install` for new worktrees where dependencies are missing.
- Configured the installer to use `--frozen-lockfile` and `--ignore-scripts` to preserve security and lockfile integrity.
- Integrated the bootstrap step into the worker startup process to ensure workspace packages are resolvable.
2026-06-19 17:22:48 +02:00
can1357 aca5d5f48a feat(python): implemented pull request vouching and gated review system
- Introduced a vouching mechanism to manage PR authorization via a tracked user list and discussion-based management workflows.
- Added automated PR gatekeeping workflows to close contributions from unvouched users and require specific labels for review.
- Refactored PR event handling to support label-based review deferral and enforce authorization checks for labelers.
- Added comprehensive test coverage for vouch-gate logic, including label activation and unauthorized access scenarios.
2026-06-19 03:24:04 +02:00
lycaon a82697de7d fix(robomp): close lifecycle review gaps 2026-06-18 00:20:24 -06:00
lycaon feb04e8a37 fix(robomp): suppress superseded recent failures 2026-06-17 22:43:59 -06:00
lycaon 1961b830ba fix(robomp): harden lifecycle contract review cases 2026-06-17 22:21:45 -06:00
lycaon a20f6d46ce fix(robomp): prefer live events over stale latest rows 2026-06-17 21:48:49 -06:00
lycaon 107302adcf feat(robomp): replace status tables with lifecycle cards 2026-06-17 21:23:23 -06:00
can1357 c052cf893c feat(robomp): resume needs-info issues (#2728) 2026-06-18 02:48:29 +02:00
oldschoola 75fc25c9ba fix(robomp): keep label failures best effort 2026-06-16 01:54:14 -07:00
oldschoola f2015a0a21 fix(robomp): defer needs-info cleanup 2026-06-15 20:27:16 -07:00
oldschoola abd5e71d06 fix(robomp): align needs-info prompt guidance 2026-06-15 18:36:57 -07:00
oldschoola b945f54962 fix(robomp): clear needs-info on resume 2026-06-15 18:22:34 -07:00
oldschoola a409fd3216 feat(robomp): resume needs-info issues 2026-06-15 17:55:48 -07:00
can1357 77ea88e436 fix(coding-agent): fixed crashes when system prompts were provided as strings
- Normalized agent `setSystemPrompt` to wrap string inputs into one-item arrays.
- Updated session creation to accept string `systemPrompt` values and normalize callback or direct results to string arrays.
- Adjusted extension result handling and test fixtures to accept string `systemPrompt` and missing `assistant_message` fields without crashing.
2026-06-14 21:53:24 +02:00
can1357 31138bf7ec test(python/robomp): added cleanup guards to queue cancel and shutdown tests
- Wrapped queue shutdown and cancel test assertions in `try`/`finally` blocks.
- Cancelled and awaited worker and in-flight tasks in finalizers to prevent lingering background tasks.
- Handled expected `CancelledError` exceptions during task cleanup with `suppress`.
2026-06-14 19:03:58 +02:00
can1357 46ea12f1a1 feat(python/robomp): added automatic event retry scheduling with backoff delays
- Added event retry settings with parsed delay schedules and jittered delay computation.
- Extended event persistence to persist an `available_at` timestamp, honor it during dequeuing, and clear it when re-queuing.
- Updated worker failure handling to queue bounded retries with backoff and transition to failed only when the retry budget is exhausted.
2026-06-14 09:18:48 +02:00
can1357 c4ed34ea6c feat(python/omp-rpc): added effort-based model thinking config parsing
- Updated `ThinkingConfig` and related types to model effort-based thinking settings with optional defaults and routing metadata.
- Added a dedicated parser for `model.thinking` payloads to validate efforts and normalize new optional thinking fields.
- Extended protocol tests to verify effort-based thinking data is parsed correctly and unknown efforts are rejected.
2026-06-14 08:34:38 +02:00
can1357 86b4ed421d fix(omp-rpc): fixed rpc process cleanup and moved status data off the event loop
- Updated `RpcClient` to spawn `omp` in a new session, cache its process group, and terminate descendants on stop.
- Fixed `stop()` to signal the cached process group with SIGTERM then SIGKILL so leaked grandchildren are terminated.
- Moved status-query reads in `create_app` to `asyncio.to_thread`, preventing FastAPI event-loop stalls.
- Added regression coverage for stopping a spawned grandchild process in the client tests.
2026-06-14 00:11:26 +02:00
can1357 08a941a14e feat: added standalone snapcompact package and model-specific frame shaping
- Added a new @oh-my-pi/snapcompact package and redirected compaction call sites to it.
- Added provider-aware snapcompact shape resolution for model-specific mixed-frame behavior.
- Added optional image detail support by extending ImageContent and passing hints through OpenAI providers.
- Added native snapcompact render options, including 5x8/8x8 font loading and palette/geometry controls.
2026-06-10 21:50:03 +02:00
can1357 5e6a001f5e fix(python/robomp): raised runtime errors for agent stopReason=error
- In _run_rpc_blocking, added a check for an assistant_message stopReason after timeout handling.
- When stopReason is "error", the worker now reads errorMessage (or a default message) and raises a RuntimeError.
2026-06-08 22:31:34 +02:00
roboomp ae89b68b90 fix(robomp): parameterized bot identity in system prompts
system_append.md and system_append_pr_review.md hardcoded the literal
'robomp' as the bot persona, so the agent self-mentioned an account
that does not exist when deployments configure ROBOMP_BOT_LOGIN to a
different login. Affected users saw the agent ask for @robomp mentions
that GitHub never resolved to the actual bot.

Thread the configured login through persona.system_append and
persona.system_append_pr_review as a bot_login keyword, render it
via the existing {{bot_login}} placeholder, and pass
settings.bot_login at the worker callsite. Regression test asserts the
templated login lands in both prompts and the legacy literal is gone.

Fixes #1932
2026-06-05 14:15:07 +00:00
can1357 0bc6815ede Merge remote-tracking branch 'origin/farm/ad517ba0/worktree-add-fails-on-partial-clone-pool' 2026-06-04 14:52:36 +02:00
roboomp d5eb9caacf fix(robomp): serialized same-issue event claims
Prevented the durable queue from claiming a queued event while another event with the same issue key is still running, so duplicate worker instances cannot resume the same RpcClient session concurrently.

Added regression coverage for blocked same-issue events and for skipping blocked queue heads without stalling unrelated issues.

Fixes #1840
2026-06-04 10:48:35 +00:00
roboomp a692ffeb31 fix(robomp): backfilled partial-clone blobs before worktree add
`SandboxManager.ensure_workspace` calls `fetch_base_ref` (then
`worktree add origin/<ref>`) and `fetch_pr_head` (then
`worktree add --detach FETCH_HEAD`). Both used to issue a plain
`git fetch origin <ref>`. On a `--filter=blob:none` pool the fetch
inherits `remote.origin.partialclonefilter` from the pool config and
brings the commit + tree but no blobs. The next `worktree add` runs
in a non-token subprocess, hits a missing blob, and tries a lazy
promisor fetch — which under `ProxyGitTransport` deployments has no
PAT in the orchestrator container and dies with

    fatal: could not read Username for 'https://github.com'
    fatal: could not fetch <sha> from promisor remote

`git_ops.fetch_ref` and `fetch_pr_head` now pass `--refetch
--no-filter` so the fetch (which already runs through the token-bearing
transport) eagerly materializes every blob reachable from the requested
ref. `--refetch` is required: without it git short-circuits on "we
already have this commit" and the lazy-fetch path stays primed.
`fetch_prune` (the periodic pool refresh) is untouched, so the
partial-clone disk savings are preserved on the steady-state path.
`remote.origin.partialclonefilter` is left intact in the pool config.

Fixes #1818
2026-06-04 05:39:46 +00:00
can1357 f18eb90324 feat(agent): added implementation authorization gate for branch/PR tools
- Added `is_implementation_authorizer` check requiring OWNER or allowlisted maintainer to authorize implementation work.
- Blocked `gh_push_branch` and `gh_open_pr` for unclassified/enhancement/proposal issues without explicit directive authorization.
- Auto-allowed bug and documentation issues without requiring a directive.
- Propagated `authorizes_impl` flag through events, server, tasks, and worker bindings.
2026-06-02 08:44:59 +02:00