fix(runtime): enforce manifest policies and fix replay timeout safety bug#10
fix(runtime): enforce manifest policies and fix replay timeout safety bug#10simonovic86 merged 2 commits intomainfrom
Conversation
… bug - Fix critical safety bug: replay ticks now have 100ms timeout preventing malicious agents from hanging replay indefinitely - Add ParseManifest() for full manifest parsing (ResourceLimits, MigrationPolicy) - Thread full manifest through agent loading; reject agents exceeding 64MB memory - Enforce MigrationPolicy in migration service (enabled flag, max price) - Add tick timeout enforcement test with infinite-loop WASM agent - Update example manifest with resource_limits and migration_policy sections Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The `make agent` step requires TinyGo which isn't installed by `make bootstrap`. Add acifani/setup-tinygo@v2 action with v0.40.1 matching the version in DEVELOPMENT.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee1c60083d
ℹ️ 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".
| if m.MigrationPolicy != nil && | ||
| m.MigrationPolicy.MaxPricePerSecond > 0 && | ||
| s.pricePerSecond > m.MigrationPolicy.MaxPricePerSecond { |
There was a problem hiding this comment.
Use billed price when enforcing max_price_per_second
validateIncomingManifest rejects based on s.pricePerSecond, but incoming agents are still started with pkg.PricePerSecond from the checkpoint and tick metering charges that stored value. When those two prices differ, this new policy gate enforces against the wrong number: it can reject migrations that would actually bill within the max, or accept migrations that will bill above the declared max.
Useful? React with 👍 / 👎.
| } | ||
|
|
||
| type migrationPolicyJSON struct { | ||
| Enabled bool `json:"enabled"` |
There was a problem hiding this comment.
Treat omitted migration_policy.enabled as unspecified
Because enabled is decoded into a plain bool, any manifest that includes migration_policy but omits enabled is parsed as Enabled=false; validateIncomingManifest then treats it as an explicit disable and blocks migration. This makes partial policies like only setting max_price_per_second fail unexpectedly even though migration was not explicitly turned off.
Useful? React with 👍 / 👎.
Summary
ParseManifest()readsResourceLimitsandMigrationPolicy(previously parsed but ignored)enabledflag andmax_price_per_secondbefore accepting incoming agentsWithCloseOnContextDoneactually interrupts infinite-loop WASM execution at ~100msTest plan
make test— all existing + 12 new tests pass (16 packages)make lint— no new lint issuesmake check— full pre-commit suite passesmake build && make agent— binary and WASM agent build successfullyTestReplayTick_Timeoutconfirms infinite-loop agent is interruptedTestTick_TimeoutEnforcementconfirms ~100ms wall-clock enforcementTestLoadAgent_ExcessiveMemoryRejected/TestLoadAgent_ValidMemoryAcceptedTestMigration_PolicyDisabled,TestMigration_PriceTooHigh,TestMigration_NoPolicyAllowed,TestMigration_PriceWithinLimitmigration_policystill migrate freely🤖 Generated with Claude Code