Skip to main content

Internals

The orun binary is one Go module. Cobra command wiring, flag definitions, and the thin handlers live in cmd/orun; everything else lives under internal/. The packages are grouped below by subsystem. The one-line descriptions come from each package's own doc comment; when a package has none, the description names its primary types.

Compiler​

PackageRole
internal/loaderLoad intent, discover component manifests, and load composition assets (LoadIntent, LoadResolvedIntent, LoadJobRegistry)
internal/schemaJSON Schema validation for intent, components, and job registries (Validator)
internal/normalizeCanonicalize the raw intent before expansion (NormalizeIntent)
internal/expandMaterialize environment × component instances, merge parameters, and resolve dependencies (Expander, DependencyResolver, ComponentAnalyzer)
internal/plannerBind component instances to jobs, resolve job dependencies, detect cycles, and order the DAG (JobPlanner, JobGraph)
internal/renderMaterialize the deterministic plan artifact (Renderer, PlanViewer)
internal/modelThe stage contracts: intent, component manifests, compositions, jobs, component instances, and plans
internal/compositionComposition packages: resolving sources, archives, dependency modes, profiles, and publish plans
internal/presetIntent presets: load extends references and merge them into the resolved intent
internal/discoveryWalk upward from the working directory to find intent.yaml
internal/triggerMatch normalized trigger events against trigger bindings
internal/triggerctxThe trigger context model and resolver — captures why a plan was compiled as a TriggerOccurrence
internal/revkeyDerive the human revision key (rev-<scope>-<sha7>-p<planHash8>) from a trigger occurrence and a plan hash

Runtime and workflows​

PackageRole
internal/runnerExecute a compiled plan: ordering, state, lifecycle hooks, per-job workspace isolation, job output secrets, workflow steps and approval gates
internal/executorThe executor interface and its local, Docker, and GitHub Actions backends
internal/ghaThe GitHub Actions compatibility engine: use: steps, file commands, expression evaluation
internal/execmodelDurable execution value types — the in-memory shape of a run's per-job and per-step state
internal/flowThe orun workflow language (kind: Workflow): run: / action: / workflow: verbs, needs: edges, CEL expressions, typed inputs, remote references
internal/approvalHuman-in-the-loop gates for workflow steps — the pending request and the decision are run facts under .orun/approvals, never plan content
internal/runbundleHydrate run shards from remote artifacts (HydrateOptions, PlanShard)
internal/artifactstoreThe generic artifact Store interface with GitHub Actions and in-memory implementations
internal/statebackendThe remote state and coordination backend contract: init, claim, heartbeat, log chunks, terminal updates, hermetic memoization

Catalog and change detection​

PackageRole
internal/catalogmodelEvery persisted component-catalog data type, the canonical-JSON encoder, sanitizers, ID helpers, and the embedded component.yaml JSON Schema
internal/catalogresolveThe catalog resolution pipeline: discover manifests, parse, and build the graph
internal/catalogrefreshThe shared "resolve the workspace into the object-model catalog" engine used by orun catalog refresh, orun plan, and the cockpit
internal/catalogdiffCompare two resolved catalog snapshots and report component- and graph-level differences
internal/catalogextTyped extension registry for x-<vendor> blocks in the catalog envelope
internal/codeownersParse a GitHub-style CODEOWNERS file so the resolver can derive ownership
internal/sourcectxThe source-context resolver that produces a SourceSnapshot for the workspace at refresh time
internal/affectedThe single change-detection engine behind plan --changed, run --changed, the cockpit, and orun catalog affected
internal/inputglobValidates and matches a component's spec.change.inputs globs: repository-root-relative, doublestar-style patterns that let a component claim files outside its own directory
internal/gitGit change detection and intent diffing (ChangeDetector, IntentDiffResult)
internal/ciDetect the CI provider and the refs it exposes (DetectedRefs)

Object model​

PackageRole
internal/objectstoreThe L0 content-addressed object store — the only path through which object bytes are written; objectstore/refstore holds the refs
internal/nodesThe L1 typed-node layer: record schemas, canonical encoding, validation, and the closed kind list (SourceSnapshot … Task)
internal/nodewriterComposes objectstore, refstore, and nodes into the tolerant-strict write walk
internal/objplanAdapts resolver outputs into object-model nodes so orun plan writes the content-addressed graph
internal/objreadThe native read layer: reconstruct execution detail from objects and refs, or from the live working tree
internal/objindexL3 derived indexes under <root>/index/ — rebuildable caches, never authoritative
internal/objgcThe reachability garbage collector: retention, then sweep
internal/objremoteObject substitution between two endpoints — syncing is a set difference
internal/objrunSession glue that drives the object model from a runner's lifecycle: open a working tree, project state on every tick, stream logs, seal on terminal
internal/objviewAdapts object-model execution views into the legacy execmodel value types the renderers and cockpit consume
internal/objmodelThe unified read seam (ModelReader) the cockpit, CLI porcelain, and hosted console all consume
internal/objcatalogThe read view over the object-model component catalog
internal/execsealSeals a finished execution into the content-addressed graph — the "commit" half of the working-tree/seal model
internal/runworktreeThe live, mutable half: the atomically rewritten working file the runner mutates as jobs and steps progress
internal/workingviewThe L4 inspection surface: fsck, a human-readable checkout, and the read primitives behind orun objects
internal/clockInjectable wall clock; object-model production code never calls time.Now() directly

Cockpit​

PackageRole
internal/cockpitThe shared view layer: bridge (one read path over .orun/ or a remote backend), viewmodel, render, style (design tokens), surface, watch (polling stream), and catalogread
internal/tuiCockpit v1 — the default orun tui
internal/tui2Cockpit v2 — orun tui-next: shell, frame, store, design (Northwind Mono), data, surfaces/*, agentfold, demo
internal/uiANSI colour handling, the GitHub Actions output renderer, and the live region used by non-TUI commands

Cloud client​

PackageRole
internal/cliauthCLI login flows, the OS credential store with file fallback, ~/.orun/config.yaml, and repo links
internal/remotestateHTTP client, token resolution, plan conversion, and run-ID derivation for the remote state backend; holds DefaultCloudURL
internal/configsurfaceClient for the platform's workspace/project/environment-scoped config surface (secrets)
internal/cloudflareCloudflare REST client used to provision a self-hosted backend (D1, R2, Workers, queues)
internal/backendbundleThe embedded self-hosted backend artifacts: Worker bundle, D1 migrations, manifest
internal/githubretryWhen a GitHub API read is worth retrying

Secrets and policy​

PackageRole
internal/scoperefThe scope-reference grammar (secret://, config, flag) — the only value-shaped thing allowed in intent, plans, or objects
internal/secretrefDeprecated secret-only face of the grammar; delegates to scoperef
internal/secretpolicyLoader and model for the portable kind: SecretPolicy document
internal/redactMasks resolved secret values in step output before any sink — console, live tail, remote chunks, sealed blobs
internal/materializeDeploy-time delivery of resolved secrets into an application's native store (v1: Cloudflare Worker bindings)

Agent runtime and MCP​

PackageRole
internal/agentThe agent runtime: the delegation loop that turns a frozen brief into a PR; subpackages driver (the AgentDriver seam), attach (the attach protocol), live (live sessions), ground (grounding a sandbox session in a repository)
internal/agenttypeLoads agents/*.md agent-type definitions and seals them into AgentTypeSnapshot nodes
internal/mcpserveThe shared stdio MCP transport: one JSON-RPC loop composing ToolProviders
internal/platformmcpThe platform tool plane over the public API (catalog, runs, tasks, secrets, …)
internal/penmcpThe provenance pen over MCP: the pr_open tool
internal/integrationscliRenders registry-served integration verb trees as Cobra commands

Scaffolding, baselines, and provenance​

PackageRole
internal/scaffoldThe unified scaffolding and instantiation engine: one language for scaffolding a component and bootstrapping a whole repository
internal/actionsThe closed, versioned registry of typed actions a blueprint hook may call (<namespace>/<verb>@v<major>)
internal/forgeThe small GitHub surface bootstrap actions need: does this repository exist, has this workflow run finished
internal/provenanceThe pen: every PR carries its lineage in the branch name, the body manifest, and the Orun-Task commit trailer

Tasks​

PackageRole
internal/contractThe agent runtime's task contract — goal, blast-radius ceiling, done-when list, and gates
internal/taskfileReads authored tasks/<KEY>.TaskContract.yaml documents
internal/taskobjSeals tasks into the object graph under refs/tasks/<key> and reads them back

Test fixtures and conformance​

PackageRole
internal/testfxTest helpers: objfs for the object model, statefs for the state redesign
internal/objgoldenCross-language golden vectors that pin the Go and TypeScript object-model readers to the same bytes
internal/objmodele2eThe end-to-end plan → seal → index → fsck → push → pull → gc walk

Design constraints​

  • planning stages are deterministic — identical inputs produce byte-identical plans
  • runtime behaviour stays explicit in the plan artifact
  • command handlers stay thin; business logic lives under internal/
  • internal/model is the stable contract between compiler stages
  • the object model is written only through objectstore; indexes are caches, never authority
  • secrets are references in every artifact; values exist only at resolve time and are redacted at every sink