# Pathrule Pattern: Azure Functions Production Patterns (1.0.0)
# ::pathrule:package:azure-functions

### [RULE] Make every triggered effect idempotent  (path: /src/functions)
<!-- scope: folder | priority: high | strict -->

Queue, event, timer, and HTTP infrastructure can repeat an invocation after timeout, lock loss, ambiguous acknowledgement, or client retry. Exactly-once business effects must be created above the trigger delivery guarantee.

- Choose an event, message, schedule occurrence, or client idempotency identifier that remains stable across delivery attempts.
- Persist the operation state with the business transition where possible and detect completed, in-progress, and retryable-failure outcomes explicitly.
- Propagate the same identity to downstream queues, APIs, email, and payments rather than generating a new key at each hop.
- Treat timeout after an external call as ambiguous and reconcile by operation key before retrying an effect that may already have committed.

See /infra for the adjacent decision or procedure that completes this constraint.

---

### [RULE] Keep invocation state isolated and dependencies bounded  (path: /src/functions)
<!-- scope: folder | priority: high | strict -->

A warm function process can handle multiple invocations over time or concurrently depending on the host and language worker. Mutable globals can leak tenant or request state and unbounded clients can exhaust connections.

- Keep actor, tenant, payload, and per-invocation decisions in local immutable values or an explicit context object.
- Reuse expensive clients only when their libraries support concurrent use and their pools are bounded for the maximum host concurrency.
- Do not cache authorization results, mutable configuration, or user data globally without a key, expiry, invalidation, and memory bound.
- Ensure cancellation and timeout propagate to outbound calls so an invocation does not continue consuming dependencies after the host has abandoned its result.

See /host.json for the adjacent decision or procedure that completes this constraint.

---

### [MEMORY] Trigger settings are part of capacity and retry design  (path: /host.json)

The host can deliver more concurrent work than the database or remote service can absorb. Defaults that look efficient on a queue can produce lock loss, retry storms, and connection exhaustion downstream.

- Set concurrency and batch behavior from measured execution time, dependency pools, and the largest safe in-flight work count.
- Keep processing time within the trigger's lock or visibility strategy and make renewal or timeout behavior observable.
- Use bounded retries with a poison or dead-letter destination and preserve the original operation identity and failure reason.
- Separate transient dependency failures from permanent validation or authorization failures so poison handling does not repeatedly attack an unrecoverable message.

See /src/functions for the rule or workflow that puts this decision into practice.

---

### [MEMORY] A function app is a shared deployment and scaling boundary  (path: /infra)

Functions in one app share a host process and operational envelope. Combining an HTTP latency path, memory-heavy batch, and high-volume queue consumer can create noisy-neighbor behavior and coupled deployments.

- Group by compatible runtime, permissions, network access, dependency footprint, scaling profile, and ownership rather than by a broad product name.
- Split functions when one workload needs independent concurrency, memory, deployment timing, or secret access.
- Keep host-level settings and extension configuration versioned with the deployment and test them in a representative environment.
- Expose per-function and host-level latency, failure, retry, throttle, and dependency signals so shared-host contention is distinguishable from handler bugs.

See /host.json for the rule or workflow that puts this decision into practice.
