Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "push"
version = "0.8.0"
version = "0.8.1"
Comment thread
owainlewis marked this conversation as resolved.
edition = "2021"
license = "MIT"
description = "A tiny messaging gateway that turns coding agents into a personal assistant you text."
Expand Down
7 changes: 4 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,10 @@ the trust boundary. iMessage uses `imessage.self_handles` and
and `telegram.allow_chat_ids`; Slack uses stable `slack.allow_user_ids` member
IDs and verifies the authenticated workspace.

Push does not override sandbox, approval, permission-mode, or tool-list settings.
Chats and jobs use the selected agent's own configuration and must use work
directories that do not overlap Push-owned state or configuration.
Push preserves sandbox, approval, permission-mode, and tool-list settings for
chats. Codex and Claude jobs bypass interactive permissions so unattended work
can complete. Every job must use a work directory that does not overlap
Push-owned state or configuration.

## Roadmap

Expand Down
12 changes: 6 additions & 6 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ allow_user_ids = [123456789]
```

`channel` is the easiest single-provider setup. `agent` is `claude`, `codex`,
or `pi`. Push does not set sandbox, approval, permission-mode, or tool flags.
Configure those in the selected agent.
or `pi`. Push preserves backend permission settings for chats. Codex and Claude
jobs bypass interactive permissions so unattended runs can complete.

### Pi setup

Expand Down Expand Up @@ -177,10 +177,10 @@ Thread keys are:

## Agent permissions

Permissions belong to the agent, not the gateway. Push invokes Claude Code,
Codex, and Pi without overriding their sandbox, approval mode, or tool lists.
This keeps interactive and gateway behavior aligned. Configure permissions in
the selected agent and review [permissions and security](security.md).
For chats, Push invokes Claude Code, Codex, and Pi without overriding their
sandbox, approval mode, or tool lists. Codex and Claude jobs bypass interactive
permissions because scheduled work has no operator available to approve
requests. Review [permissions and security](security.md) before enabling jobs.

## Settings reference

Expand Down
6 changes: 4 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ sends the result back when the work is done.
<article>
<span>04</span>
<h3>Use your existing tools</h3>
<p>Keep the MCP servers, skills, permissions, and integrations already configured in Claude Code, Codex, or Pi.</p>
<p>Keep the MCP servers, skills, and integrations already configured in Claude Code, Codex, or Pi. Chats also preserve your configured permissions.</p>
</article>
</div>

Expand All @@ -99,7 +99,9 @@ sends the result back when the work is done.

Push does not replace your coding agent. It handles chat, history, schedules,
approvals, and delivery. Claude Code, Codex, or Pi keeps control of models,
tools, skills, permissions, and authentication.
tools, skills, and authentication. Chats preserve configured agent permissions;
Codex and Claude jobs bypass interactive permissions so scheduled work can
finish without an operator.

[See the full architecture](architecture.md){ .push-inline-link }

Expand Down
10 changes: 6 additions & 4 deletions docs/jobs.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ and primary delivery destination.
## Execution and delivery guarantees

- Every job and evaluator run uses a fresh backend session, without chat history.
- Jobs use the selected agent's own permission configuration.
- Codex and Claude jobs bypass interactive permissions so unattended work can
complete. Evaluators remain restricted.
- Push does not retry failed or timed-out backend execution because the agent
may have completed external side effects before failing.
- Success, failure, timeout, overlap, and delivery state are stored separately.
Expand Down Expand Up @@ -209,6 +210,7 @@ job. Rejection leaves the proposal inactive.

!!! warning

Jobs use the selected agent's own permissions. A headless backend may not
ask for approval interactively, so configure its
unattended permissions carefully and keep job work directories narrow.
Jobs have no interactive approval path. Push runs Codex jobs with full
access and no prompts and Claude jobs in `bypassPermissions` mode. Treat
every enabled job as code execution by the Push service user, keep job work
directories narrow, and allow only trusted senders and job definitions.
10 changes: 6 additions & 4 deletions docs/jobs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ an agent runtime.
- Push has one long-running gateway process with no inbound server port.
Commands may run as short-lived local processes against the same SQLite
store.
- Claude Code, Codex, and Pi own their permission controls. Push passes no
permission or tool overrides.
- Chats use the selected agent's permission controls without overrides. Codex
and Claude jobs bypass interactive permissions so unattended runs can finish;
Pi has no native filesystem sandbox or approval prompt.
- Scheduled work can have external side effects, so duplicate execution is more
dangerous than skipping a missed run.
- Job files, `SOUL.md`, and `context/` belong to the Git-versioned assistant
Expand Down Expand Up @@ -143,8 +144,9 @@ A scheduled occurrence is cancelled if its trigger no longer exists in that
validated snapshot. Immediately before spawning a backend, Push resolves the
work directory again so a path replacement is likely to be detected. This
path-based check does not eliminate a replacement race between validation and
child startup; the agent's configuration and OS permissions remain the
enforcement boundary. The timeout must not exceed the configured jobs maximum.
child startup. Jobs bypass interactive backend permissions, so OS permissions
remain the enforcement boundary. The timeout must not exceed the configured
jobs maximum.

Notification behavior follows the trigger rather than job metadata. A manual
run prints its result to the invoking terminal and does not send a message. A
Expand Down
18 changes: 13 additions & 5 deletions docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ Slack allowlists use stable member IDs, never mutable display names.
## Agent permissions

Push does not pass sandbox, approval-policy, permission-mode, or tool-list
overrides to Claude Code, Codex, or Pi. The selected agent's own configuration
is the sole permission source for chats and jobs.
overrides for chats. The selected agent's own configuration is the permission
source for chat requests.

This makes Push behave like the agent you already configured, but it also means
every agent-approved capability may be one accepted message away. Review the
Expand All @@ -40,9 +40,17 @@ selected agent instead.

## Job permissions

Jobs use the selected agent's own permission configuration. Push requires a
fixed, existing work directory and rejects overlap with Push-owned files,
including the loaded config file.
Jobs must complete without an interactive approval channel. Push therefore runs
Codex jobs with full filesystem and network access and no approval prompts, and
runs Claude jobs in `bypassPermissions` mode. Pi already has no native
filesystem sandbox or interactive permission prompt. Evaluators remain
read-only with tools disabled.

This makes job bodies equivalent to unattended code execution as the Push
service user. Push requires a fixed, existing work directory and rejects overlap
with Push-owned files, including the loaded config file. Keep allowed senders
and job definitions trusted, and run the service with only the OS permissions
its jobs require.

Do not place secrets in a job body. Make them available through the backend or
service environment using the narrowest policy that works.
Expand Down
5 changes: 3 additions & 2 deletions docs/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,9 @@ is completed.
Managed services run without a person watching the terminal. An allowed sender
can instruct the configured backend to use its tools, subject to your backend
settings. Keep `imessage.allow_from` narrow and configure each selected agent
for unattended use. Push passes no sandbox, approval, or tool overrides. Jobs
are kept away from Push-owned paths by work-directory validation.
for unattended use. Push preserves backend permissions for chats. Codex and
Claude jobs bypass interactive permissions so they can finish without an
operator. Jobs are kept away from Push-owned paths by work-directory validation.

Store config files, state files, audit logs, backend credentials, and service
logs with permissions appropriate for the service user. Logs may contain
Expand Down
14 changes: 14 additions & 0 deletions src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ impl Runner {
}
}

pub async fn run_unattended(
&self,
req: Request<'_>,
timeout: Duration,
) -> Result<RunOutput, RunError> {
match self {
Runner::Claude(r) => r.run_unattended(req, timeout).await,
Runner::Codex(r) => r.run_unattended(req, timeout).await,
Runner::Pi(r) => r.run(req, timeout).await,
#[cfg(test)]
Runner::Fake(r) => r.run(req, timeout).await,
}
}

pub async fn run_evaluator(
&self,
req: Request<'_>,
Expand Down
2 changes: 1 addition & 1 deletion src/assistant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ This Git repository contains the durable, user-owned parts of one Push assistant
- `evals/` contains reusable agent evaluation criteria.
- `jobs/` contains installed Push job runbooks.

Push owns channels, scheduling, history, security, approvals, and delivery outside this repository. Project skills may live here, while the configured agent runtime owns discovery, execution, permissions, global skills, MCP servers, and authentication.
Push owns channels, scheduling, history, security, approvals, and delivery outside this repository. Project skills may live here, while the configured agent runtime owns discovery, execution, global skills, MCP servers, and authentication. Chats preserve configured agent permissions. Codex and Claude jobs bypass interactive permissions so unattended work can finish.
"#;

const CONTEXT_README: &str = r#"# Context
Expand Down
Loading
Loading