> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blockx.chaintable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Function Code View

> The Worker's immutable function code snapshots (epoch / digest), the BlockDB and Redis syncers, and the static function code audit performed before dispatch

Function Code View is a component inside the Worker process that maintains `functionId -> source` as a series of immutable snapshots, so that every task sees the same code for its whole lifetime. Function code audit is an admission gate attached to the same chain: before dispatch, a Python static auditor checks the source, and the call is rejected if it fails. Neither is deployed separately. See the [Architecture overview](/en/architecture/overview) for where they sit in the system.

## Responsibilities and boundaries

Responsible for:

* Maintaining the Worker-local `SnapshotStore`: every code update publishes a complete new snapshot with a new `epoch`; published snapshots are never modified.
* Providing `CurrentEpoch()` and `Pin(epoch)` for task activation; building a `TaskFunctionView` per task that resolves both snapshot functions and the task's own inline source into a source-free `digest`.
* Publishing upstream function table changes as new snapshots through a syncer (BlockDB Online table subscription, or Redis metadata hash polling).
* Fetching source by `digest` on an Executor compiled-cache miss and handing it back to the Executor.
* Before dispatch, looking up the audit cache by `(digest, entrySelector)` and, on a miss, calling the `blockx_audit` daemon for static auditing (Go side: `internal/functioncode/audit`).

Not responsible for:

* Defining how the publishing side writes the function table; it also does not require BlockDB to store an `epoch` or a global version number.
* Letting the Executor access BlockDB directly or query Function Code View directly.
* Guaranteeing that `epoch` values are consistent or comparable across Workers.
* The audit rules themselves. All rules live in the Python package `python/blockx_audit/`; the Go side only provides the process pool, cache, and gate.

Core invariants:

* `epoch` is a Worker-local opaque string (`bootID:seq`) that is meaningful only within the current process.
* A task is pinned to the same `epoch` for its whole lifetime; new code only affects new tasks.
* Snapshots are append-only and never modified. `InstallSnapshot` only accepts a complete next view, and does not bump `epoch` when the logical content is unchanged.
* A single Worker never publishes views out of order: if it sees function `a` change and then `b` change, there is never a snapshot where `b` is new but `a` is still old.
* `digest` is SHA-256(source), always computed locally at a trusted Worker entry point (snapshot install / inline normalization); the upstream-declared `Digest` never enters the execution path. The digest of empty source is SHA-256(`""`), not the empty string.
* Audit enforce mode is fail-closed: both a violation and an unavailable auditor reject the dispatch.

## Code location

| Path                                                                                                                                                                                                          | Purpose                                                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `internal/functioncode/core/snapshot_store.go`                                                                                                                                                                | `SnapshotStore`, `SnapshotView`, `FunctionCode` / `FunctionCodeRef`, epoch allocation, retention and pruning of historical snapshots                                                                  |
| `internal/functioncode/core/task_view.go`                                                                                                                                                                     | `TaskFunctionView`: task-level overlay handling inline registration, digest resolution, and source lookup by digest                                                                                   |
| `internal/functioncode/core/digest.go`                                                                                                                                                                        | `SourceDigest`, `PrepareFunctionCode` (trusted digest derivation)                                                                                                                                     |
| `internal/functioncode/adapters/blockdb/syncer.go`                                                                                                                                                            | BlockDB syncer: subscribes to the `system.function` change stream, full scans, reconnects, builds the next complete view and calls `InstallSnapshot`                                                  |
| `internal/functioncode/adapters/redis/`                                                                                                                                                                       | Redis syncer: polls the `chaintable:v12:function` hash (`RedisSource.LoadAll`); an alternative code source to BlockDB, not a cache                                                                    |
| `internal/functioncode/audit/`                                                                                                                                                                                | Go-side audit: `Pool` (`blockx_audit` daemon process pool + digest cache + singleflight), `Check` / `Observe` gate semantics, `SpaceAllowlist`, `BuildReport`                                         |
| `python/blockx_audit/`                                                                                                                                                                                        | Python static auditor: `auditor.py` (AST allowlist walker), `kinds.py` (kind tracking), `tables.py` (allowlist tables), `bytecode.py` (bytecode backstop), `daemon.py` (framed stdin/stdout protocol) |
| `internal/worker/adapters/audit_gate.go`                                                                                                                                                                      | `FunctionAuditGate`: invokes the audit at dispatch time and produces `uds.AuditGatePayload`, distinguishing enforce / dark                                                                            |
| `internal/worker/adapters/task_runtime.go`                                                                                                                                                                    | `FunctionCodeViewProvider` / `EpochResolver` interfaces; `resolveCallDigests`, `resolveFunctionCode`, `resolveFunctionCodeForDispatch`                                                                |
| `internal/worker/adapters/orchestrator_phases.go`                                                                                                                                                             | `CurrentEpoch()` → `Pin()` → `NewTaskFunctionView()` at task activation                                                                                                                               |
| `internal/worker/adapters/orchestrator_dispatch.go`                                                                                                                                                           | `DispatchCallCmd` handling: resolves the digest, passes the audit gate, builds `ExecuteCallPayload`                                                                                                   |
| `internal/worker/adapters/executor/function_code_source.go`                                                                                                                                                   | Handles the Executor's `CallWaiting(waitKind=function_code)` and replies with `ResumeCall`                                                                                                            |
| `internal/worker/app/function_code.go`                                                                                                                                                                        | Worker startup assembly: selects the devstub / Redis / BlockDB source, `newFunctionCodeAudit` (audit mode and daemon pool)                                                                            |
| `internal/worker/devstub/function_code.go`                                                                                                                                                                    | `MemoryFunctionCodeStore`: in-memory function store for local development and e2e                                                                                                                     |
| `python/blockx_executor/module_registry.py`                                                                                                                                                                   | Executor side: `_verify_audit_gate` re-verifies the gate, caches compiled artifacts by digest, requests source on a cache miss                                                                        |
| `internal/functioncode/**/*_test.go`, `internal/worker/app/function_code*_test.go`, `internal/worker/adapters/audit_gate_test.go`, `python/tests/test_audit_*.py`, `python/tests/test_executor_audit_gate.py` | Tests                                                                                                                                                                                                 |
| `docs/specs/function-code-view.md`, `docs/specs/function-code-audit-design.md`, `docs/specs/function-code-python-whitelist.md`, `docs/specs/2026-07-23-execute-call-function-code-reference.md`               | Design docs (blockx repo)                                                                                                                                                                             |

## Core types and interfaces

* `SnapshotStore` (`internal/functioncode/core/snapshot_store.go`): the Worker-local snapshot repository. `CurrentEpoch()`, `Pin(codeEpoch)`, `Fetch(functionID, codeEpoch)`, `InstallSnapshot(next, publishedAt)`, `PruneSnapshotsBefore(cutoff)`.
* `SnapshotView` (same file): the read-only handle a task can pin.

```go theme={null}
type SnapshotView interface {
	Epoch() string
	Lookup(functionID string) (FunctionCodeRef, error)
	SourceByDigest(digest string) (string, error)
}
```

* `FunctionCode` / `FunctionCodeRef` (same file): the former is the payload carrying source (`SourceCode`, `Digest`, `VerifiedDigest`, `Space`); `VerifiedDigest` is tagged `json:"-"` and never comes in from serialized input. The latter is the source-free trusted identity (`SourceDigest`, `Space`) and is the only form a snapshot publishes externally.
* `SnapshotMeta` (same file): `Epoch`, `PublishedAt`, `SupersededAt`, `FunctionCnt`. `SupersededAt` is the starting point of the pruning clock.
* `TaskFunctionView` (`internal/functioncode/core/task_view.go`): the task-level overlay. `Resolve(functionID, code)` is the source entry boundary; `ResolveForDispatch(functionID, expectedDigest)` returns the `FunctionCodeRef` and `entrySelector` without loading source; `SourceByDigest(digest)` is only called on an audit miss or an Executor miss.
* `SourceDigest(source)` / `PrepareFunctionCode(code)` (`internal/functioncode/core/digest.go`): SHA-256 derivation.
* `blockdb.Syncer` (`internal/functioncode/adapters/blockdb/syncer.go`): `Bootstrap(ctx)` (subscribe → scan → replay → first snapshot), `Run(ctx)` (steady-state subscribe/apply/reconnect loop). Depends on `Deps{Store, ScanClient, SubscribeClient, RowReader, InstallAudit}`.
* `redis.Syncer` / `redis.RedisSource` (`internal/functioncode/adapters/redis/`): `Bootstrap` / `Run` have the same semantics as above, polling `LoadAll` every `PollInterval`.
* `audit.Pool` (`internal/functioncode/audit/auditor.go`): implements `Auditor` (`Audit(ctx, source, entrySelector)`, source-first, used by snapshot reports and the sync-invoker) and `DigestAuditor` (`AuditByDigest(ctx, digest, entrySelector, loadSource)`, used by Worker dispatch).
* `audit.Result` / `audit.Finding` / `audit.RejectionError` (`result.go`, `gate.go`): the wire struct returned by the daemon, a single violation, and the deterministic rejection error. `audit.IsRejection(err)` distinguishes a violation from an auditor failure.
* `audit.SpaceAllowlist` (`space_allowlist.go`): an operational allowlist that bypasses the gate by `FunctionCode.Space`; an empty `Space` never matches.
* `adapters.FunctionAuditGate` (`internal/worker/adapters/audit_gate.go`): `Check(ctx, callID, digest, entrySelector, loadSource) (*uds.AuditGatePayload, error)`.
* `adapters.FunctionCodeViewProvider` / `adapters.EpochResolver` (`internal/worker/adapters/task_runtime.go`): the Orchestrator's two dependency interfaces on Function Code View, exposing only `Pin` and `CurrentEpoch` respectively.
* `uds.AuditGatePayload` / `uds.ExecuteCallPayload.FunctionCodeDigest` (`api/uds/types.go`): the gate and digest sent down to the Executor.

## Data flow / execution flow

### Code update path

```mermaid theme={null}
flowchart LR
  BDB["BlockDB Online table system.function"] -->|"Subscribe changeEvent"| PUMP["subscriptionPump"]
  BDB -->|"ScanAll / BatchGetRows"| SYNC
  PUMP --> SYNC["blockdb.Syncer applyEventToView"]
  SYNC -->|"complete map functionId to FunctionCode"| STORE["SnapshotStore.InstallSnapshot"]
  STORE -->|"content changed: new epoch bootID:seq"| SNAP["new immutable snapshot"]
  STORE -->|"content unchanged: epoch not bumped"| KEEP["keep current epoch"]
  STORE -.->|"async when created is true"| HOOK["InstallAudit hook: BuildReport and warm the audit cache"]
  SYNC --> PRUNE["PruneSnapshotsBefore now minus retention"]
```

Key behaviors of the BlockDB syncer (`internal/functioncode/adapters/blockdb/syncer.go`):

* `Bootstrap`: first `Subscribe([system.function])` and buffer events into `subscriptionPump`, then `ScanAll` to obtain the base view, then replay the buffered events in order, and finally `InstallSnapshot`. The subscription established during bootstrap is handed directly to `Run` for continued consumption, so no events are lost in the handover window.
* `Run`: for every `changeEvent` received, read the current values of the affected rows by `RowIDs` with `BatchGetRows`, derive the next complete view copy-on-write from the previous view, then `InstallSnapshot`. `io.EOF` and transient errors reconnect after `ReconnectDelay` (default 200ms), using the `CreatedAt` of the most recently applied event as `StartAt`.
* Only the `id` and `code` columns are read (`readColumns()`); the `space` column is currently read opportunistically and is an empty string when missing, so it never matches the allowlist.
* After every install, `pruneIfNeeded()` and `obs.RecordFunctionCodeSnapshotStore` are called.

The Redis syncer (`internal/functioncode/adapters/redis/`) goes through the same `InstallSnapshot` entry point; only the source differs, with a full `HGetAll` refresh every `PollInterval`. `decodeFunctionValue` accepts hash values that are either raw source or JSON (any of the `code` / `sourceCode` / `source_code` / `source` fields).

<Note>
  `InstallSnapshot` only compares `FunctionCodeRef` (digest + Space). The same source reuses the already-computed digest across adjacent snapshots (`cloneFunctionRefs` looks it up in the previous snapshot's `sourcesByDigest`), so an update that changes a single function performs only one SHA-256.
</Note>

### Query path

```mermaid theme={null}
sequenceDiagram
  participant O as Orchestrator
  participant S as SnapshotStore
  participant V as TaskFunctionView
  participant G as FunctionAuditGate
  participant E as Python Executor
  O->>S: CurrentEpoch()
  O->>S: Pin(epoch)
  O->>V: NewTaskFunctionView(snapshotView)
  Note over O,V: after the builder produces the CallList, call Resolve(functionID, code) to get the digest
  O->>V: ResolveForDispatch(functionID, expectedDigest)
  V-->>O: FunctionCodeRef and entrySelector
  opt audit enforce or dark and Space not in allowlist
    O->>G: Check(callID, digest, entrySelector, loadSource)
    G-->>O: AuditGatePayload or RejectionError
  end
  O->>E: ExecuteCall functionCodeDigest + entrySelector + audit
  opt compiled cache miss
    E->>O: CallWaiting waitKind=function_code
    O->>V: SourceByDigest(digest)
    O-->>E: ResumeCall resumeKind=function_code sourceCode
  end
```

<Steps>
  <Step title="Pin the epoch at task activation">
    `Orchestrator.activateAndRun` (`internal/worker/adapters/orchestrator_phases.go`) calls `epochResolver.CurrentEpoch()`, then `functionCodeViewProvider.Pin(epoch)` to obtain the shared read-only `SnapshotView`, and checks that `snapshotView.Epoch() == epoch`. It then builds a `TaskFunctionView` from it and stores it in `taskRuntime.functionCodeView`. Failure at any step goes to `HandleTaskActivationFailed`.
  </Step>

  <Step title="Resolve digests before entering the Dispatcher">
    After the builder produces the CallList, `resolveCallDigests` calls `TaskFunctionView.Resolve(functionID, code)` for each call: snapshot functions do one `Lookup`, and inline functions register their source once per `*FunctionCode` pointer. From then on the call carries only `FunctionCodeDigest` for the rest of its lifetime, and the builder's `Code` pointer is cleared.
  </Step>

  <Step title="Fetch metadata and pass the audit gate at dispatch">
    When handling `DispatchCallCmd` (`orchestrator_dispatch.go`), `resolveFunctionCodeForDispatch` calls `ResolveForDispatch(functionID, expectedDigest)` to obtain only `Space` and `entrySelector`, without reading source. If a gate exists and `Space` is not in the allowlist, it calls `FunctionAuditGate.Check`; the `loadSource` callback is `resolveFunctionCode(taskID, digest)` and only runs on an audit cache miss. On rejection, `evCallFailed` is emitted with `errorKind` `function_code_audit_rejected`, which is not retryable.
  </Step>

  <Step title="Send the digest to the Executor and fetch source on a miss">
    `ExecuteCallPayload` sets only `FunctionCodeDigest`, `EntrySelector`, and the optional `Audit`; it carries no source. When the Executor's `ModuleRegistry.load_callable` misses the digest, it sends `CallWaiting(waitKind=function_code)`; on the Worker side, `handleFunctionCodeRequest` calls `TaskFunctionView.SourceByDigest` through the `resolveFunctionCode` registered via `SetFunctionCodeResolver` and replies with `ResumeCall(resumeKind=function_code)`. This request does not enter the dispatcher's WAITING state and is not counted in IO metrics. On receipt, the Executor recomputes the SHA-256 and compares it against the digest, then `_verify_audit_gate` re-verifies `sourceDigest` and `pass`.
  </Step>
</Steps>

### Audit call chain

* Both audit entry points share one `audit.Pool`: `newFunctionCodeAudit` (`internal/worker/app/function_code.go`) starts 2 `python -u -m blockx_audit` daemons in enforce / dark mode.
* Snapshot install audit: the `InstallAudit` hook runs `audit.BuildReport` asynchronously after every new epoch is published, auditing each function with `functionId` as the `entrySelector` and logging `function-code install audit`. It does not affect snapshot content; its main purpose is to warm the `(digest, entrySelector)` cache so the first dispatch usually hits.
* Dispatch audit: `FunctionAuditGate.Check` → `audit.CheckByDigest` → `Pool.AuditByDigest`. On a cache miss, the singleflight leader calls `loadSource`, recomputes the digest and compares it against the trusted digest, then sends the source to the daemon as a JSON frame with a 4-byte length prefix (`proc.go`). The daemon returns `Result{Pass, SourceDigest, EntryName, Findings}`; `Pool` then verifies `res.SourceDigest == digest`.
* On the Python side, `blockx_audit.audit(source, function_id)` combines a default-deny AST node allowlist (`_ALLOWED_NODES`), free-name / import / attribute allowlists (`tables.py`), kind tracking and capability boundaries (`kinds.py`), and a bytecode backstop (`bytecode.py`) that only runs when the walker has no findings, into a single `pass` bit. It only does `ast.parse`, never executes user code, and runs on the pure stdlib.
* Effect on the task / call: under enforce, both `RejectionError` (violation) and ordinary errors (daemon timeout / crash) fail the call with `function_code_audit_rejected`; under dark, only a warn log is emitted and the call is dispatched as usual with a gate-less payload; when `Space` matches the allowlist, the audit is skipped and the Executor loads the function in the unrestricted namespace.

Sync Invoker's `Precheck` reuses the same `audit.Pool` through the source-first `audit.Check` / `audit.Observe` interfaces, auditing without executing; see [Sync Invoker](/en/components/sync-invoker) for details.

## State and lifecycle

* `epoch` generation: `SnapshotStore.installSnapshot` does `seq++` under the write lock and sets `epoch = fmt.Sprintf("%s:%d", bootID, seq)`; `bootID` is generated by `newFunctionCodeBootID()` as `boot-<pid>-<unixnano>`.
* Retention and pruning: `PruneSnapshotsBefore(cutoff)` deletes only snapshots that are not current and whose `SupersededAt` is earlier than cutoff. The clock starts when a snapshot is superseded, not when it is published, so a long task that pinned a just-superseded epoch still gets the full retention window. Both syncers call it with `now - SnapshotRetention` after every install; there is no separate timer.
* A pinned `SnapshotView` is kept alive by the task's Go reference; removing that epoch from the store does not affect already-activated tasks. When the calls phase ends, `orchestrator_actor.go` sets `rt.functionCodeView` to `nil` so the writer phase no longer holds a historical snapshot.
* Startup: `setupFunctionCodeView` completes `syncer.Bootstrap` before the gRPC service starts; failure calls `os.Exit(1)` directly. Therefore the first snapshot is guaranteed to be published by the time the Worker becomes externally visible.
* Idempotency: `InstallSnapshot` returns the current epoch with `created=false` for a logically identical view; `TaskFunctionView.RegisterInline` does not re-hash the same `*FunctionCode` pointer; binding the same `functionID` to different source, or colliding with a snapshot function name, "poisons" that ID so subsequent dispatches fail deterministically.
* Audit modes (`FunctionCodeAuditMode`): `off` (default; no daemon, no gate), `enforce` (fail-closed; the Worker fails to start if the daemon pool fails to start), `dark` (audits and logs the same way but does not block; if the daemon pool fails to start, it degrades to off with a warn).

## Configuration

The following fields come from `internal/worker/app/config.go` (`WorkerFullConfig`); see `internal/worker/app/app.go` for environment variable overrides.

| Field                                          | Environment variable                   | Default                                                | Description                                                                                             |
| ---------------------------------------------- | -------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
| `FunctionSnapshotRetentionMs`                  | `FUNCTION_SNAPSHOT_RETENTION_MS`       | `0`, meaning `Worker.MaxTaskTimeoutMs + 10s`           | Retention window for historical snapshots. `Validate` requires it to be no less than `MaxTaskTimeoutMs` |
| `FunctionCodeAuditMode`                        | `FUNCTION_CODE_AUDIT_MODE`             | `""` (equivalent to `off`)                             | `off` / `enforce` / `dark`                                                                              |
| `FunctionCodeAuditSpaceAllowlist`              | `FUNCTION_CODE_AUDIT_SPACE_ALLOWLIST`  | empty                                                  | Comma-separated list of `Space` values that bypass the gate                                             |
| `FunctionCodeRedis.URL`                        | `FUNCTION_CODE_REDIS_URL`              | empty                                                  | When non-empty, takes precedence over BlockDB as the code source                                        |
| `FunctionCodeRedis.FunctionKey`                | `FUNCTION_CODE_REDIS_KEY`              | `chaintable:v12:function`                              | Redis hash key                                                                                          |
| `FunctionCodeRedis.PollIntervalMs`             | `FUNCTION_CODE_REDIS_POLL_INTERVAL_MS` | `0`, meaning the syncer's `defaultPollInterval` of 60s | Redis full refresh period                                                                               |
| `FunctionCodeRedis.QueryTimeoutMs`             | none                                   | 5000                                                   | Timeout for a single `HGetAll`                                                                          |
| `FuncDebug`                                    | none                                   | `false`                                                | Forces the devstub in-memory function store                                                             |
| `PythonBin`                                    | none                                   | `python3`                                              | Interpreter shared by the audit daemon and the Executor                                                 |
| `BlockDB.TableReadAddr` / `TableSubscribeAddr` | see `internal/sdk/blockdb`             | empty                                                  | Falls back to devstub when either is empty and Redis is not configured                                  |

The remaining audit pool parameters are hard-coded in `newFunctionCodeAudit`: `Size: 2`, `Module: "blockx_audit"`; `audit.Config.withDefaults` fills in `CallTimeout` 10s and `MaxCache` 4096. The BlockDB syncer's `ReconnectDelay` defaults to 200ms and is not exposed as Worker configuration.

<Note>
  The `redis(key=... poll=...)` description printed by `setupRedisFunctionCodeView` says 120s when `PollIntervalMs` is not configured, but the value actually in effect is the 60s from `fcredis.SyncConfig.withDefaults`.
</Note>

## Extension points

* Adding a code source: implement a loader shaped like `redis.Source`, write a syncer that holds a `*fccore.SnapshotStore` and publishes complete views only through `InstallSnapshot`; add a branch in `setupFunctionCodeView` that returns `functionCodeSetup{provider, resolver, start, close}`. Never let the query path perform external IO.
* Extending the audit allowlist: edit `python/blockx_audit/tables.py` (plus `kinds.py` and `auditor.py` when kinds are involved), and update the facade in `python/blockx_executor/restricted_runtime.py` and `python/tests/test_audit_*.py` in step. See `docs/specs/function-code-python-whitelist.md` §13 in the blockx repo for the maintenance tables and self-check list.
* Changing the daemon protocol: the Go side `internal/functioncode/audit/proc.go` and the Python side `python/blockx_audit/daemon.py` must be updated together (frame format, hello frame, `Result` field names), along with `python/tests/test_audit_protocol.py`.
* Adding gate semantics or error classifications: edit `internal/functioncode/audit/gate.go` (`Check` / `Observe` / `RejectionError`) and `internal/worker/adapters/audit_gate.go`.
* Registering test functions for local development: `newDevFunctionCodeStore()` in `internal/worker/app/function_code.go` calls `MemoryFunctionCodeStore.Register`.

## Testing

```bash theme={null}
# Go side: core / syncer / audit pool
go test ./internal/functioncode/... -short
# Worker assembly and gate
go test ./internal/worker/app/ -run 'FunctionCode|FunctionSnapshot|SetupFunctionCodeView' -short
go test ./internal/worker/adapters/ -run FunctionAuditGate -short

# Python side: auditor, protocol, Executor gate
uv sync --project python
PYTHONPATH=python uv run --project python python -m unittest discover -s python/tests -p 'test_audit_*.py'
PYTHONPATH=python uv run --project python python -m unittest python.tests.test_executor_audit_gate
```

* `internal/functioncode/core/*_test.go`: immutability, epoch never going backwards, `Pin` sharing the view, pinned views remaining usable after pruning, pruning by `SupersededAt`, rejection of inline / snapshot name collisions.
* `internal/functioncode/adapters/blockdb/syncer_test.go`: `Bootstrap`'s subscribe/scan/replay, event ordering, resubscribing from `lastApplied` on reconnect, duplicate events not bumping the epoch.
* `internal/functioncode/adapters/redis/*_test.go`: payload decoding, rate-limited refresh failure logs, `InstallAudit` trigger conditions; `TestRedisSourceLive` requires `FUNCTION_CODE_REDIS_URL` and is skipped otherwise.
* `internal/functioncode/audit/*_test.go`: `auditor_test.go` starts a real daemon (depends on `python/.venv`, skipped if missing); `gate_test.go`, `space_allowlist_test.go`, `proc_robustness_test.go` cover gate semantics and process crash / timeout replacement.
* `internal/worker/app/function_code_test.go`, `function_code_audit_test.go`: source selection, retention resolution, startup behavior of the three audit modes.
* `python/tests/test_audit_*.py`: `test_audit_features.py` (subset rules), `test_audit_tables.py` / `test_audit_kinds.py`, `test_audit_bytecode.py`, `test_audit_protocol.py` (daemon frame protocol), `test_audit_corpus.py` (v12 function corpus). `test_executor_audit_gate.py` covers the Executor's gate re-verification.
* E2E: `cmd/worker/worker_process_function_code_test.go` (miniredis end to end), `worker_process_activation_test.go` (`STUB_EPOCH_FAIL` triggers activation failure), `worker_process_localtestservice_test.go` (passes through the gate under `FUNCTION_CODE_AUDIT_MODE=enforce`). See [Testing](/en/development/testing) for the overall test organization.

## Related docs

Specs in the blockx repo:

* `docs/specs/function-code-view.md`: detailed design of snapshots, epochs, retention and pruning, and the query chain.
* `docs/specs/function-code-audit-design.md`: the audit mechanism, the two gates, error codes, and the Executor restricted runtime.
* `docs/specs/function-code-python-whitelist.md`: the complete allowlist, aligned table by table with `blockx_audit`.
* `docs/specs/2026-07-23-execute-call-function-code-reference.md`: the protocol decision that `ExecuteCall` sends only the digest and fetches source on a miss.
* `docs/specs/architecture.md` §4.2.4.4: where Function Code View sits in the overall architecture.
* `docs/specs/sync-invoker.md` §3.1: the relationship between `Precheck` and audit modes.

Related pages on this site:

* [Worker](/en/components/worker): task activation and the Orchestrator.
* [Call execution subsystem](/en/components/call-execution): the dispatcher and executor adapter.
* [Python Executor](/en/components/python-executor): `ModuleRegistry` and the restricted runtime.
* [Sync Invoker](/en/components/sync-invoker): `Precheck` and auditing for synchronous invocation.
* [Protocols and interfaces](/en/architecture/protocols): UDS `ExecuteCall` / `CallWaiting` / `ResumeCall`.
