Skip to content
Closed
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
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ See [CLAUDE.md](CLAUDE.md) for project rules and design decisions.

## Commit messages

You **must** read and follow [COMMITS.md](COMMITS.md) when writing or reviewing commit messages. Getting the prefix right is not optional — GoReleaser uses it to build release notes.
Use [Conventional Commits](https://www.conventionalcommits.org/) format for every commit. The allowed types are: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `ci`, `perf`, `build`. See [CONTRIBUTING.md](CONTRIBUTING.md#commit-messages) for the full specification.

This is not optional — GoReleaser parses commit prefixes to build release notes. A missing or wrong prefix produces incorrect changelogs.

When reviewing PRs, check that commit messages and PR titles follow this format. Flag violations as a required change — they are not cosmetic.

## Forge abstraction

Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Fullsend is a platform for fully autonomous agentic development for GitHub-hoste
- Keep core problem documents organization-agnostic. Organization-specific details belong in `docs/problems/applied/<org-name>/`.
- The target audience is any contributor community considering autonomous agents — keep language accessible, avoid presuming solutions.
- Always run `make lint` before submitting changes and fix any failures.
- You **must** read and follow [COMMITS.md](COMMITS.md) when writing or reviewing commit messages. Getting the prefix right is not optional — GoReleaser uses it to build release notes.
- Use [Conventional Commits](https://www.conventionalcommits.org/) for all commit messages. See [CONTRIBUTING.md](CONTRIBUTING.md#commit-messages) for the full specification. This is critical — GoReleaser uses commit prefixes to generate release notes.
- Never commit secrets (tokens, API keys, PEM keys, gcloud credentials) or sensitive data (GCP project names, service account identifiers, Model Armor template names, internal hostnames). Use environment variables with no defaults for sensitive values.

## Go code
Expand Down
73 changes: 0 additions & 73 deletions COMMITS.md

This file was deleted.

50 changes: 49 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,55 @@ Thank you for your interest in contributing! This document covers the social nor

## Commit messages

This project uses [Conventional Commits](https://www.conventionalcommits.org/). See [COMMITS.md](COMMITS.md) for the full specification, type selection rules, and examples.
This project uses [Conventional Commits](https://www.conventionalcommits.org/). Every commit on `main` feeds the auto-generated release notes (via GoReleaser), so getting the format right matters.

### Format

```
<type>(<scope>): <short description>

<optional body>

<optional trailers>
```

### Types

| Type | Purpose | Appears in release notes? |
|---|---|---|
| `feat` | New functionality | Yes — under **Features** |
| `fix` | Bug fix | Yes — under **Bug Fixes** |
| `refactor` | Code restructuring (no behavior change) | Yes — under **Refactoring** |
| `docs` | Documentation only | No |
| `test` | Adding or updating tests | No |
| `chore` | Maintenance (CI, deps, tooling) | No |
| `ci` | CI/CD pipeline changes | No |
| `perf` | Performance improvement | Yes — under **Others** |
| `build` | Build system or dependency changes | No |

### Scope

The parenthesized scope is optional but encouraged. Use it to identify the subsystem: `feat(appsetup)`, `fix(mint)`, `docs(adr)`, `chore(ci)`. When fixing a specific issue, prefer the issue number as scope: `fix(#123): ...`.

### Breaking changes

Append `!` after the type/scope to flag a breaking change: `feat(cli)!: rename --gcp flags to --inference`. Include a `BREAKING CHANGE:` trailer in the body explaining migration steps. Breaking changes trigger a major version bump.

### Examples

```
feat(review-agent): add outcome labels to post-review.sh

fix(#933): use .yaml extension for shim workflow path

docs: add mint URL stability note to installation guide

chore(ci): update goreleaser to v2
```

### Why this matters

GoReleaser groups changelog entries by type prefix (see `.goreleaser.yml`). Commits without a recognized prefix land under "Others". Commits prefixed `docs:`, `test:`, `chore:`, `ci:`, or `build:` are excluded from release notes entirely. A wrong prefix means the change shows up in the wrong section — or not at all.

## DCO (Developer Certificate of Origin)

Expand Down
7 changes: 6 additions & 1 deletion docs/ADRs/0038-universal-harness-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,4 +364,9 @@ The proposed model follows the GitHub Actions approach: URL-based references wit

## Implementation Plan

See `docs/plans/universal-harness-access.md` for full implementation details, security analysis, and migration path. See `docs/plans/universal-harness-access-phase1.md` for the phased PR breakdown (Phase 1 MVP), `docs/plans/universal-harness-access-phase2.md` for Phase 2 (transitive dependency resolution), `docs/plans/universal-harness-access-phase3.md` for Phase 3 (lock files), and `docs/plans/universal-harness-access-phase4.md` for Phase 4 (runtime dependency loading).
See `docs/plans/universal-harness-access.md` for full implementation details, security analysis, and migration path. Per-phase PR breakdowns:

- `docs/plans/universal-harness-access-phase1.md` — Phase 1: URL detection, fetch, cache, schema, resolver, CLI (complete)
- `docs/plans/universal-harness-access-phase2.md` — Phase 2: Transitive dependency resolution (complete)
- `docs/plans/universal-harness-access-phase3.md` — Phase 3: Lock files (complete)
- `docs/plans/universal-harness-access-phase4.md` — Phase 4: Runtime dependency loading (in progress)
2 changes: 2 additions & 0 deletions docs/ADRs/0045-forge-portable-harness-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ compatibility.
| `sandbox_timeout_seconds` | Sandbox-level timeout, not forge-specific |
| `security` | Security scanning is forge-agnostic |
| `allowed_remote_resources` | URL allowlist for resource fetching (ADR 0038) |
| `allow_runtime_fetch` | Opt-in for runtime dependency loading (ADR 0038) |
| `max_runtime_fetches` | Rate limit for runtime fetches (ADR 0038) |
| `description` | Documentation, no runtime effect |
| `role` | Agent identity is forge-agnostic |
| `slug` | Kept top-level; per-forge slug differences handled via `base` composition or a future `forge.<platform>.slug` extension — see trade-off note below |
Expand Down
14 changes: 1 addition & 13 deletions docs/guides/dev/cli-internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,19 +235,7 @@ Install: process 1→7 (forward)
Uninstall: process 7→1 (reverse)
```

Per-repo mode does not use the layer stack — it runs the same phases inline in `runPerRepoInstall()` and `runGitHubSetupPerRepo()` since there's no need for composable uninstall ordering with a single repo. Binary vendoring (when `--vendor-fullsend-binary` is set) and stale binary cleanup are handled inline or via shared helpers; per-org mode uses `VendorBinaryLayer`.

### Binary acquisition (`internal/binary`)

Linux binary resolution for `fullsend run` and vendoring lives in `internal/binary`:

| Function | Policy |
|----------|--------|
| `ResolveForRun` | Release download (released CLI only) → cross-compile → latest release |
| `ResolveForVendor` | Cross-compile → matching release (released CLI only) → fail (no latest) |
| `ResolveExplicit` | Validate linux/{arch} ELF for `--fullsend-binary` |

Vendoring commit messages use title + body (upload and stale delete). `admin analyze` reports stale vendored binaries at `bin/fullsend` or `.fullsend/bin/fullsend` without install-intent flags.
Per-repo mode does not use the layer stack — it runs the same phases inline in `runPerRepoInstall()` since there's no need for composable uninstall ordering with a single repo. Binary vendoring (when `--vendor-fullsend-binary` is set) and stale binary cleanup are handled inline rather than through `VendorBinaryLayer`.

---

Expand Down
11 changes: 2 additions & 9 deletions docs/guides/getting-started/github-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ For the all-in-one setup that provisions both GCP and GitHub in a single command
- **GitHub CLI** (`gh`) authenticated — the installer runs a preflight check and tells you which scopes are missing. When prompted, run the `gh auth refresh -s <scopes>` command it suggests.
- **fullsend CLI** — download the latest binary from [GitHub Releases](https://github.com/fullsend-ai/fullsend/releases)
- **From your Mint service provider admin** (currently GCP-managed; other providers planned):
- Token mint URL (`--mint-url`) — the HTTPS endpoint of the deployed mint Cloud Function. If you are using the fullsend hosted mint, the URL is `https://fullsend-mint-gljhbkcloq-uc.a.run.app` (see [Hosted mint](../infrastructure/mint-administration.md#hosted-mint)).
- Token mint URL (`--mint-url`) — the HTTPS endpoint of the deployed mint Cloud Function
- **From your Inference provider admin** (currently GCP Agent Platform, formerly Vertex AI; other providers planned):
- GCP project ID (`--inference-project`) — the project where Agent Platform is enabled (e.g., `my-gcp-project`)
- WIF provider resource name (`--inference-wif-provider`) — the full resource path, e.g., `projects/123456789/locations/global/workloadIdentityPools/fullsend-inference/providers/github-oidc` (note: the leading number is the GCP **project number**, not the project ID string; your GCP admin can find it with `gcloud projects describe <project-id> --format='value(projectNumber)'`)
Expand Down Expand Up @@ -118,16 +118,9 @@ fullsend github setup acme-corp \
| `--app-set` | No | `fullsend-ai` | App set name prefix for GitHub Apps |
| `--enroll-all` | No | `false` | Enroll all repositories without prompting (per-org only) |
| `--enroll-none` | No | `false` | Skip enrollment without prompting (per-org only) |
| `--vendor-fullsend-binary` | No | `false` | Resolve and upload a linux/amd64 fullsend binary for CI (see [Vendoring the CLI binary](#vendoring-the-cli-binary)) |
| `--fullsend-binary` | No | | Path to a Linux fullsend binary when vendoring (skips auto-resolution) |
| `--vendor-fullsend-binary` | No | `false` | Build and upload the fullsend binary to the config repo for local dev testing (e.g., macOS with a Podman Linux VM) |
| `--dry-run` | No | `false` | Preview changes without making them |

### Vendoring the CLI binary

Same policy as [admin install](installation.md#vendoring-the-cli-binary): `--fullsend-binary` → checkout cross-compile → matching release (released CLI only) → fail. Per-repo setup now wires vendoring and stale-binary cleanup when the flag is off.

`fullsend admin analyze <org>` reports when a stale vendored binary is present (no install-intent flags on analyze).

## Per-repo setup

Per-repo mode bootstraps a single repository with a `.fullsend/` directory, shim workflow, and repo-level secrets:
Expand Down
22 changes: 1 addition & 21 deletions docs/guides/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,7 @@ The installer automatically provisions [Workload Identity Federation (WIF)](http
| `--skip-mint-check` | `false` | Skip mint validation, GCP provisioning, and app setup; requires `--mint-url` |
| `--enroll-all` | `false` | Enroll all repositories without prompting (per-org only) |
| `--enroll-none` | `false` | Skip repository enrollment without prompting (per-org only) |
| `--vendor-fullsend-binary` | `false` | Resolve and upload a linux/amd64 fullsend binary for CI (see [Vendoring the CLI binary](#vendoring-the-cli-binary)) |
| `--fullsend-binary` | | Path to a Linux fullsend binary to upload when `--vendor-fullsend-binary` is set (skips auto-resolution) |
| `--vendor-fullsend-binary` | `false` | Cross-compile and vendor the fullsend binary for development iteration |

The `--skip-mint-check` flag bypasses all mint validation, GCP provisioning, and app setup. It requires `--mint-url` to be set and only validates that the URL uses HTTPS. This is useful when the mint infrastructure is managed externally or you want to skip GCP API calls entirely.

Expand All @@ -267,25 +266,6 @@ The installer automatically detects when the deployed mint function is up-to-dat

A single token mint can serve multiple GitHub organizations. See [Mint service administration — Multi-org setup](../infrastructure/mint-administration.md#multi-org-setup) for the complete multi-org workflow.

### Vendoring the CLI binary

Use `--vendor-fullsend-binary` to upload a linux/amd64 `fullsend` binary into the config repo (`bin/fullsend`) or per-repo path (`.fullsend/bin/fullsend`). CI workflows prefer this file over downloading from GitHub releases.

When the flag is set, the binary is resolved in this order:

1. **`--fullsend-binary <path>`** — upload that file (validated as linux/amd64 ELF)
2. **Checkout build** — cross-compile from the fullsend module root (`go env GOMOD`), stamped `{version}-vendored`
3. **Release fetch** — only if step 2 is unavailable **and** the running CLI is a released version (e.g. `0.4.0`); downloads the matching GitHub release (no `-vendored` suffix)
4. **Fail** — dev CLI outside a checkout fails with a clear error (no “latest release” fallback)

When the flag is **off**, any existing vendored binary is removed so CI uses released versions.

**Notes:**

- Vendoring the CLI alone does not air-gap the full pipeline (OpenShell, gateway, sandbox image, upstream scaffold still download at runtime).
- Release fallback requires network access at install time; CI consumes the uploaded file.
- Works from any directory inside the module checkout (module root discovery via `GOMOD`).

### Merge enrollment PRs

If you chose to enroll repositories during install, the installer dispatches a workflow that creates an enrollment PR in each enrolled repo. These PRs add a shim workflow (`.github/workflows/fullsend.yaml`) that wires events to the agent pipeline.
Expand Down
12 changes: 1 addition & 11 deletions docs/guides/infrastructure/mint-administration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,7 @@

This guide covers deploying and managing the fullsend token mint Cloud Function. The mint is the OIDC token exchange service that lets GitHub Actions workflows authenticate as GitHub Apps — it is infrastructure that serves all enrolled organizations and repositories.

> **This guide is for platform operators** who deploy, manage, or troubleshoot the token mint Cloud Function. If you are an end user setting up fullsend for your organization, see [Installing fullsend](../getting-started/installation.md) instead — the mint is typically deployed once by a platform operator, and organizations are enrolled as needed.

## Hosted mint

The fullsend team operates a public hosted mint service. If your organization is enrolled, you can use it directly without deploying your own:

```
https://fullsend-mint-gljhbkcloq-uc.a.run.app
```

Pass this URL as `--mint-url` when running `fullsend admin install`, or set the `FULLSEND_MINT_URL` repository/org variable in GitHub. If you are using the hosted mint, the rest of this guide (deploying, enrolling, troubleshooting) is handled by the fullsend team — you do not need to manage mint infrastructure yourself.
> **This guide is for platform operators** who deploy, manage, or troubleshoot the token mint Cloud Function. If you are an end user setting up fullsend for your organization, see [Installing fullsend](../getting-started/installation.md) instead — the mint is typically deployed once by a platform operator, and organizations are enrolled as needed. Work is in progress to offer a hosted public mint service, which will further reduce the need for per-org mint administration.

## Prerequisites

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/user/running-agents-locally.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ to the server (gateway). It is likely that you need to bind the gateway to `0.0.
- Check that it's registered: `openshell gateway list`

**`Syntax error: "(" unexpected` inside sandbox**
- The macOS Mach-O binary was injected instead of a Linux ELF. Update to fullsend 0.4.0+ which auto-resolves the correct binary, or provide one explicitly with `--fullsend-binary`
- The macOS Mach-O binary was injected instead of a Linux ELF. The CLI auto-resolves the correct binary (download or cross-compile). If auto-resolution fails, provide one explicitly with `--fullsend-binary`

**Agent fails with missing environment variable**
- Check your env file contains all variables listed in the agent's harness YAML (`harness/{agent}.yaml` in the `.fullsend` config directory)
Expand Down
Loading
Loading