Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,10 @@ jobs:
# #1040 A32 reloc type, #1080 extraction snapshots). An open issue
# with no rivet artifact is invisible to the release plan and
# resurfaces as a cut-time surprise — the issue-hunt anti-pattern.
ARTIFACT_FLOOR=484
# 484 -> 486: #1102 (rv32 dangling synth_func_N on a declined
# internal, exit 0) and #1100 (MC/DC report-side floors are
# layout-coupled), both triaged in the same wave that found them.
ARTIFACT_FLOOR=486
MEASURED=$(rivet list 2>/dev/null | grep -Eo '^[0-9]+ artifacts$' | tail -1 | cut -d' ' -f1)
echo "artifact-load floor=$ARTIFACT_FLOOR measured=${MEASURED:-<none>}"
if [ -z "$MEASURED" ]; then
Expand Down
20 changes: 20 additions & 0 deletions artifacts/release-v0.61/RQ-61-CICAP.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,23 @@ artifacts:
verification-track: review
issue: "#1062"
done-when: "manual: at least the plain-cargo required jobs run on rust-cpu, each moved in its own PR with a green cycle; Bazel and Z3 only after their toolchains are proven on that pool"
# INCREMENT 1 LANDED as #1101 — recorded here rather than flipping the
# status, because the artifact is explicitly multi-increment and the
# REQUIRED jobs (the ones that actually block merges) have not moved.
# `landed:` is the machine-readable "increment landed, the artifact is
# not done" that R4 exists to demand; silence would be red, and a flip
# to `implemented` would claim an outcome that has not happened.
#
# WHAT INCREMENT 1 MEASURED, and it corrects the plan rather than
# confirming it: the moved job ran on pulseengine-ci-01-10 and passed,
# but timing against main's ubuntu-latest run of the same job was
# rust-cpu queue 3s exec 67s total 70s
# ubuntu-latest queue 4s exec 37s total 41s
# — the self-hosted runner is ~2x SLOWER to execute and the queue wait
# was equal, because the queue was empty at that moment. The benefit is
# CONTENTION RELIEF on the required path, not per-job speed, so the
# conclusion is MOVE LESS, NOT MORE: each further move needs its own
# contention justification and re-measurement, and one that neither
# relieves contention nor runs faster should be reverted rather than
# kept for tidiness.
landed: "#1101 (increment 1 — one non-required job retargeted)"
60 changes: 60 additions & 0 deletions artifacts/release-v0.61/RQ-61-DANGLE.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
artifacts:
- id: RQ-61-DANGLE
type: system-req
title: "rv32 ships an unlinkable object with exit 0 when a retained function calls a DECLINED internal function"
description: >
#1102 (gale), reproduced by the coordinator on a minimal 10-line module
rather than on the reported real-world driver.

A retained function that calls a declined INTERNAL function emits an
undefined `synth_func_N` and the compile EXITS 0:

(func $big (param i32) (result i32) ;; declines on rv32:
(i32.load offset=1048588 (local.get 0)));; "immediate too large"
(func (export "entry") (param i32) (result i32)
(call $big (local.get 0)))

warning: skipping function 'func_0' ... immediate 1048588 too large
Compiled 1 functions EXIT=0
symtab: defined ['entry'] · UNDEFINED ['synth_func_0']
ld.lld: undefined symbol: synth_func_0

WHY THE EXISTING GUARDS MISS IT, and this is the reusable part: #952
converts a declined REQUESTED EXPORT into a non-zero exit, and #1013
gave aarch64 a refusal for the same class. Both are keyed on EXPORTS.
`func_0` here is INTERNAL — nobody requested it, so no export guard
fires — yet an exported entry point relocates against it. The mechanism
exists and is pointed one level too shallow, which is this release's
recurring shape.

CROSS-BACKEND, MEASURED on a module every backend now declines (a
parameter-taking block type, #1093):

rv32 exit 0, dangling `synth_func_0` <- the defect
aarch64 exit 1, refuses <- #1013's guard working
arm thumb-2 / a32 exit 0 with the skip, and NOT YET CHARACTERISED —
synth's ARM relocatable objects carry `.rel.text` with NO `.symtab`
in this configuration, so the symtab probe that works for rv32 and
aarch64 cannot answer the question. NOTE FOR WHOEVER TAKES THIS:
a HEALTHY ARM object (no declines) has the same shape, so the
absent symtab is pre-existing and is NOT evidence of the defect —
the coordinator nearly recorded it as one. ARM needs a different
probe (resolve the reloc's `r_info_sym` against whatever symbol
source the ARM path actually emits) before any claim either way.

THE FIX SHAPE, not the fix: match aarch64's refusal — a relocation
against a function the backend declined must fail the compile loudly,
as #952 does for exports. Do not fabricate a stub, and do not silently
drop the call: both convert an unlinkable object into a wrong one.
status: proposed
release: v0.61
tags: [riscv, elf, relocations, decline-honesty, silent-failure]
links:
- type: derives-from
target: BR-001
fields:
req-type: functional
priority: must
verification-track: differential
issue: "#1102"
done-when: "manual: a retained function relocating against a declined internal function fails the compile loudly on rv32; ARM characterised either way with a probe that works on its object shape; aarch64's exit-1 behaviour unchanged"
55 changes: 55 additions & 0 deletions artifacts/release-v0.61/RQ-61-MCDCFLOOR.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
artifacts:
- id: RQ-61-MCDCFLOOR
type: system-req
title: "The MC/DC gate's report-side floors are layout-coupled — adding code anywhere moves them, and re-stating a number each time is not a gate"
description: >
#1100, filed from RQ-61-MVPANIC's second red and its manifest diff.

Adding the #1093 arity guard moved witness's REPORT-side reconstruction
on functions the change never touched: 32 dec / 141 cond / 60 proved ->
27 / 132 / 56, with the loss decomposing onto `sp_slot_store` (-2, its
full_mcdc decision vanishing from the report),
`validate_final_allocation_rv32` (-4 on a 13->12 regrouping),
`build_options` (-1) and `validate_reloc_resolutions` (-1).

THE INSTRUMENT SIDE SAYS NOTHING WAS LOST — verified independently with
the gate's own extraction: 175 -> 176 scored branches across 20
functions, exactly ONE population differing
(`compile_function_with_opts` 9 -> 10, the intended guard), and 19/19
of the equal-count functions carrying byte-identical
`(kind, instr_index)` signatures.

So the report-side floors measure witness's layout-sensitive decision
reconstruction as much as they measure synth's coverage. This is the
SECOND instance (after #990/RQ-59-ZEROINIT) and it was handled the same
way — a re-statement WITH evidence, FLOOR_PROVED 57 -> 56, zero slack,
per the protocol already written into `scripts/mcdc_gate.py`.

THE PROBLEM WITH THAT BEING THE STANDING ANSWER: a floor re-stated on
every unrelated-code PR is a number being maintained, not a property
being asserted. The deletion-sensitive check already lives on the
stable surface (`BRANCH_POPULATION`, exact per-function instrument-side
counts); the report-side floors are the part that keeps moving. Options,
to be decided with evidence rather than taste: express the report-side
assertion as a DELTA against the same run's instrument-side population
instead of an absolute; or scope the floors per-function where the
population is pinned; or retire the absolutes and let BRANCH_POPULATION
plus the row-driver sanity test carry the gate. Upstream fix in
witness#208 would remove the need entirely — a fresh instance is
already commented there.

NOT A LICENCE TO LOWER FLOORS. Every re-statement so far carried the
manifest diff that proved nothing real was lost; that requirement stays
whatever shape the gate ends up in.
status: proposed
release: v0.61
tags: [mcdc, witness, gates, fragility]
links:
- type: derives-from
target: BR-001
fields:
req-type: process
priority: should
verification-track: review
issue: "#1100"
done-when: "manual: the report-side assertion no longer needs re-stating on an unrelated-code PR — or it is retired in favour of the stable surface, with the reasoning written down"
Loading