← FlowerCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Flower
Snapshot Sep 30, 2026 · 23:13 UTC · version 0.3.3
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "flower-action-runtime-guide",
"description": "Use when creating, building, modifying, reviewing, migrating, or testing Java code that uses flower-action-runtime, including new Maven or Gradle project setup, Maven Central dependency and backend-module selection, ActionProposal and ActionDefinition design, registry/validation/policy/approval/pre-execution controls, visibility-safe owner-aware in-memory or JDBC duplicate handling, explicit failure retry policy, synchronous/async/deferred executor selection, ActionRun and RunStore persistence, JDBC CAS concurrency, completion/cancellation/recovery, Flower workflow or event-loop backends, and 0.1/0.2-to-0.3 migration.",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 282
},
{
"relative_path": "references/00-guide-version.md",
"size_in_bytes": 1503
},
{
"relative_path": "references/01-runtime-quick-rules.md",
"size_in_bytes": 3848
},
{
"relative_path": "references/05-build-and-module-selection.md",
"size_in_bytes": 9696
},
{
"relative_path": "references/10-action-model-and-controls.md",
"size_in_bytes": 5761
},
{
"relative_path": "references/20-execution-modes.md",
"size_in_bytes": 4314
},
{
"relative_path": "references/30-persistence-and-concurrency.md",
"size_in_bytes": 6137
},
{
"relative_path": "references/40-flower-backends.md",
"size_in_bytes": 2329
},
{
"relative_path": "references/50-testing.md",
"size_in_bytes": 6109
},
{
"relative_path": "references/60-host-integration.md",
"size_in_bytes": 4639
},
{
"relative_path": "references/90-verification.md",
"size_in_bytes": 4343
}
],
"skill_md_contents": "---\r\nname: flower-action-runtime-guide\ndescription: Use when creating, building, modifying, reviewing, migrating, or testing Java code that uses flower-action-runtime, including new Maven or Gradle project setup, Maven Central dependency and backend-module selection, ActionProposal and ActionDefinition design, registry/validation/policy/approval/pre-execution controls, visibility-safe owner-aware in-memory or JDBC duplicate handling, explicit failure retry policy, synchronous/async/deferred executor selection, ActionRun and RunStore persistence, JDBC CAS concurrency, completion/cancellation/recovery, Flower workflow or event-loop backends, and 0.1/0.2-to-0.3 migration.\n---\n\n# Flower Action Runtime Guide\n\r\n## Overview\r\n\r\nUse this skill to keep business actions behind one explicit control boundary\r\nwhile supporting approval, audit, asynchronous work, durable completion, and\r\nsafe concurrent state changes.\r\n\r\nThis skill owns action-runtime guidance. When the host also authors Flower\r\nFlows, Steps, Guards, Workers, event waits, or checkpoints, also load the\r\nsibling `flower-app-guide` skill and follow both sets of rules.\r\n\r\n## Start Here\r\n\r\nAlways read:\r\n\r\n- `references/00-guide-version.md`\r\n- `references/01-runtime-quick-rules.md`\r\n- `references/90-verification.md`\r\n\r\nThen read the reference that matches the task.\r\n\r\n## Reference Routing\n\n- Creating a Maven or Gradle host, choosing Action Runtime modules, adding or\n upgrading dependencies, or resolving Flower compatibility: read\n `references/05-build-and-module-selection.md`.\n- Designing actions, proposal identity, definitions, policy, approval,\n pre-execution checks, results, audit, or idempotency: read\r\n `references/10-action-model-and-controls.md`.\r\n- Choosing synchronous, in-process async, or durable deferred execution and\r\n implementing completion/cancellation: read\r\n `references/20-execution-modes.md`.\r\n- Working with `ActionRun`, custom `RunStore`, JDBC schema/migrations, CAS,\r\n recovery, or multiple server instances: read\r\n `references/30-persistence-and-concurrency.md`.\r\n- Selecting `DefaultActionRuntime`, the workflow backend, or the event-loop\r\n backend: read `references/40-flower-backends.md`.\r\n- Writing unit, parity, concurrency, persistence, or recovery tests: read\r\n `references/50-testing.md`.\r\n- Integrating the runtime into REST, MCP, schedulers, AI planners, Spring, a\n domain application, or Flower's common observation pipeline: read\n `references/60-host-integration.md`.\n\r\n## Workflow\r\n\r\n1. Identify the business side effect and every entry point that can request it.\r\n2. Before changing a host build, read\n `references/05-build-and-module-selection.md`, preserve compatible host\n dependency management, and select only requirement-backed modules. Pin the\n published Maven Central `0.3.3` artifacts and verify APIs against the\n `v0.3.3` source tag. Inspect a mutable checkout only when modifying the\n runtime itself; its main branch may be a later SNAPSHOT.\n3. Define a stable action id and register exactly one controlled executor.\r\n4. Map request channel, proposer type, execution principal, tenant, run id, and\n idempotency key without collapsing them into one actor field. In 0.3,\n `ActionOrigin` no longer exists.\n5. Configure validation, policy, approval, duplicate handling, audit/trace, and\r\n the pre-execution guard before exposing the action.\r\n6. Choose the executor mode by lifetime and durability, not by convenience.\r\n7. Use a queryable `RunStore` for approval, async, deferred, callback, or\n cancellation work. `InMemoryRunStore` may be sufficient for same-JVM\n local/test use; use a shared durable store for restart-sensitive,\n multi-instance, or production deferred work.\n8. If Flower drives the backend, keep Worker/EventWorker ticks non-blocking and\r\n keep governance semantics in the shared action pipeline.\r\n9. Add focused failure, resume, race, and recovery tests. Before reporting the\n work complete, map every applicable control to a named test and apply the\n controlled-action completion gate below, then run the complete verification\n appropriate to the changed modules.\n\n## Controlled-Action Completion Gate\n\nA generic duplicate test is not evidence for every duplicate-safety property.\nFirst classify completed-result visibility as tenant-global/shareable,\nprincipal-restricted, resource-bound, or a combination. Do not invent a\nprincipal or resource boundary merely to satisfy this checklist. Keep each\napplicable scenario as a distinct named test:\n\n1. When policy has a denied-principal boundary, complete an authorized request,\n then retry the same tenant, action id, idempotency key, and resource when one\n applies, as a denied execution principal. Assert policy denial before\n `RETURN_EXISTING`, no cached output/result or protected run/resource\n disclosure, and no additional domain side effect.\n2. When the action or result is resource-bound, complete a request for resource\n A, then reuse the same tenant, action id, and idempotency key for resource B\n with a request that is otherwise valid and authorized for B. Assert that A's\n result and protected data are not returned for B.\n\nRecord a short N/A reason for a genuinely absent visibility dimension or an\nintentionally shareable result.\n\nWhen a stateful duplicate policy claims concurrent duplicate suppression\nand caches or finalizes reservations, also run a deterministic full-pipeline\nrace. Both contenders must call the Action Runtime; any accepted request must\npass through the registered executor. Place barriers or latches immediately\nbefore the atomic reserve/complete transitions and never wait while holding the\nper-scope lock. Assert exactly one `DuplicateActionDecisionType.ACCEPT`\nreservation, exactly one executor invocation/domain side effect, and no\nterminal overwrite. During the race the duplicate may observe the in-progress\nrejection or the original result; every later duplicate must return the\nunchanged original cached terminal result. A policy-only race is still useful\nfor ownership and ABA assertions, but it does not prove the runtime side-effect\ncount and cannot replace this full-pipeline test.\n\n## Unsafe Control-Bypass Response Contract\n\nWhen a request asks an admin, callback, retry, recovery, or other entry point\nto call the side effect directly or return an existing result before\nauthorization, the agent-authored user-facing response must:\n\n1. Explicitly refuse both the direct side-effect path and the\n pre-authorization duplicate/result lookup.\n2. State that trusted execution principal and tenant come from host context\n and remain separate from request channel and proposer metadata.\n3. Preserve definition resolution, validation, authorization/policy,\n visibility-safe duplicate handling, approval, audit, `PreExecutionGuard`,\n and the registered executor boundary.\n4. State that approval/resume re-resolves the definition, re-validates current\n input, re-evaluates current policy, and runs `PreExecutionGuard` immediately\n before dispatch.\n5. Explain that an early or insufficiently scoped cached-result lookup can\n disclose another tenant's, principal's, or resource's result.\n\nDo not leave these consequences and controls implicit or only in referenced\nguidance, and do not suggest a feature flag, alternate service, raw SQL, or\ncallback path that recreates the bypass.\n\n## Non-Negotiable Rules\n\n- Treat UI, REST, batch, MCP, scheduler, and AI output as proposals. Only a\n registered `ActionExecutor` may perform the controlled side effect.\n- Never bypass registry, validation, policy, approval, duplicate handling, or\r\n audit in a resume, callback, retry, recovery, or admin path.\r\n- Re-resolve, re-validate, re-evaluate policy, and run `PreExecutionGuard`\r\n after approval and immediately before dispatch.\r\n- Do not block Flower Worker or EventWorker ticks with domain work, HTTP, LLM,\r\n tools, sleeps, or `Future.get()`.\r\n- Use `ActionExecutionResult.code()` and `RetryDisposition` for machine\n decisions. Do not parse human messages or leave failure retry safety\n implicit.\n- Give every action request a unique `runId`. Use the idempotency key to group\r\n transport retries; do not reuse a run id for a new request.\r\n- Make every `RunStore` transition versioned CAS. Do not add an unconditional\r\n update/upsert path to the runtime SPI.\r\n- Authenticate callback callers and verify tenant, run id, and attempt token.\r\n- Make external cancellation hooks idempotent for the same run attempt and\n operation id.\n- Scope duplicate reservations by at least tenant, action id, and idempotency\n key. Add principal or resource scope when an existing result is not safely\n shareable within the tenant.\n- In `0.3.3`, `InMemoryDuplicateActionPolicy` scopes by tenant, action id,\n idempotency key, and an optional trusted visibility scope. Do not use the\n tenant-wide default when a cached result contains\n principal- or resource-restricted data. Authorizing the current request\n before lookup is insufficient when that authorization may concern a\n different resource from the cached result. Bind reservation/result lookup to\n a stable trusted principal or canonical resource identity through\n `DuplicateVisibilityScopeResolver`, or reject the duplicate without returning\n the cached result. Never derive that scope from arbitrary request payload,\n AI output, or an unverified callback. Run the corresponding\n denied-principal or authorized cross-resource test when that visibility\n boundary exists; otherwise record the dimension as N/A without inventing it.\n- The `0.3.3` `InMemoryDuplicateActionPolicy` uses one owner-aware atomic state\n per scope and can suppress concurrent duplicates inside one JVM. It remains\n non-durable and unbounded: reservations/results disappear on restart, do not\n coordinate multiple processes, and are never evicted. Use\n `JdbcDuplicateActionPolicy` or another shared durable policy when restart or\n multi-instance coordination matters.\n- Keep duplicate reservation state separate from `ActionRun` lifecycle state.\n For the shipped JDBC policy, apply the matching host-owned\n `db/action_duplicate/<dialect>.sql` or additive migration. Do not add an\n automatic TTL/lease takeover: an old `RUNNING` reservation does not prove\n that an external side effect stopped. Reconcile `ActionRun` and domain state\n before any explicit repair.\n- Treat duplicate reservation, completion, and release as one atomic\n owner-aware per-scope state machine. Retain the current reservation owner\n from trusted execution identity, normally the unique `runId`; apply\n `complete()` or `release()` only while that caller still owns the\n reservation. Do not coordinate `completed` and `running` through separate\n unguarded reads and writes. A reserve racing with completion must observe the\n existing reservation or completed result, never accept again or overwrite\n terminal truth. A stale or repeated completion/release must not alter a\n newer owner's reservation. Use one lock or atomic map transition in-process\n and durable uniqueness/CAS in production. Test reserve-versus-complete plus\n stale/double-complete and stale/double-release ABA sequences with barriers\n or latches; prove one accepted execution, one side effect, stable terminal\n truth, and preservation of the current owner.\n- Resolve, validate, and authorize the current request before duplicate\n reservation or `RETURN_EXISTING` result lookup.\n- Treat `CANCELLED` as the runtime's terminal acceptance decision, not proof\n that an external operation physically stopped.\n- Treat deferred dispatch as at-least-once-capable integration, not an\n exactly-once guarantee. Require deterministic operation ids, idempotent\n dispatch, authenticated callbacks, reconciliation, and an orphan policy.\n- Treat `ActionRun` as runtime lifecycle truth. Flower checkpoints, events,\r\n signals, futures, and callback payloads are orchestration or delivery data.\r\n\r\n## Source Of Truth\r\n\r\nFor a consuming application, the published `0.3.3` artifacts and the matching\n`v0.3.3` source tag are authoritative. Never make a distributable guide,\nsample, or plugin depend on a mutable checkout, `mavenLocal()`, or a SNAPSHOT.\nWhen modifying the runtime itself, its checked-out source and tests become the\nworking source of truth. Useful upstream documents include:\n\r\n```text\r\nflower-action-runtime/README.md\r\nflower-action-runtime/flower-action-runtime-core/README.md\r\nflower-action-runtime/docs/architecture/DEFERRED_ACTION_EXECUTION.md\r\nflower-action-runtime/docs/architecture/ACTION_RUN_PERSISTENCE.md\nflower-action-runtime/docs/architecture/DURABLE_DUPLICATE_HANDLING.md\nflower-action-runtime/docs/architecture/EXECUTION_BACKEND_STRATEGY.md\r\nflower-action-runtime/docs/architecture/V0_2_MIGRATION_AND_MODULE_IMPACT.md\nflower-action-runtime/docs/architecture/V0_3_MIGRATION_AND_MODULE_IMPACT.md\n```\n"
}SHA-256: 3471a2053435f2d5b346bf06823b7b55a26665d0c491017c9b54bc5ace21733e