Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
023909e
Serve exactly the pinned official routes under /v1
SaladDay Sep 25, 2026
8724394
Test the administrator Runtime observation list
SaladDay Sep 25, 2026
aab4d6e
Hold /v1 fields and routes to the pinned SDK
SaladDay Sep 25, 2026
3908b76
Merge remote-tracking branch 'origin/main' into codex/core-web-bounda…
SaladDay Sep 25, 2026
47e0e9e
Remove the startup configuration and history capability reads left wi…
SaladDay Sep 25, 2026
20f4025
Serve /core/v1 as one Core-key tree and issue executor credentials there
SaladDay Sep 25, 2026
3d53520
Forward every signed-in /core/v1 request from the console with the Co…
SaladDay Sep 25, 2026
8af26ce
Give the Core clients their own /core/v1 request layer
SaladDay Sep 25, 2026
80cd357
Generate the /core/v1 contract as core.openapi.yaml
SaladDay Sep 25, 2026
d828a74
Test that each credential works only in its own namespace
SaladDay Sep 25, 2026
2ed7318
Document the three namespaces and the Core-key executor credentials
SaladDay Sep 25, 2026
4900b8c
Name the Core key in the machine connection contract
SaladDay Sep 25, 2026
a6cbbda
Merge origin/main (Core-key sign-in #124, allocation phase time #123,…
SaladDay Sep 25, 2026
6219ad0
Test executor credential key_id form and unknown-key rotation over HTTP
SaladDay Sep 25, 2026
24c0b48
Refuse executor credential issuance and rotation in an archived Project
SaladDay Sep 25, 2026
b734d51
Say "Core key only" in the /core/v1 operation descriptions
SaladDay Sep 25, 2026
8f4be65
Check executor credential writes in the agreed order
SaladDay Sep 25, 2026
158f6b9
Issue the release guide's executor credential with the Core key
SaladDay Sep 25, 2026
09070b8
Treat CoreMetricsClient baseUrl as a prefix like the other Core clients
SaladDay Sep 25, 2026
7dba5e7
Add the node enrollment token to the credential matrix
SaladDay Sep 25, 2026
f2ab0ac
Tag the Core execution configuration read like the other /core/v1 reads
SaladDay Sep 25, 2026
f9e5996
Read the console's data through Core's new routes
SaladDay Sep 25, 2026
b13f18c
Check the project reader against Core's client type
SaladDay Sep 25, 2026
e56a5df
Issue, rotate and revoke executor credentials from a self-hosted Session
SaladDay Sep 25, 2026
b9dc469
Rotate restores a revoked executor credential, as in Core
SaladDay Sep 25, 2026
144ed8b
Match Core's executor credential rules in the fixture
SaladDay Sep 25, 2026
6341375
Hide executor credential writes on an archived project
SaladDay Sep 25, 2026
de32aed
Derive the fixture's error type as Core does
SaladDay Sep 25, 2026
5c93243
Describe the console's /core/v1 prefix forwarding in the Web docs
SaladDay Sep 25, 2026
d766039
Never recover an executor credential the administrator already managed
SaladDay Sep 25, 2026
05aa4d7
Reject a non-JSON executor credential body with 400, as Core does
SaladDay Sep 25, 2026
f9b145c
Correct the executor credential rules in the Web docs
SaladDay Sep 25, 2026
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
65 changes: 51 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,55 @@
# Parsar Core development

Read [CONTRIBUTING.md](CONTRIBUTING.md) before changing code. Work in an isolated
Git worktree and submit a PR. Keep product business code in the Parsar repository.

Preserve the pinned public Agent API and documented extensions. Do not add product
database dependencies or bypass Core execution ownership. Core Web must consume the administrator API through the `AdminClient` in
`packages/agents-client`; applications consume the public contract separately.
Neither client may reproduce Core execution truth or expose server-side
administrator credentials in the browser. See `docs/design-principles.md`. Update
architecture and generated contracts with changes. Run `make check` before
reporting completion.

Choose independent blind review according to change risk; follow CONTRIBUTING.md
for reviewer context and re-review criteria. Small, verified fixes may use self-review.
Never use `codex exec` as a substitute reviewer.
Parsar Core is the independent execution service behind Parsar. Product business
code, its database and migrations stay in the Parsar repository. Read
[CONTRIBUTING.md](CONTRIBUTING.md) before changing code.

## Interfaces and credentials

Core serves three namespaces. Each has one kind of caller and its own credential;
no credential works in another namespace.

| Namespace | Caller | Credential | Contents |
| --- | --- | --- | --- |
| `/v1` | Applications | Project API key | Exactly the pinned OpenAI Agents API route set ([upstream.json](contracts/agents-api/upstream.json): SDK 3.13.0, `agents=v1`). Fields the official types lack live only in `x_agents_core` on Agents and Sessions (`harness`, `model_provider`). Nothing about deployment belongs here. |
| `/core/v1` | Core Web's server and operator scripts | Core key; Core stores its digest | Everything about operating the deployment: Projects and keys, resource reads and deletion, Session archive, credential issuance (node enrollment tokens, executor credentials), observability, audit, sandbox deployment and nodes. |
| `/api/v1` | Nodes, Runtime daemons, self-hosted executors | Machine credentials issued through `/core/v1` | Machine connections only; each credential works only on its own routes. |

- Core Web calls only `/core/v1`, through the Core clients in
`packages/agents-client` (`AdminClient`, `SandboxAdminClient`,
`CoreMetricsClient`). It never calls `/v1` or `/api/v1`, never uses
`OpenAIAgentsClient` and never forwards machine transport.
- Users sign in to Web with the Core key. Web's server forwards signed-in,
same-origin `/core/v1` requests with that key and never sends it to a browser.
The Core key cannot call `/v1`; a Project API key cannot call `/core/v1`.
- A new console need becomes a `/core/v1` route. Never add console or operations
features to `/v1`, or application features to `/core/v1`.
- List every route with its caller and credential in [docs/api/README.md](docs/api/README.md).

## Ownership

Backend: Core, `contracts/`, `packages/agents-client`, `services/core-console`,
the daemon, adapters, node service and installer. Frontend: `apps/web` and
`docs/web`. Agree on API shapes across the boundary; do not edit the other side's
code to make a test pass.

## Making changes

- Work in an isolated Git worktree on a feature branch and submit a PR.
- Run `make sqlc-generate` after query changes and `make openapi` after handler
annotation changes; review the generated diffs. `make openapi` writes
`openapi.yaml` (`/v1`), `core.openapi.yaml` (`/core/v1`) and
`runtime.openapi.yaml` (`/api/v1`) in `contracts/agents-api/`. Update the
matching contract there and the API index in the same change.
- Do not add product database dependencies, bypass Core execution ownership, or
reproduce execution truth in a client.
- Run `make check` before reporting completion.

## Review

Choose independent blind review by risk: security, shared lifecycle ownership or
cross-package behavior. Give the reviewer only requirements, acceptance criteria,
boundaries, the repository path and the comparison baseline. Small verified fixes
may use self-review. Never use `codex exec` as a reviewer.

Documentation and code comments are English; user-facing copy may be bilingual.
99 changes: 51 additions & 48 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,23 @@ fixes may use self-review, including focused corrections after a blind review;
repeat independent review when a correction materially changes the design or risk.
Fix in-scope blockers before delivery. Do not use `codex exec` as a substitute reviewer.

The [API documentation index](docs/api/README.md) separates application,
administrator and Runtime transport contracts. New or changed routes must identify
their caller and authentication authority there, and link their detailed contract.
The [API documentation index](docs/api/README.md) lists the three namespaces:
`/v1` for applications (Project API key), `/core/v1` for Core Web's server and
operator scripts (Core key) and `/api/v1` for machine connections (credentials
issued through `/core/v1`). New or changed routes must identify their caller and
credential there, and link their detailed contract.
Keep current integration guidance separate from historical qualification evidence.

The Core Web is an administrator console. Its server authenticates to the explicit
`/core/v1/admin` management surface and existing sandbox administration, never to
`/v1` on behalf of a browser. Applications use an API key issued inside a Project. One Project owns one execution
The Core Web is an administrator console. Web calls only `/core/v1`, with the Core
key held on its server, and never `/v1` or `/api/v1`. Applications use an API key issued inside a Project. One Project owns one execution
tenant and principal; all its keys share assets and permissions while writes retain
individual key provenance. Projects and keys are database-owned, with no static
business keys or configuration synchronization. Revocation affects one key;
archiving a Project revokes all its keys, retaining assets and admitted execution.
Do not add Core users, roles, memberships or cross-Project sharing. Management
provides safe reads, public deletion preconditions, explicit hosted Session archive
and Project and key operations; it cannot copy, execute or edit arbitrary assets.
provides safe reads, public deletion preconditions, explicit hosted Session archive,
Project and key operations and credential issuance; it cannot copy, execute or edit
arbitrary assets.
Keep administrator target scope separate from caller principals. See
[design principles](docs/design-principles.md) and the
[administrator contract](contracts/agents-api/admin-api.md).
Expand Down Expand Up @@ -156,9 +158,8 @@ trailing slash kept, and other escapes such as `%2F` and `%5C` left encoded;
or authorize on a path outside that wrapper. On the Beta
group the constant OpenAI-Beta check (exactly one `agents=v1` value) runs before
authentication, and authentication still precedes every Beta handler, 404 and 405.
Every Agents API 401 has type `invalid_request_error`: null code on Beta routes; on Files,
Skills and Core project extensions `invalid_api_key` only for a rejected Bearer
credential. Agents API responses carry a fresh `X-Request-Id` (also in the log
Every Agents API 401 has type `invalid_request_error`: null code on Beta routes; on Files
and Skills `invalid_api_key` only for a rejected Bearer credential. Agents API responses carry a fresh `X-Request-Id` (also in the log
context), `OpenAI-Version`, `OpenAI-Processing-Ms` and nosniff through the API
router's own middleware, not the shared log middleware. HEAD runs GET routes;
streaming, content-download, live directory, Runtime observation and Runtime
Expand Down Expand Up @@ -190,9 +191,9 @@ migrations. The public protocol schema is `contracts/agents-api/openapi.yaml`;
there is no product swaggo contract in this repository. Preserve its pinned types,
coverage ledgers and official SDK/raw HTTP tests when changing API behavior.
Run `make openapi` after handler annotation changes. It reuses the original
Core-only swaggo v1.16.4 generator, then separates project paths under `/v1` from
`/core/v1` administration in `sandbox-manager.openapi.yaml` and `/api/v1` machine
connections in `runtime.openapi.yaml` (both base path `/`), each keeping only the
Core-only swaggo v1.16.4 generator, then splits the result by namespace: `/v1`
into `openapi.yaml`, `/core/v1` into `core.openapi.yaml` and `/api/v1` into
`runtime.openapi.yaml` (the last two with base path `/`), each keeping only the
security schemes its operations use. All generated schemas remain free of product
routes.

Expand All @@ -207,7 +208,7 @@ current validation entrypoints.

## Core operational metrics

The administrator-only `/core/v1/admin/core-metrics` contract is documented in
The Core-key-only `/core/v1/metrics` contract is documented in
[core-metrics.md](contracts/agents-api/core-metrics.md). Keep this separate from
Agent outcome and Sandbox capacity views. Instrument existing worker and job
owners without changing scheduling, lease or retention behavior. Periodic pool
Expand Down Expand Up @@ -733,8 +734,8 @@ does not qualify its isolation or enable public creation.
Default installation includes Core, Web and PostgreSQL but no execution node.
It always creates the Core key. Core receives only its digest; the paired console
server receives the private key, uses it for sign-in and injects it only on
approved management routes after console login and same-origin checks. The
browser never receives that key. Node and daemon connections use `/api/v1`
`/core/v1` requests after console login and same-origin checks. The browser
never receives that key. Node and daemon connections use `/api/v1`
with their own credentials; the reverse proxy sends them directly to Core, never
through Web. Zero-node Core receives neither the Docker socket nor KVM.
The Web and deployment administrator API select one provider, public Core origin,
Expand Down Expand Up @@ -827,8 +828,8 @@ The [Hosted Sandbox Manager](services/agents-api/HOSTED-SANDBOX-MANAGER.md) is a
deployment-level admin surface, separate from Project credentials. The paired
console's Core key stays on its server. Enrollment credentials authorize
initial node configuration reads and registration; durable node credentials authorize
retained configuration reads and node transport. Project keys can read a narrow node
directory and their own Session placement, never global allocations.
retained configuration reads and node transport. Project keys cannot read nodes,
placement or allocations.

One execution owner manages local and remote nodes through the same finite
Provider protocol. Local opt-in uses the same standalone node installer and
Expand Down Expand Up @@ -905,10 +906,8 @@ capacity transactions and revision/one-shot receipts remain authoritative, with
no external operation holding a database lock.

Commit environment-to-node placement with Session creation and its creation retry
identity. Automatic selection chooses an eligible node; explicit
`x_agents_core.sandbox_node_id` fails if unavailable or full. The optional
model-provider extension remains independent. Existing retries keep their original
node even when it is offline. Node capacity counts pending reservations and
identity. Placement is automatic: Core chooses an eligible node, and callers cannot
select one. Existing retries keep their original node even when it is offline. Node capacity counts pending reservations and
unresolved resources; new placement and suspended-to-restoring admission share a
database lock. Confirmed cleanup releases placement capacity. Retained ownership requires exact
provider evidence; a socket path, missing instance or empty listing cannot prove
Expand Down Expand Up @@ -1770,11 +1769,15 @@ image containing a private test CA or model credential as a release input.
Repository visibility is independent of publication. Do not add repository
credentials to installed node/Runtime configuration to bypass download access.

Project-authenticated executor-credential extensions remain outside the upstream
API namespace and reuse the existing restricted issuer. They require the exact
creator of a live self-hosted Environment; deployment administrator authority and
shared Session read access do not grant credential issuance. The console does not
serve these routes; callers reach Core directly. Self-hosted installation reuses
Executor credentials are issued by the operator with the Core key, through Web or
a Core-key script, under
`/core/v1/projects/{project_id}/environments/{environment_id}/executor-credentials`
and reuse the existing restricted issuer. The target must be a self_hosted
Environment of that Project whose Session exists; anything else is 404. The
Project's principal is the credential's execution principal, its scope stays
daemon enrollment and connection for that one Environment, and issue, rotate and
revoke each record an administrator audit entry in the write's transaction without
the secret. Project API keys cannot issue them. Self-hosted installation reuses
Docker Runtime isolation, owns no sandbox node or Core allocation, and retains
user-owned native history after uncertain launches. Report started, connected and real execution success separately.
Self-hosted installation confirms connection through the private daemon transport
Expand Down Expand Up @@ -1842,18 +1845,18 @@ existing write-only model execution extension, with the installation's persisten
credential encryption key. Provider identity/backend namespace and native history
must not change on a repeated install.

`services/core-console` serves the production Web build and proxies only finite
administrator and sandbox-management routes after console login. It requires the
private Core key file named by `CORE_CONSOLE_CORE_KEY_FILE` and holds no project
caller credential. Every `/v1` and `/api/v1` request returns 404, including
explicit Bearer and WebSocket requests; Web forwards no node or daemon transport.
The installer mounts only the Core key into Web and only its digest
(`AGENTS_API_CORE_KEY_DIGESTS_FILE`) into Core. The browser receives safe
configuration, never that key. The deployment's TLS reverse proxy routes `/v1`
(applications) and `/api/v1` (nodes and Runtime daemons, with their own
credentials) directly to Core and everything else to Web, except the
Project-authenticated `/core/v1/environments/*/executor-credentials` routes, which
also go straight to Core.
`services/core-console` serves the production Web build and, after console login
and same-origin checks, forwards every `/core/v1` request with the Core key; Core
decides whether the route exists. It requires the private Core key file named by
`CORE_CONSOLE_CORE_KEY_FILE` and holds no project caller credential. Every `/v1`
and `/api/v1` request returns 404, including explicit Bearer and WebSocket
requests; Web forwards no node or daemon transport. The installer mounts only the
Core key into Web and only its digest (`AGENTS_API_CORE_KEY_DIGESTS_FILE`) into
Core. The browser receives safe configuration, never that key. The deployment's
TLS reverse proxy routes `/v1` (applications) and `/api/v1` (nodes and Runtime
daemons, with their own credentials) directly to Core and everything else,
including `/core/v1`, to Web. Operator scripts call `/core/v1` on Core's loopback
port.
Nodes and Core come from one distribution; older nodes using the removed
`/core/v1/sandbox` node paths cannot connect and are replaced through the drained
upgrade and re-enrollment workflow.
Expand Down Expand Up @@ -1881,8 +1884,9 @@ The command verifies the installer checksum before execution, retains normal TLS
verification, and passes the enrollment credential only to the installer process.


Management proxy paths retain fixed-origin, cross-site, safe-path, redirect and Upgrade
restrictions through the standard Go reverse proxy with streaming/cancellation.
The `/core/v1` proxy retains fixed-origin, cross-site, safe-path, redirect and Upgrade
restrictions through the standard Go reverse proxy with streaming/cancellation;
literal or encoded dot segments can never move a request out of `/core/v1`.
The console implements no product identity, resource semantics, Runtime discovery
or execution loop. Signing in with the Core key grants the complete console
surface; do not introduce Web accounts, roles, invitations or per-project Web
Expand Down Expand Up @@ -2236,16 +2240,16 @@ replaced; do not carry obsolete compatibility code forward to satisfy this secti
retain one source. Project reads redact all deployment provider details. Old
Sessions expose persisted model/harness with unknown sources and unavailable
provider metadata, without backfill. Projection metadata does not alter retry
identity; retries cannot replace it. Keep this query separate from runtime
observations and do not touch activity or wake sandboxes. The versioned contract
is `contracts/agents-api/execution-configuration.md`.
identity; retries cannot replace it. Keep this administrator query separate from
runtime observations and do not touch activity or wake sandboxes. The versioned
contract is `contracts/agents-api/execution-configuration.md`.
- Provider input validation uses the adapter-owned rules in `internal/harnessconfig`.
Keep one internal registry for protocol and token-limit validation; Core owns
credential environment and endpoint admission policy. These rules are not a
public discovery API or Runtime registration descriptor. Operation qualification
and live readiness retain their existing owners. The Core startup view keeps its
basic supported/configured deployment snapshot and accepts no query parameters.
Session frozen execution-configuration reads remain a separate Core extension.
Session frozen execution-configuration reads remain a separate administrator read.
- Public Agent updates use `POST /v1/agents/{agent_id}` with the same tenant/Beta
boundary and shared saved-field validation. Preserve omission separately from
null; only supplied fields replace saved values. Metadata is a separate whole-map
Expand Down Expand Up @@ -3448,8 +3452,7 @@ retain the official Agent response shape. See the [extension contract](contracts
for null/retry behavior and operator configuration.

Hosted provider selection belongs to deployment configuration and is independent
of the engine. Session creation fixes a node through a Core extension or automatic
placement; retained allocations keep that node and provider identity. Runtime images must satisfy their existing qualification rules.
of the engine. Session creation fixes a node through automatic placement; retained allocations keep that node and provider identity. Runtime images must satisfy their existing qualification rules.
Transient model options are partitioned by engine and must not expose another
engine's credentials. Do not infer an engine from a model name or template.

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ openapi:
--output "$$output" \
--outputTypes yaml --parseInternal; \
python3 scripts/patch-agents-openapi.py "$$output/swagger.yaml"; \
go run ./scripts/openapi-split "$$output/swagger.yaml" contracts/agents-api/openapi.yaml contracts/agents-api/sandbox-manager.openapi.yaml contracts/agents-api/runtime.openapi.yaml
go run ./scripts/openapi-split "$$output/swagger.yaml" contracts/agents-api/openapi.yaml contracts/agents-api/core.openapi.yaml contracts/agents-api/runtime.openapi.yaml

check-sqlc:
python3 scripts/check-sqlc.py
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ credentials are supplied through the existing write-only API extension.

Hosted deployments select E2B cloud or one provider across their own local/remote
nodes (Docker or microsandbox). The
Hosted Sandbox Manager shows node health, capacity and Session placement. New
Sessions use automatic placement by default or an explicitly selected node;
existing Sessions retain their node across disconnects and resume.
Hosted Sandbox Manager shows node health, capacity and Session placement. Core
places new Sessions automatically; existing Sessions retain their node across
disconnects and resume.

## Start here

Expand Down
Loading
Loading