Documentation
¶
Index ¶
- Constants
- func BoundedDetail(value string) string
- func EnsureAncestors(target string) error
- func ListenSocket(stateRoot, socketPath string) (net.Listener, func(), error)
- func LoadPolicies(path string, cfg *config.Config) (map[string]Policy, error)
- func NewHTTPHandler(service *Service) http.Handler
- func ReviewCandidateUnchanged(dir, branch, head, tree string) bool
- func ReviewGitIdentity(dir, revision string) (string, string, error)
- func RunIDFromEnv() string
- func SanitizeReviewText(value string, maxBytes int) string
- type CompanionPolicy
- type Config
- type CreateRemoteSessionRequest
- type DiscardPlan
- type DiscardRequest
- type EventDTO
- type Host
- type OperationDTO
- type PlanDiscardRequest
- type PlanDiscardResult
- type Policy
- type RemotePullRequestBinding
- type ReviewDossier
- type ReviewGate
- type ReviewGateFunc
- type ReviewGateResult
- type ReviewGateStatus
- type ReviewRebaseStatus
- type RunReviewRequest
- type Runner
- type RunnerFactory
- type RunnerFunc
- type Service
- func (s *Service) AcceptTurnCandidate(ctx context.Context, key, sessionID, turnID, digest string) (session.Turn, error)
- func (s *Service) CancelTurn(ctx context.Context, key string, req session.CancelTurnRequest) (session.Turn, error)
- func (s *Service) Close(ctx context.Context, key string, req session.CloseSessionRequest) (session.Session, error)
- func (s *Service) CloseSession(ctx context.Context, key string, req session.CloseSessionRequest) (session.Session, error)
- func (s *Service) CreateRemoteSession(ctx context.Context, key string, req CreateRemoteSessionRequest) (session.Session, error)
- func (s *Service) CreateRemoteSessionAsync(ctx context.Context, key string, req CreateRemoteSessionRequest) (session.Operation, error)
- func (s *Service) Discard(ctx context.Context, key string, req DiscardRequest) (session.Session, error)
- func (s *Service) ExtendBudget(ctx context.Context, key string, req session.ExtendBudgetRequest) (session.Session, error)
- func (s *Service) GetChanges(ctx context.Context, sessionID string) (WorkspaceChanges, error)
- func (s *Service) GetChangesPage(ctx context.Context, sessionID string, patchOffset int64, patchLimit int) (WorkspaceChanges, error)
- func (s *Service) GetOperation(ctx context.Context, key string) (session.Operation, error)
- func (s *Service) GetOperationByID(ctx context.Context, id string) (session.Operation, error)
- func (s *Service) GetOutputArtifact(ctx context.Context, sessionID, turnID, artifactID string) (session.OutputArtifact, error)
- func (s *Service) GetSession(ctx context.Context, id string) (session.Session, error)
- func (s *Service) GetTurn(ctx context.Context, sessionID, turnID string) (session.Turn, error)
- func (s *Service) ListEvents(ctx context.Context, sessionID string, after int64, limit int) ([]session.Event, error)
- func (s *Service) ListSessions(ctx context.Context, limit int) ([]session.Session, error)
- func (s *Service) ListTurns(ctx context.Context, sessionID string, afterOrdinal int64, limit int) ([]session.Turn, error)
- func (s *Service) OpenReviewPatch(ctx context.Context, operationID string) (*os.File, ReviewDossier, error)
- func (s *Service) PlanDiscard(ctx context.Context, key string, req PlanDiscardRequest) (PlanDiscardResult, error)
- func (s *Service) PrepareSession(ctx context.Context, id string, expectedRevision int64) (session.Session, error)
- func (s *Service) RejectTurnCandidate(ctx context.Context, key string, req session.RejectTurnCandidateRequest) (session.Turn, error)
- func (s *Service) RunReview(ctx context.Context, key string, req RunReviewRequest) (ReviewDossier, error)
- func (s *Service) Start(parent context.Context) error
- func (s *Service) Stop() error
- func (s *Service) Store() *session.Store
- func (s *Service) SubmitTurn(ctx context.Context, key string, req session.SubmitTurnRequest) (session.Turn, error)
- type SessionChangeDTO
- type SessionChangesDTO
- type SessionCompanionDTO
- type SessionDTO
- type SessionDiscardPlanDTO
- type SessionDiscardWorkspaceDTO
- type SessionParentDivergenceDTO
- type SessionPlanDiscardDTO
- type SessionReviewDTO
- type TurnArtifactDTO
- type TurnDTO
- type WorkspaceChanges
- type WorkspaceDiscardPlan
Constants ¶
const ( // PolicyFileLimit bounds a session policy file, so a command that validates one before // handing it over reads the same amount this package will. PolicyFileLimit = 1 << 20 // DefaultStopTimeout is how long the service waits for in-flight work to wind down, and the // budget a host's own HTTP shutdown should match. DefaultStopTimeout = 5 * time.Second )
const MaxReviewErrorBytes = session.MaxErrorDetailBytes
MaxReviewErrorBytes bounds a gate's startup-error prose, so a host implementing ReviewGate truncates the same way the service's own paths do.
Variables ¶
This section is empty.
Functions ¶
func BoundedDetail ¶
func EnsureAncestors ¶
EnsureAncestors creates missing parents of the state root without weakening permissions on an existing home/config directory. The state root itself is hardened by session.Open.
func LoadPolicies ¶
LoadPolicies parses the strict operator policy file. A config is required when the caller wants credential availability checked; passing nil performs syntax/target/repository validation only and is useful for isolated parser tests.
func NewHTTPHandler ¶
func RunIDFromEnv ¶
func RunIDFromEnv() string
func SanitizeReviewText ¶
Types ¶
type CompanionPolicy ¶
type Config ¶
type Config struct {
StateRoot string
PolicyPath string
Policies map[string]Policy
SourceConfig *config.Config
Config *config.Config
Runtime runtime.Runtime
Executable string
Host Host
Runner Runner
RunnerFactory RunnerFactory
ReviewGate ReviewGate
StopTimeout time.Duration
CleanupInterval time.Duration
OperationStaleAfter time.Duration
Logger *slog.Logger
}
type CreateRemoteSessionRequest ¶
type CreateRemoteSessionRequest struct {
Policy string `json:"policy"`
Task string `json:"task"`
PullRequest *RemotePullRequestBinding `json:"pull_request,omitempty"`
}
type DiscardPlan ¶
type DiscardPlan struct {
SessionID string `json:"session_id"`
Revision int64 `json:"revision"`
Workspace WorkspaceDiscardPlan `json:"workspace"`
Companions []sessionCompanionDiscardPlan `json:"companions,omitempty"`
}
type DiscardRequest ¶
type DiscardRequest struct {
PlanOperationID string `json:"plan_operation_id"`
}
type EventDTO ¶
type EventDTO struct {
ID string `json:"id"`
SessionID string `json:"session_id"`
Sequence int64 `json:"sequence"`
TurnID string `json:"turn_id,omitempty"`
Type session.EventType `json:"type"`
Version int `json:"version"`
OccurredAt time.Time `json:"occurred_at"`
// Payload is the event's own record of what happened. It was withheld for
// a long time, which left a caller able to count that a turn failed but
// not to say why, and able to see that a turn ran without seeing any of
// the work inside it.
Payload json.RawMessage `json:"payload,omitempty"`
}
type Host ¶
type Host struct {
// PolicyScan flags credential-looking or execution-risk changes in a review candidate,
// with the SAME decider that shadows secrets from the box. Nil means no findings, which
// makes a review MORE publishable — so a real serving host must always wire it.
PolicyScan func(repo, ref string) []string
// ReviewGateFactory builds the gate a review runs when the caller injected none. It is a
// factory, not a gate, because the runtime is detected lazily: the service opens (and takes
// the state-root lock) before any runtime-specific startup work happens.
ReviewGateFactory func(*config.Config, runtime.Runtime) ReviewGate
// Warnf reports a non-fatal condition to the operator — a failed janitorial cleanup that
// something else will retry. Rendering belongs to the CLI, so this package never imports
// internal/ui.
Warnf func(format string, args ...any)
}
Host is what the sessions service needs from the CLI that owns the terminal and the merge policy, and cannot own itself: the fork/git contracts it shares live in leaf packages (internal/forkspace, internal/ladder) and are plain imports, so only these three remain.
Every field is optional and a zero Host is usable — a test that drives the service directly injects the gate it wants and never scans or warns. The seams are deliberately functions, not an interface: each is one call, and there is exactly one implementation (internal/cli).
type OperationDTO ¶
type OperationDTO struct {
ID string `json:"id"`
Method string `json:"method"`
State session.OperationState `json:"state"`
ResourceType string `json:"resource_type,omitempty"`
ResourceID string `json:"resource_id,omitempty"`
ErrorCode session.ErrorCode `json:"error_code,omitempty"`
ErrorDetail string `json:"error_detail,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type PlanDiscardRequest ¶
type PlanDiscardResult ¶
type PlanDiscardResult struct {
OperationID string `json:"operation_id"`
Plan DiscardPlan `json:"plan"`
}
type Policy ¶
type Policy struct {
Name string
Repository string
Remote string
Branch string
Companions []CompanionPolicy
Targets []agents.Target
OmitEnv bool
OmitMCP bool
RepositoryReadOnly bool
MaxTurns int
MaxQueuedTurns int
MaxQueuedBytes int
TurnTimeout time.Duration
WarmIdleTimeout time.Duration
MaxPatchBytes int
}
Policy is operator-owned authority for one remote session. It is intentionally small: repository, target, and resource bounds are not request fields.
func (*Policy) UnmarshalJSON ¶
UnmarshalJSON retains the write-ahead intent format written before target ladders. Policy files use YAML and new JSON intents marshal Targets, so compatibility stays read-only.
type RemotePullRequestBinding ¶
type RemotePullRequestBinding struct {
Number int `json:"number"`
HeadCommit string `json:"head_commit"`
}
RemotePullRequestBinding selects one GitHub pull-request head through the operator-owned remote configured by the session policy. The caller cannot name a repository, remote, or arbitrary ref, and the expected head makes a PR update racing session creation fail closed instead of silently changing the task's approved source.
type ReviewDossier ¶
type ReviewDossier struct {
OperationID string `json:"operation_id"`
SessionID string `json:"session_id"`
SessionRevision int64 `json:"session_revision"`
PolicyDigest string `json:"policy_digest"`
PullRequest *session.PullRequestBinding `json:"pull_request,omitempty"`
CreationBase string `json:"creation_base"`
SourceHead string `json:"source_head"`
SourceTree string `json:"source_tree"`
ParentHead string `json:"parent_head"`
ParentTree string `json:"parent_tree"`
CandidateHead string `json:"candidate_head"`
CandidateTree string `json:"candidate_tree"`
Rebase ReviewRebaseStatus `json:"rebase"`
Gate ReviewGateStatus `json:"gate"`
GateError string `json:"gate_error,omitempty"`
PolicyFindings []string `json:"policy_findings,omitempty"`
Patch []byte `json:"patch,omitempty"`
PatchTruncated bool `json:"patch_truncated"`
PatchArtifactID string `json:"patch_artifact_id,omitempty"`
PatchDigest string `json:"patch_digest,omitempty"`
PatchBytes int64 `json:"patch_bytes"`
Publishable bool `json:"publishable"`
NotPublishableReasons []string `json:"not_publishable_reasons,omitempty"`
}
type ReviewGate ¶
ReviewGate is the narrow gate seam used by RunReview. Implementations must not mutate gateRepo. A gate may create ignored build output in the disposable candidate; RunReview rejects any change to its pinned commit, tree, branch, tracked files, or non-ignored untracked files.
type ReviewGateFunc ¶
func (ReviewGateFunc) Run ¶
func (f ReviewGateFunc) Run(ctx context.Context, gateRepo, treeDir string) (ReviewGateResult, error)
type ReviewGateResult ¶
ReviewGateResult is the complete outcome of the trusted parent gate. StartupError is a successful review outcome, not a failed operation.
type ReviewGateStatus ¶
type ReviewGateStatus string
const ( ReviewGateNone ReviewGateStatus = "none" ReviewGatePassed ReviewGateStatus = "passed" ReviewGateFailed ReviewGateStatus = "failed" ReviewGateStartupError ReviewGateStatus = "startup_error" ReviewGateNotRun ReviewGateStatus = "not_run" )
type ReviewRebaseStatus ¶
type ReviewRebaseStatus string
const ( ReviewRebaseClean ReviewRebaseStatus = "clean" ReviewRebaseConflict ReviewRebaseStatus = "conflict" )
type RunReviewRequest ¶
type RunnerFactory ¶
type RunnerFunc ¶
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func (*Service) AcceptTurnCandidate ¶
func (*Service) CancelTurn ¶
func (*Service) CloseSession ¶
func (*Service) CreateRemoteSession ¶
func (*Service) CreateRemoteSessionAsync ¶
func (s *Service) CreateRemoteSessionAsync( ctx context.Context, key string, req CreateRemoteSessionRequest, ) (session.Operation, error)
CreateRemoteSessionAsync durably admits a create before returning. Slow Git resolution and workspace materialization run under the service lifetime, independent of the HTTP request that admitted them.
func (*Service) ExtendBudget ¶
func (*Service) GetChanges ¶
func (*Service) GetChangesPage ¶
func (*Service) GetOperation ¶
func (*Service) GetOperationByID ¶
func (*Service) GetOutputArtifact ¶
func (*Service) GetSession ¶
func (*Service) ListEvents ¶
func (*Service) ListSessions ¶
func (*Service) OpenReviewPatch ¶
func (*Service) PlanDiscard ¶
func (s *Service) PlanDiscard(ctx context.Context, key string, req PlanDiscardRequest) (PlanDiscardResult, error)
func (*Service) PrepareSession ¶
func (*Service) RejectTurnCandidate ¶
func (*Service) RunReview ¶
func (s *Service) RunReview(ctx context.Context, key string, req RunReviewRequest) (ReviewDossier, error)
type SessionChangeDTO ¶
type SessionChangesDTO ¶
type SessionChangesDTO struct {
BaseCommit string `json:"base_commit"`
ForkHead string `json:"fork_head"`
ForkTree string `json:"fork_tree"`
PullRequestTree string `json:"pull_request_tree,omitempty"`
ParentHead string `json:"parent_head"`
Committed []SessionChangeDTO `json:"committed"`
Staged []SessionChangeDTO `json:"staged"`
Unstaged []SessionChangeDTO `json:"unstaged"`
Untracked []SessionChangeDTO `json:"untracked"`
Conflicts []SessionChangeDTO `json:"conflicts"`
ParentDivergence SessionParentDivergenceDTO `json:"parent_divergence"`
Patch []byte `json:"patch,omitempty"`
Truncated bool `json:"truncated"`
PatchDigest string `json:"patch_digest,omitempty"`
PatchBytes int64 `json:"patch_bytes"`
PatchOffset int64 `json:"patch_offset"`
PatchNextOffset int64 `json:"patch_next_offset"`
PatchHasMore bool `json:"patch_has_more"`
}
type SessionCompanionDTO ¶
type SessionDTO ¶
type SessionDTO struct {
ID string `json:"id"`
ExternalRef string `json:"external_ref"`
Target string `json:"target"`
Policy string `json:"policy"`
PolicyDigest string `json:"policy_digest"`
RepositoryReadOnly bool `json:"repository_read_only"`
BaseCommit string `json:"base_commit"`
PullRequest *session.PullRequestBinding `json:"pull_request,omitempty"`
Companions []SessionCompanionDTO `json:"companions,omitempty"`
ForkName string `json:"fork_name"`
Revision int64 `json:"revision"`
State session.SessionState `json:"state"`
Activity session.ActivityState `json:"activity"`
MaxTurns int `json:"max_turns"`
MaxQueuedTurns int `json:"max_queued_turns"`
MaxQueuedBytes int `json:"max_queued_bytes"`
TurnsUsed int `json:"turns_used"`
QueuedTurnCount int `json:"queued_turn_count"`
QueuedPromptBytes int `json:"queued_prompt_bytes"`
ActiveTurnID string `json:"active_turn_id,omitempty"`
LastEventSequence int64 `json:"last_event_sequence"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
These DTOs are the public v1 wire types. They deliberately do not mirror the durable records: the latter contain prompts, operation secrets, native provider identities, and host paths.
type SessionDiscardPlanDTO ¶
type SessionDiscardPlanDTO struct {
SessionID string `json:"session_id"`
Revision int64 `json:"revision"`
Workspace SessionDiscardWorkspaceDTO `json:"workspace"`
}
type SessionDiscardWorkspaceDTO ¶
type SessionDiscardWorkspaceDTO struct {
Branch string `json:"branch"`
Head string `json:"head"`
StatusDigest string `json:"status_digest"`
Dirty bool `json:"dirty"`
Unmerged bool `json:"unmerged"`
Running bool `json:"running"`
AcceptedDirty bool `json:"accepted_dirty,omitempty"`
AcceptedUnmerged bool `json:"accepted_unmerged,omitempty"`
}
type SessionPlanDiscardDTO ¶
type SessionPlanDiscardDTO struct {
OperationID string `json:"operation_id"`
Plan SessionDiscardPlanDTO `json:"plan"`
}
type SessionReviewDTO ¶
type SessionReviewDTO struct {
OperationID string `json:"operation_id"`
SessionID string `json:"session_id"`
SessionRevision int64 `json:"session_revision"`
PolicyDigest string `json:"policy_digest"`
PullRequest *session.PullRequestBinding `json:"pull_request,omitempty"`
CreationBase string `json:"creation_base"`
SourceHead string `json:"source_head"`
SourceTree string `json:"source_tree"`
ParentHead string `json:"parent_head"`
ParentTree string `json:"parent_tree"`
CandidateHead string `json:"candidate_head"`
CandidateTree string `json:"candidate_tree"`
Rebase ReviewRebaseStatus `json:"rebase"`
Gate ReviewGateStatus `json:"gate"`
GateError string `json:"gate_error,omitempty"`
PolicyFindings []string `json:"policy_findings,omitempty"`
Patch []byte `json:"patch,omitempty"`
PatchTruncated bool `json:"patch_truncated"`
PatchArtifactID string `json:"patch_artifact_id,omitempty"`
PatchDigest string `json:"patch_digest,omitempty"`
PatchBytes int64 `json:"patch_bytes"`
Publishable bool `json:"publishable"`
NotPublishableReasons []string `json:"not_publishable_reasons,omitempty"`
}
type TurnArtifactDTO ¶
type TurnDTO ¶
type TurnDTO struct {
ID string `json:"id"`
SessionID string `json:"session_id"`
Ordinal int64 `json:"ordinal"`
State session.TurnState `json:"state"`
SendState session.SendState `json:"send_state"`
AssistantMessage string `json:"assistant_message,omitempty"`
StopReason session.StopReason `json:"stop_reason,omitempty"`
ErrorCode session.ErrorCode `json:"error_code,omitempty"`
ErrorDetail string `json:"error_detail,omitempty"`
QueuedAt time.Time `json:"queued_at"`
StartedAt time.Time `json:"started_at,omitempty"`
FinishedAt time.Time `json:"finished_at,omitempty"`
OutputArtifacts []TurnArtifactDTO `json:"output_artifacts,omitempty"`
Usage session.Usage `json:"usage,omitzero"`
Candidate *session.TurnCandidate `json:"candidate,omitempty"`
ValidationCandidateSHA256 string `json:"validation_candidate_sha256,omitempty"`
ValidationAttempt int `json:"validation_attempt,omitempty"`
ValidationError string `json:"validation_error,omitempty"`
ValidationReceipt string `json:"validation_receipt,omitempty"`
}
type WorkspaceChanges ¶
type WorkspaceChanges struct {
BaseCommit string `json:"base_commit"`
ForkHead string `json:"fork_head"`
ForkTree string `json:"fork_tree"`
PullRequestTree string `json:"pull_request_tree,omitempty"`
ParentHead string `json:"parent_head"`
Committed []sessionWorkspaceChange `json:"committed,omitempty"`
Staged []sessionWorkspaceChange `json:"staged,omitempty"`
Unstaged []sessionWorkspaceChange `json:"unstaged,omitempty"`
Untracked []sessionWorkspaceChange `json:"untracked,omitempty"`
Conflicts []sessionWorkspaceChange `json:"conflicts,omitempty"`
ParentDivergence sessionWorkspaceParentDivergence `json:"parent_divergence"`
Patch string `json:"patch,omitempty"`
Truncated bool `json:"truncated"`
PatchDigest string `json:"patch_digest,omitempty"`
PatchBytes int64 `json:"patch_bytes"`
PatchOffset int64 `json:"patch_offset"`
PatchNextOffset int64 `json:"patch_next_offset"`
PatchHasMore bool `json:"patch_has_more"`
}
type WorkspaceDiscardPlan ¶
type WorkspaceDiscardPlan struct {
Repo string `json:"repo"`
Name string `json:"name"`
Workspace string `json:"workspace"`
WorkspaceIdentity sessionWorkspaceIdentity `json:"workspace_identity"`
Branch string `json:"branch"`
Head string `json:"head"`
ParentHead string `json:"parent_head"`
StatusDigest string `json:"status_digest"`
Dirty bool `json:"dirty"`
Unmerged bool `json:"unmerged"`
Running bool `json:"running"`
AcceptedDirty bool `json:"accepted_dirty,omitempty"`
AcceptedUnmerged bool `json:"accepted_unmerged,omitempty"`
}