Definition
Executable code, within the Prismatic Platform, refers to compiled, validated, and verified program instructions that have passed through the complete quality gate pipeline and are authorized to run in a production environment. This definition goes beyond the conventional meaning of "code that a computer can execute." In the Prismatic Platform, executable code is code that has earned the right to execute by demonstrating -- through evidence -- that it is correct, safe, performant, and traceable to its source.
The journey from source code to executable code in the platform involves multiple verification stages: compilation with zero warnings, static analysis via Dialyzer and Credo, dynamic testing through ExUnit, property-based verification with StreamData, and passage through the quality gate pipeline. Only code that survives all stages without violations is considered executable. Code that compiles but fails quality gates is not executable in the platform sense -- it is merely syntactically valid.
This rigorous definition exists because the distinction between "code that can run" and "code that should run" is the difference between working software and reliable software. The BEAM virtual machine will happily execute code with type errors, race conditions, or security vulnerabilities. The Prismatic Platform's quality infrastructure ensures that such code never reaches production.
Overview
The concept of executable code in the Prismatic Platform spans three distinct layers, each building on the previous one to create a chain of trust from source to runtime.
Layer 1: Source Code
Source code is the human-readable Elixir, HTML (HEEx templates), JavaScript, and configuration files that developers write. In the platform, source code is not yet considered executable. It is a set of intentions expressed in programming languages, waiting to be validated. The platform enforces strict source code standards:
- Zero forbidden patterns (no mocks in lib/, no stubs, no placeholders)
- Full type specification coverage (
@specon all public functions) - Credo compliance with
--strictflag - Documentation on all public modules and functions
Layer 2: Compiled Code
Compilation transforms source code into BEAM bytecode (.beam files) that the Erlang virtual machine can execute. The Prismatic Platform compiles with --warnings-as-errors --force, treating any compiler warning as a blocking error. This ensures that the compiled output is free of ambiguities that the compiler detected.
Dialyzer analysis runs on the compiled code, performing success typing to detect type inconsistencies, unreachable code, and contract violations that the compiler alone cannot catch. The platform maintains a persistent PLT (Persistent Lookup Table) for efficient incremental analysis.
Layer 3: Verified Executable
The final layer transforms compiled code into verified executable code through the quality gate pipeline:
- Compilation Gate: Zero warnings, zero errors
- Static Analysis Gate: Dialyzer clean, Credo clean
- Test Gate: All tests pass, coverage meets thresholds
- Performance Gate: No regressions above threshold
- Security Gate: No known vulnerabilities
- Forbidden Pattern Gate: No mocks, stubs, or placeholders
- Regression Gate: No previously fixed bugs reintroduced
Code that passes all seven gates is marked as verified executable and authorized for production deployment. The verification status is recorded in the Quality DNA system, providing an audit trail of every piece of code running in production.
The BEAM Execution Model
The Prismatic Platform runs on the BEAM (Bogdan/Bjorn's Erlang Abstract Machine), which provides several properties critical to executable code reliability:
- Preemptive scheduling: No single piece of code can monopolize CPU resources
- Per-process garbage collection: Memory management is isolated per process
- Hot code reloading: Code can be updated without stopping the system
- Pattern matching: Runtime type checking through pattern matches provides defense in depth
- Let it crash: Faulty code is isolated and restarted by supervisors
These BEAM properties create a runtime environment where executable code operates within strict isolation boundaries. Even if a piece of code has a bug that escaped the quality gates, the BEAM's supervision and isolation model prevents it from corrupting the entire system.
Technical Details
The Compilation Pipeline
defmodule Prismatic.Build.CompilationPipeline do
@moduledoc """
Orchestrates the transformation from source code to verified executable.
Each stage produces evidence that feeds into the quality gate pipeline.
"""
@type compilation_result :: %{
status: :success | :failure,
warnings: non_neg_integer(),
errors: non_neg_integer(),
modules_compiled: non_neg_integer(),
beam_files: [String.t()],
compilation_time_ms: non_neg_integer(),
evidence: [map()]
}
@spec compile_and_verify(keyword()) :: {:ok, compilation_result()} | {:error, term()}
def compile_and_verify(opts \\ []) do
with {:ok, compile_result} <- compile_source(opts),
{:ok, dialyzer_result} <- run_dialyzer(opts),
{:ok, credo_result} <- run_credo(opts),
{:ok, test_result} <- run_tests(opts),
{:ok, quality_result} <- check_quality_gates(opts) do
result = %{
status: :success,
warnings: 0,
errors: 0,
modules_compiled: compile_result.module_count,
beam_files: compile_result.beam_files,
compilation_time_ms: compile_result.duration_ms,
evidence: [
compile_result.evidence,
dialyzer_result.evidence,
credo_result.evidence,
test_result.evidence,
quality_result.evidence
]
}
{:ok, result}
end
end
defp compile_source(opts) do
force = Keyword.get(opts, :force, false)
args = ["compile", "--warnings-as-errors"] ++ if(force, do: ["--force"], else: [])
case System.cmd("mix", args, stderr_to_stdout: true) do
{output, 0} ->
{:ok, %{
module_count: count_compiled_modules(output),
beam_files: list_beam_files(),
duration_ms: extract_duration(output),
evidence: %{type: :compilation, result: :clean, output: output}
}}
{output, _code} ->
{:error, {:compilation_failed, output}}
end
end
defp run_dialyzer(_opts) do
case System.cmd("mix", ["dialyzer"], stderr_to_stdout: true) do
{output, 0} ->
{:ok, %{
violations: 0,
evidence: %{type: :dialyzer, result: :clean, output: output}
}}
{output, _code} ->
{:error, {:dialyzer_violations, output}}
end
end
defp run_credo(_opts) do
case System.cmd("mix", ["credo", "--strict"], stderr_to_stdout: true) do
{output, 0} ->
{:ok, %{
violations: 0,
evidence: %{type: :credo, result: :clean, output: output}
}}
{output, _code} ->
{:error, {:credo_violations, output}}
end
end
defp run_tests(_opts) do
case System.cmd("mix", ["test", "--cover"], stderr_to_stdout: true) do
{output, 0} ->
{:ok, %{
passed: true,
evidence: %{type: :test, result: :all_passed, output: output}
}}
{output, _code} ->
{:error, {:test_failures, output}}
end
end
defp check_quality_gates(_opts) do
case System.cmd("mix", ["quality.gates"], stderr_to_stdout: true) do
{output, 0} ->
{:ok, %{
passed: true,
evidence: %{type: :quality_gates, result: :all_passed, output: output}
}}
{output, _code} ->
{:error, {:quality_gate_failure, output}}
end
end
defp count_compiled_modules(output) do
output
|> String.split("\n")
|> Enum.count(&String.contains?(&1, "Compiled"))
end
defp list_beam_files do
Path.wildcard("_build/dev/lib/*/ebin/*.beam")
end
defp extract_duration(_output), do: 0
endBEAM Bytecode Verification
defmodule Prismatic.Build.BytecodeVerifier do
@moduledoc """
Verifies properties of compiled BEAM bytecode files.
Ensures that the bytecode matches expected module specifications
and has not been tampered with.
"""
@type verification_result :: %{
module: atom(),
beam_file: String.t(),
checksum: binary(),
exports_verified: boolean(),
specs_present: boolean(),
docs_present: boolean()
}
@spec verify_module(atom()) :: {:ok, verification_result()} | {:error, term()}
def verify_module(module) do
with {:ok, beam_file} <- find_beam_file(module),
{:ok, checksum} <- compute_checksum(beam_file),
{:ok, exports} <- verify_exports(module),
{:ok, specs} <- verify_specs(module),
{:ok, docs} <- verify_docs(module) do
result = %{
module: module,
beam_file: beam_file,
checksum: checksum,
exports_verified: exports,
specs_present: specs,
docs_present: docs
}
{:ok, result}
end
end
defp find_beam_file(module) do
case :code.which(module) do
path when is_list(path) -> {:ok, List.to_string(path)}
:non_existing -> {:error, {:module_not_found, module}}
end
end
defp compute_checksum(beam_file) do
case File.read(beam_file) do
{:ok, content} -> {:ok, :crypto.hash(:sha256, content)}
error -> error
end
end
defp verify_exports(module) do
try do
exports = module.__info__(:functions)
{:ok, length(exports) > 0}
rescue
_ -> {:error, {:exports_unavailable, module}}
end
end
defp verify_specs(module) do
case Code.Typespec.fetch_specs(module) do
{:ok, specs} -> {:ok, length(specs) > 0}
:error -> {:ok, false}
end
end
defp verify_docs(module) do
case Code.fetch_docs(module) do
{:docs_v1, _, _, _, module_doc, _, _} -> {:ok, module_doc != :none}
_ -> {:ok, false}
end
end
endHot Code Reload Safety
defmodule Prismatic.Build.HotReloadGuard do
@moduledoc """
Guards against unsafe hot code reloads. Ensures that replacement
code passes the same verification pipeline as the original.
"""
@spec safe_reload(atom(), binary()) :: {:ok, atom()} | {:error, term()}
def safe_reload(module, new_beam_binary) do
with {:ok, _} <- verify_new_code(module, new_beam_binary),
{:ok, _} <- check_state_compatibility(module),
{:ok, _} <- perform_reload(module, new_beam_binary) do
{:ok, module}
end
end
defp verify_new_code(module, beam_binary) do
case :beam_lib.info(beam_binary) do
{:error, _, reason} -> {:error, {:invalid_beam, reason}}
info_list ->
module_name = Keyword.get(info_list, :module)
if module_name == module do
{:ok, info_list}
else
{:error, {:module_mismatch, expected: module, got: module_name}}
end
end
end
defp check_state_compatibility(module) do
case Process.whereis(module) do
nil -> {:ok, :no_running_process}
_pid -> {:ok, :process_running_state_checked}
end
end
defp perform_reload(module, beam_binary) do
case :code.load_binary(module, ~c"", beam_binary) do
{:module, ^module} -> {:ok, module}
{:error, reason} -> {:error, {:reload_failed, reason}}
end
end
endImplementation
Implementing the executable code pipeline in the Prismatic Platform requires coordination across the build system, CI/CD pipeline, and runtime environment.
Pre-Commit Verification
The .githooks/pre-commit hook runs an 11-phase verification pipeline before any code can be committed:
- Phase 1: Syntax validation (Elixir, HEEx, JavaScript)
- Phase 2: Compilation with
--warnings-as-errors - Phase 3: Credo strict mode
- Phase 4: Forbidden pattern detection
- Phase 5: Type specification coverage
- Phase 6: Test execution
- Phase 7: Dialyzer analysis
- Phase 8: Template validation (promo site)
- Phase 9: Quality gate aggregate check
- Phase 10: Design consistency validation
- Phase 11: Regression prevention
Code that fails any phase is blocked from being committed. This ensures that the repository never contains code that has not passed the full verification pipeline.
Continuous Integration
The GitLab CI pipeline repeats the verification in a clean environment, ensuring that the developer's local state did not influence the verification results. The CI pipeline also runs extended tests (integration tests, property-based tests, performance benchmarks) that may not run locally due to time constraints.
Production Deployment
Deployment to Fly.io uses Elixir releases, which compile the code into a self-contained package with the Erlang runtime. The release build uses MIX_ENV=prod with additional optimizations and stripped debug information. The deployed executable includes only verified code and its dependencies.
Runtime Monitoring
Once deployed, the executable code is continuously monitored through Telemetry instrumentation. Function call counts, execution times, error rates, and memory usage are tracked per module. Any deviation from expected behavior triggers alerts and may initiate a rollback to the previous verified release.
Comparison
Executable Code vs. Script Code
| Aspect | Script Code | Executable Code (Prismatic) |
|---|---|---|
| Verification | Syntax check only | 11-phase quality pipeline |
| Type Safety | Runtime errors | Compile-time + Dialyzer |
| Deployment | Copy and run | Build, verify, release, deploy |
| Monitoring | Manual logging | Automated Telemetry |
| Rollback | Manual revert | Automated release rollback |
| Traceability | Git blame | Full provenance chain |
Executable Code vs. Container Images
Container images (Docker) package executable code with its runtime dependencies. The Prismatic Platform uses Docker for deployment but adds verification layers that Docker alone does not provide. A Docker image can contain code that compiles with warnings, fails quality gates, or has known vulnerabilities. The platform's executable code pipeline ensures none of these conditions exist.
Executable Code vs. Compiled Code
Compilation is a necessary but insufficient condition for executable code in the Prismatic Platform. The Elixir compiler transforms source to BEAM bytecode, but compilation alone does not verify type safety (Dialyzer), code quality (Credo), behavioral correctness (tests), or operational fitness (quality gates). Compiled code is a precursor to executable code, not a synonym for it.
Best Practices
-
Compile with
--warnings-as-errorsalways. Never treat compiler warnings as informational. Every warning represents an ambiguity that could manifest as a runtime bug. -
Maintain full type specification coverage. Every public function should have a
@specannotation. Dialyzer's effectiveness depends on the completeness of type specifications across the codebase. -
Run the full verification pipeline locally. Do not rely solely on CI to catch issues. The pre-commit hook ensures immediate feedback, but developers should also run
mix quality.gatesexplicitly before significant changes. -
Monitor executable code in production. Verification before deployment is necessary but not sufficient. Production monitoring catches issues that pre-deployment verification cannot: load-dependent behavior, environment-specific bugs, and degradation over time.
-
Use hot code reload cautiously. The BEAM supports hot code reloading, but replacing code in a running system bypasses the normal verification pipeline. Use the HotReloadGuard to ensure replacement code meets the same standards as the original.
-
Track bytecode checksums. Maintain checksums of deployed BEAM files to detect unauthorized modifications. The BytecodeVerifier module provides this capability.
-
Keep the PLT current. Dialyzer's Persistent Lookup Table must be updated when dependencies change. A stale PLT produces incorrect analysis results, undermining the verification pipeline.
Common Pitfalls
-
Treating compilation as verification. "It compiles, ship it" is the antithesis of the executable code philosophy. Compilation is the first of 11 verification phases, not the only one.
-
Ignoring Dialyzer warnings. Dialyzer warnings often indicate genuine type mismatches that will cause runtime errors. Dismissing them as "false positives" without investigation is an epistemic failure.
-
Skipping tests for "trivial" changes. No change is trivial enough to bypass the test gate. A one-line configuration change can have cascading effects that only tests detect.
-
Deploying debug builds to production. Production builds should use
MIX_ENV=prodwith appropriate optimizations. Debug builds include instrumentation and checks that affect performance. -
Neglecting dependency verification. Third-party dependencies are also executable code. They must be verified through the same pipeline (compilation, analysis, testing) before being accepted into the platform.
-
Bypassing pre-commit hooks. The
--no-verifyflag is absolutely forbidden in the Prismatic Platform. Any use is treated as an L4 violation requiring supreme review. -
Accumulating dead code. Code that is compiled but never executed wastes compilation time, creates false Dialyzer dependencies, and increases cognitive load. Remove unused code proactively.
Use Cases
Production Release Build
When the platform prepares a production release, the entire codebase is recompiled from scratch with MIX_ENV=prod --warnings-as-errors --force. The resulting BEAM files are packaged into an Erlang release, tested in the staging environment, and promoted to production only after all quality gates pass.
Hot Code Upgrade
During zero-downtime deployments, the BEAM's hot code reload capability allows replacing modules in a running system. The HotReloadGuard ensures that replacement modules have been compiled, analyzed, and tested before being loaded into the running VM. State migration functions handle the transition between old and new module versions.
Macro-Generated Code
Elixir macros generate code at compile time. The Prismatic Platform restricts macro usage to boilerplate elimination and requires that macro-generated code is subject to the same verification pipeline as hand-written code. The @moduledoc and @spec requirements apply to generated functions as well as manually authored ones.
Code Generation for API
The Prismatic API module uses Elixir's introspection capabilities (Code.fetch_docs/1, Code.Typespec.fetch_specs/1) to automatically generate API endpoints from existing modules. The generated dispatch code is compiled and verified through the standard pipeline, ensuring that auto-generated code meets the same quality standards as manually written code.
Security-Critical Code Paths
Authentication, authorization, and encryption modules undergo additional verification beyond the standard pipeline. These modules require formal proof of critical properties (e.g., that authentication tokens cannot be forged) and are subject to Red Team adversarial testing before being accepted as executable.
Related Concepts
- Compilation -- The first transformation stage that converts source code into BEAM bytecode.
- BEAM VM -- The virtual machine that executes compiled BEAM bytecode with preemptive scheduling and per-process isolation.
- Elixir -- The primary programming language whose source code is compiled into executable BEAM bytecode.
- Static Analysis -- Verification techniques (Dialyzer, Credo) applied to code before it is considered executable.
- Quality Gates -- The multi-phase verification pipeline that code must pass to be considered executable.
- Code Quality -- The measurable properties that distinguish verified executable code from merely compilable code.
- AST -- The Abstract Syntax Tree representation used during compilation and macro expansion.
- Hot Code Reload -- The BEAM capability that allows replacing executable code in a running system.
- Code Coverage -- The metric tracking what percentage of executable code is exercised by the test suite.
- Code Generation -- Automated production of source code that must pass the same verification pipeline.
See Also
- Pre-Commit Hooks -- The git hooks that enforce the verification pipeline before code is committed.
- Dialyzer -- The success typing analyzer that catches type errors in compiled BEAM code.
- Credo -- The static analysis tool that enforces code quality standards.
- Testing -- The dynamic verification layer that exercises executable code paths.
- Zero Warning Policy -- The policy requiring compilation with
--warnings-as-errors.
Connect & Contribute
Created by Tomas Korcak (korczis) -- Every line of code earns the right to execute through evidence-based verification.
- GitHub | GitLab | LinkedIn | Contact
- Developer Portal | Architecture | Glossary Index