Experiment formal soak transition registration red plan 01 - kmosoti/FabricO11y GitHub Wiki

R3 measured exposure transition: registration red pre-flight 01

Prospective NOT RUN. Clean trust-only 7ff16db56adf519d37096e6460ab9508a6ebed05 follows the unchanged ff3c182 production source and five actual source greens. The separate C-081-ACKed prospective phase amendment changes only test/protocol registration. No runtime schedule, helper, native lifetime, source authority or production function has changed.

Offered exposure/cohort boundaries stay exactly7200 seconds. Phase ceilings become setup170/exposure7210/drain60/shutdown20/checkpoint20/closeout20, total7500. Exposure permits only10seconds of measured boundary/observation/transition within that phase, never shorter offers or late probe admission. S1 requires all five non-exposure samples plus a separate exposure_transition sample under the same real/source/stop conditions and25% margin. Setup maximum136seconds, transition maximum8seconds. If real measurements cannot fit, request an exact larger owner deadline using those measurements. No larger deadline is requested here. Historical C062180/7200 evidence remains bound to its revisions.

Independent literal reference controls retain each hard phase/global boundary and real25% margin, updated prospectively to the registered6 samples. Exact boundaries and +1ns maxima are checked. The two new actual mechanism controls inspect its published allocation and submit all five fitting old samples without transition. Expected8methods:6literal positives plus2named assertion failures (old180/7200 allocation differs; missing real transition sample is incorrectly accepted). No setup/import errors or mechanism-headroom positive error is expected; this command does not run the separately-known5460-default method.

One serial default-capped source cell, fresh full DATA census/full1GiB reserve/95GB admission including reserve/100GBceiling/16GiBhigh20GiBmax/no swap/1800seconds. Pure integer/receipt observations only, no real files/workloads, compile, VM, browser, simulator, smoke or FULL. Preserve actual failure/stop evidence and read #59 before any correction.

Exact command

python3 -B /run/media/kmosoti/data/FabricO11y/results/candidate-build-fresh-8fb6f413179b-01/run-step-soak-transition-red-01.py soak-transition-registration-red-01 1073741824 env PYTHONPATH=tools/qualification python3 -B -m unittest -v test_soak_exposure.LiteralExposureControls test_soak_exposure.PhaseTransitionControls

Pins

  • /run/media/kmosoti/data/FabricO11y/results/candidate-build-fresh-8fb6f413179b-01/run-step-soak-transition-red-01.py SHA-256 f346b74e746e56f4705ade3f3c0c76ed9f50573fa8040324ff9e6f8f5ed4b02e.
  • /run/media/kmosoti/data/FabricO11y/scratch/soak-exposure/tools/qualification/soak_exposure.py SHA-256 a3a5e4d444ae0e57839b74f87eaf74146268295770db341b8ac0fda9126b5e81.
  • /run/media/kmosoti/data/FabricO11y/scratch/soak-exposure/tools/qualification/test_soak_exposure.py SHA-256 771748ba80bc6baf786643cf0b5ae146a78f2cd0481697755567caa6e0132c04.
  • /run/media/kmosoti/data/FabricO11y/scratch/soak-exposure/docs/experiments/benchmarks/soak-protocol-r3.md SHA-256 db47a801cebf6d983f9d3ed58f671c4545f76200113b1a766547bf3db26b5bdf.

Full registration delta

diff --git a/docs/experiments/benchmarks/soak-protocol-r3.md b/docs/experiments/benchmarks/soak-protocol-r3.md
index 6f9dc25..25ec01e 100644
--- a/docs/experiments/benchmarks/soak-protocol-r3.md
+++ b/docs/experiments/benchmarks/soak-protocol-r3.md
@@ -89,8 +89,8 @@ remaining deadline. No phase borrows another phase's allowance.
 
 | Phase | Ceiling |
 | --- | ---: |
-| `setup` — enrollment, browser readiness and fixture admission | 180 s |
-| `exposure` — actual offered workload, warmup included | 7,200 s |
+| `setup` — enrollment, browser readiness and fixture admission | 170 s |
+| `exposure` — 7,200 s offers plus measured boundary observation/transition | 7,210 s |
 | `drain_seal` — shared simulator drain and sealing | 60 s |
 | `shutdown` — orderly production shutdown | 20 s |
 | `checkpoint` — stopped raw tree and resource checkpoint | 20 s |
@@ -104,6 +104,14 @@ The simulator's watchdog sets a stop flag before joining workers; it is not
 an absolute drain deadline. Forced shutdown, exhausted budget, phase overlap,
 unexpected exit or unconfirmed cleanup fails and preserves evidence.
 
+The prospective [C-081 amendment](https://github.com/kmosoti/FabricO11y/issues/59#issuecomment-6138310799)
+keeps the actual offered interval and cohort edges exactly 7,200 seconds. The
+ten-second allowance covers only native boundary anchoring, observation and
+transition; it never excuses early simulator exit, shorter offered coverage,
+rounding, delayed probes or borrowing drain time. The previous 180/7,200
+allocation and its source-control results remain tied to their original
+revisions. This separately registered change does not reinterpret them.
+
 **C-062 S1 must be satisfied before any full run.** Measure each of the five
 non-exposure phases on real R2 evidence or a short smoke at the full registered
 data rate. Post each observed maximum, source receipt/hash and ceiling. Require
@@ -116,6 +124,20 @@ Do not copy the raw dataset into the 20-second checkpoint phase. If any measured
 phase plus margin does not fit, request a concrete larger deadline from the
 owner with the actual numbers; do not infer approval or shave exposure.
 
+Also require a separate real `exposure_transition` sample with the same source
+receipt/hash and confirmed-stop requirements, maximum at most eight seconds
+before the 25% margin. Setup maximum is at most 136 seconds. The transition is
+part of exposure, not a seventh phase or additional outer allowance. Missing
+transition evidence blocks FULL even when all five other samples fit.
+
+Register the literal `PhaseTransitionControls` before correction: the prior
+allocation must differ from the current table, and five fitting samples without
+transition evidence must be refused. The independent literal controls retain
+each phase/global boundary and check the six maxima at the exact 25% boundary
+and one nanosecond beyond it. No runtime schedule or helper authority changes
+in this registration. Native helper authority is registered separately; no
+simulator build, smoke or FULL is admitted here.
+
 ## Stopped checkpoint and separate grading
 
 Complete production shutdown first. Record actual empty production/browser/
diff --git a/tools/qualification/test_soak_exposure.py b/tools/qualification/test_soak_exposure.py
index e54575d..af0d260 100644
--- a/tools/qualification/test_soak_exposure.py
+++ b/tools/qualification/test_soak_exposure.py
@@ -18,8 +18,10 @@ HERE = Path(__file__).resolve().parent
 MECHANISM = HERE / 'soak_exposure.py'
 NS = 1_000_000_000
 EDGES = (60, 853, 1646, 2440, 3233, 4026, 4820, 5613, 6406, 7200)
-CEILINGS = {'setup': 180, 'exposure': 7200, 'drain_seal': 60,
+CEILINGS = {'setup': 170, 'exposure': 7210, 'drain_seal': 60,
             'shutdown': 20, 'checkpoint': 20, 'closeout': 20}
+HEADROOM = {name: seconds for name, seconds in CEILINGS.items() if name != 'exposure'}
+HEADROOM['exposure_transition'] = 10
 
 
 def reference_cohort(timestamp, began):
@@ -51,12 +53,12 @@ def reference_remaining(phase, launcher_begin, phase_begin, now):
 
 
 def reference_headroom(measured):
-    if set(measured) != set(CEILINGS) - {'exposure'}:
+    if set(measured) != set(HEADROOM):
         raise ValueError('phase headroom')
     for name, record in measured.items():
         maximum = record.get('maximum_ns')
         if (type(maximum) is not int or maximum <= 0
-                or (5 * maximum + 3) // 4 > CEILINGS[name] * NS
+                or (5 * maximum + 3) // 4 > HEADROOM[name] * NS
                 or record.get('kind') not in ('native-r2', 'full-rate-smoke')
                 or record.get('stop_confirmed') is not True
                 or len(record.get('source_sha256', '')) != 64
@@ -185,7 +187,8 @@ class LiteralExposureControls(unittest.TestCase):
                 self.subject.remaining_ns(*args)
 
     def test_each_real_phase_requires_25_percent_headroom(self):
-        maxima = {'setup': 144, 'drain_seal': 48, 'shutdown': 16, 'checkpoint': 16, 'closeout': 16}
+        maxima = {'setup': 136, 'exposure_transition': 8, 'drain_seal': 48,
+                  'shutdown': 16, 'checkpoint': 16, 'closeout': 16}
         measured = {name: {'maximum_ns': seconds * NS, 'kind': 'full-rate-smoke',
                            'source_sha256': 'a' * 64, 'stop_confirmed': True}
                     for name, seconds in maxima.items()}
@@ -260,6 +263,30 @@ class ExposureMechanismAvailability(unittest.TestCase):
         self.assertTrue(MECHANISM.is_file(), 'R3 soak_exposure.py mechanism unavailable; not a product failure')
 
 
+class PhaseTransitionControls(unittest.TestCase):
+    """C-081: literal phase allocation and a previously unwitnessed transition."""
+    @classmethod
+    def setUpClass(cls):
+        spec = importlib.util.spec_from_file_location('soak_transition_controls', MECHANISM)
+        cls.subject = importlib.util.module_from_spec(spec)
+        spec.loader.exec_module(cls.subject)
+
+    def test_registered_phase_transition_allocation_is_available(self):
+        self.assertEqual(self.subject.CEILINGS, CEILINGS)
+        self.assertEqual(sum(CEILINGS.values()), 7500)
+        self.assertEqual(CEILINGS['exposure'] - 7200, 10)
+
+    def test_missing_real_transition_sample_is_refused(self):
+        # All five old phase samples fit. They cannot evidence the new transition.
+        maxima = {'setup': 136, 'drain_seal': 48, 'shutdown': 16,
+                  'checkpoint': 16, 'closeout': 16}
+        measured = {name: {'maximum_ns': seconds * NS, 'kind': 'full-rate-smoke',
+                           'source_sha256': 'a' * 64, 'stop_confirmed': True}
+                    for name, seconds in maxima.items()}
+        with self.assertRaisesRegex(ValueError, 'phase headroom'):
+            self.subject.validate_phase_headroom(measured)
+
+
 @unittest.skipUnless(MECHANISM.is_file(), 'R3 mechanism absent; availability assertion remains red')
 class ExposureMechanismControls(LiteralExposureControls):
     @classmethod