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
8 changes: 7 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ The Runtime is not a sandbox; see
- Fix shared lifecycle, admission, cancellation, reuse and performance problems
in the common protocol or flow, not with Harness-, Runtime- or vendor-specific
branches in Core. Adapters may differ natively but keep shared semantics.
- Public Harnesses explicitly implement every extension interface, returning the
shared Unsupported error when unqualified; required lifecycle obligations cannot
be skipped. Capability declarations must be complete. Follow the single
[Harness onboarding contract](contracts/agents-api/harness-onboarding.md).
- Express compatibility through declared capabilities and validate selected
combinations explicitly. Public MCP origin and credential authority follow the
[Environment MCP contract](contracts/agents-api/environments.md#public-mcp-connection-origin);
Expand Down Expand Up @@ -241,7 +245,9 @@ The Runtime is not a sandbox; see

Shared wire types and validators live only in `internal/agentdaemon/proto`.
Change both peers together with an exact wire-version check; do not add a
parallel schema or a historical wire fallback.
parallel schema or a historical wire fallback. Capability completeness and
interface coverage are mandatory extension gates under the
[explicit declaration contract](docs/runtime-protocol.md#explicit-capability-declarations).

### Pre-release policy

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ check-go:
check-runtime-contract:
go test ./internal/agentdaemon/proto ./internal/agentdaemon/gateway ./apps/parsar-daemon/internal/transport ./apps/parsar-daemon/internal/dispatch ./apps/parsar-daemon/internal/contracttest -count=1
go test ./services/agents-api/internal/execution -run '^TestRuntimeProtocol' -count=1
go test ./apps/parsar-daemon/internal/agent/... -run '^TestSharedTextLifecycle$$' -count=1
go test ./apps/parsar-daemon/internal/agent/... -run '^(TestSharedTextLifecycle|TestPublicHarnessContractDeclarations|TestRegistryRejectsEveryOmittedCapabilityBeforeReplacement|TestUnsupportedExtensionsHaveNoNativeEffects)$$' -count=1

build-daemon:
@set -e; output="$${OAC_DEV_HOME:-$$HOME/.oac}/build/daemon"; \
Expand Down
134 changes: 106 additions & 28 deletions apps/docs/content/docs/harness-onboarding.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Start from two entry points:
- [`internal/harnessconfig/harness.go`](https://github.com/MiniMax-AI/parsar-core/blob/f6d258735fc601c521dd990e6f9e1ed261f4ef2d/internal/harnessconfig/harness.go):
the shared model configuration contract (declarations and preparation).
- [`agent/harness.go`](https://github.com/MiniMax-AI/parsar-core/blob/f6d258735fc601c521dd990e6f9e1ed261f4ef2d/apps/parsar-daemon/internal/agent/harness.go): the
execution lifecycle, optional interfaces and registration methods.
execution lifecycle, explicit extension contracts and registration methods.


## Ownership
Expand Down Expand Up @@ -77,11 +77,15 @@ model communication configuration, not Turn scheduling or native process ownersh
[Harness integration](https://github.com/MiniMax-AI/parsar-core/blob/f6d258735fc601c521dd990e6f9e1ed261f4ef2d/contracts/agents-api/harnesses.md#acceptance-checklist). Record results in
the [qualification table](https://github.com/MiniMax-AI/parsar-core/blob/f6d258735fc601c521dd990e6f9e1ed261f4ef2d/contracts/agents-api/harnesses.md#current-qualified-operations).

Start with the mandatory text lifecycle, then qualify optional operations one at
a time. Call the reusable `agent/contracttest.TextLifecycle` assertions with the
Implement the mandatory text lifecycle and explicitly handle every extension.
Qualify supported extensions one at a time; an unqualified extension returns
`agent.ErrUnsupportedOperation` without native effects. Call the reusable `agent/contracttest.TextLifecycle` assertions with the
adapter's prepared Executor and deterministic native fixture. These assertions
cover healthy reuse, durable input and cancellation; keep native fault and live
acceptance separate. Name the entry test `TestSharedTextLifecycle` so
cover healthy reuse, durable input and cancellation for adapters whose native
owner remains reusable. A native cancellation may instead require retirement:
`Reusable=false` carries a reason and the caller must confirm `Executor.Close`.
Do not force reuse to fit a test helper. Keep native fault and live acceptance
separate. Name the entry test `TestSharedTextLifecycle` so
`make check-runtime-contract` includes it. Do not copy an adapter's native
limitations into the shared Core protocol.

Expand All @@ -94,15 +98,16 @@ limitations into the shared Core protocol.
- A new engine supplies an adapter, a qualified profile, registration and an
independently verified deployment. It adds no engine-name branches to API
handlers, persistence, dispatch, scheduling or Environment providers.
- Keep required lifecycle declarations, optional interfaces and registration
- Keep required lifecycle declarations, extension interfaces and registration
methods in `agent/harness.go`. Result types, errors and Registry storage may
stay in focused files. Keep this guide linked to that entry point.
- Use the existing `proto.SupportedAgentKind` and `AgentKindCapabilities`
schema. Do not add a second capability descriptor or a combined optional
interface.
- Onboarding does not require feature equality. Verify common lifecycle
obligations and use the same public assertions for each declared operation.
Optional native differences are separate capability work, not onboarding blockers.
Native differences do not block onboarding, but an omitted declaration or
missing extension implementation does.
- Never equate accepted parameters with applied native behavior.

## Native model configuration
Expand Down Expand Up @@ -156,9 +161,11 @@ ownership are in the [unified model configuration design](https://github.com/Min

[`agent/harness.go`](https://github.com/MiniMax-AI/parsar-core/blob/f6d258735fc601c521dd990e6f9e1ed261f4ef2d/apps/parsar-daemon/internal/agent/harness.go) is the
canonical interface entry point. Its required lifecycle is `ExecutorFactory`,
`Executor`, `Turn` and `TurnSettlement`. Optional Turn and workspace interfaces
remain separate; their result types and error values stay in the corresponding
operation files in the same package. All use the existing neutral protocol types.
`Executor`, `Turn` (including `DurableSteerer`) and `TurnSettlement`. Required
methods must perform their native obligations; returning Unsupported is not an
implementation of cancellation, receipts, settlement or cleanup. Turn and workspace
extension interfaces remain small and separate, but every public adapter implements
each explicitly. Their result types and errors stay in focused operation files. All use the existing neutral protocol types.

The [Core–Runtime lifecycle contract](/runtime-protocol#executor-and-turn-lifetimes)
owns preparation failure, partial StartTurn results, output closure, settlement,
Expand All @@ -175,7 +182,7 @@ native Session. Their implementations expose the same Executor and Turn contract
Implement cancellation on the exact Turn through `agent.Session`. Follow the
[lifecycle and settlement rules](/runtime-protocol#executor-and-turn-lifetimes);
the adapter must supply native completion evidence to the shared Runtime.
Permission and user-choice responses use the optional interfaces below.
Permission and user-choice responses use the explicit extension interfaces below.

## Events, inputs and optional capabilities

Expand All @@ -194,20 +201,50 @@ before consuming a pending interaction. Do not map answers by header or position
Resume only the exact history bound to the Session; missing or ambiguous required
history fails before new model input.

| Interface or contract | When required | Obligation |
| Interface or contract | Required handling | Obligation |
| --- | --- | --- |
| `agent.DurableSteerer` | Current public text execution | Distinguish write and application receipts; preserve retry identity; independent of the optional non-durable `Steerer` |
| `agent.FunctionResultSubmitter` | Public function tools | Match call/result identity and acknowledge native application |
| `agent.PermissionResponder`, `agent.UserChoiceResponder` | When emitting these interactions | Route exact identities and settle receipts |
| `agent.WorkspaceReader`, `agent.WorkspaceDirectoryLister`, `agent.WorkspaceWriter` | Qualified workspace operations | Use the fixed authorized workspace and retain accepted operations through close |
| Neutral message, image, MCP, structured-output and Subagent observations | Only when qualified and advertised | Preserve the operation-specific contract and reject unsupported combinations |

Optional features need not match another harness. The service profile qualifies
public combinations; the Runtime advertises this installation's available support.
Neither replaces schema validation or tenant authorization. Declaring a capability
without implementing its semantics is an error. Workspace reads may use separate
read-only preparations; those do not start model work or provide another execution
lifecycle.
| `ExecutorFactory`, `Executor.StartTurn`, `Executor.Close` | Real implementation | Prepare without model input; keep failed or uncertain resource ownership; confirm cleanup |
| `Turn`, `Session.Cancel`, `CancellationOutcome`, `AwaitSettlement` | Real implementation | Cancel the exact Turn, preserve observed results and confirm settlement independently of cancellation requests |
| `DurableSteerer` | Real implementation on every Turn | Distinguish complete write from native application receipt; preserve retry identity |
| `Steerer` | Explicit implementation or Unsupported | Additional non-durable active-turn input |
| `FunctionResultSubmitter` | Explicit implementation or Unsupported | Match native call/result identity and acknowledge application |
| `PermissionResponder`, `UserChoiceResponder` | Explicit implementation or Unsupported | Respond to exact emitted identities; unknown/expired interactions remain distinct from Unsupported |
| `WorkspaceReader`, `WorkspaceDirectoryLister`, `WorkspaceWriter` | Explicit on Turn, Executor and Prepared owners | Use the authorized workspace, confirm access/commit/close, or return the operation's Unsupported error |
| `Prepared`, `PreparedCancellation` | Real implementation for an executable preparation | Preserve resource and output ownership across Start, cancellation and unused cleanup |
| Neutral messages, images, MCP, structured output and Subagent observations | Explicit capability decisions | Preserve each operation's protocol semantics; reject unsupported input before submission |

Each adapter's `contracts.go` contains individual compile-time assertions for these
small interfaces. Do not embed a default implementation that makes future
interfaces appear implemented. Adding a contract also requires classification in
the common completeness check and an explicit assertion for every public adapter;
the check follows the authored Harness catalog.

For a design-level refusal, implement the method directly, for example:

```go
func (s *Session) SubmitFunctionResult(context.Context, proto.FunctionResultPayload) error {
return fmt.Errorf("%w: native public function tools are not qualified", agent.ErrUnsupportedOperation)
}
```

The reason is a fixed safe string, never submitted content, a credential or raw
native diagnostics. Unsupported guarantees no native side effect. It is not a
successful empty operation. Installation unavailability, unknown interaction IDs,
native failures and uncertain outcomes keep their existing errors and ownership.
A nil `Turn` still means no input was submitted and output remains with the caller;
it must not be repurposed as an Unsupported marker.

Workspace capability describes the actual Runtime/resource-owner combination.
Codex and MiniMax resource objects explicitly reject native workspace access while
the common authorized `localworkspace` owner provides it. Claude can expose native
read/list access; writes are provided by the common owner. Interface presence alone
must never select a resource or advertise support.

The service profile qualifies public combinations; the Runtime advertises the
installed combination. Neither replaces schema validation or tenant authorization.
Native behavior tests must agree with supported declarations. An advertised
operation returning Unsupported is a contract violation, never success or grounds
for automatic replay.

## Register the adapter

Expand All @@ -224,8 +261,29 @@ from [`cli/agent_registration.go`](https://github.com/MiniMax-AI/parsar-core/blo
| 3 | `RegisterPreparation(kind, workspaceRead, agent.PreparationFactory)` | Optional. Separate read-only workspace preparation when qualified workspace operations need it. |

The direct-call `agent.Factory` should delegate to the same Executor
implementation. Every other capability declaration must match behavior verified
for that installation. Runtime registration does not grant Core qualification;
implementation. Every `proto.AgentKindCapabilities` field must be explicitly
`proto.CapabilitySupported` or `proto.CapabilityUnsupported`.
`proto.CapabilityUnspecified` is invalid: zero values and omitted fields do not mean
Unsupported. Installation probes may use `proto.CapabilityFromBool` for an
individual field; they must not populate all unmentioned or future fields.
Availability remains separate in `SupportedAgentKind.Available`.

Registration and wire decoding validate the complete declaration. The wire carries
an explicit boolean for every field; omitted and null fields are invalid. A new
field requires a decision by every production declaration. Runtime consumers use
`IsSupported()` and reject unsupported requests before native operations; an
interface assertion only verifies implementation, never support. Every declaration
must match behavior verified for that installation.

The admission mapping is explicit: `Steering` controls non-durable `Steerer` input;
`DurableInputReceipts` controls `DurableSteerer` input and also requires the Turn
settlement contract. Neither implies the other. Core's current public text profile
requires both advertised capabilities. `Permissions` qualifies permission and
user-choice responses together; a supported declaration requires both native
response paths. Workspace declarations describe the selected authorized resource
owner, including the common Runtime workspace implementation.

Runtime registration does not grant Core qualification;
that belongs to the service profile.

The runnable test-only example is
Expand Down Expand Up @@ -276,7 +334,7 @@ The [Harness selection contract](https://github.com/MiniMax-AI/parsar-core/blob/
deployment enablement, defaults and immutable Session binding. This guide adds no
second selector or fallback rule.

## Required versus optional operations
## Required versus extension operations

The current public text path requires durable turns, applied input receipts,
ordered observations, cancellation and enforcement of disabled execution controls.
Expand All @@ -287,7 +345,7 @@ of enforcement.

MCP, public function calls, deferred function discovery, structured output, image inputs, verbosity controls and other optional
operations do not need to match another engine. Reject unqualified combinations
explicitly and record the gap. Never advertise a capability to bypass selection.
with Unsupported and record the gap. Never advertise a capability to bypass selection.

Structured-output adapters consume `ExecutionControls.OutputFormat` and publish
confirmed native output through the existing Message contract. Register public
Expand Down Expand Up @@ -334,6 +392,26 @@ not add routes, storage branches or a harness-specific Core scheduler. Report
unsupported native facts explicitly; completing a child task is not closing its
Subagent. Native background work must remain owned through settlement and cancel.

## Contract verification

Run `make check-runtime-contract`, the three adapter test packages and `make check`.
The common completeness gate covers capability omissions and interface assertions;
adapter tests must cover actual native semantics, not only method presence.

| Boundary | Existing focused evidence |
| --- | --- |
| Codex reuse, cancellation and unconfirmed cleanup | `codex/executor_test.go`, `terminal_cleanup_test.go`, `prepared_cancel_test.go` |
| Codex input receipts and strict recovery | `codex/function_write_receipt_test.go`, `function_receipt_test.go`, `resume_test.go`, `recovery_test.go` |
| Claude input ownership, cancellation and preparation cleanup | `claudesdk/executor_test.go`, `cancellation_test.go`, `preparation_test.go` |
| MiniMax cancellation retirement, failed Start and cleanup retry | `mcode/executor_test.go`, `executor_backpressure_test.go` |
| MiniMax native history binding | `mcode/session_test.go` |
| Explicit refusals without native effects or fabricated results | Each adapter's `unsupported_test.go` |

These paths are relative to `apps/parsar-daemon/internal/agent`. Controlled native
transport fixtures establish failure and ownership behavior; they are not live model
qualification. Preserve the separate native acceptance requirements in
[Harness integration](https://github.com/MiniMax-AI/parsar-core/blob/f6d258735fc601c521dd990e6f9e1ed261f4ef2d/contracts/agents-api/harnesses.md#acceptance-checklist).

## Native installer participation

An adapter may supply `agent.Installation` from `installation.go` in its own
Expand Down
31 changes: 31 additions & 0 deletions apps/docs/content/docs/runtime-protocol.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,37 @@ leases and evicts old Run/interaction routes; the new connection does not inheri
them. A valid credential and connection are not authority to choose another
Session or Environment binding.

### Explicit capability declarations

`AgentKindCapabilities` describes the composed Runtime and Harness, independently
of `Available` and the Core model profile. Every field uses `CapabilitySupport`:
`CapabilitySupported` or `CapabilityUnsupported`. Zero means unspecified and is
invalid even for an unavailable Harness. Registration validates the complete
struct before changing the registry; there is no implicit basic descriptor.

The wire still uses JSON booleans and includes every field, including `false`.
Encoding incomplete declarations fails; decoding rejects omitted, null, invalid
or unknown capability fields, including a missing capability object. An invalid
heartbeat clears the connection's admission snapshot and closes its transport.
That establishes no native completion or cancellation result. Both peers use the
same exact wire version; no historical declaration format is accepted.

Each admitted Executor and Turn retains its declaration. Rediscovery cannot add
operations to an existing owner. Optional operations check this snapshot before
native calls; interface presence alone never grants support. A declared operation
returning `agent.ErrUnsupportedOperation` is a contract violation, distinct from
unavailability, a failed native call or an uncertain write. Uncertain operations
keep their existing receipts and ownership; they are never automatically replayed.
Workspace support includes the common Runtime workspace implementation, so a
native adapter's unsupported workspace method does not disable that composition.

New fields require an explicit decision in each production declaration. Contract
tests enumerate every field for registration, wire round trips and the persisted
boolean projection. The shared test fixture lists current fields individually;
it does not supply defaults for future fields. The Harness interface inventory
also requires a role decision and compile assertions for every public adapter;
see [Harness onboarding](/harness-onboarding).

### Executor and Turn lifetimes

This section owns the separation of execution and resource lifetimes.
Expand Down
Loading