Skip to content

feat(sandbox): adopt provider-backed policy composition - #2671

Merged
maruiz93 merged 14 commits into
fullsend-ai:mainfrom
maruiz93:776-policy-composition
Jul 8, 2026
Merged

feat(sandbox): adopt provider-backed policy composition#2671
maruiz93 merged 14 commits into
fullsend-ai:mainfrom
maruiz93:776-policy-composition

Conversation

@maruiz93

@maruiz93 maruiz93 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces duplicated network rules across harness policy files with composable provider profiles, using OpenShell's provider-backed policy composition (v0.0.37+).

  • 6 provider profiles define network access rules (GitHub read-write, GitHub read-only, Vertex AI, package registries, gitleaks, GitHub artifacts)
  • 6 provider definitions declare credentials and link to profiles
  • Harness files now declare which providers they need via a providers: field; policy files shrink to non-composable sandbox restrictions only (filesystem, landlock, process)
  • Single base.yaml replaces 6 per-agent policy files — network rules come from provider profiles at sandbox fetch time
  • ADR 0055 documents the decision and trade-offs (3 options evaluated)
  • User guide updated: providers as recommended approach, inline policies as alternative
  • fullsend run imports profiles, creates providers in parallel, enables providers_v2_enabled, and warns on undeclared providers

OpenShell CLI workarounds

  • openshell settings set now requires --key/--value flags + --yes
  • Profile import is not idempotent — delete-before-reimport pattern
  • Credential-less providers need unique _NOOP_<NAME>= dummy credentials (NVIDIA/OpenShell#1978)

Follow-up

  • #2672 — Provider and profile definitions cannot be resolved from URL-referenced base harnesses
  • NVIDIA/OpenShell#1978 — Credential-less provider support (removes NOOP workaround)

Closes #776

Test plan

  • Unit tests pass (make go-test)
  • Scaffold integration test updated for base.yaml
  • Smoke test: fullsend run triage against live repo with new provider composition
  • Internal code review (14 findings fixed, 6 dismissed)
  • Post-review smoke test passed

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown

E2E tests are running

Authorization passed for this commit. See the E2E Tests workflow for results.

@github-actions

Copy link
Copy Markdown

E2E tests did not run

E2E tests run automatically for org/repo members and collaborators on pull requests.

For other contributors, a maintainer must add the ok-to-test label after the latest push.

See E2E testing guide for details.

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown

Site preview

Preview: https://75b80ec0-site.fullsend-ai.workers.dev

Commit: 95fc2b15a31a59d44dae97087f95d70bc0ac95c3

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Adopt provider-backed network policy composition for scaffold sandboxes
✨ Enhancement 📝 Documentation 🧪 Tests 🕐 40+ Minutes

Grey Divider

Description

• Replace duplicated per-agent network policies with composable provider profiles.
• Teach fullsend run to enable providers v2, import profiles, and create providers in parallel.
• Collapse scaffold policies to a single base.yaml and document the new provider workflow.
Diagram

graph TD
  A["fullsend run"] --> B["Enable providers v2"] --> C["Import profiles/"] --> D["Load provider defs"] --> E["Ensure providers (parallel)"] --> F["Create sandbox (--provider)"] --> G[("OpenShell gateway")]
  C --> H["profiles/*.yaml"]
  D --> I["providers/*.yaml"]
  G --> J["Effective policy (base + _provider_*)"]

  subgraph Legend
    direction LR
    _cli["CLI step"] ~~~ _file["YAML file"] ~~~ _gw[("Gateway")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep monolithic per-agent inline network policies
  • ➕ No dependency on OpenShell >= 0.0.37 or providers_v2_enabled
  • ➕ All sandbox constraints visible in a single file per agent
  • ➖ High duplication across agents; endpoint changes require multi-file edits
  • ➖ Greater risk of drift between agents over time
2. Template/generate per-agent policy YAMLs from shared fragments
  • ➕ Single source of truth for endpoints while still producing standalone policy files
  • ➕ Avoids provider_v2 gateway setting and profile import steps
  • ➖ Introduces a build/generation step and new tooling surface area
  • ➖ Still ships expanded policies; composition benefits (isolation under provider*) are lost
3. Hybrid model (providers for common services + allow inline exceptions)
  • ➕ Supports one-off agent endpoints without creating new profiles
  • ➕ Can migrate incrementally from legacy policies
  • ➖ Two mechanisms for network access makes effective policy harder to reason about
  • ➖ Allows duplication to creep back in without strong conventions

Recommendation: The chosen approach (all shared network access via provider profiles, non-network constraints in a shared base policy) is the cleanest long-term maintenance model: one profile per service, uniform policy files, and fetch-time composition isolation. If future requirements demand per-agent GitHub read-only vs read-write, split profiles by access level (e.g., fullsend-github-ro/fullsend-github-rw) rather than reintroducing inline network blocks.

Files changed (31) +1687 / -71

Enhancement (2) +155 / -19
run.goEnable providers v2, import profiles, and parallelize provider creation +58/-7

Enable providers v2, import profiles, and parallelize provider creation

• When a harness declares providers, 'fullsend run' now enables 'providers_v2_enabled', imports profile YAMLs, then ensures providers concurrently. Provider definitions are filtered to only those declared, and the CLI warns if a harness declares a provider with no corresponding definition file.

internal/cli/run.go

sandbox.goAdd profile import + providers v2 enablement helpers and harden provider CLI calls +97/-12

Add profile import + providers v2 enablement helpers and harden provider CLI calls

• Adds 'EnableProvidersV2' and 'ImportProfiles' wrappers around OpenShell CLI, including delete-before-import for non-idempotent profile imports and updated settings flags. Hardens provider creation/update by adding timeouts, deterministic argument ordering, and support for empty/noop credentials via inline 'KEY=' (OpenShell workaround).

internal/sandbox/sandbox.go

Refactor (2) +29 / -3
harness.goFilter/validate provider defs and validate harness provider names +27/-3

Filter/validate provider defs and validate harness provider names

• Extends 'LoadProviderDefs' to optionally load only selected provider files (by stem) and adds validation for provider name/type characters. Harness validation now also validates entries in 'providers:' for allowed characters.

internal/harness/harness.go

scaffold.goRegister profiles/ and providers/ as layered scaffold directories +2/-0

Register profiles/ and providers/ as layered scaffold directories

• Adds 'profiles/' and 'providers/' to the scaffold layered directories so they are provided at runtime and not installed into '.fullsend' during scaffold installation.

internal/scaffold/scaffold.go

Tests (3) +38 / -16
scaffold_integration_test.goUpdate scaffold integration test for base policy +1/-1

Update scaffold integration test for base policy

• Adjusts expectations so the default triage harness references 'policies/base.yaml' instead of a per-agent policy file.

internal/harness/scaffold_integration_test.go

sandbox_test.goAdd tests for profile import and providers v2 enablement; adjust empty-credential behavior +24/-4

Add tests for profile import and providers v2 enablement; adjust empty-credential behavior

• Updates provider-arg tests to reflect inline 'KEY=' credentials behavior and adds coverage for the new 'ImportProfiles'/'EnableProvidersV2' error paths when 'openshell' is unavailable.

internal/sandbox/sandbox_test.go

scaffold_test.goUpdate scaffold tests for base policy and new layered/customized dirs +13/-11

Update scaffold tests for base policy and new layered/customized dirs

• Updates expected scaffold file set to include 'policies/base.yaml', verifies profiles/providers are treated as layered dirs, and ensures customized profiles/providers directories are installed via '.gitkeep' placeholders.

internal/scaffold/scaffold_test.go

Documentation (5) +1251 / -27
0055-provider-backed-policy-composition.mdAdd ADR documenting provider-backed policy composition decision +161/-0

Add ADR documenting provider-backed policy composition decision

• Introduces ADR 0055 describing the motivation (duplicated network rules), evaluated options, and the decision to standardize on provider-backed composition. Captures consequences like OpenShell version requirements and the single shared base policy approach.

docs/ADRs/0055-provider-backed-policy-composition.md

architecture.mdRecord composition decision in architecture overview +4/-0

Record composition decision in architecture overview

• Adds an explicit architecture decision note pointing to ADR 0055 and clarifying that network access is now provider-profile driven while policies focus on non-composable restrictions.

docs/architecture.md

building-custom-agents.mdUpdate custom agent guide to prefer providers for network access +48/-27

Update custom agent guide to prefer providers for network access

• Adds 'providers:' examples to harness config, explains providers vs inline 'network_policies', and updates host_file destination paths. Positions provider profiles as the recommended mechanism while keeping inline policies as a supported alternative.

docs/guides/user/building-custom-agents.md

2026-06-22-provider-backed-policy-composition.mdAdd detailed implementation plan for provider-backed composition +865/-0

Add detailed implementation plan for provider-backed composition

• Adds a task-by-task plan covering profiles/providers scaffolding, run-flow wiring, tests, and policy consolidation. Serves as execution guidance and traceability for the change set.

docs/superpowers/plans/2026-06-22-provider-backed-policy-composition.md

2026-06-17-provider-backed-policy-composition-design.mdAdd design spec describing profiles, run flow, and migration +173/-0

Add design spec describing profiles, run flow, and migration

• Defines the new profiles/providers directories, updates to the 'fullsend run' sequence (enable setting + import profiles), and the shift to a shared base policy. Documents OpenShell composition semantics and backward compatibility expectations.

docs/superpowers/specs/2026-06-17-provider-backed-policy-composition-design.md

Other (19) +214 / -6
.gitkeepAdd customized profiles directory placeholder +0/-0

Add customized profiles directory placeholder

• Creates a '.gitkeep' to ensure 'customized/profiles/' exists for user overrides without committing layered defaults.

internal/scaffold/fullsend-repo/customized/profiles/.gitkeep

.gitkeepAdd customized providers directory placeholder +0/-0

Add customized providers directory placeholder

• Creates a '.gitkeep' to ensure 'customized/providers/' exists for user overrides without committing layered defaults.

internal/scaffold/fullsend-repo/customized/providers/.gitkeep

code.yamlSwitch code harness to base policy and declare required providers +6/-1

Switch code harness to base policy and declare required providers

• Moves 'policy' to 'policies/base.yaml' and declares providers needed for code execution (vertex-ai, github, package-registries, gitleaks).

internal/scaffold/fullsend-repo/harness/code.yaml

fix.yamlSwitch fix harness to base policy and declare required providers +6/-1

Switch fix harness to base policy and declare required providers

• Moves 'policy' to 'policies/base.yaml' and declares providers needed for fix flows (vertex-ai, github, package-registries, gitleaks).

internal/scaffold/fullsend-repo/harness/fix.yaml

prioritize.yamlSwitch prioritize harness to base policy and declare required providers +4/-1

Switch prioritize harness to base policy and declare required providers

• Moves 'policy' to 'policies/base.yaml' and declares vertex-ai and github providers for prioritization workflows.

internal/scaffold/fullsend-repo/harness/prioritize.yaml

retro.yamlSwitch retro harness to base policy and declare artifacts provider +5/-1

Switch retro harness to base policy and declare artifacts provider

• Moves 'policy' to 'policies/base.yaml' and declares vertex-ai, github, and github-artifacts providers to support workflow artifact/log retrieval.

internal/scaffold/fullsend-repo/harness/retro.yaml

review.yamlSwitch review harness to base policy and declare required providers +4/-1

Switch review harness to base policy and declare required providers

• Moves 'policy' to 'policies/base.yaml' and declares vertex-ai and github providers for review workflows.

internal/scaffold/fullsend-repo/harness/review.yaml

triage.yamlSwitch triage harness to base policy and declare required providers +4/-1

Switch triage harness to base policy and declare required providers

• Moves 'policy' to 'policies/base.yaml' and declares vertex-ai and github providers for triage workflows.

internal/scaffold/fullsend-repo/harness/triage.yaml

base.yamlIntroduce shared base sandbox policy without network rules +19/-0

Introduce shared base sandbox policy without network rules

• Adds a single scaffold policy containing filesystem/landlock/process restrictions only. Network access is intentionally omitted and is expected to come from provider profile composition.

internal/scaffold/fullsend-repo/policies/base.yaml

fullsend-github-artifacts.yamlAdd GitHub artifacts provider profile +18/-0

Add GitHub artifacts provider profile

• Defines read-only endpoints needed for GitHub Actions artifact downloads, restricted to the 'gh' binary.

internal/scaffold/fullsend-repo/profiles/fullsend-github-artifacts.yaml

fullsend-github.yamlAdd GitHub provider profile +21/-0

Add GitHub provider profile

• Defines GitHub API and transport endpoints with read-write access and constrains usage to 'gh', 'git', 'node', and 'pre-commit'.

internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml

fullsend-gitleaks.yamlAdd gitleaks releases provider profile +23/-0

Add gitleaks releases provider profile

• Defines read-only GitHub release download endpoints used by 'pre-commit' to fetch gitleaks assets.

internal/scaffold/fullsend-repo/profiles/fullsend-gitleaks.yaml

fullsend-package-registries.yamlAdd package registries provider profile +55/-0

Add package registries provider profile

• Defines read-only endpoints for npm/yarn, PyPI, and Go module registries and constrains access to package manager/runtime binaries.

internal/scaffold/fullsend-repo/profiles/fullsend-package-registries.yaml

fullsend-vertex-ai.yamlAdd Vertex AI provider profile +19/-0

Add Vertex AI provider profile

• Defines Anthropic and Google APIs endpoints with read-write access, restricted to 'claude' and 'node' binaries for model/inference use.

internal/scaffold/fullsend-repo/profiles/fullsend-vertex-ai.yaml

github-artifacts.yamlAdd github-artifacts provider definition with noop credential +6/-0

Add github-artifacts provider definition with noop credential

• Defines a provider instance mapping to the 'fullsend-github-artifacts' profile type and includes a noop credential key to satisfy OpenShell constraints.

internal/scaffold/fullsend-repo/providers/github-artifacts.yaml

github.yamlAdd github provider definition with noop credential +6/-0

Add github provider definition with noop credential

• Defines a provider instance mapping to the 'fullsend-github' profile type and includes a noop credential key to satisfy OpenShell constraints.

internal/scaffold/fullsend-repo/providers/github.yaml

gitleaks.yamlAdd gitleaks provider definition with noop credential +6/-0

Add gitleaks provider definition with noop credential

• Defines a provider instance mapping to the 'fullsend-gitleaks' profile type and includes a noop credential key to satisfy OpenShell constraints.

internal/scaffold/fullsend-repo/providers/gitleaks.yaml

package-registries.yamlAdd package-registries provider definition with noop credential +6/-0

Add package-registries provider definition with noop credential

• Defines a provider instance mapping to the 'fullsend-package-registries' profile type and includes a noop credential key to satisfy OpenShell constraints.

internal/scaffold/fullsend-repo/providers/package-registries.yaml

vertex-ai.yamlAdd vertex-ai provider definition with noop credential +6/-0

Add vertex-ai provider definition with noop credential

• Defines a provider instance mapping to the 'fullsend-vertex-ai' profile type and includes a noop credential key to satisfy OpenShell constraints.

internal/scaffold/fullsend-repo/providers/vertex-ai.yaml

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 25, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 4:19 PM UTC · Ended 4:21 PM UTC
Commit: 2d8adb7 · View workflow run →

@qodo-code-review

qodo-code-review Bot commented Jun 25, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 58 rules

Grey Divider


Action required

1. fullsend-github grants write access ✓ Resolved 📎 Requirement gap ⛨ Security
Description
The scaffold uses a single fullsend-github profile with access: read-write even though the plan
states some harnesses (review/retro) require read-only GitHub access. This violates the requirement
to model differing access levels as separate provider profiles and risks over-privileging read-only
agents.
Code

internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml[R6-16]

+endpoints:
+  - host: api.github.com
+    port: 443
+    protocol: rest
+    access: read-write
+    enforcement: enforce
+  - host: github.com
+    port: 443
+    protocol: rest
+    access: read-write
+    enforcement: enforce
Relevance

⭐⭐ Medium

Least-privilege changes often accepted, but ADR/design explicitly accepts GitHub RW superset and
defers splitting profiles.

PR-#657
PR-#286

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance rule requires separate profiles when different access levels are needed. The
implementation creates fullsend-github with access: read-write, while the plan explicitly notes
that review/retro currently use read-only access; the review and retro harnesses still declare the
github provider, inheriting the read-write profile.

Create separate provider profiles for differing access levels to the same service
docs/superpowers/plans/2026-06-22-provider-backed-policy-composition.md[53-57]
internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml[6-16]
internal/scaffold/fullsend-repo/harness/review.yaml[6-10]
internal/scaffold/fullsend-repo/harness/retro.yaml[6-11]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A single provider profile `fullsend-github` is used for GitHub access and grants `read-write` access, even though some harnesses are intended to be read-only.

## Issue Context
Provider-backed policy composition is additive-only, so you cannot safely “narrow” an over-broad provider grant in the harness/policy; differing access levels must be modeled as distinct profiles/providers.

## Fix Focus Areas
- internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml[1-21]
- internal/scaffold/fullsend-repo/providers/github.yaml[1-6]
- internal/scaffold/fullsend-repo/harness/review.yaml[6-10]
- internal/scaffold/fullsend-repo/harness/retro.yaml[6-11]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Exec errors hidden ✓ Resolved 🐞 Bug ◔ Observability
Description
ImportProfiles and EnableProvidersV2 discard the underlying exec error and only report
CombinedOutput, which is often empty for failures like missing openshell or context timeouts.
This produces opaque messages (e.g., "failed to enable providers_v2:") and makes sandbox setup
failures difficult to debug.
Code

internal/sandbox/sandbox.go[R279-294]

+	out, err := exec.CommandContext(ctx, "openshell", "provider", "profile", "import", "--from", dir).CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("provider profile import from %s failed: %s", dir, strings.TrimSpace(string(out)))
+	}
+	return nil
+}
+
+// EnableProvidersV2 enables the providers_v2_enabled setting globally in the
+// openshell gateway. This is idempotent and can be called multiple times.
+func EnableProvidersV2() error {
+	ctx, cancel := context.WithTimeout(context.Background(), providerTimeout)
+	defer cancel()
+	out, err := exec.CommandContext(ctx, "openshell", "settings", "set", "--key", "providers_v2_enabled", "--value", "true", "--global", "--yes").CombinedOutput()
+	if err != nil {
+		return fmt.Errorf("failed to enable providers_v2: %s", strings.TrimSpace(string(out)))
+	}
Relevance

⭐⭐⭐ High

Sandbox exec/debuggability fixes commonly accepted; include underlying exec error aligns with prior
observability improvements.

PR-#761
PR-#2323

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Both functions build errors exclusively from command output and drop err, even though
CombinedOutput surfaces important failures through err (binary missing, context deadline
exceeded, non-zero exit).

internal/sandbox/sandbox.go[244-296]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`ImportProfiles` / `EnableProvidersV2` return errors that omit the underlying `err` from `exec.CommandContext(...).CombinedOutput()`. When the command cannot start or times out, stdout/stderr is frequently empty, so users get near-empty error messages.

### Issue Context
These functions are called from `fullsend run` during sandbox setup; clear errors are critical for diagnosing environment/setup problems.

### Fix Focus Areas
- internal/sandbox/sandbox.go[244-296]

### Suggested fix
- Include the underlying error using `%w` and keep output as additional context.
 - Example pattern:
   - `return fmt.Errorf("provider profile import from %s failed: %w (output: %s)", dir, err, strings.TrimSpace(string(out)))`
   - `return fmt.Errorf("failed to enable providers_v2: %w (output: %s)", err, strings.TrimSpace(string(out)))`
- (Optional) For better UX, if `strings.TrimSpace(string(out)) == ""`, still return a message that clearly indicates the command invocation failed (and rely on `%w` for the details).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Provider file stem filtering ✓ Resolved 🐞 Bug ≡ Correctness
Description
LoadProviderDefs filters provider YAMLs by filename stem (before parsing) rather than by the
provider name field, so a valid provider definition can be skipped if its filename doesn’t match
the harness provider name. runAgent then only warns and proceeds to sandbox creation with the
declared providers, increasing the chance of a confusing later failure instead of a clear
“definition not found” error.
Code

internal/harness/harness.go[R76-81]

+		if filter != nil {
+			stem := strings.TrimSuffix(strings.TrimSuffix(e.Name(), ".yaml"), ".yml")
+			if _, ok := filter[stem]; !ok {
+				continue
+			}
+		}
Relevance

⭐⭐ Medium

No close precedent on filename-stem provider filtering; team does accept stricter harness validation
patterns (role required).

PR-#2446

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The loader skips files solely based on filename stem membership in the declared-provider set, and
runAgent continues even when a declared provider wasn’t created, then creates the sandbox using
the full provider list.

internal/harness/harness.go[54-104]
internal/cli/run.go[500-594]
internal/sandbox/sandbox.go[361-388]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`LoadProviderDefs` applies its `only` filter based on the YAML filename stem, not the parsed `ProviderDef.Name`. This introduces a brittle coupling: the file basename must match the harness provider name, otherwise the definition is never loaded.

### Issue Context
`runAgent` passes the set of harness-declared provider names into `LoadProviderDefs`, then later warns if a declared provider wasn’t created but still passes the full `h.Providers` list into `sandbox.CreateWithRetry`.

### Fix Focus Areas
- internal/harness/harness.go[54-104]
- internal/cli/run.go[500-594]

### Suggested fix
- Change `LoadProviderDefs` to parse each YAML first, then apply the `only` filter using `def.Name` (not the filename).
 - This preserves the optimization intent (skip creating providers not declared) without introducing filename/name coupling.
- (Optional but recommended) If you want to keep the convention, explicitly validate `stem == def.Name` and return a clear error when they differ, rather than silently skipping/ignoring.
- Consider upgrading the warning in `runAgent` to a hard error when a declared provider has no definition *and* does not already exist on the gateway (to fail early with a clear message), if that matches intended behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml
@maruiz93
maruiz93 force-pushed the 776-policy-composition branch from 96bc82c to 2d17fc7 Compare June 25, 2026 16:23
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 25, 2026

Copy link
Copy Markdown

🤖 Finished Review · ❌ Failure · Started 4:26 PM UTC · Completed 4:40 PM UTC
Commit: 2d17fc7 · View workflow run →

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 48.68421% with 78 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/cli/run.go 0.00% 44 Missing ⚠️
internal/sandbox/sandbox.go 77.65% 13 Missing and 8 partials ⚠️
internal/harness/harness.go 7.14% 12 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review

Well-structured migration from duplicated per-agent network policies to composable provider profiles. The implementation is correct: parallel provider creation with proper synchronization, hash-based idempotent profile import, input validation on provider names and types, and comprehensive test coverage. ADR 0065 accurately documents the decision and trade-offs, and all current user-facing documentation has been updated.

Findings

Low

  • [privilege-escalation] internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml — Triage and prioritize agents now use the github provider (fullsend-github profile) which includes **/pre-commit and **/git in its binary allowlist. Previously these agents only had **/gh and **/node. Practical risk is low — these agents run in the sandbox image without pre-commit workflows — but this widens the theoretical attack surface.
    Remediation: Consider a reduced-binary GitHub profile for triage/prioritize in a follow-up.

  • [race-condition] internal/sandbox/sandbox.goImportProfiles deletes existing profiles before reimporting, creating a narrow window where the gateway has no profiles if two processes race with stale caches. Mitigated by hash-based caching (reimport only on change) and the already exists fallback.
    Remediation: Consider an import-first strategy in a follow-up.

  • [stale-policy-references] docs/ADRs/0038-universal-harness-access.md, docs/ADRs/0045-forge-portable-harness-schema.md — Historical ADRs and implementation plans reference removed policy files (policies/code.yaml, policies/triage.yaml). These are accurate for their era but may confuse readers post-migration.
    Remediation: Consider adding footnotes noting that ADR 0065 supersedes the policy model shown.

Previous run

Review

Findings

Low

  • [privilege-escalation] internal/scaffold/fullsend-repo/harness/triage.yaml — Triage and prioritize agents now use the github provider (fullsend-github profile) which includes **/pre-commit and **/git in its binary allowlist. Previously these agents only had **/gh and **/node. Practical risk is low — these agents run in the sandbox image without pre-commit workflows — but this widens the theoretical attack surface.
    Remediation: Consider a reduced-binary GitHub profile for triage/prioritize in a follow-up.

  • [race-condition] internal/sandbox/sandbox.goImportProfiles deletes existing profiles before reimporting, creating a narrow window where the gateway has no profiles if two processes race with stale caches. Mitigated by hash-based caching (reimport only on change) and the already exists fallback.
    Remediation: Consider an import-first strategy in a follow-up.

  • [stale-policy-references] docs/ADRs/0038-universal-harness-access.md, docs/ADRs/0045-forge-portable-harness-schema.md — Historical ADRs and implementation plans reference removed policy files (policies/code.yaml, policies/triage.yaml). These are accurate for their era but may confuse readers post-migration.
    Remediation: Consider adding footnotes noting that ADR 0065 supersedes the policy model shown.

Previous run

Review

Findings

Low

  • [privilege-escalation] internal/scaffold/fullsend-repo/harness/triage.yaml — Triage and prioritize agents now use the github provider (fullsend-github profile) which includes **/pre-commit and **/git in its binary allowlist. Previously these agents only had **/gh and **/node. Practical risk is low — these agents run in the sandbox image without pre-commit workflows — but this widens the theoretical attack surface.
    Remediation: Consider a reduced-binary GitHub profile for triage/prioritize in a follow-up.

  • [race-condition] internal/sandbox/sandbox.goImportProfiles deletes existing profiles before reimporting, creating a narrow window where the gateway has no profiles if two processes race with stale caches. Mitigated by hash-based caching (reimport only on change) and the already exists fallback.
    Remediation: Consider an import-first strategy in a follow-up.

  • [stale-policy-references] docs/ADRs/0038-universal-harness-access.md, docs/ADRs/0045-forge-portable-harness-schema.md — Historical ADRs and implementation plans reference removed policy files (policies/code.yaml, policies/triage.yaml). These are accurate for their era but may confuse readers post-migration.
    Remediation: Consider adding footnotes noting that ADR 0065 supersedes the policy model shown.

Previous run (2)

Review

Findings

Medium

  • [internal-consistency] docs/ADRs/0065-provider-backed-policy-composition.md:19 — The H1 heading reads # 55. Provider-backed policy composition but the frontmatter title is 65. Provider-backed policy composition and the filename is 0065-.... This is a copy-paste error that creates a contradiction within the document.
    Remediation: Change line 19 from # 55. to # 65.
Previous run (3)

Review

Findings

Medium

  • [privilege-escalation] internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml:21 — The fullsend-github profile includes **/pre-commit in its binaries list. Triage and prioritize harnesses declare the github provider, which maps to this profile. Under the previous per-agent policy model, only code and fix agents had pre-commit binary access for GitHub endpoints (triage and prioritize had only **/gh and **/node). Now triage and prioritize agents inherit pre-commit access through the shared fullsend-github provider, widening their effective sandbox capabilities. A fullsend-github-ro profile already exists without pre-commit for review/retro, suggesting awareness of per-role binary scoping — but no analogous reduced-binary profile exists for triage/prioritize.
    Remediation: Create a fullsend-github-no-precommit profile (or similar) for triage and prioritize agents that includes **/gh, **/git, and **/node but omits **/pre-commit, or split the github provider into github-rw (with pre-commit, for code/fix) and github (without, for triage/prioritize).

Previous stale-policy-reference findings (docs/ADRs/0038, docs/plans/universal-harness-access.md, docs/plans/universal-harness-access-phase2.md) remain present but are downgraded — these are historical/plan documents not modified by this PR, and their references to policies/code.yaml are accurate for the era they describe.

Previous run (4)

Review

Findings

Medium

  • [privilege-escalation] internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml:20 — The fullsend-github profile includes **/pre-commit in its binaries list. Under the previous per-agent policy model, only code and fix agents had pre-commit binary access. Now triage and prioritize agents inherit pre-commit access through the shared fullsend-github provider. The pre-commit binary can clone arbitrary hook repos and pip-install hook dependencies, widening the attack surface for agents that previously lacked this capability.
    Remediation: Create a separate profile without pre-commit for triage and prioritize agents, or switch them to fullsend-github-ro (which lacks pre-commit).

  • [concurrency-error-handling] internal/cli/run.go — Provider creation uses parallel goroutines with WaitGroup + Mutex-protected slice + errors.Join() for error aggregation. While correct and race-free, this pattern differs from the errgroup pattern used elsewhere in the codebase for concurrent work with error collection.
    Remediation: Consider using errgroup.Group for consistency with existing concurrency patterns.

  • [stale-policy-reference] docs/ADRs/0038-universal-harness-access.md:31 — References removed policy file policies/code.yaml in harness YAML example snippets.
    Remediation: Update the example harness YAML to reference policies/base.yaml, or add a note that the example reflects the pre-composition era.

  • [stale-policy-reference] docs/plans/universal-harness-access.md:31 — References removed policy file policies/code.yaml in example harness configurations.
    Remediation: Update example harness YAML snippets to use policies/base.yaml.

  • [stale-policy-reference] docs/plans/universal-harness-access-phase2.md:332 — References removed policy file policies/code.yaml in an example harness configuration.
    Remediation: Update the example to reference policies/base.yaml.


Previous findings from the prior review (command-injection in sandbox.go, cross-ADR coherence gap) have been addressed or downgraded — credential/config key validation is mitigated by exec.Command argv isolation and trusted repo content, and the coherence gap is explicitly documented as deferred to #2672 in ADR 0055.

Previous run (5)

Review

Findings

Medium

  • [privilege-escalation] internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml:20 — The fullsend-github profile includes **/pre-commit in its binaries list. Under the previous per-agent policy model, only code and fix agents had pre-commit binary access. Now triage and prioritize agents inherit pre-commit access through the shared fullsend-github provider. The pre-commit binary can clone arbitrary hook repos and pip-install hook dependencies, widening the attack surface for agents that previously lacked this capability.
    Remediation: Create a separate profile without pre-commit for triage and prioritize agents, or switch them to fullsend-github-ro (which lacks pre-commit).

  • [concurrency-error-handling] internal/cli/run.go — Provider creation uses parallel goroutines with WaitGroup + Mutex-protected slice + errors.Join() for error aggregation. While correct and race-free, this pattern differs from the errgroup pattern used elsewhere in the codebase for concurrent work with error collection.
    Remediation: Consider using errgroup.Group for consistency with existing concurrency patterns.

  • [stale-policy-reference] docs/ADRs/0038-universal-harness-access.md:31 — References removed policy file policies/code.yaml in harness YAML example snippets.
    Remediation: Update the example harness YAML to reference policies/base.yaml, or add a note that the example reflects the pre-composition era.

  • [stale-policy-reference] docs/plans/universal-harness-access.md:31 — References removed policy file policies/code.yaml in example harness configurations.
    Remediation: Update example harness YAML snippets to use policies/base.yaml.

  • [stale-policy-reference] docs/plans/universal-harness-access-phase2.md:332 — References removed policy file policies/code.yaml in an example harness configuration.
    Remediation: Update the example to reference policies/base.yaml.


Previous findings from the prior review (command-injection in sandbox.go, cross-ADR coherence gap) have been addressed or downgraded — credential/config key validation is mitigated by exec.Command argv isolation and trusted repo content, and the coherence gap is explicitly documented as deferred to #2672 in ADR 0055.

Previous run (6)

Review

Findings

Medium

  • [command-injection] internal/sandbox/sandbox.go — Credential and config map keys from provider YAML files are passed directly into CLI arguments (--credential KEY, --config KEY=VALUE) without validation. The PR adds validProviderName regex checks for name and type fields in LoadProviderDefs but does not validate credential or config keys. While exec.Command prevents OS-level shell injection, openshell-level argument injection remains possible — a crafted key like --name could be interpreted as a flag by openshell's argument parser. Risk is mitigated by provider YAML files being author-controlled scaffold content.
    Remediation: Add a regex validation check (e.g., ^[a-zA-Z_][a-zA-Z0-9_]*$) for credential and config map keys in LoadProviderDefs before they reach buildProviderArgs.

  • [privilege-escalation] internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml — The fullsend-github profile includes **/pre-commit in its binaries list. Previously, only code and fix agents had pre-commit in their GitHub network policy binaries. The triage and prioritize agents now inherit this binary allowlist because they use the github provider (linked to fullsend-github profile). This is a minor expansion of their effective sandbox capabilities beyond what the previous per-agent policies granted.
    Remediation: Consider whether triage and prioritize agents need pre-commit binary access. If not, create a variant profile without pre-commit to maintain least-privilege.

  • [stale-policy-reference] docs/ADRs/0038-universal-harness-access.md:31 — References removed policy file policies/code.yaml in harness YAML example snippets. The per-agent policy files were removed in favor of policies/base.yaml with provider-backed composition.
    Remediation: Update the example harness YAML to reference policies/base.yaml, or add a note that the example reflects the pre-composition era.

  • [stale-policy-reference] docs/plans/universal-harness-access-phase2.md:332 — References removed policy file policies/code.yaml in an example harness configuration.
    Remediation: Update the example to reference policies/base.yaml.

  • [stale-policy-reference] docs/plans/universal-harness-access.md:31 — References removed policy file policies/code.yaml in multiple example harness configurations.
    Remediation: Update example harness YAML snippets to use policies/base.yaml.


Previous findings from the prior review (concurrent error handling in run.go, cross-ADR coherence gap) have both been addressed — errors are now collected with errors.Join, and the design gap is documented with tracking issue #2672.

Previous run

Review

Findings

Medium

  • [error-handling] internal/cli/run.go:530 — When concurrent EnsureProvider goroutines run, only the first error is captured via the mutex-guarded firstErr. If multiple providers fail simultaneously, diagnostic information from subsequent failures is silently dropped. Each goroutine calls printer.StepFail so the user sees that multiple providers failed, but the returned error only contains details for one.
    Remediation: Collect all errors (e.g., append to a []error under the mutex) and combine with errors.Join before returning.

  • [cross-adr-coherence] docs/ADRs/0055-provider-backed-policy-composition.md:39 — ADR 0055 acknowledges that URL-based resolution for remote base harnesses is not addressed. The current implementation resolves provider/profile definitions from local directories only, creating a design gap with ADR 0038 (universal harness access) and ADR 0045 (forge-portable harness schema). This is explicitly documented as a known limitation with tracking issue #2672.


Previous findings from the prior review (stale references in architecture.md, customizing-agents.md, and ADR profile count inconsistency) have all been addressed in this revision.


Labels: PR modifies Go sandbox/harness code alongside policy composition changes and documentation.

Previous run (7)

Review

Findings

Medium

  • [stale-reference] docs/architecture.md:566 — The ASCII-art diagram shows policy: policies/code.yaml which is deleted in this PR. The PR adds new content to this file (provider-backed composition note at line 73) but does not update the diagram.
    Remediation: Update the diagram to show policy: policies/base.yaml and add a providers: field.

  • [stale-reference] docs/guides/user/customizing-agents.md:17 — Example harness configuration at line 17 references policy: policies/code.yaml which no longer exists. A second reference exists at line 256. The PR does not modify this file.
    Remediation: Update both examples to use policy: policies/base.yaml and add a providers: block.

  • [internal-inconsistency] docs/ADRs/0055-provider-backed-policy-composition.md:127 — The ADR states "Five custom profiles ship with the scaffold" and lists 5 in the table, but the PR actually ships 6 profile YAMLs. The fullsend-github-ro profile is omitted from the table. Additionally, line 166 says "If per-agent access differentiation is needed later, split into separate profiles" but that split already exists in this PR (fullsend-github for read-write, fullsend-github-ro for read-only).
    Remediation: Add fullsend-github-ro to the profile table (updating the count to six), and revise the sentence at line 166 since the split is already implemented.


Labels: PR modifies sandbox policy composition, harness provider wiring, and user-facing documentation.


Labels: PR modifies sandbox policy composition, harness provider declarations, and user-facing documentation (ADR, architecture, user guide).

Previous run (8)

Review

Findings

Medium

  • [privilege escalation via shared profile] internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml:10 — The shared fullsend-github profile grants access: read-write to api.github.com and github.com for all agents that declare the github provider. Previously, the review and retro agents had access: read-only for GitHub endpoints (enforced by their per-agent policy files). After this change, both agents receive read-write access because all agents share the same profile. The ADR acknowledges this tradeoff ("Single profile per service means all agents get the broadest access level") but defers mitigation.
    Remediation: Create separate fullsend-github-ro and fullsend-github-rw profiles. Assign fullsend-github-ro to review and retro agents.

  • [stale-reference] docs/architecture.md:566 — The ASCII-art diagram shows policy: policies/code.yaml which is deleted in this PR. The PR adds new content to this file (provider-backed composition note at line 73) but does not update the diagram.
    Remediation: Update the diagram to show policy: policies/base.yaml and add providers.

  • [stale-reference] docs/guides/user/customizing-agents.md:17 — Example harness configuration at line 17 references policy: policies/code.yaml which no longer exists. A second reference exists at line 256. The PR does not modify this file.
    Remediation: Update both YAML code examples to use policy: policies/base.yaml and add a providers: section.


Labels: PR modifies sandbox policy composition and harness provider wiring.

Previous run (9)

Review

Findings

Medium

  • [command-injection] internal/sandbox/sandbox.go — Credential and config map keys from provider YAML files are passed directly into CLI arguments (--credential KEY, --config KEY=VALUE) without validation. The PR adds validProviderName regex checks for name and type fields in LoadProviderDefs but does not validate credential or config keys. While exec.Command prevents OS-level shell injection, openshell-level argument injection remains possible — a crafted key like --name could be interpreted as a flag by openshell's argument parser. Risk is mitigated by provider YAML files being author-controlled scaffold content.
    Remediation: Add a regex validation check (e.g., ^[a-zA-Z_][a-zA-Z0-9_]*$) for credential and config map keys in LoadProviderDefs before they reach buildProviderArgs.

  • [privilege-escalation] internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml — The fullsend-github profile includes **/pre-commit in its binaries list. Previously, only code and fix agents had pre-commit in their GitHub network policy binaries. The triage and prioritize agents now inherit this binary allowlist because they use the github provider (linked to fullsend-github profile). This is a minor expansion of their effective sandbox capabilities beyond what the previous per-agent policies granted.
    Remediation: Consider whether triage and prioritize agents need pre-commit binary access. If not, create a variant profile without pre-commit to maintain least-privilege.

  • [stale-policy-reference] docs/ADRs/0038-universal-harness-access.md:31 — References removed policy file policies/code.yaml in harness YAML example snippets. The per-agent policy files were removed in favor of policies/base.yaml with provider-backed composition.
    Remediation: Update the example harness YAML to reference policies/base.yaml, or add a note that the example reflects the pre-composition era.

  • [stale-policy-reference] docs/plans/universal-harness-access-phase2.md:332 — References removed policy file policies/code.yaml in an example harness configuration.
    Remediation: Update the example to reference policies/base.yaml.

  • [stale-policy-reference] docs/plans/universal-harness-access.md:31 — References removed policy file policies/code.yaml in multiple example harness configurations.
    Remediation: Update example harness YAML snippets to use policies/base.yaml.


Previous findings from the prior review (concurrent error handling in run.go, cross-ADR coherence gap) have both been addressed — errors are now collected with errors.Join, and the design gap is documented with tracking issue #2672.

Previous run (10)

Review

Findings

Medium

  • [error-handling] internal/cli/run.go:530 — When concurrent EnsureProvider goroutines run, only the first error is captured via the mutex-guarded firstErr. If multiple providers fail simultaneously, diagnostic information from subsequent failures is silently dropped. Each goroutine calls printer.StepFail so the user sees that multiple providers failed, but the returned error only contains details for one.
    Remediation: Collect all errors (e.g., append to a []error under the mutex) and combine with errors.Join before returning.

  • [cross-adr-coherence] docs/ADRs/0055-provider-backed-policy-composition.md:39 — ADR 0055 acknowledges that URL-based resolution for remote base harnesses is not addressed. The current implementation resolves provider/profile definitions from local directories only, creating a design gap with ADR 0038 (universal harness access) and ADR 0045 (forge-portable harness schema). This is explicitly documented as a known limitation with tracking issue #2672.


Previous findings from the prior review (stale references in architecture.md, customizing-agents.md, and ADR profile count inconsistency) have all been addressed in this revision.


Labels: PR modifies Go sandbox/harness code alongside policy composition changes and documentation.

Previous run (11)

Review

Findings

Medium

  • [stale-reference] docs/architecture.md:566 — The ASCII-art diagram shows policy: policies/code.yaml which is deleted in this PR. The PR adds new content to this file (provider-backed composition note at line 73) but does not update the diagram.
    Remediation: Update the diagram to show policy: policies/base.yaml and add a providers: field.

  • [stale-reference] docs/guides/user/customizing-agents.md:17 — Example harness configuration at line 17 references policy: policies/code.yaml which no longer exists. A second reference exists at line 256. The PR does not modify this file.
    Remediation: Update both examples to use policy: policies/base.yaml and add a providers: block.

  • [internal-inconsistency] docs/ADRs/0055-provider-backed-policy-composition.md:127 — The ADR states "Five custom profiles ship with the scaffold" and lists 5 in the table, but the PR actually ships 6 profile YAMLs. The fullsend-github-ro profile is omitted from the table. Additionally, line 166 says "If per-agent access differentiation is needed later, split into separate profiles" but that split already exists in this PR (fullsend-github for read-write, fullsend-github-ro for read-only).
    Remediation: Add fullsend-github-ro to the profile table (updating the count to six), and revise the sentence at line 166 since the split is already implemented.


Labels: PR modifies sandbox policy composition, harness provider wiring, and user-facing documentation.


Labels: PR modifies sandbox policy composition, harness provider declarations, and user-facing documentation (ADR, architecture, user guide).

Previous run (12)

Review

Findings

Medium

  • [privilege escalation via shared profile] internal/scaffold/fullsend-repo/profiles/fullsend-github.yaml:10 — The shared fullsend-github profile grants access: read-write to api.github.com and github.com for all agents that declare the github provider. Previously, the review and retro agents had access: read-only for GitHub endpoints (enforced by their per-agent policy files). After this change, both agents receive read-write access because all agents share the same profile. The ADR acknowledges this tradeoff ("Single profile per service means all agents get the broadest access level") but defers mitigation.
    Remediation: Create separate fullsend-github-ro and fullsend-github-rw profiles. Assign fullsend-github-ro to review and retro agents.

  • [stale-reference] docs/architecture.md:566 — The ASCII-art diagram shows policy: policies/code.yaml which is deleted in this PR. The PR adds new content to this file (provider-backed composition note at line 73) but does not update the diagram.
    Remediation: Update the diagram to show policy: policies/base.yaml and add providers.

  • [stale-reference] docs/guides/user/customizing-agents.md:17 — Example harness configuration at line 17 references policy: policies/code.yaml which no longer exists. A second reference exists at line 256. The PR does not modify this file.
    Remediation: Update both YAML code examples to use policy: policies/base.yaml and add a providers: section.


Labels: PR modifies sandbox policy composition and harness provider wiring.

Comment thread docs/ADRs/0065-provider-backed-policy-composition.md
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 25, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 5:01 PM UTC · Ended 5:09 PM UTC
Commit: 2d8adb7 · View workflow run →

@maruiz93
maruiz93 force-pushed the 776-policy-composition branch from 03a77ac to 7812426 Compare June 25, 2026 17:08
@maruiz93

Copy link
Copy Markdown
Contributor Author

Addressed all three Qodo findings:

  1. fullsend-github grants write access — Split into fullsend-github (read-write) and fullsend-github-ro (read-only) profiles. Review and retro harnesses now use github-ro provider, matching original per-agent policy access levels.

  2. Exec errors hidden — All four exec error sites (EnsureProvider, updateProvider, ImportProfiles, EnableProvidersV2) now include the underlying err via %w alongside command output.

  3. Provider file stem filtering — Added validation that def.Name must match the filename stem. Mismatches now produce a clear error instead of silent skipping.

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 25, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:14 PM UTC · Completed 5:30 PM UTC
Commit: 6de4719 · View workflow run →

@fullsend-ai-review fullsend-ai-review Bot added requires-manual-review Review requires human judgment component/sandbox OpenShell sandbox environment component/harness Agent harness, config, and skills loading component/docs User-facing documentation labels Jun 25, 2026
@maruiz93
maruiz93 added this pull request to the merge queue Jul 8, 2026
Merged via the queue into fullsend-ai:main with commit fd2cfc7 Jul 8, 2026
16 of 18 checks passed
@maruiz93
maruiz93 deleted the 776-policy-composition branch July 8, 2026 09:33
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jul 8, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 9:35 AM UTC · Completed 9:43 AM UTC
Commit: 95fc2b1 · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

PR #2671 migrated duplicated per-agent network policies to composable provider profiles — a large, well-structured change (858 additions, 562 deletions, 38 files) by a human author using Claude Code. Two human reviewers approved after substantive discussion. The fullsend review agent ran 17 times (7 cancelled, 1 failed, 8 successful). Qodo caught the critical RW/RO profile split first. Human reviewers caught things agents missed: an errors.Join improvement for concurrent error aggregation, and cross-document naming confusion. The review agent's privilege-escalation finding about triage/prioritize agents gaining extra binary access was noted but merged without being addressed or tracked. Three proposals filed: (1) track the triage/prioritize privilege escalation follow-up, (2) add AGENTS.md guidance on Go concurrent error aggregation, (3) evidence for #1331 on review run waste.

Proposals filed

ralphbean added a commit that referenced this pull request Jul 8, 2026
- Remove Ship of Theseus reference (too obscure without explanation)
- Remove explicit agent list from intro (will go stale)
- Broaden "the rule" to acknowledge general-purpose harness fields
  alongside documented extension points, resolving the inconsistency
  between the rule and the classification table
- Drop conditional language around policy composition (PR #2671 merged)
- Sweep docs/ link text: "Customizing" → "Configuring" for guides about
  documented extension points, reserving "custom" for from-scratch agents
- Update glossary entries to match

Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ralph Bean <rbean@redhat.com>
ralphbean added a commit that referenced this pull request Jul 8, 2026
- Remove Ship of Theseus reference (too obscure without explanation)
- Remove explicit agent list from intro (will go stale)
- Broaden "the rule" to acknowledge general-purpose harness fields
  alongside documented extension points, resolving the inconsistency
  between the rule and the classification table
- Drop conditional language around policy composition (PR #2671 merged)
- Sweep docs/ link text: "Customizing" → "Configuring" for guides about
  documented extension points, reserving "custom" for from-scratch agents
- Update glossary entries to match

Assisted-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Ralph Bean <rbean@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/docs User-facing documentation component/harness Agent harness, config, and skills loading component/sandbox OpenShell sandbox environment go Pull requests that update go code ready-for-merge All reviewers approved — ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adopt provider-backed policy composition to reduce harness policy duplication

3 participants