Visual guide to C1–C4#

The first four enforcing constraint types answer four different questions about the observed architecture graph: does a component exist, does it use the governed edge, does a prohibited import exist, and does an extracted component live under a prohibited path? This is a visual reading aid; the constraint taxonomy in the specification is normative.

The module-graph notes on C2 and C3 describe profiles released in bce-engine@0.3.0, alongside the framework-specific semantics shown in the diagrams.

ConstraintQuestion BCE answersEvidence graded
C1 requiredComponentDoes at least one component of this type exist?observed component set
C2 requiredDependencyDoes every target component have the governed outgoing edge?observed components and edges
C3 forbiddenDependencyDoes any matching importer point to the prohibited module?observed import edges
C4 forbiddenPathDoes an extracted component path match the prohibited glob?extracted component paths

C1 — requiredComponent#

C1 requiredComponent compares a required pluginSurface type with the observed component set. Finding zero pluginSurface components produces exactly one blocking violation.

C1 is a presence assertion over component types. It does not count source files or accept a filename as proof. The selected extractor must recognize at least one component of the named type; zero observed components produces one violation.

C2 — requiredDependency#

C2 requiredDependency compares every observed pluginSurface with its required provides edge. A greeting plugin without governed registration blocks, and finding zero target components also fails closed.

C2 is universal over the target component set: every matching component needs a satisfying outgoing edge. A missing edge produces a violation anchored to that component. An empty target set also produces a violation, because “nothing existed to check” cannot prove a governed registration path.

Under typescript-module-graph and python-module-graph, C2 uses scopePaths for importer modules and a to selector for the required direct target. The component is typescriptModule or pythonModule, respectively. A matching source with no such edge fails; unresolved imports cannot be used as proof of the required edge.

C3 — forbiddenDependency#

C3 forbiddenDependency finds an observed import from greeting.plugin to axios at src/greeting.plugin.ts line 16 and emits one blocking no-direct-http-client violation.

C3 inspects real import edges. from may name one component or use * for any importer; optional scopePaths narrow which importer files count. Every matching edge to to is a separate violation, including an import from a file the extractor could not attribute to a recognized component.

Under both module-graph profiles, C3 filters only imports edges, uses scopePaths for importer modules, and requires from to be absent or *. Both accept module: and package: targets; TypeScript also accepts builtin:. An unresolved import inside the source scope fails closed because BCE cannot prove that it avoids the forbidden target. See the TypeScript and Python module-graph guides.

C4 — forbiddenPath#

C4 forbiddenPath finds an extracted legacy.plugin component under src/legacy, matches the prohibited path glob, and emits one blocking violation. Raw files that extract no component require C5 forbiddenFile instead.

C4 compares paths attached to extracted components with the declared glob. That distinction is deliberate: to reject every scanned file under a path even when it produces no component, use C5 forbiddenFile.

Read a result#

All four constraints flow through the same evaluator and report contract. A graded violation exits 1 in enforced mode; an inability to grade honestly exits 2. The report names the constraint, severity, component, observed fact, expected fact, and a file-and-line evidence reference where the extractor can provide one.

Declared-stack rules — released in 0.5.0#

The public 0.5.0 release adds five declared-stack rules to the ordinary gate to selected dependency, image and Node declarations. See the accepted enforcement RFC and normative specification.

RuleRequirement
pinnedVersionEvery matching non-root package has the exact version, every matching selected image has the exact digest, or the selected Node declaration has the exact version; a match must exist.
stackClosureMatchThe canonical declared stack digest equals the expected digest; this does not prove installed state or dependency topology.
forbiddenStackPackageNo modeled non-root package has the prohibited name, including transitive packages; opaque identities prevent proof of absence.
requirePinnedImagesAt least one selected external image exists, and every selected image carries a syntactically valid SHA-256 digest.
allowedNodeVersionsThe declared Node version belongs to an explicit set of exact versions; this does not inspect the executing Node process.

Author minEngineVersion: "0.5.0", required declaredStack evidence with onMissing: "block", and an explicit stack source block: one supported root npm-v3 or pnpm-v9 lockfile, package.json, and exact imageFiles and runtimeFiles lists. Lists are required even when empty; they do not enable discovery. Image rules cover the selected files, not every image in the repository. The RFC provides the complete JSON shape and path restrictions.

Missing inputs, conflicting declarations and insufficient relevant evidence refuse with exit 2, verdict indeterminate and a null score. Selected Compose parsing currently records incomplete image evidence, so it cannot establish a passing image-policy result. Selected pnpm workspace grading is unsupported and refuses; root-only pnpm is supported. Unsupported Dockerfile syntax, unresolved image variables and non-exact Node declarations also prevent relevant grading. An npm peer explicitly marked optional in peerDependenciesMeta may be absent without making unrelated image or runtime evidence indeterminate; missing non-optional dependency edges still refuse conservatively. Advisory mode and baselines do not turn these refusals into passes.

Version 2 evidence bundles support offline replay of the selected facts and policy. Verification checks artifact bindings and re-evaluates the report: it proves internal consistency, not source provenance, authenticity or deployed state. A coherently rewritten unsigned bundle does not establish who produced its inputs. Repair automation and cross-repository coordination are deferred.

Read Markdown · Source: docs/constraint-guide.md