EXPERIMENT: prohibition becomes a query over emitted relations
I said prohibition could not move because "a #error has no runtime". That
conflated two separable things: WHEN a violation is detected (build time --
correct, and unchanged) and WHERE the rule and the checker live (the compiler
-- assumed).
A prohibition is a containment relation over the call graph. So codegen now
records what it saw:
sneaky calls raw_sql
allowed calls raw_sql
allowed calls @repository
repository calls prohibits:raw_sql
and tools/check/prohibitions.sh decides, at build time, outside the compiler.
PREDICTIONS AND RESULTS
P1 codegen can emit the call graph it already walks TRUE
P2 the check becomes a query outside the compiler TRUE
P3 all prohibition decisions leave codegen TRUE zero #errors now
P4 violations still caught at build time TRUE exit=1
P5 codegen drops below the 4661 baseline FALSE 4962, +301
P5 is the finding. The TRAVERSAL is irreducible -- you must walk the AST to
find calls, and those ~120 lines do not move no matter who decides. What is not
irreducible is the rule (which names) or the decision (#error). Those left. I
predicted the whole 223 lines would go because I had not separated walking from
adjudicating.
Still compiled, and measured rather than assumed: the capability-tier system
(cap_check_call, is_self_formation_call, is_dharma_call, is_llm_call,
cap_record_violation, emit_cap_violations) is 76 lines of the same shape --
prohibits_WITHIN rather than prohibits_outside, so the checker needs the
opposite polarity to absorb it.
98/98 native, 4/4 prohibition_query.sh, 7/7 seam_binding.sh, fixpoint ok.
This commit is contained in:
@@ -806,23 +806,8 @@ test "undeclared-guard-emits-nothing" {
|
||||
// ── Declared constructs: wraps and prohibitions ──────────────────────────────
|
||||
|
||||
|
||||
test "declared-prohibition-fires-outside-the-boundary" {
|
||||
let src: String = "@decorator(\"prohibits_outside\", \"raw_sql\")\nfn repository() {}\nfn sneaky() -> Int { raw_sql(\"DROP\") return 1 }"
|
||||
let out: String = compile_capture(src)
|
||||
assert str_contains(out, "raw_sql may only be called from an @repository fn"), "a program-declared prohibition is enforced"
|
||||
}
|
||||
|
||||
test "declared-prohibition-permits-inside-the-boundary" {
|
||||
let src: String = "@decorator(\"prohibits_outside\", \"raw_sql\")\nfn repository() {}\n@repository\nfn allowed() -> Int { raw_sql(\"SELECT\") return 1 }"
|
||||
let out: String = compile_capture(src)
|
||||
assert !str_contains(out, "raw_sql may only be called"), "the owning construct permits the call"
|
||||
}
|
||||
|
||||
test "seeded-vbd-prohibition-still-enforced" {
|
||||
let src: String = "fn leaky() -> Int { dharma_emit(\"x\", \"y\") return 1 }"
|
||||
let out: String = compile_capture(src)
|
||||
assert str_contains(out, "may only be called from an @manager fn"), "the compiled-in core prohibition survives being declared rather than branched"
|
||||
}
|
||||
|
||||
// ── Runtime seam ─────────────────────────────────────────────────────────────
|
||||
//
|
||||
@@ -925,3 +910,17 @@ test "zero-param-fn-emits-valid-c" {
|
||||
assert str_contains(out, "struct __env_noargs { char __e0; };"), "zero-param env has a field"
|
||||
assert !str_contains(out, "__env = { }"), "and no empty initialiser"
|
||||
}
|
||||
|
||||
|
||||
// ── Prohibition is a query, not an emission ─────────────────────────────────
|
||||
//
|
||||
// The compiler records what it saw -- who calls what, who carries what, who
|
||||
// prohibits what. Whether that is legal is decided by tools/check/prohibitions.sh
|
||||
// against the emitted relations, at build time. An emitter that also adjudicates
|
||||
// has to contain every rule anyone will ever want.
|
||||
|
||||
test "compiler-no-longer-emits-prohibition-errors" {
|
||||
let src: String = "@decorator(\"prohibits_outside\", \"raw_sql\")\nfn repository() {}\nfn sneaky() -> Int { raw_sql(\"DROP\") return 1 }"
|
||||
let out: String = compile_capture(src)
|
||||
assert !str_contains(out, "boundary violation"), "the emitter does not adjudicate"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user