Skip to content

feat(isolation): support backend-supplied provider roots - #522

Merged
mogul merged 3 commits into
mainfrom
feat/521-backend-supplied-provider-root
Oct 21, 2026
Merged

mogul merged 3 commits into
mainfrom
feat/521-backend-supplied-provider-root

Conversation

@mogul

@mogul mogul commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Version the provider-input contract so sandbox backends can supply their proven read-only root without changing the provider-relative layout.

Issue resolved

#521

  • Preserve the released v1 schema and fixed path unchanged.
  • Add a separate v2 schema with models/providers/<providerId>.
  • Provide an explicit host-validator CLI for staged external bundles.
  • Define fail-closed backend obligations and authoritative-empty semantics.
  • Keep runtime mount/consumer implementation in the Quickstart backend layer.

Before and after

Before this PR: Provider bundles required one fixed absolute guest root that MSB could provide but current SBX could not.

After merge: Version 2 preserves a stable provider-relative path beneath a backend-supplied read-only root, while version 1 remains byte-compatible for existing consumers.

Verification

  • Provider contract tests: 168 passed
  • make validate-provider-input-contract: passed
  • make validate: passed
  • make generate-check: passed
  • make test-kits: passed
  • Ruff format/lint and git diff --check: passed
  • Independent adversarial reviews: all blockers resolved

Security impact

The mandatory host validator retains strict JSON, path containment, symlink, executable, credential-binding, URL, duplicate-provider, and cross-field checks. Schema and credential-binding inputs must come from trusted pinned/backend control-plane sources. Rejected candidates fail provisioning rather than becoming an empty provider set.

Relationships

Fixes: #521
Parent epic: #357
Unblocks: GSA-TTS/agentic-coding-quickstart#600, GSA-TTS/agentic-coding-quickstart#606, and #516

Rollback

Revert both commits in this PR. The released version 1 schema remains unchanged throughout.

AI-assisted by OpenCode. Human review required.

Version provider input bundles so v2 preserves the provider-relative layout while consumers compose it beneath a backend-supplied read-only root. Retain v1 validation and fixed-path compatibility.

Co-authored-by: OpenCode Agent <[email protected]>
@mogul
mogul requested a review from a team as a code owner October 21, 2026 18:23
@mogul mogul linked an issue Oct 21, 2026 that may be closed by this pull request
Preserve the v1 schema identity, add a consumable v2 validator interface, and define fail-closed backend obligations.

Co-authored-by: OpenCode Agent <[email protected]>

@wz-gsa wz-gsa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI-assisted adversarial review by OpenCode (usai/gpt-6-astra) of #522 at d547ce1.

One medium-priority regression needs correction: the new version dispatch inspects unvalidated JSON before the schema can reject its type. See the inline finding. This is an error-contract regression, not an acceptance bypass: the CLI still exits 1.

Verification on the reviewed head, in an isolated Python 3.13.16 environment with the repository's exact PyYAML, jsonschema, pytest, and Ruff pins:

  • Provider contract suite: 168 passed.
  • Full scripts/tests suite: 652 passed.
  • make validate-provider-input-contract: validated 3 bundles.
  • Ruff lint and format checks on both changed Python files: pass.
  • git diff --check: pass.
  • Released v1 bundle schema: byte-identical to the pre-PR base.
  • Additional execution probes: 10 unsafe/mismatched v2 paths rejected cleanly; mixed-provider and mixed-v1/v2 explicit batches accepted; intermediate artifact symlinks and non-executable normalizers rejected for both versions.
  • All seven malformed-input cases in the inline finding raised ContractError in the pre-PR validator; the reviewed head raises AttributeError or TypeError instead.

Integration notes (not additional blockers):

  • Pass every candidate using repeated --bundle flags in ONE invocation to get set-wide duplicate-provider checks. Separate per-provider invocations reset the uniqueness set.
  • Zero --bundle flags select repository discovery and report the shipped fixtures/kit as valid. This must not be treated as validation of an empty external provider set. The consumer-facing example would benefit from stating both CLI rules.
  • The two-distinct-backend-root acceptance criterion from #521 is not demonstrated here. The PR explicitly delegates mount/root enforcement to the backend layer; the unit tests establish the package contract, not live MSB/SBX enforcement. Keep that acceptance evidence with GSA-TTS/agentic-coding-quickstart#600 and GSA-TTS/agentic-coding-quickstart#606.

No live backend mount or consumer execution was performed. The source worktree remains clean.

Preserve the validator error contract by checking manifest and schema-version types before schema dispatch.

Co-authored-by: OpenCode Agent <[email protected]>
@mogul

mogul commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Addressed the malformed-manifest error-contract regression at 7c99212. The validator now checks that the decoded root is an object and schemaVersion is a string before dispatch, raising path-qualified ContractError instead of AttributeError/TypeError. Added parameterized direct-API and CLI coverage for null, array, string, number, boolean roots and array/object/non-string schema versions; CLI cases assert exit 1 with no traceback. Also clarified repeated --bundle set-wide validation and zero-bundle repository discovery semantics.

Verification: 188 contract tests, validator command, Ruff format/lint, and diff checks pass. Independent adversarial re-review found no blockers. Fresh CI is running; please re-review.

@mogul
mogul requested a review from wz-gsa October 21, 2026 19:47

@wz-gsa wz-gsa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI-assisted adversarial re-review by OpenCode (usai/gpt-6-astra) of #522 at 7c99212.

The P2 finding from my previous review is resolved. I inspected the complete three-file delta from d547ce1 and re-ran the original malformed-input probes independently of the new tests. Non-object JSON roots and array/object schema versions now raise path-qualified ContractError; the CLI returns 1 without a traceback. Missing/null versions also reject cleanly. The guards run before either .get on the root or the schema-map lookup, which fixes both failure mechanisms.

The 20 new parameterized API/CLI cases cover the requested regression and additional non-string version values. The consumer documentation also now explains set-wide repeated --bundle validation and the zero-flag repository-discovery behavior.

Verification on this exact head in the existing isolated Python 3.13.16 environment with repository-pinned direct dependencies:

  • Provider contract suite: 188 passed.
  • Host validator: validated 3 shipped bundles.
  • Original malformed-input probes: all reject with ContractError, exit 1, no traceback.
  • Ten unsafe/mismatched v2 paths reject; mixed-provider and mixed-v1/v2 batches pass; intermediate artifact symlinks and non-executable normalizers reject for both versions.
  • Ruff lint/format and diff whitespace checks pass; review worktree is clean.
  • All seven current-head GitHub checks report success, including Python 3.12 compatibility.

No new blockers. This approval supersedes my changes-requested verdict on d547ce1. Backend mount/root enforcement remains the separately tracked integration acceptance; no live MSB/SBX execution is claimed.

@mogul

mogul commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Merge-queue recovery: required checks cannot run on the current queue ref because their workflows lacked merge_group triggers. #524 contains the reviewed fix. After #524 passes normal PR checks and is admin-merged, this PR should be removed/requeued so the three required contexts run on a fresh merge-group SHA.

mogul added a commit that referenced this pull request Oct 21, 2026
## Summary

Run the required status checks on GitHub merge-queue commits so approved
pull requests can leave the queue.

## Issue resolved

**#523**

- Required checks ran for pull requests but not merge groups.
- Merge-queue commits waited forever for contexts that never started.
- PR-title validation depends on pull-request event data unavailable to
merge groups.
- Required context names must remain unchanged.

## Before and after

**Before this PR:** Merge-queue entries waited indefinitely for
`Conventional Commit Title`, `Python Lint & Test`, and `Pattern
Validation`.

**After merge:** CI runs required validation on merge-group commits,
while the title job reports the same required context without invoking
PR-only logic.

## Verification

- Workflow YAML parses successfully
- Required context ownership verified: `ci.yml` owns Python and Pattern
checks; `pr-lint.yml` owns title check
- Merge-group event context and concurrency behavior reviewed
- Independent adversarial review: PASS, no security findings
- Live merge-group execution will be proven by requeueing
#522

## Security impact

Permissions remain read-only. Actions remain SHA-pinned. The merge-group
no-op emits a static string and receives no token environment.

## Relationships

Fixes: #523
Unblocks: #522
Related epic: #357

## Rollback

Revert this PR to remove merge-group workflow triggers.

AI-assisted by OpenCode. Human review required.
@mogul
mogul removed this pull request from the merge queue due to a manual request Oct 21, 2026
@mogul
mogul added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit 78d88e4 Oct 21, 2026
7 checks passed
@mogul
mogul deleted the feat/521-backend-supplied-provider-root branch October 21, 2026 20:59
github-merge-queue Bot pushed a commit that referenced this pull request Oct 21, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.16.0](v1.15.0...v1.16.0)
(2026-10-21)


### Features

* **isolation:** support backend-supplied provider roots
([#522](#522))
([78d88e4](78d88e4))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Version provider projection contract for backend-supplied read-only roots

2 participants