Skip to content

Local Petal Plugins v2 and GitHub source installs#50

Open
josh-richardson wants to merge 78 commits into
masterfrom
feat/local-petal-plugins
Open

Local Petal Plugins v2 and GitHub source installs#50
josh-richardson wants to merge 78 commits into
masterfrom
feat/local-petal-plugins

Conversation

@josh-richardson

@josh-richardson josh-richardson commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR makes local Petal apps v2-only, adds trusted GitHub source installation, and supplies the generic host capabilities required for the external Polymarket Petal to reach native functional parity without Polymarket-specific IPC.

Bloom host

  • Adds structured bloom:sign/signing@0.2 approval-required outcomes while retaining signing@0.1 compatibility.
  • Seals signing actions from trusted package, route, operation, path, exact hash, wallet, and declared intent; signatures require an in-memory bounded grant and recover to the prepared owner.
  • Adds generic bloom:tx/outbox@0.1 stage, confirm, and origin-bound inspect operations with canonical EVM bytes, warning acknowledgement, fee overrides, and receipt-derived terminal states.
  • Binds local-app EVM execution origin to package plus exact route provenance and serializes scan/stage reuse to prevent duplicate concurrent actions.
  • Extends generic mediated chain reads needed by external Petals; no bloom:polymarket/* IPC or native Polymarket shortcut was added.
  • Adds trusted GitHub source installs for bloom-directory/* Petal repositories with local source builds, v2 validation, provenance, SemVer tag selection, and path/build hardening.

External Polymarket Petal

The implementation lives in bloom-directory/bloom-petal-polymarket PR #2. It covers onboarding, account reads, funding, order creation/posting/reconciliation/cancellation, builder keys, redemption, approval revocation, pUSD withdrawal, obligations, policy acknowledgement, crash-safe relayer handling, and public redacted receipts. Geoblock behavior is excluded.

The Petal uses only generic signing, transaction outbox, chain read, HTTP, store, and VFS capabilities. Its exact contract contains 57 functional routes and builds 127 validated components.

Validation

Bloom:

  • cargo fmt --all -- --check
  • git diff --check
  • cargo test -p bloom-daemon -p bloom-petals -p bloom-tx (48 + 116 + 139 passed)
  • cargo test -p bloom-auth-api -p bloom-proto -p bloom-vfs (91 + 185 + 469 passed, 1 ignored)
  • cargo test --workspace --no-run
  • strict clippy for bloom-daemon, bloom-petals, and bloom-tx

External Petal:

  • route tests: 36 passed; strict clippy clean
  • vendored protocol crate: 71 passed, 3 live tests ignored; 49 passed without default features
  • scripts/build.sh: 127 components
  • Bloom package validation: b54812555a7309c7e46308db86d386331895c4bdb285bb5544cbd167162041fb
  • three final adversarial review passes: APPROVE, no actionable findings

Checklist

  • Tests added or updated for behavior changes
  • Architecture docs (docs/architecture/) updated if contracts or behavior changed — N/A; the implementation contract is documented in docs/specs/2026-07-09-polymarket-petal-parity.md and affected source/WIT documentation
  • Sealed Approval invariants respected (no signing outside a grant or bounded capability, no PRF/grant persistence, execution from sealed bytes) — signing and EVM execution fail closed outside exact daemon-sealed grants/capabilities; only redacted ceremony metadata is persisted
  • Agent Documentation updated (crates/bloom-vfs/src/docs/agent-guidance.md and affected Petal READMEs) — external Petal README and route metadata are updated; no native agent-guidance command surface changed

@josh-richardson josh-richardson changed the title Local Petal Plugins v1 Local Petal Plugins v2 Jun 24, 2026
@josh-richardson josh-richardson marked this pull request as ready for review June 24, 2026 16:52

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80ea9b0234

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread examples/local-petal-apps/build-polymarket-v2.sh Outdated
Comment thread examples/local-petal-apps/build-polymarket-v2.sh Outdated
@josh-richardson josh-richardson changed the title Local Petal Plugins v2 Local Petal Plugins v2 and GitHub source installs Jun 24, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e322404b8a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/bloom-petals/src/v2.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad9747a203

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/bloom-petals/src/router.rs Outdated
Comment thread crates/bloom/tests/cli.rs Outdated
Comment thread .github/workflows/acceptance.yml Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 21dd910a91

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/bloom-polymarket/src/lib.rs Outdated
Comment on lines +81 to +84
if name.is_empty()
|| name.contains('/')
|| name.contains('\\')
|| name.contains('\0')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep wallet-name validation aligned with keystore

The new shared validator is now used by the credential/order stores, but it only rejects separators/NUL and dropped the old length, leading-dot, and ASCII allow-list checks. Direct store calls now accept names such as .alice or alice prod that the Bloom keystore rejects, so Polymarket state can be created for wallets that cannot be resolved or is hidden/unmanageable on disk; preserve the previous/keystore-compatible restrictions here.

Useful? React with 👍 / 👎.

Comment on lines +517 to +521
if kind == RouteEntryKind::File && ops.contains(&RouteOp::Write) {
install_metadata.mode |= 0o222;
}
if kind == RouteEntryKind::File
&& install_metadata.mode & 0o222 != 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require a write export before advertising writes

When a sidecar declares ops = ["write"] (or static metadata returns a writable mode), this block marks the route writable without checking validation.has_write_export. Such a package installs and advertises a writable VFS path, but every write later fails when dispatch_component_route cannot find the component's write export; reject writable metadata/ops unless the route actually exports write.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 24ef9d9256

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/bloom-petals/src/v2.rs
…ugins

# Conflicts:
#	.github/workflows/acceptance.yml
#	.github/workflows/ci.yml
#	.gitignore
#	Cargo.lock
#	Cargo.toml
#	crates/bloom-daemon/Cargo.toml
#	crates/bloom-daemon/src/ipc.rs
#	crates/bloom-daemon/src/lib.rs
#	crates/bloom-petal-manifest/Cargo.toml
#	crates/bloom-petal-manifest/src/extract.rs
#	crates/bloom-petals/Cargo.toml
#	crates/bloom-petals/src/lib.rs
#	crates/bloom-petals/src/meta.rs
#	crates/bloom-polymarket/Cargo.toml
#	crates/bloom-polymarket/src/lib.rs
#	crates/bloom/Cargo.toml
#	crates/bloom/src/main.rs
#	crates/bloom/tests/cli.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a771909f41

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

fn validate_route_conflicts(routes: &[RouteRecord]) -> Result<(), PetalError> {
for (idx, a) in routes.iter().enumerate() {
for b in routes.iter().skip(idx + 1) {
if a.specificity == b.specificity && patterns_overlap(&a.pattern, &b.pattern)? {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject file routes that shadow descendant routes

When a package contains both a file route such as app/demo/foo.wasm and a descendant such as app/demo/foo/bar.wasm, this check only compares routes with identical specificity, so the package installs. At runtime lookup/read for /apps/demo/foo match the file route first while static listing also treats foo as a directory for the child route, so mounted clients that lookup before listing see foo as a file and cannot traverse to /apps/demo/foo/bar. Please reject file routes that are ancestors of other route patterns, or require the ancestor to be a $index directory route.

Useful? React with 👍 / 👎.

}
if context.app_root.trim().is_empty()
|| context.route_id.trim().is_empty()
|| context.path.trim().is_empty()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow root v2 routes to request signatures

For an app-root $index.wasm route that calls bloom:sign/sign-hash while serving /apps/<app>, the VM passes the root request path as the empty string in V2SignContext.path. This validation treats that legitimate root path as incomplete and rejects before staging Sealed Approval, so sign-capable root routes cannot use the v2 signing path; allow an empty path to mean the app root while still validating the other context fields.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6399ba5f99

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +243 to +245
let route_binding = blake3::hash(
format!("{}\0{}\0{}", context.route_id, context.op, context.path).as_bytes(),
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use package-scoped outbox provenance

Deriving the persisted ExecutionOrigin from route_id, operation, and path makes every route in the same package a different petal_id. Since evm_tx_confirm and evm_tx_inspect later require the stored origin to equal the current route's origin, a transaction staged by one route cannot be confirmed or inspected by a separate status/confirm route in the same app, even though the tx/outbox API passes only an outbox-id for package workflows. Keep the outbox origin at the app/package scope and bind route details separately if they are needed for audit.

Useful? React with 👍 / 👎.

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.

2 participants