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
2 changes: 1 addition & 1 deletion .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ cleanup or cancellation does not undo GitHub operations that already succeeded.

Add another reusable workflow only when the capability has a distinct trigger,
permission, or trust contract. Keep review and merge separate, and keep
repository-specific task behavior in [workloads/](../../workloads/) rather than
repository-specific task behavior in [tasks/](../../tasks/) rather than
growing a single workflow with general-purpose image, policy, provider, or
command inputs.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
- run: CGO_ENABLED=0 go build -o harness ./workflow
- run: CGO_ENABLED=0 go build -o harness ./runner
- run: ./test/suite/run.sh

lint:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:

- name: Run local integration
run: |
CGO_ENABLED=0 go build -ldflags '-s -w -X main.version=ci' -o harness ./workflow
CGO_ENABLED=0 go build -ldflags '-s -w -X main.version=ci' -o harness ./runner
./test/test-flow.sh local-container
env:
TEST_LOG_FILE: /tmp/test-logs/test-flow-local.log
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-review-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
path: harness
persist-credentials: false
- name: Install default review skill
run: install -D -m 0644 harness/workloads/github-pr-reviewer/workflow/skills/pr-review/SKILL.md harness/skills/pr-review/SKILL.md
run: install -D -m 0644 harness/tasks/github-pr-reviewer/workflow/skills/pr-review/SKILL.md harness/skills/pr-review/SKILL.md
- name: Install caller skill
if: inputs.skill-path != ''
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/upstream-canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
openshell --help
- name: Run credential-free local lifecycle
run: |
CGO_ENABLED=0 go build -ldflags '-s -w -X main.version=upstream-canary' -o harness ./workflow
CGO_ENABLED=0 go build -ldflags '-s -w -X main.version=upstream-canary' -o harness ./runner
./test/test-flow.sh local-container --ci
env:
TEST_LOG_FILE: /tmp/test-logs/upstream-canary.log
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ reviewer.yaml
skills-lock.json

# Repository-owned workload documents are not scratch configs.
!workloads/**/harness.yaml
!tasks/**/harness.yaml

# Local audit working notes
docs/audit-*.md
Expand Down
2 changes: 1 addition & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ project_name: harness

builds:
- binary: harness
main: ./workflow
main: ./runner
env:
- CGO_ENABLED=0
goos:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ all: cli dev-sandbox

## Build the harness CLI binary
cli:
CGO_ENABLED=0 go build -ldflags '$(LDFLAGS)' -o harness ./workflow
CGO_ENABLED=0 go build -ldflags '$(LDFLAGS)' -o harness ./runner
@echo "Built: ./harness ($(VERSION))"

## Install/refresh the pinned OpenShell CLI + gateway (reads .openshell-version)
Expand Down
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ temporary workspace.

| Task bundle | Allowed GitHub operation | Integration status |
|---|---|---|
| [PR reviewer](workloads/github-pr-reviewer/) | Read the selected PR and post inline comments to it | Used by the reusable review workflow |
| [PR merger](workloads/github-pr-merger/) | Read the selected PR and head checks, then request a merge under a separate approval and credential contract | Opt-in bundle; consumer enablement and live validation are separate steps |
| [PR reviewer](tasks/github-pr-reviewer/) | Read the selected PR and post inline comments to it | Used by the reusable review workflow |
| [PR merger](tasks/github-pr-merger/) | Read the selected PR and head checks, then request a merge under a separate approval and credential contract | Opt-in bundle; consumer enablement and live validation are separate steps |

For review, trusted setup obtains a repository-scoped GitHub App installation
token with `Contents: read` and `Pull requests: write`. The
[OpenShell REST policy](workloads/github-pr-reviewer/openshell/policy.yaml)
[OpenShell REST policy](tasks/github-pr-reviewer/openshell/policy.yaml)
further restricts sandbox requests to the chosen PR's read endpoints and inline
comment `POST` endpoint. The agent uses `gh api`; OpenShell's network proxy
enforces the permitted host, HTTP methods, and paths.
Expand All @@ -47,7 +47,7 @@ and a failed or cancelled run may already have performed permitted actions.

`harness-openshell` packages the integration around OpenShell. The `harness`
CLI is its generic composition and sandbox lifecycle component. A **task
bundle**, called a workload in this repository, combines agent instructions,
bundle** combines agent instructions,
an image, native OpenShell policy, provider references, and payloads. A
**harness workflow document** declares a run; a **GitHub Actions workflow**
supplies its CI trigger and trusted host setup.
Expand Down Expand Up @@ -118,7 +118,7 @@ data. The `ai-review` label is explicit opt-in. See
| [Reusable workflow](.github/workflows/pr-review-reusable.yml) | Trusted checkout, job permissions, App token, and setup/execution steps |
| [`setup-openshell`](.github/actions/setup-openshell/action.yml) | Invoke the installer for the pinned OpenShell CLI release and wait for gateway readiness |
| [`scripts/pr-review.sh`](scripts/pr-review.sh) | Stage the diff, create a temporary workspace and providers, configure inference, render the PR policy, and invoke the CLI |
| [`harness` CLI](workflow/) | Compose the task and manage its sandbox lifecycle |
| [`harness` CLI](runner/) | Compose the task and manage its sandbox lifecycle |

The current reviewer uses a local gateway on the CI runner. The CLI's direct
managed-gateway connection is implemented, but the reusable reviewer has not
Expand Down Expand Up @@ -159,8 +159,8 @@ openshell gateway add https://127.0.0.1:17670 --local --name openshell
openshell gateway select openshell
```

Choose a task from [workloads/](workloads/) and prepare its documented inputs.
The [PR reviewer](workloads/github-pr-reviewer/) includes the native OpenShell
Choose a task from [tasks/](tasks/) and prepare its documented inputs.
The [PR reviewer](tasks/github-pr-reviewer/) includes the native OpenShell
inputs; [docs/ci.md](docs/ci.md#label-driven-pr-review) gives the trusted wrapper
commands for running it locally. For your own prepared workflow document:

Expand All @@ -183,11 +183,11 @@ agent, collects declared output files, and deletes the sandbox.
| Component | Owns |
|---|---|
| Consuming repository | Opt-in triggers, trusted task inputs, review criteria, and approval rules |
| [.github/workflows/](.github/workflows/) | Repository CI and reusable jobs with fixed permissions, trusted checkout, concurrency, and workload selection |
| [.github/workflows/](.github/workflows/) | Repository CI and reusable jobs with fixed permissions, trusted checkout, concurrency, and task selection |
| [.github/actions/setup-openshell/](.github/actions/setup-openshell/action.yml) | OpenShell installation and gateway readiness for the current local CI path |
| [scripts/pr-review.sh](scripts/pr-review.sh) | Trusted review preparation and temporary workspace/provider bootstrap |
| [workloads/](workloads/) | Task instructions, policy, provider references, image selection, payloads, and outputs |
| [workflow/](workflow/) | Generic `plan`/`apply` composition and sandbox lifecycle |
| [tasks/](tasks/) | Task instructions, policy, provider references, image selection, payloads, and outputs |
| [runner/](runner/) | Generic `plan`/`apply` composition and sandbox lifecycle |
| [images/](images/) | Reusable runtime toolchains |
| Platform administration | Managed gateway access, workspace membership, provider credential lifecycle, and inference configuration |
| OpenShell | Gateway resources, credential-backed proxies, inference routing, policy enforcement, and sandbox isolation |
Expand Down Expand Up @@ -231,7 +231,7 @@ and sandbox inspection.

## Documentation and validation

- [workflow/](workflow/) — implementation and lifecycle of the `harness` CLI
- [runner/](runner/) — implementation and lifecycle of the `harness` CLI
- [docs/workflow-format.md](docs/workflow-format.md) — version 1 workflow contract
- [docs/ci.md](docs/ci.md) — trusted CI setup and managed deployment requirements
- [docs/compatibility.md](docs/compatibility.md) — tested dependency versions
Expand Down
2 changes: 1 addition & 1 deletion docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ comments only; they do not approve, request changes, or merge.
The active reviewer runs OpenCode with Gemini 2.5 Pro through `inference.local`
and Google Vertex AI. The model is selected in
[`scripts/pr-review.sh`](../scripts/pr-review.sh) and
[`opencode-harness.yaml`](../workloads/github-pr-reviewer/workflow/opencode-harness.yaml).
[`opencode-harness.yaml`](../tasks/github-pr-reviewer/workflow/opencode-harness.yaml).
Keep those selections aligned and verify model access with the CI identity
when changing them.

Expand Down
6 changes: 3 additions & 3 deletions docs/workflow-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use Kubernetes-style `kind`, `apiVersion`, `metadata`, or `spec` wrappers.

This illustrates the schema. Supply a usable image, existing providers, and
the task's policy and payloads before applying it; see the
[task bundles](../workloads/) for concrete inputs.
[task bundles](../tasks/) for concrete inputs.

```yaml
version: 1
Expand Down Expand Up @@ -68,7 +68,7 @@ optional. Unknown fields are rejected so a typo cannot silently change a run.
Run a workflow with outputs by choosing an explicit host directory:

```bash
harness workflow apply workflow.yaml --output-dir ./workflow-artifacts
harness workflow apply workflow.yaml --output-dir ./runner-artifacts
```

Downloads happen before the sandbox cleanup step, including when the agent
Expand Down Expand Up @@ -109,6 +109,6 @@ bootstrap-owned route; isolated workspaces may use the compatibility write.

## Compatibility policy

The Go parser in `workflow/internal/config` is the executable source of truth. Parser,
The Go parser in `runner/internal/config` is the executable source of truth. Parser,
plan, apply, and redaction tests are the format contract. A future incompatible
shape increments `version` and fails clearly; there is no migration layer.
2 changes: 1 addition & 1 deletion images/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A task bundle selects an image, and the `harness` CLI passes that image referenc
to OpenShell when it creates the sandbox. Local and managed gateways use the
same contract. Add a separate image only when a task needs a materially
different system toolchain; otherwise reuse an existing image and keep
task-specific behavior in `workloads/`.
task-specific behavior in `tasks/`.

StackRox image profiles and build instructions are documented in
[`stackrox/README.md`](stackrox/README.md).
6 changes: 3 additions & 3 deletions workflow/README.md → runner/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Workflow runner
# Runner

This directory contains the Go implementation of the `harness` CLI, the small
composition and sandbox lifecycle component of `harness-openshell`. A harness
Expand Down Expand Up @@ -37,10 +37,10 @@ The repository keeps `go.mod` at its root so the runner, integration tests, and
repository tooling remain one Go module. Build the CLI with:

```bash
go build -o harness ./workflow
go build -o harness ./runner
```

Task bundles remain under `workloads/`; they are inputs to this runner, not
Task bundles remain under `tasks/`; they are inputs to this runner, not
Go packages. Repository-level integration tests remain under `test/` because
they exercise shell workflows and gateway lifecycle behavior rather than the
runner packages themselves.
Expand Down
2 changes: 1 addition & 1 deletion workflow/cmd/apply.go → runner/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"

"github.com/spf13/cobra"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
)

func NewApplyCmd(newClient openshell.Factory) *cobra.Command {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"os"
"time"

"github.com/stackrox/harness-openshell/workflow/internal/source"
"github.com/stackrox/harness-openshell/runner/internal/source"
)

// applyResult deliberately excludes configuration, raw errors, and agent output:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (

fake "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/fake"
"github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/types"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/workflow/internal/testutil"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/testutil"
)

type resultSDK struct {
Expand Down
10 changes: 5 additions & 5 deletions workflow/cmd/apply_service.go → runner/cmd/apply_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
"io"
"os"

"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/workflow/internal/plan"
"github.com/stackrox/harness-openshell/workflow/internal/reconcile"
"github.com/stackrox/harness-openshell/workflow/internal/run"
"github.com/stackrox/harness-openshell/workflow/internal/status"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/plan"
"github.com/stackrox/harness-openshell/runner/internal/reconcile"
"github.com/stackrox/harness-openshell/runner/internal/run"
"github.com/stackrox/harness-openshell/runner/internal/status"
)

type applyRequest struct {
Expand Down
4 changes: 2 additions & 2 deletions workflow/cmd/connect_plan.go → runner/cmd/connect_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"fmt"
"io"

"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/workflow/internal/plan"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/plan"
)

// connectAndBuildPlan uses the same target connection and offline fallback for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import (
"strings"
"testing"

"github.com/stackrox/harness-openshell/workflow/internal/config"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/workflow/internal/plan"
"github.com/stackrox/harness-openshell/workflow/internal/testutil"
"github.com/stackrox/harness-openshell/runner/internal/config"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/plan"
"github.com/stackrox/harness-openshell/runner/internal/testutil"
)

func TestConnectAndBuildPlanOfflineKeepsProvidersUninspected(t *testing.T) {
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion workflow/cmd/plan.go → runner/cmd/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"

"github.com/spf13/cobra"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
)

// NewPlanCmd constructs the "harness workflow plan" command.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"sort"
"strings"

"github.com/stackrox/harness-openshell/workflow/internal/config"
"github.com/stackrox/harness-openshell/workflow/internal/plan"
"github.com/stackrox/harness-openshell/runner/internal/config"
"github.com/stackrox/harness-openshell/runner/internal/plan"
)

// redactedPlan returns a display-only copy of p. Planning and reconciliation
Expand Down
6 changes: 3 additions & 3 deletions workflow/cmd/plan_test.go → runner/cmd/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (

fake "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/fake"
"github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/types"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/workflow/internal/plan"
"github.com/stackrox/harness-openshell/workflow/internal/testutil"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/plan"
"github.com/stackrox/harness-openshell/runner/internal/testutil"
)

// captureStdout runs fn and returns captured stdout.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"
"testing"

"github.com/stackrox/harness-openshell/workflow/internal/config"
"github.com/stackrox/harness-openshell/runner/internal/config"
)

func TestCanonicalRunRequestRejectsLocalImages(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion workflow/cmd/target.go → runner/cmd/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"fmt"

"github.com/spf13/cobra"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
)

// registerTargetFlags adds the standard --gateway/--workspace flags to cmd and
Expand Down
6 changes: 3 additions & 3 deletions workflow/cmd/workflow.go → runner/cmd/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"os"
"path/filepath"

"github.com/stackrox/harness-openshell/workflow/internal/config"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/workflow/internal/plan"
"github.com/stackrox/harness-openshell/runner/internal/config"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/plan"
)

// resolvedWorkflow is the single resolved input shared by plan and apply.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import (
"path/filepath"
"strings"

"github.com/stackrox/harness-openshell/workflow/internal/config"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/workflow/internal/plan"
"github.com/stackrox/harness-openshell/workflow/internal/run"
"github.com/stackrox/harness-openshell/workflow/internal/source"
"github.com/stackrox/harness-openshell/workflow/internal/status"
"github.com/stackrox/harness-openshell/runner/internal/config"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/plan"
"github.com/stackrox/harness-openshell/runner/internal/run"
"github.com/stackrox/harness-openshell/runner/internal/source"
"github.com/stackrox/harness-openshell/runner/internal/status"
"gopkg.in/yaml.v3"
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import (

fake "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/fake"
"github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/types"
"github.com/stackrox/harness-openshell/workflow/internal/config"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/workflow/internal/testutil"
"github.com/stackrox/harness-openshell/runner/internal/config"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/testutil"
)

func TestCanonicalWorkflowPlanAndApplyShareResolvedTarget(t *testing.T) {
Expand Down Expand Up @@ -700,7 +700,7 @@ func boolPtr(value bool) *bool { return &value }

func TestGitHubReviewerCustomSkillUsesWorkflowPayloadPath(t *testing.T) {
dir := t.TempDir()
exampleDir := filepath.Join("..", "..", "workloads", "github-pr-reviewer", "workflow")
exampleDir := filepath.Join("..", "..", "tasks", "github-pr-reviewer", "workflow")
workflowPath := filepath.Join(dir, "opencode-harness.yaml")
workflowBytes, err := os.ReadFile(filepath.Join(exampleDir, "opencode-harness.yaml"))
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package cmd

import (
"github.com/spf13/cobra"
"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
)

// NewWorkflowCmd groups the commands that operate on repository workflows.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
gw "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/gateway"
"github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/types"

"github.com/stackrox/harness-openshell/workflow/internal/openshell"
"github.com/stackrox/harness-openshell/runner/internal/openshell"
)

// connBranch represents the auth mode branch decision for connection setup.
Expand Down
Loading
Loading