Repository navigation
Releases: kabirnarang39/pando
Release list
v3.5.1
Added
- Website: a new landing page and a pricing page with a Team cost calculator. The product name,
links and list prices live insite/site.conf, whichscripts/build-site.shfills in; the
pages self-host their fonts. URLs are unchanged: the landing page at the site root, docs under
/docs/, the console demo under/console/, and the new/pricing.html. - Releases attach the web console,
pando-console-vVERSION.tar.gzwith its.sha256, covered by
the release's signed provenance and SBOM attestations. pandod server --console-dir DIR(PANDO_CONSOLE_DIR) serves the console at/on the
server's own address: links into the app fall back toindex.html, hashed assets are cached for
a year and everything else revalidated, with CSP,nosniff, framing and referrer headers
(ADR-036).- A cross-tenant isolation suite, a release gate: every method in the protocol is called with
another organisation's tokens (a person, an agent, tokens limited to a repository) at an
organisation's repositories, change requests, issues, webhooks, protections, locks, teams and
tokens, and must be refused or show nothing of theirs; a method missing from its table fails it.
Fixed
docs/platform.mdsaid git manages 2 lands/s at 200 agents; the benchmark measured 0.5.docker compose upfailed: every service listens on the network without a token, which
pandod refuses. The compose file now requiresPANDO_TOKENin.env(with a clear error when
it is missing) and passes it to the server, the cache and the daemon.- A bare
PANDO_SERVER(no/OWNER/NAME) naming a clone's own server no longer hides the
clone's repository, sopando protectandpando crwork inside a clone with it set. - The remote MCP endpoint answers clients on protocol versions before 2026-07-28 (their
initialize) without a session, instead of "Session management is not supported". --repos-objects file:///…/{repo_id}no longer makes a directory literally named{repo_id}
(readiness checks the template's base directory), and a--platformserver no longer creates
an unused./pando-data: its default--metadatais nowmemory.pando admin limits suspendsays when the server doesn't enforce limits (not
--multi-tenant);pando org usageprints dates instead of epoch milliseconds.pando migrateprints thepando mirrorcommand for any git source, not only GitHub.- The working copy reads
.pandoignore;.sapignorestill works, with a deprecation warning. pando webhook add --helplists theissueevent;pandod backup --helppoints to
docs/backup.md.- The console demo on the public site no longer asks for
/login/providers(a 404). docs/platform.mdno longer claims per-path owners in repository settings.
Security
- Creating a token limited to repositories told whether a private repository you can't see
exists; such a name is now "no repository", like everywhere else. - Granting a repository to a team told whether another organisation has a team of that name;
only the owning organisation's teams are recognised.
v3.5.0
Added
pando login [SERVER_URL]signs the CLI in from the browser (OAuth device flow) and saves a
90-day token in~/.config/pando/credentials.json(mode 0600), used when neither--tokennor
PANDO_TOKENis given;pando logoutrevokes it andpando whoamishows the account (ADR-033).- Invitations: organisation administrators invite by email (
CreateInvitation,
ListInvitations,RevokeInvitation); the single-use, 7-day link signs the person in (creating
an account if needed) and adds them with the invited role (ADR-033). - First sign-ins ask the person to confirm they are 18 or older and accept the terms
(--terms-url,--privacy-url) before an account is created; the time is stored on the account. Viewerreturns the calling token's id, so clients can sign out by revoking it.- Console: "Sign in with …" buttons and an email form when the server has sign-in pages, sign out,
a guided set-up for a new organisation (name it, invite teammates, connect an agent), and
invitations on the organisation's People tab. pandod repo disable|enable OWNER/NAMEtakes a repository down at once without deleting it,
andpandod repo delete OWNER/NAMEremoves it and its storage; documented with a secret purge
procedure in docs/deploy.md.--trust-proxy: audit-log client addresses fromX-Forwarded-Forsent by a local proxy.- Console: "New repository" on the organisation page; an empty repository shows how to clone it,
make the first change or bring in a git repository; a new token shows ready-to-copy CLI and MCP
setup.
Changed
- SQLite commits are synced to disk (
synchronous=FULL) so an acknowledged land survives power
loss;--sqlite-synchronous normalrestores the previous behaviour.file://object stores
fsync every object and its directory (ADR-034). --metricsalso serves/healthzand/readyz; gRPC health checks need no token and report
NOT_SERVING when the registry or a data directory fails, and from the start of shutdown.- SIGTERM drains calls in progress and stops the webhook worker before exiting.
- Platform servers limit each account to 128 calls in progress (
--max-calls-per-principal)
and request messages to 64 MiB (--max-request-mb), keep at most 256 repositories open
(--max-open-repos,--repo-idle-minutes), and page repository listings. - Webhooks: deliveries run concurrently, two at a time per webhook, 30 s each; delivery is at
least once (dedupe byX-Pando-Delivery); finished deliveries are deleted after 30 days. - The audit log is written to one file per UTC day and kept
--audit-retention-days(365). --web-originsis now--cors-origin(the old name still works);pando mcp --httptakes
--allowed-originand stops on SIGTERM.- The registry records its schema version and applies ordered migrations.
- Console UX pass: a first visit to a server with sign-in pages opens sign-in instead of the demo;
set-up asks for the organisation's name and derives its short name; the full repository header
shows on Overview only; gold marks landings only (dark-theme buttons, selection and unread marks
use Fishlake blue); form errors read as sentences.
Fixed
- Console: the clone and mount commands name the repository (
SERVER/OWNER/NAME) on servers that
host many; Home shows an error instead of loading forever when the server is unreachable or
refuses the token; Issues breadcrumbs; Escape closes the phone navigation drawer; wide tables no
longer widen the page on phones; imported git authors show their name without the email; the
Connect page's "remember" checkbox is visible.
Security
- Production hardening (ADR-034): metric labels only for methods the protocol defines (no
unbounded series from made-up paths); internal errors return an id, not SQL or paths; the
registry survives a panic while locked; inbox, events, issue and repository listings scan a
bounded number of rows and never open every repository; archived repositories refuse writes;
Locks/Listshows only paths the caller may read; the MCP gateway refuses browser origins unless allowed; the
free-tier cloud-init no longer trusts a demo console origin; a stored object that fails its
hash check is repaired by pushing it again. - Plans and limits (ADR-035): platform servers record each organisation's active agents (agents
that landed a change in the calendar month), people, storage (measured hourly, with the month's
peak) and private repositories. With--multi-tenant, organisations' limits are enforced:
suspended organisations and those over storage can read but not write, new agents beyond the
active-agent limit can't land while active ones keep landing, and seats and private
repositories are checked when added. Defaults come from--default-org-limits. New RPCs
GetUsage,SetLimits,SetSuspended,GetCapabilitiesandGetLicense; commands
pando org usageandpando admin limits show|set|suspend|restore; a Usage & plan tab in
the console with a Change plan button linking to--billing-url, and a banner on every page of
a suspended organisation linking to--support-url. - Support licences:
pandod server --license FILEandpandod license verify FILEcheck an
Ed25519-signed licence offline and report it; nothing is turned off without one.
Changed
- The sign-in pages (
/login/*: sign in, check your email, create your account, CLI approval,
invitations, errors) carry the console's brand: the Pando mark, its palette in light and dark,
labelled fields, a clear primary action and plain error messages, still self-contained under
default-src 'none'.
v3.4.0
Added
pandod server --multi-tenant(PANDO_MULTI_TENANT) for servers that strangers share:
internal repositories are for the owning organisation's members, members and grants must name
existing accounts, and any person may create up to--max-orgs-per-account(default 3)
organisations, in a namespace shared with logins and with service names reserved (ADR-032).- Browser sign-in for platform servers (
pandod server --login-listen): Google and any OpenID
Connect provider (--oidc ID=ISSUER), and single-use email links (--smtp-url,
--mail-from, optional Cloudflare Turnstile). A sign-in creates a 30-day platform token for
the console; first sign-ins create an account if--signupallows (default: a waitlist,
managed withpando admin signup allow|remove|list).pando admin identity linklets an
existing account, such as the first administrator, sign in from a browser (ADR-031).
Changed
- Looking up one organisation reads only that organisation.
Security
-
Protected branches: a change's author can no longer approve it through an agent they mint,
approve an agent's change they answer for, or report its required checks; such approvals don't
count (ADR-030). -
Single sign-on:
--oidc-require CLAIM=VALUEbinds tokens to your tenant, and pandod refuses to
start with GitHub Actions or Google as issuer without one. Tokens can't sign in as a platform
administrator (unless listed with--oidc-admin) or as anagent/orbot/account. Unknown
signing keys refetch the key set at most once a minute. -
Paths named
.gitor.pandoin any case, with trailing dots or spaces, as an NTFS stream or
as an 8.3 short name (GIT~1) are refused by the server, by checkouts and by imports, so a
writer can't plant git hooks or config in other people's checkouts. Existing history holding
such paths can no longer be read. -
Static tokens that are empty, shorter than 16 characters or a placeholder (
CHANGE-ME) are
refused at startup. -
Access answers are no longer re-cached from a read that raced a write, so a removed member or
grant loses access at once. -
pando migrate: the GitHub token comes fromPANDO_GITHUB_TOKEN(orGITHUB_TOKEN) or
--github-token-file;--github-tokenwarns that it is visible to other users. Source URLs
are printed without credentials, and the mirror clone goes to a private, randomly named
directory. -
Platform servers refuse repository calls that name no repository. Before, such a call reached
the server's own--metadatarepository with no access check, so any signed-in caller (or any
token, however limited) could read and write it. A non-UTF-8x-pando-repoheader is refused. -
Webhooks no longer call loopback, private networks (RFC 1918, 100.64.0.0/10, fc00::/7) or cloud
metadata (including 100.100.100.200, fd00:ec2::254 and IPv4 written as IPv6: mapped, NAT64,
6to4). Start with--webhook-allow-privateto let a self-hosted server call its internal
network (metadata stays refused). The address is checked when a webhook is saved and at every
delivery, deliveries connect only to the checked address (no DNS rebinding), DNS lookups time
out after 5 s, proxies from the environment are ignored, and a failed delivery or ping reports
only the HTTP status or "unreachable", never why.
Added
pandod backupsnapshots a platform server's registry and every repository's database to a
directory or object store while it runs;docs/deploy.mddocuments the restore.
Changed
- Docs: a platform server (
--platform) is single-node; only servers without it scale out. - Go SDK: requires Go 1.26.9 and uses
golang.org/x/net0.60.0 andgolang.org/x/text
0.42.0, fixing six known HTTP/2 and text-parsing vulnerabilities (GO-2026-6603, 6610, 6611,
6612, 6617, 6629). - Releases attach their signed SLSA provenance (
*.intoto.jsonl) next to the archives. - CI hardening: least-privilege workflow tokens, every action pinned to a commit, CodeQL on
every change, and Dependabot for Go, npm and Python as well as Rust and Actions.
v3.3.0
Security
- On platform servers a change is attributed to whoever made it: a member can no longer record
someone else as the author. Repository administrators may still record other authors, so
imports andpando migratekeep the original history. Single-repository servers keep git's
free-form authors.
Fixed
- Platform servers no longer slow landing down: access answers are cached per process (cleared
by every write that changes them) and push events are prepared off the landing path only when
a webhook wants them. With 200 agents on one branch, p99 latency through a hosted repository
went from 2.8–3.8 s to 0.22–0.25 s, matching a server without the platform (ADR-029).
Added
pando migrate FROM --to SERVER/OWNER/NAME(ADR-028,docs/migrate.md): moves a repository
from GitHub, GitLab, Bitbucket or any git host with its full history on every branch; from
GitHub (and GitHub Enterprise Server with--github-api), open pull requests become change
requests and issues come with comments, labels and state. It prints thepando mirror
command that keeps the old host current while you move.- Issues (ADR-027): open, discuss, label and assign issues to people or agents, in the console
(Issues tab), the CLI (pando issue) and over MCP (pando_issues,pando_issue,
pando_open_issue,pando_comment_on_issue,pando_update_issue). Issues and change
requests share numbers; a change request saying "fixes #N" closes the issue when it lands.
Issues assigned to you are in your inbox;issuewebhook events let an agent runner start work
as soon as an issue is assigned. - Remote MCP (ADR-026):
pando mcp --http ADDR --server URLserves a whole server to agents
anywhere over the stateless MCP 2026-07-28 protocol. With a URL and a token an agent reads,
writes and lands files, opens, reviews and lands change requests, reports checks and reads its
inbox, without a checkout; each request's token is passed through, so the server's
permissions, token limits and audit log apply. - An agent's change request asks the person the agent answers to for review; change requests
nobody was asked to review show in the inbox of everyone who may approve them. - Changesets created without an author are attributed to the authenticated caller.
- Webhooks (ADR-025,
docs/webhooks.md):push,change_request,review,commentand
checkevents posted to URLs and signed like GitHub's (X-Pando-Signature-256), retried
with backoff from a queue that is safe across replicas.pando webhook add|list|ping|log|remove
and repository Settings → Webhooks in the console. pando landon a protected branch opens a change request from areview/branch instead of
failing. The console can open a change request from any branch.
Added
- Change requests and review on platform servers (ADR-024): open a change request from a branch,
comment on lines with suggestions, approve or request changes, report CI checks, and land it as
one changeset once nothing blocks it;pando cr rebasereplays it on its target. Protected
branches (pando protect, or repository Settings in the console) require approvals and passing
checks, make approvals stale on a new push, and refuse direct lands except for those allowed to
bypass review. An inbox (review requested, changes requested, agents' changes ready) and an
activity feed. CLI:pando cr create|list|view|comment|review|check|land|rebase|ready|close|reopen. - The web console's review screens work against a platform server, and admins protect branches
from repository Settings.
v3.2.0
Added
- Accounts, organisations, members, teams, per-repository roles and access tokens on platform
servers (ADR-023):pando org,pando team,pando repo grantandpando token, and the
same in the web console (Tokens, organisation People, repository Settings → Access). Tokens
start withpando_, are stored as a hash, can act as an agent, be limited to repositories and
a highest role, and expire within a year. pandod token --platform URL --account LOGINcreates the first administrator's token
without a running server.
Changed
- Platform servers now check every repository call: reading needs the Read role and anything
else Write; repositories are private to their organisation unless made internal or public.
After upgrading from 3.1, add people withpando org member ORG LOGIN ROLE. Servers without
any authentication stay open, for local development.
v3.1.0
Added
- Console review comments on code: a "+" on every line, shift-click for a range of lines, a
Markdown editor with preview, suggested changes shown as a small diff of current and proposed
lines, ⌘/Ctrl+Enter to send, Escape to cancel, and resolved conversations collapsed. pando mirror --to URL [--every SECONDS]: keeps GitHub, GitLab, Bitbucket or any git
remote up to date with a branch. Incremental, deterministic commits, never force-pushes,
refuses to overwrite commits it did not make, and redacts credentials in messages.- One server, many repositories:
pandod server --platform REGISTRY --repos-metadata TEMPLATE [--repos-objects TEMPLATE] --platform-admins NAMES. Each repository has its own storage and
landing queues; clients addressSERVER/OWNER/NAME; calls without a repository reach the
default one (ADR-022). pando repo create OWNER/NAMEandpando repo list.- The web console lists a server's repositories and shows only what the server supports.
Changed
pandod serverandpandod cachelisten on 127.0.0.1 by default; listening on a network is a
deliberate--listen 0.0.0.0:7420.
Fixed
- Console: the phone code view cut off line numbers and the first characters of each line;
long titles no longer truncate to one line on phones; keys typed in a form never trigger
page shortcuts. - The web console kept one data cache across connections, so data from the demo or a previous
server could appear after switching. Each connection now has its own cache.
v3.0.0
Added
- The web console (
console/): browse code with blame and history, follow changes as they land
with word-level diffs, see who and which agent landed what on a live fleet timeline, find files
from a command menu, and see locks. Works with anypandod; a demo of the full platform (several
repositories, change requests, reviews, a land gate and rebase) runs in the browser. See
docs/console.md. pandodaccepts gRPC-Web from browsers (webfeature flag, on by default) and allows the
origins in--web-origins/PANDO_WEB_ORIGINSto call it.- The platform contract,
pando_platform.proto: organisations, repositories, accounts and agents,
tokens, change requests, reviews, comments, protected branches (ADR-021).
Changed
- Security (breaking): without
PANDO_TOKENSor an OIDC issuer,pandodrefuses to listen on
a non-loopback address unless--allow-anonymous/PANDO_ALLOW_ANONYMOUS=1is set, so a server
is never open to a network by accident. The Docker image therefore needs a token:
docker run -e PANDO_TOKENS=me:SECRET .... - Request limits: each call may run at most
--request-timeout(600 s); beyond--max-in-flight
(4,096) calls in progress, new calls are refused with Unavailable instead of queueing; 256
concurrent calls per connection. - A new mark: the letter P drawn as a branch landing back on main.
v2.4.0
Added
pando mounton macOS and Windows. macOS serves a read-only NFSv3 view on localhost and
mounts it with the systemmount_nfs: no kernel extension, nothing to install, no admin
rights. Windows uses the built-in Projected File System, loaded at run time. Both are
tested in CI against the real kernels, file by file againstpando clone(ADR-020).pando mount --serve-onlyon any Unix prints the mount command instead of mounting.PANDO_LOG=debugturns on client-side logs.
v2.3.0
Added
- File locking for files that cannot be merged:
pando lock,pando unlock [--force],
pando locks. A land that changes a file someone else has locked is refused. Locks
are compare-and-swap system refs (ADR-019), need write access, are audited, and sit
behind thelocksfeature flag.
Fixed
- A land refused by a pre-land check or a lock showed as a garbled storage error on the
client; it now readsrejected: <reason>.
v2.2.0
Added
pandod copy: back up, restore, or move a repository between backends (SQLite,
Postgres, CockroachDB; disk, S3, GCS, Azure). Consistent while the source serves,
incremental when repeated, keeps compacted objects compact and verifies whole objects.
Storage ports gain paged listing, covered by the adapter contract tests.--audit-log FILE: an audit trail as JSON lines. One record per authenticated request
(principal, client address, method, status, duration), per rejected request (address and
reason, never the token), and per land, branch move, content read and history query,
with paths and results. Off by default.- Coverage-guided fuzzing (cargo-fuzz) of every decoder of untrusted bytes: objects,
trees, changesets, chunk manifests, deltas and paths, with a seed corpus of valid
inputs. Ten minutes per target nightly, one minute on pull requests.