beam4pm
beam4pm is a BEAM-first process-mining substrate whose application source is
manufactured entirely by ggen from an
RDF ontology and a vendored ggen-marketplace pack. There is no generated/
directory: manufactured code lives in the same src/, lib/, test/,
gleam/, schema/, and docs/reference/ directories hand-authored code
would use — provenance is signalled per-file by a GENERATED by ggen ... Do not edit. header, never by directory placement. beam4pm_pro is the planned
future commercial layer on top of this substrate; its core reconciliation
modules already exist as real code with matching test suites
(beam4pm_billing/BeamPM.Billing, MP6 usage/billing reconciliation;
beam4pm_entitlement/BeamPM.Entitlement, MP3 entitlement reconciliation) —
the remaining gap is marketplace/pricing/RevOps tooling, not these core
modules (PRO_CAPABILITY_SEEDS: PARTIAL_ALIVE), and no separately
installable/licensed beam4pm_pro product boundary, distribution channel, or
control plane exists yet (PRO_PRODUCT_BOUNDARY: UNSUPPORTED,
PRO_DISTRIBUTION_AND_UPGRADE: UNSUPPORTED, PRO_CONTROL_PLANE: UNSUPPORTED).
See docs/jira/v26.8.29/ for the full doctrine, vision,
and RevOps package, and docs/v26.8.30/README.md
for the current gap-closure status and acceptance criteria.
Source-authority doctrine
Direct edits to application source are refused by default, for humans and LLMs
alike. The only legitimate manufacturing inputs are ontology.ttl, ggen.toml,
rebar.config, mix.exs, src/beam4pm.app.src, and the templates inside the
vendored ggen-marketplace pack
(vendor/ggen-marketplace/packs/beam4pm-process-model-pack). Any file whose
first line reads GENERATED by ggen ... Do not edit. is ggen output and must
never be hand-edited, regardless of which directory it lives in — if it's
wrong, fix the ontology or the pack's templates and regenerate. See
docs/jira/v26.8.29/03-architecture-and-ggen-manufacturing.md
for the full policy, including the narrow, receipted privileged-exception path
for direct intervention.
Current status
A wide, still-growing slice, manufactured via the beam4pm-process-model-pack
(vendor/ggen-marketplace/packs/beam4pm-process-model-pack) from the
bpm:RecordType individuals currently admitted in ontology.ttl (981 as of
2026-09-27; the pre-WS2 slice was 290, and the merge-day 2026-09-27 merge
added 30 bpm:aloop_*_rt ALOOP episode-loop record types).
- 981 record types admitted in the graph (still 647
Ash.Resourcemodules — see below; the 30 ALOOP episode-loop record types added on merge-day 2026-09-27 have no Ash projection yet). The original process-mining/runtime core is still there — event/log identity (ocel_event,ocel_object,ocel_relationship,event_log,event_type,object_type,ocel_attribute,object_attribute_change,log_trace), process models (dfg_edge,petri_place,petri_transition,petri_arc,path_schema,path_schema_query,type_edge,heuristic_arc), conformance/alignment (alignment_move,conformance_result,oc_declare_constraint,process_variant,case_stats,sojourn_time,sync_time), and adjacent runtime/planning/policy concepts (resource_allocation,queue_snapshot,service_span,k8s_object_ref,planning_action,planning_state,policy_decision) — but most of the growth from the original 31 is thebeam4pm_procommercial/RevOps/compliance domain (billing, entitlement, tenant, procurement, renewal, support, and security/audit-evidence types such asbilling_account,entitlement_grant,tenant_resource_quota,renewal_risk,vulnerability_scan_evidence). Seedocs/reference/beam4pm_types_reference.md(itself ggen-generated) for the full, exact field-level reference of all 981. - Four projections: Erlang, Elixir, Gleam (
gleam/, with two disclosed type divergences noted in its generated comments), and Ash (lib/beam4pm_ash/resources/— 647Ash.Resourcemodules, one file per resource — manufactured by a second, Elixir-native engine: theggen_igniterhex package viascripts/igniter_sync.sh; its manifest probe renders byte-identical to the Rust ggen output). - Each type is a data structure plus a validating constructor
(
new_<type>/1in Erlang, the equivalent in Elixir/Gleam) that checks required fields are present and returns{ok, Record}or{error, {missing_field, Field}}. A reflection manifest (beam4pm_types_manifest/BeamPM.Types.Manifest) lists every admitted record and its field names. A generated JSON Schema (schema/beam4pm_types.schema.json) documents the wire shape of every type. - First real process-mining behavior: generated codecs
(
beam4pm_codec/BeamPM.Codec— map/JSON in both directions) and discovery/conformance (beam4pm_discovery/BeamPM.Discoveryand the Gleambeam4pm/discovery—traces_from_events/2,dfg_from_traces/1,conformance/2). No alignment search, no Petri-net replay.conformance_result.precisionIS computed in all three projections — real ETC (escaping-edges) precision viabeam4pm_precision:etc_precision/2,3(src/beam4pm_precision.erl,lib/beam4pm_precision.ex), called fromsrc/beam4pm_discovery.erl:243, and via Gleam'sbeam4pm/precision(gleam/src/beam4pm/precision.gleam), called fromgleam/src/beam4pm/discovery.gleam:149. - Cross-language identity is proven for THREE directions:
bash scripts/roundtrip_check.shround-trips every admitted record type × full/minimal variants over the JSON wire between Erlang and Elixir in both directions, and verifies the same Erlang-written samples through the Ash/BeamPM.Codecpath a third way (Ash's identity relation isDateTime.compare == :eqfor datetime fields, not byte identity; the synthetic:idprimary key is the one disclosed Ash-only attribute). Gleam has no codec leg yet. bash playground/playground.shruns the fresh-user workflow end to end from a cleangit clone --recurse-submodules— manufacture, all three test suites, real discovery demos in Erlang/Elixir/Gleam, and the roundtrip proof. Gate-by-gate standing:docs/jira/v26.8.29/16-gate-closure-m0-m6.md.- A DfCM planning crown,
BeamPM.Dfcm(lib/beam4pm_dfcm.ex): SELECT-only with deliberately no DO surface (itsallocate_options/2delegates cascade allocation to the external certifiedcmcaCLI — see the 2026-09-28 admission wave below). It preserves admitted alternatives, applies explicit fences, records every exclusion with a deterministic receipt and falsifier, and returns either a decision-relevant observation request or a SELECT candidate. It composes the WS2 FOND/HDDL contracts and is Chicago-qualified against the formal HDDL/FOND fixtures (qualification/fixtures/dfcm/). - A replanning ladder,
BeamPM.ReplanRouter(lib/beam4pm_replan_router.ex): pureroute/2checks, in order, the stale preimage (:refuse_stale— includingpolicy_digestenforcement, so a plan that does not digest to the admitted policy is never followed) and malformed observations (:refuse_malformed), then climbs a monotone ladder:close→:reobserve→:follow_policy→:suffix_reuse→:session_replan→:hddl_replan→:strategic_recompile; the rung never moves down within an episode. Giving the observation's optional:observed_atmakes a replay produce byte-identical events. Each ladder step is linked byBeamPM.PlanLineage(lib/beam4pm_plan_lineage.ex), a sha256 hash chain over plan generations (digests of a canonical JSON rendering) whoseverify/1recomputes the chain and refuses the first link that does not match. - Plan admission is fail-closed by default (2026-09-28 admission wave,
commits
2a437a7e,82438aee,0f304857,6955b894,cf418a79):config :beam4pm, :admission_mode(config/config.exs) defaults to:required, so a solved candidate plan carrying no admission spec is refused{:error, {:admission_missing, _}}(lib/beam4pm_replan_router.ex); per-call opt-outs areadmission: :skip,graphlaw_court: false, andgraphlaw_gate: false. The graphlaw and ferroplan wasm engines run supervised underBeamPM.EngineSupervisor(lib/beam4pm_application.ex) — an engine child is started only when its artifact exists and, for graphlaw, the sha256 pin (native/graphlaw/graphlaw_wasm.wasm.sha256, written byscripts/graphlaw_wasm_fetch.sh) verifies and the running engine'scapabilitiesreports the expectedabi_version(ABI handshake,BeamPM.GraphlawAdmission,lib/beam4pm_replan_router.ex:1247-1310). - PDDL action models and independent policy admission (same wave):
BeamPM.ActionModel.from_pddl/2(lib/beam4pm_replan_router.ex:1470) derives aBeamPM.PlanAdmissionadmission spec from PDDL domain/problem text — STRIPS + typing, with negated plain atoms admitted aspre_not/goal_not(previously typed{:error, {:unsupported, _}});BeamPM.GraphlawAdmission.admit_policy/3(lib/beam4pm_replan_router.ex:1228) checks a ferroplanUniversalPlanstrong-cyclic via the graphlaw court ({:ok, admitted}or{:error, {:refused, refusal}}); andBeamPM.ReplanRouter.load_policy/4loads aUniversalPlaninto state only when it digests to the admittedpreimage.policy, running the graphlaw court by default in:requiredmode. BeamPM.Dfcm.allocate_options/2(lib/beam4pm_dfcm.ex) delegates cascade allocation to the external certifiedcmcaCLI (autofde cmca allocate): when the CLI is present but refuses (cardinality law, transport failure), a refused map with reason{:cmca_allocate_failed, detail}is returned — the uniform option-preserving fallback is never silently substituted for a real refusal. Authority ceiling stays:selectin every branch.Beam4PM.CastleCapabilityIntake(lib/beam4pm_castle_capability_intake.ex): a runtime-readable CASTLE capability donor registry admitting EX4PM only as a process-execution kernel behind Beam4PM's PROCESS_COORDINATION ownership — authority ceiling:construct,dispatch_authority?/1alwaysfalse, no actuation path.- Ash-native evidence emission via
AshEx4pm(26.10.1): the hex dep is in,Ex4pm.Evidence.Store(the emission sink) auto-starts, and the ingest / dedup / refusal / BRCE-gate contracts are test-pinned. The generated-resource wiring (extensions: [AshEx4pm]+ a create-onlyex4pmblock per resource) is rendered by the pack template from thebpm:ocelTypeExprladder and lands with the next Ash-leg regeneration (currently blocked by a pre-existing ggen_igniter reconciliation deadlock —docs/jira/v26.10.1/RESOLUTIONS.mdR14) — additive to beam4pm's own telemetry→OTel→OcelIngest/ReceiptChainchain, which is not rerouted through it.
Build and test
git clone --recurse-submodules <this-repo-url>
cd beam4pm
source scripts/env/rust4pm_reactor_env.sh # points RF2/RF3 tests at the built native oracle binaries
rebar3 eunit # EUnit tests over the generated Erlang types, manifest, and behavior (3100 at the 424d04c6 verified run; grows with the admitted graph)
mix test # ExUnit tests over the generated Elixir types, manifest, and behavior (1108 at the 424d04c6 verified run; grows with the admitted graph)
--recurse-submodules is required: three git submodules manufacture or back
this repo — vendor/ggen-marketplace (the pack that manufactures every
record type), native/ferroplan (the PDDL planner engine), and
vendor/rust4pm-powl (the reference process_mining crate the POWL 2.0 wire
types are checked against for field-shape parity). Skipping the
source scripts/env/rust4pm_reactor_env.sh step leaves RF2_ORACLE_BIN/
RF3_ORACLE_BIN unset, which fails 11 of the ExUnit tests loudly with a
System.EnvError naming the exact fix — never a silent skip.
A Rust/cargo toolchain is required, even though the primary manufacturing
pipeline (ggen/Tera) does not otherwise need Rust: compiling the ggen_igniter
hex dependency builds its oxigraph query engine as a Rustler NIF, and the
RF1/RF2/RF3 Chicago tests spawn real Rust subprocess oracles
(native/rf1-dfg-oracle, native/rf2-conformance-oracle,
native/rf3-ocel-oracle) — see scripts/igniter_sync.sh and
playground/playground.sh's own step 1/10 toolchain preflight, which checks
for cargo (alongside ggen, erlc, rebar3, elixir, mix, gleam) and
fails closed with BLOCKED: required tool 'cargo' not on PATH before
attempting the igniter sync, rather than failing deep into the build.
Regenerating
ggen sync run
(ggen.lock is committed at this pin — tracked again by the merge-day
2026-09-27 merge, dba2e267 — so a plain ggen sync run uses it; removing it
is only warranted after raising the vendor pin.) This re-runs the ggen pipeline against ontology.ttl and the vendored pack,
regenerating every manufactured file (see scripts/gate_m2_check.sh for the
authoritative marker-driven definition and current count) from scratch.
Full doctrine and vision
See docs/jira/v26.8.29/README.md for the
complete v26.8.29 package: architecture and manufacturing doctrine, product
requirements, pricing/packaging, GTM, security/airgap, release gates, and the
beam4pm_pro commercial vision.