Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: pullfrog/pullfrog
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.1.112
Choose a base ref
...
head repository: pullfrog/pullfrog
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.1.113
Choose a head ref
  • 5 commits
  • 18 files changed
  • 1 contributor

Commits on Nov 3, 2026

  1. models: list Zen's free promos from the published catalogs, so a new …

    …one needs no PR (#1636)
    
    * models: list Zen's free promos from the published catalogs, so a new one needs no PR
    
    * models: key auto-listed Zen promos by their own -free id, so a runner on its bundled registry passes the slug through to the model Zen serves
    colinhacks authored and pullfrog[bot] committed Nov 3, 2026
    Configuration menu
    Copy the full SHA
    994aaf9 View commit details
    Browse the repository at this point in the history
  2. OSS menu: MiniMax M3.1 Flash replaces M2, DeepSeek Flash follows its …

    …own snapshots
    
    - the funded OSS default is no longer pinned to one dated OpenRouter id: the served registry follows models.dev's canonical id for `deepseek-flash`, so it moved to 1017 and will follow the next snapshot with no PR
    - `openrouter/minimax-flash` (M3.1 Flash, 0.075/0.30) joins the registry and replaces MiniMax M2 on the OSS menu; OpenRouter M2 picks fall back to it
    - the three campaign templates for the 2026-11 OSS model emails, their ledger keys, and the outreach selector keyed per campaign, with September's idle batch approvals counted as not-yet-in-program
    colinhacks authored and pullfrog[bot] committed Nov 3, 2026
    Configuration menu
    Copy the full SHA
    71f12e6 View commit details
    Browse the repository at this point in the history
  3. codenav: point the review at codenav callers in checkout_pr's reply…

    …, and drop codenav when the sandbox probe disables the shell (#1635)
    colinhacks authored and pullfrog[bot] committed Nov 3, 2026
    Configuration menu
    Copy the full SHA
    93c5467 View commit details
    Browse the repository at this point in the history
  4. Isolate the MCP server's own git calls and dependency installs in the…

    … exec sandbox (#1616)
    
    * action: run the MCP server's own git calls and dependency installs in the exec sandbox
    
    The shell MCP tool runs in a PID+mount namespace, but the MCP server's own
    unauthenticated git calls ($() in action/utils/shell.ts) and the dependency
    installers ran plain spawnSync/spawn in the action process. A repo-planted
    ~/.gitconfig core.fsmonitor / core.hooksPath / filter driver / diff.external,
    or a postinstall script / pip.conf index, executed repo-controlled code in the
    action's PID namespace, where it could read /proc/<action-pid>/environ — the
    OIDC mint ticket (full-permission token), the job token, customer env: secrets.
    delete process.env does not scrub the kernel's exec-time environ snapshot, so
    env-filtering alone never closed it.
    
    Route every such exec through the same unshare --pid --fork --mount-proc sandbox
    the shell tool and lifecycle hooks already use: a planted hook/filter/postinstall
    fires in a fresh PID namespace (no action/agent PID visible) with the filtered
    env. Factor the sandbox-exec primitive into a leaf action/utils/sandbox.ts shared
    by the shell path (spawnShell), the sync MCP git path (spawnGitSandboxedSync) and
    the installers (buildSandboxedCommand). The git profile omits the .git read-only
    bind so commits still write .git; the installer keeps it. No namespace available
    => run directly (no agent shell to plant config either). $git() fetch/push is
    untouched (already hardened).
    
    Adds the githookprocexfil deny-path test; updates wiki/security.md, wiki/askpass.md,
    docs/security.mdx.
    
    * action: close review findings — sandbox the post-run git status, block non-https $git transports
    
    Review of #1616 surfaced three real findings; verified each against the code:
    
    - getGitStatus (post-run dirty check) ran a bare execFileSync("git","status")
      with full env in the action process — the same planted-fsmonitor /proc-read
      vector this PR closes for $(). Route it through $() (sandboxed + filtered env
      in CI). Moved from agents/shared.ts to agents/postRun.ts (its only caller) so
      the shell sandbox stays out of the root TS program: shared.ts is root-reachable,
      and importing $ there pulled spawnSync-with-filtered-env under Next's ProcessEnv
      (the documented NODE_ENV trap).
    
    - $git() pinned hooks/fsmonitor but not the transport, so a planted ~/.gitconfig
      url.*.insteadOf -> ext:: / remote-helper / ssh+ProxyCommand could exec on fetch
      (no URL check there, and the transport runs before the askpass host check). Add
      GIT_ALLOW_PROTOCOL=https; every $git caller talks to github.com over https.
    
    - Fixed a stale comment/doc claim that MCP commits go through $git() outside the
      namespace (they go through $() in its own gitWritable sandbox).
    
    Swept all direct git execs: instructions.ts `git status` is pre-agent (outside the
    injection window); changeImpact `git grep` already uses filtered env and greps a
    treeish (no fsmonitor/filter); cat-file/rev-parse/config exec no config code.
    
    * action: keep .git writable in the dependency-install sandbox so husky can install its hooks
    
    The installer sandbox kept the shell's .git read-only bind, so husky's `prepare`
    (`git config core.hooksPath .husky/_`) failed with "could not lock config file
    .git/config: Read-only file system" while npm still exited 0. A customer's husky,
    lefthook or pre-commit hooks then silently stopped running on agent commits.
    Reproduced in the docker sandbox (sudo-unshare). With .git writable the hooks
    install, and a postinstall still sees no parent environ in /proc (0 matches vs 1
    unsandboxed). The bind bought nothing there: a hook fired by an MCP git call can
    already write .git. buildSandboxedCommand drops its gitWritable parameter.
    
    * action: resolve the repo root only when the .git read-only bind is built
    
    resolveRepoRoot memoizes its first answer. Now that every $("git") call builds a
    sandbox invocation, runFixture's setupTestRepo git calls ran it before
    GITHUB_WORKSPACE pointed at the test repo, pinning the pullfrog/app checkout:
    the shell's .git bind then protected the wrong directory and fs-exfil-claude
    saw .git/config writable. The git and installer profiles need no bind, so only
    gitReadOnlyMount() resolves the root now, restoring main's first-call timing.
    Production was unaffected (GITHUB_WORKSPACE is constant for the run).
    
    * wiki: sudo logs the sandbox's env argv to a journal the runner can read
    colinhacks authored and pullfrog[bot] committed Nov 3, 2026
    Configuration menu
    Copy the full SHA
    a120452 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    e78ef90 View commit details
    Browse the repository at this point in the history
Loading