Experiment formal simulator native registration source plan 01 - kmosoti/FabricO11y GitHub Wiki
Simulator native registration: prospective source-only preflight01
Status: NOT RUN. Root/Olo requests only the four source/documentation cells below at clean e8a557a216b0b47d86a5a54d04081aad38b7d5c0. This checks finite wire/authority registration source, not native begin/lifetime/ACK/publication or a candidate gate. C-093/C-094 belong to the earlier16-method checker and do not admit this new revision. The native CLI is never invoked by the source suite; no socket/server/helper/compiler is requested.
The driver explicitly sets FABRIC_STORAGE_ROOT to DATA before invoking tools/resource_group.py, and the launcher forwards that storage root to the contained command. Full1GiB allowance and fresh strict namespace census apply before each serial cell, admission<=95e9 under the100GB ceiling. Default16/20GiB no-swap/1800s applies. Raw command/log/outer resource receipts, actual stop/temp removal and clean source status are required. Any failure is recorded at this exact revision; no skip becomes native success.
Changed paths, exact git tree/parent, unchanged protected bytes and static method enumeration are below. Compile input Rust, canonical packages/helpers/manifests and independent query/delivery/rate oracles stay unchanged. The nine native diagnostics/four refusal cells, complete sysroot/coldbuild and atomic/pre-offer controls remain separately blocked and are not included here.
python3 -B /run/media/kmosoti/data/FabricO11y/results/candidate-build-fresh-8fb6f413179b-01/run-step-simulator-native-registration-source-01.py simulator-native-registration-source-controls-01 1073741824 env PYTHONPATH=tools/qualification:tools python3 -B -m unittest -v test_simulator_exposure test_simulator_native_controls
python3 -B /run/media/kmosoti/data/FabricO11y/results/candidate-build-fresh-8fb6f413179b-01/run-step-simulator-native-registration-source-01.py simulator-native-registration-docs-check-01 1073741824 env PATH=/run/media/kmosoti/data/FabricO11y/tools/bun-1.4.0:/usr/local/bin:/usr/bin:/bin BUN_INSTALL_CACHE_DIR=/run/media/kmosoti/data/FabricO11y/tools/docs-bun-cache bun tools/docs/check.mjs
python3 -B /run/media/kmosoti/data/FabricO11y/results/candidate-build-fresh-8fb6f413179b-01/run-step-simulator-native-registration-source-01.py simulator-native-registration-docs-tests-01 1073741824 env PATH=/run/media/kmosoti/data/FabricO11y/tools/bun-1.4.0:/usr/local/bin:/usr/bin:/bin BUN_INSTALL_CACHE_DIR=/run/media/kmosoti/data/FabricO11y/tools/docs-bun-cache bun tools/docs/check.test.mjs
python3 -B /run/media/kmosoti/data/FabricO11y/results/candidate-build-fresh-8fb6f413179b-01/run-step-simulator-native-registration-source-01.py simulator-native-registration-docs-hooks-01 1073741824 python3 -B tools/docs/test_hooks.py
results/candidate-build-fresh-8fb6f413179b-01/simulator-native-registration-source-command-plan-01.json
SHA-256 98424ade39f5d6c138519008e32df30bad8bc22479b61e1cbaad557d12a3767e, 9063 bytes.
{
"scope": "source only; no compile/native/socket/server/acceptance",
"clean_head": "e8a557a216b0b47d86a5a54d04081aad38b7d5c0",
"tree": "fbeb8ae946b161dd55871d9af39cfd6a3fdb5ca0",
"parent": "958f99ab1e00b4946b46457408560880a00c312e",
"status": "",
"changed_paths": {
"docs/experiments/benchmarks/simulator-exposure-witness-protocol.md": {
"sha256": "e846b2755721ee7a2247ef9bca566b13b5dba3615866ce8f36b516f74bcc5ac0",
"bytes": 12325,
"lines": 199,
"mode": "100644"
},
"docs/experiments/benchmarks/simulator-native-witness-canonical.json": {
"sha256": "23f3c7f259e5a4f3f3cfd36e59f20426f0ad62c9510fa2e2fe10a4f2e36445d1",
"bytes": 604,
"lines": 9,
"mode": "100644"
},
"docs/experiments/benchmarks/simulator-native-witness-protocol.md": {
"sha256": "f39fe53721ad43ad08935c60ccc6c05d32bfdc3fb7c2f2ac6bfa71490ded026f",
"bytes": 12915,
"lines": 196,
"mode": "100644"
},
"tools/qualification/simulator_native_controls.py": {
"sha256": "f5b5b68d02aa66560a4f62030a2495e1705bf1eb43809416f23780e3dee00b4b",
"bytes": 20229,
"lines": 360,
"mode": "100644"
},
"tools/qualification/test_simulator_native_controls.py": {
"sha256": "853eee22df310e2f966b2fbb807c2f64f0b17a443ac3174474c9b5e7d1271b07",
"bytes": 3642,
"lines": 71,
"mode": "100644"
}
},
"protected_paths": {
"examples/spindle_sim.rs": {
"sha256": "2b2828fed73cfe654fadc6739e31c51b9004a42a5174f51be2cb08b161385264",
"unchanged_vs_previous": true
},
"tools/qualification/simulator_exposure.py": {
"sha256": "31184b04f839e83f1e759ed6dd918d0087e2dc264ea3623d31671493c7ff985d",
"unchanged_vs_previous": true
},
"tools/qualification/test_simulator_exposure.py": {
"sha256": "1bb53d2bb730c5cb70c456d4c76bdcb95498d8ce1a86075d5b3516916cff1a87",
"unchanged_vs_previous": true
},
"tools/qualification/query_oracle.py": {
"sha256": "fc696ee1173093c258ff4451c4a796dd8e5832761f9e0ff49f89a922b411d23a",
"unchanged_vs_previous": true
},
"tools/resource_group.py": {
"sha256": "454acd27fdd5a87a35c697d6a89d2fc807c5c2757a98676dba2745efece7667e",
"unchanged_vs_previous": true
},
"tools/qualification/cross_family/inputs.py": {
"sha256": "3dfd336bd132fa7d904aea783c81db94f6832bea304474d86250cb2329dbec44",
"unchanged_vs_previous": true
}
},
"test_method_count": 24,
"test_methods": [
"tools/qualification/test_simulator_exposure.py:LiteralSimulatorControls.test_exact_native_boundary_and_one_ns_early_refusal",
"tools/qualification/test_simulator_exposure.py:LiteralSimulatorControls.test_missing_changed_and_nonexclusive_begin_refusals",
"tools/qualification/test_simulator_exposure.py:LiteralSimulatorControls.test_missing_worker_duplicate_and_final_second_offer_refusals",
"tools/qualification/test_simulator_exposure.py:LiteralSimulatorControls.test_only_one_changed_rust_compilation_input_is_admitted",
"tools/qualification/test_simulator_exposure.py:LiteralSimulatorControls.test_reversed_uncertain_and_invalid_clock_refusals",
"tools/qualification/test_simulator_exposure.py:LiteralSimulatorControls.test_separate_source_build_and_unchanged_canonical_authority",
"tools/qualification/test_simulator_exposure.py:LiteralSimulatorControls.test_summary_witness_loaded_binary_source_and_build_refusals",
"tools/qualification/test_simulator_exposure.py:SimulatorMechanismAvailability.test_separate_simulator_admission_mechanism_is_available",
"tools/qualification/test_simulator_exposure.py:SimulatorMechanismControls.test_exact_native_boundary_and_one_ns_early_refusal",
"tools/qualification/test_simulator_exposure.py:SimulatorMechanismControls.test_missing_changed_and_nonexclusive_begin_refusals",
"tools/qualification/test_simulator_exposure.py:SimulatorMechanismControls.test_missing_worker_duplicate_and_final_second_offer_refusals",
"tools/qualification/test_simulator_exposure.py:SimulatorMechanismControls.test_only_one_changed_rust_compilation_input_is_admitted",
"tools/qualification/test_simulator_exposure.py:SimulatorMechanismControls.test_reversed_uncertain_and_invalid_clock_refusals",
"tools/qualification/test_simulator_exposure.py:SimulatorMechanismControls.test_separate_source_build_and_unchanged_canonical_authority",
"tools/qualification/test_simulator_exposure.py:SimulatorMechanismControls.test_summary_witness_loaded_binary_source_and_build_refusals",
"tools/qualification/test_simulator_exposure.py:CanonicalSourceControls.test_canonical_input_guard_remains_original",
"tools/qualification/test_simulator_native_controls.py:NativeRegistrationTests.test_duplicate_truncated_unknown_and_identity_wire_refused",
"tools/qualification/test_simulator_native_controls.py:NativeRegistrationTests.test_every_canonical_pin_is_independent",
"tools/qualification/test_simulator_native_controls.py:NativeRegistrationTests.test_exact_canonical_expected_tuple",
"tools/qualification/test_simulator_native_controls.py:NativeRegistrationTests.test_first_second_requires_all_original_metric_points",
"tools/qualification/test_simulator_native_controls.py:NativeRegistrationTests.test_malformed_missing_or_extra_authority_refused",
"tools/qualification/test_simulator_native_controls.py:NativeRegistrationTests.test_payload_shape_failure_cannot_be_missing_begin_red",
"tools/qualification/test_simulator_native_controls.py:NativeRegistrationTests.test_separate_binary_keeps_original_helper_authority",
"tools/qualification/test_simulator_native_controls.py:NativeRegistrationTests.test_two_seconds_use_original_finite_shapes"
],
"driver": "/run/media/kmosoti/data/FabricO11y/results/candidate-build-fresh-8fb6f413179b-01/run-step-simulator-native-registration-source-01.py",
"driver_sha256": "be5abe55fb0bacd00e6d9823e8607bd298eb0b62430652bbc7dd02a450063216",
"storage_root": "/run/media/kmosoti/data/FabricO11y",
"reserve_per_cell_bytes": 1073741824,
"outer_seconds": 1800,
"memory_high_bytes": 17179869184,
"memory_max_bytes": 21474836480,
"swap_max_bytes": 0,
"command_cells": [
[
"simulator-native-registration-source-controls-01",
"env",
"PYTHONPATH=tools/qualification:tools",
"python3",
"-B",
"-m",
"unittest",
"-v",
"test_simulator_exposure",
"test_simulator_native_controls"
],
[
"simulator-native-registration-docs-check-01",
"env",
"PATH=/run/media/kmosoti/data/FabricO11y/tools/bun-1.4.0:/usr/local/bin:/usr/bin:/bin",
"BUN_INSTALL_CACHE_DIR=/run/media/kmosoti/data/FabricO11y/tools/docs-bun-cache",
"bun",
"tools/docs/check.mjs"
],
[
"simulator-native-registration-docs-tests-01",
"env",
"PATH=/run/media/kmosoti/data/FabricO11y/tools/bun-1.4.0:/usr/local/bin:/usr/bin:/bin",
"BUN_INSTALL_CACHE_DIR=/run/media/kmosoti/data/FabricO11y/tools/docs-bun-cache",
"bun",
"tools/docs/check.test.mjs"
],
[
"simulator-native-registration-docs-hooks-01",
"python3",
"-B",
"tools/docs/test_hooks.py"
]
],
"expected": [
"24 methods/0 failures/0 skips/exit0",
"docs check exit0",
"55 docs tests/exit0",
"10 hooks tests/exit0"
],
"native_diagnostics": "nine plus four refusals all NOT RUN and not requested by this plan",
"preconditions": "fresh whole-DATA namespace census + full reserve <=95e9, no running project unit, clean exact source; serial four cells; read#59 before each/after every run",
"method_enumeration": "AST class methods including inherited LiteralSimulatorControls; no imports or execution",
"canonical_disk_pins": {
"/run/media/kmosoti/data/FabricO11y/results/installation-package-build/fresh-8fb6f413179b-01-deb-a/receipt.json": {
"sha256": "b10a4e4c2d83d8dbed7c1d6e74673fd377a83123fc1bce31fffc97e034beb9af",
"bytes": 169075
},
"/run/media/kmosoti/data/FabricO11y/results/installation-package-build/fresh-8fb6f413179b-01-deb-a/qualification-helpers/spindle_sim": {
"sha256": "606272bfbaec86900a928f2936d79b0ba4f6d5ed900556473bc3345a63283f47",
"bytes": 3600832
},
"/run/media/kmosoti/data/FabricO11y/results/installation-package-build/fresh-8fb6f413179b-01-deb-a/qualification-helpers/server_dump": {
"sha256": "68daf3fdbaed5579ff672c4916651905ec18e10d440b4c391931ff963592312f",
"bytes": 9133904
},
"/run/media/kmosoti/data/FabricO11y/results/installation-package-build/fresh-8fb6f413179b-01-deb-a/qualification-helpers/spool_dump": {
"sha256": "e61babbb57249e25639e8413ce87752ec1a408cd7ad5d0b8c35d892a52b602bf",
"bytes": 1037424
},
"/run/media/kmosoti/data/FabricO11y/results/installation-package-build/fresh-8fb6f413179b-01-deb-a/qualification-helpers/manifest.json": {
"sha256": "604fd0b90f80f061859967f967347375f1da20417fd576519485e8d7c58c43e6",
"bytes": 78080
}
}
}
results/candidate-build-fresh-8fb6f413179b-01/run-step-simulator-native-registration-source-01.py
SHA-256 be5abe55fb0bacd00e6d9823e8607bd298eb0b62430652bbc7dd02a450063216, 7041 bytes.
import datetime, hashlib, json, os, re, signal, subprocess, sys, time
from pathlib import Path
ROOT = Path('/run/media/kmosoti/data/FabricO11y')
REPO = ROOT / 'scratch/simulator-exposure-witness'
OUT = ROOT / 'results/service-opening-candidate'
STORE = ROOT / 'scratch/service-opening-census'
FROZEN = 'e8a557a216b0b47d86a5a54d04081aad38b7d5c0'
def require(value, reason):
if not value:
raise ValueError(reason)
label, reserve_text, *command = sys.argv[1:]
reserve = int(reserve_text)
delegated = command[:1] == ['--delegate']
if delegated: command = command[1:]
require(re.fullmatch(r'[a-z0-9-]{1,80}', label) and reserve > 0 and command, 'ordinary workload admission guard')
record_path = OUT / (label + '.json')
require(not record_path.exists(), 'unique run label required')
def census():
# Rootless container files can belong to subordinate UIDs. Inspect all of
# them in the same user namespace; never skip unreadable directories.
require(not STORE.is_symlink(), 'ordinary workload admission guard')
require((STORE / '.owned-census-store').read_text() == 'service-opening-census-v1\n', 'ordinary workload admission guard')
args = ['podman', '--root', str(STORE/'graph'), '--runroot', str(STORE/'run'),
'--tmpdir', str(STORE/'tmp'), '--storage-driver', 'vfs',
'unshare', 'python3', '-B', str(OUT/'census.py')]
env = dict(os.environ, TMPDIR=str(STORE/'tmp'), TMP=str(STORE/'tmp'), TEMP=str(STORE/'tmp'))
result = subprocess.run(args, env=env, text=True, capture_output=True, timeout=25)
if result.returncode:
raise RuntimeError(f'strict namespace census failed ({result.returncode}): {result.stderr}')
observed = json.loads(result.stdout)
require(observed['uid'] == 0 and observed['gid'] == 0, 'ordinary workload admission guard')
require(type(observed['data_bytes']) is int and observed['data_bytes'] >= 0, 'ordinary workload admission guard')
return observed
def git(*args):
return subprocess.check_output(['git', *args], cwd=REPO, text=True).strip()
require(git('rev-parse', 'HEAD') == FROZEN and not git('status', '--porcelain'), 'clean frozen source required')
require(not subprocess.check_output(['systemctl', '--user', 'list-units', 'fabric-work-*', '--state=running', '--plain', '--no-legend'], text=True).strip(), 'another project workload is active')
initial = census()
used = initial['data_bytes']
record = {'label': label, 'command': command, 'delegated': delegated, 'frozen': None, 'scope': 'harness controls only; no candidate acceptance evidence', 'harness_revision': FROZEN, 'source_status_before': git('status', '--porcelain'), 'storage_root': str(ROOT), 'admission_bytes': used, 'admission_observation': initial, 'reserved_bytes': reserve, 'observations': [], 'started_utc': datetime.datetime.now(datetime.timezone.utc).isoformat()}
if used + reserve > 95_000_000_000:
record.update(state='not_run', reason='95 GB storage admission threshold')
record_path.write_text(json.dumps(record, indent=2)+'\n')
raise SystemExit('storage admission denied; project command not launched')
receipts = REPO / 'target/resource-containment/runs'
before = set(receipts.glob('*.json'))
env = dict(os.environ, FABRIC_STORAGE_ROOT=str(ROOT), CARGO_HOME=str(ROOT/'toolchain-cache/cargo'), RUSTUP_HOME=str(ROOT/'toolchain-cache/rustup'), CARGO_BUILD_JOBS='2')
env['PATH'] = str(ROOT/'tools/candidate-dpkg/bin') + ':' + env['PATH']
log_path = OUT / (label + '.log')
record.update(state='running', log=str(log_path))
record_path.write_text(json.dumps(record, indent=2)+'\n')
def find_unit():
with log_path.open() as stream:
prefix = stream.read(65536)
match = re.search(r'Running as unit: (fabric-work-[0-9a-f]+)\.service', prefix)
return match.group(1) if match else None
def stop_owned(process):
unit = find_unit()
if unit:
stopped = subprocess.run(['systemctl', '--user', 'stop', unit],
text=True, capture_output=True, timeout=25)
record['stop'] = {'unit': unit, 'exit': stopped.returncode, 'stderr': stopped.stderr}
if stopped.returncode:
# Interrupt the launcher too; its finally block independently
# confirms that this exact service has no surviving descendants.
process.send_signal(signal.SIGINT)
else:
process.send_signal(signal.SIGINT)
record['stop'] = {'unit': None, 'launcher_interrupted': True}
with log_path.open('wb') as log:
launcher = ['python3', '-B', 'tools/resource_group.py', *(['--delegate'] if delegated else []), '--', *command]
process = subprocess.Popen(launcher, cwd=REPO, env=env, stdout=log, stderr=subprocess.STDOUT)
next_census = time.monotonic() + 30
try:
while process.poll() is None:
time.sleep(1)
if time.monotonic() >= next_census:
observed = census()
record['observations'].append({'unix':time.time(), **observed})
record_path.write_text(json.dumps(record, indent=2)+'\n')
if observed['data_bytes'] >= 95_000_000_000:
record['interruption'] = '95 GB threshold reached'
break
next_census = time.monotonic() + 30
except BaseException as error:
record['interruption'] = f'{type(error).__name__}: {error}'
finally:
if record.get('interruption') and process.poll() is None:
try:
stop_owned(process)
except BaseException as error:
record['stop_error'] = f'{type(error).__name__}: {error}'
process.send_signal(signal.SIGINT)
status = process.wait()
record['launcher_exit'] = status
if record.get('interruption'): status = 2
with log_path.open('rb') as stream:
log_digest = hashlib.file_digest(stream, 'sha256').hexdigest()
record.update(state='interrupted' if record.get('interruption') else 'completed', exit=status, source_status_after=git('status', '--porcelain'), finished_utc=datetime.datetime.now(datetime.timezone.utc).isoformat(), log_sha256=log_digest, resource_receipts=[])
archive = OUT/'resource-containment'; archive.mkdir(exist_ok=True)
for p in sorted(set(receipts.glob('*.json')) - before):
value=json.loads(p.read_text())
if value['command'] != command: continue
q=archive/p.name; q.write_bytes(p.read_bytes())
record['resource_receipts'].append({'path':str(q),'sha256':hashlib.sha256(q.read_bytes()).hexdigest(),'exit':value['exit'],'stop_confirmed':value['stop_confirmed'],'retained_failure_evidence':value['retained_failure_evidence']})
if not record['resource_receipts'] or any(not r['stop_confirmed'] or r['exit'] != status for r in record['resource_receipts']):
record['receipt_error'] = 'missing or inconsistent outer resource receipt'
status = 2
record['exit'] = status
record_path.write_text(json.dumps(record, indent=2)+'\n')
print(json.dumps(record, indent=2))
if status: print(log_path.read_text()[-8000:])
raise SystemExit(status)
scratch/simulator-exposure-witness/docs/experiments/benchmarks/simulator-exposure-witness-protocol.md
SHA-256 e846b2755721ee7a2247ef9bca566b13b5dba3615866ce8f36b516f74bcc5ac0, 12325 bytes.
# Registered separate simulator exposure witness
Prospective registration, 2026-10-13. Coordination
[C-081](https://github.com/kmosoti/FabricO11y/issues/59#issuecomment-6138310799)
admits the separately frozen qualification helper and its controls, **not a
build, native trial, smoke or full soak**. The source/transition proposal is
[wiki revision 875f7f2](https://github.com/kmosoti/FabricO11y/wiki/Experiment-formal-soak-simulator-source-transition-amendment-proposal-01),
SHA-256 `c36e7068c2d46663d755598d2222b09b8e8068a865d1387f403b8e5843b6bfc4`.
This file registers helper identity and lifetime only;
the separately registered R3 phase amendment belongs to the soak harness.
No result is recorded here.
The separate [finite native control registration](simulator-native-witness-protocol.md)
defines the sealed-helper missing-begin red, loopback TLS fixture, helper-only
build prerequisites and later native refusal cells. It records no execution.
## Source question and fixed scope
Frozen candidate `8fb6f413179b094288316e25845c137440ba23fa` parses no live begin
or hold-through-boundary option in
[`examples/spindle_sim.rs`](../../../examples/spindle_sim.rs). Its worker exits
once the final due offer has been acknowledged; its begin timestamp appears in
the summary only after joins. These are source observations, not measurements
of a two-hour run. Keeping external probes alive after simulator exit does not
satisfy native lifetime or supply a native pre-offer witness.
The unchanged Rust source SHA-256 at registration is
`2b2828fed73cfe654fadc6739e31c51b9004a42a5174f51be2cb08b161385264`.
Only `examples/spindle_sim.rs` may change **Rust compilation inputs**, from the
exact candidate base. Preserve workers, identities, seeds, due-offer scheduling,
rates, bodies, burst behavior, payload/wire bytes, retries, ACK interpretation
and existing drain/failure semantics. No dependency, core or product change is
admitted. The optional `--begin-witness PATH` mode preserves old callers when
absent; it must not silently turn on for another workload. Full R3 uses 7,200
seconds, 100 identities/workers and `0xA11FA001`; short native controls need a
separately frozen command and do not establish full exposure.
## Two independent source authorities
Canonical packages, package-source tuple, three-helper manifest and helper
bytes remain unchanged. The original
[`cross_family/inputs.py`](../../../tools/qualification/cross_family/inputs.py)
must still require that exact package source and all three original helper
hashes. `server_dump` and `spool_dump` remain the graders; a new simulator must
not replace canonical `spindle_sim` or rewrite its manifest.
The additional owner-admitted helper record binds candidate base, clean helper
commit/tree, complete source manifest/bundle, changed helper-source hash,
binary hash and actual build receipt hash. Compare the **complete compilation
input path sets and bytes** against canonical source: only the helper path
may differ, and it must actually differ. Cargo manifests/lock/config, all other
Rust/protobuf/build inputs and complete vendored/transitive sources remain
equal. Added/deleted inputs, symlinks, uncensused generated input or an altered
build configuration block admission. Documentation and prospective Python
controls do not excuse a Rust compilation difference. `prepare_soak.source_paths`
is a source-census precedent, not proof that an incomplete hand-written list
is complete. Freeze dependency/toolchain/configuration and relevant environment
inputs too; refuse a dirty or unbound build source.
The build record binds actual command, Rust/toolchain/target/profile/features/
flags, source tuple, output hash, exits, cgroup/resource observations and
confirmed descendant stop. Loaded helper identity must agree with that record
and the independently admitted expected tuple. Hashes in an untrusted witness
or mutually agreeing receipts are not independent source authority. Canonical
admission runs first; the opt-in helper admission is additional, never a default
exception to it.
## Exclusive native begin and conservative lifetime
The proposed native path opens/hashes the kernel's loaded `/proc/self/exe`,
records held-descriptor device/inode plus PID, process start ticks and boot ID,
and checks identity while reading. Independent controller observations bind
the actual executable and original process identity, not just its pathname.
Linux documents the executable reference in
[`proc_pid_exe(5)`](https://man7.org/linux/man-pages/man5/proc_pid_exe.5.html).
Expected binary/source/build hashes come from the separate admitted record;
the native program does not invent its source commit from an argument.
Bracket the existing `Instant`/Unix begin with actual `CLOCK_MONOTONIC` reads
from the same process. Preserve the original `began_unix_ns` used by events and
summary. Store integer `mono_before_ns`, `mono_after_ns` and the Unix anchor;
refuse reversed/negative brackets or width over **1,000,000 ns**. Use the upper
monotonic bracket endpoint for a conservative completion boundary. The bound
is prospective; no host observation yet establishes that it is attainable.
No wall-clock offset or host clock change is allowed. The existing pinned libc
dependency is available; no new dependency is needed. Linux's
[`clock_gettime(3)`](https://man7.org/linux/man-pages/man3/clock_gettime.3.html)
defines the distinct realtime/monotonic domains. A numeric timestamp alone
does not establish that the proper clock was called.
Write a complete private record to an exclusively created owned staging file,
sync it, then publish to the fresh final witness path without overwrite. A
same-filesystem hard-link publication is the proposed no-replace operation;
[`link(2)`](https://man7.org/linux/man-pages/man2/link.2.html) refuses an existing
destination. Confirm canonical owned parent paths, no links/mounts, regular
single-link final file, mode 0400 and unchanged held-descriptor bytes; remove
only the staging name this invocation actually created after publication.
Retain partial/uncertain evidence. Publication must complete before worker
offers; failure, an existing destination or a changed witness must produce no
successful trial. Native/file-operation controls must establish exclusivity,
atomic full-record visibility and pre-offer ordering; self-asserted booleans in
the witness cannot establish them.
In witness mode, successful completion must wait until both the original
`Instant` elapsed interval reaches the requested duration and a native
monotonic end read reaches `mono_after_ns + duration_ns`. This conservatively
covers anchor uncertainty; it neither shortens exposure nor invents an exact
end. Record original elapsed nanoseconds, actual monotonic end, begin hash,
parameters and process identity in the end summary. Full-drain failures and
remaining undelivered work still refuse success. Native wait/transition time
remains inside the separately bounded exposure transition allowance; no phase
or outer deadline grows. Old callers keep their original behavior.
## Independent literal controls and admission mechanism
[`test_simulator_exposure.py`](../../../tools/qualification/test_simulator_exposure.py)
contains hand-written two-second/two-identity receipt records and a deliberately
small compilation map. Those records are not real receipts or a complete
native-source census. They exercise two prospective pure Python interfaces:
`validate_source_build(source, build, canonical, expected)` and
`validate_native(begin, summary, offers, loaded, expected)`. These read no clock
and authenticate no owner. The test-only reference encodes the registration;
it is not a fallback implementation or an oracle derived from Rust.
These are **qualification-only controls**, explicitly selected following
[C-089](https://github.com/kmosoti/FabricO11y/issues/59#issuecomment-6138944614).
They are not registered in `xtask/checks.json`; hosted CI is not represented as
running them. Root's separately admitted source cell must run all 16 methods
with zero failures and zero skips after the mechanism is implemented. Native
and complete-source-census prerequisites below remain separate.
`source/build/canonical` consume caller-read manifests and actual build file
hashes; `expected` is separately pinned. `begin` wraps caller-read witness bytes
as `{'sha256': actual_hash, 'value': parsed}`. `summary` is the original parsed
native summary, and `offers` includes original created-event evidence. `loaded`
joins independent process/binary/source/build observations and stop/exit plus
publication-control observations. Its flags are an **integration obligation**,
not evidence when fabricated by the helper. Parameter fields and identity names
are fixed by the literal records. Before grading, independently bind every raw
file hash and the exact observer/unit/cgroup/command/stop receipt.
The literal controls require:
- exact conservative boundary success and refusal one nanosecond early in
original elapsed time or the monotonic end;
- absent, changed, nonexclusive, non-atomic, late or nonregular witness refusal;
- reversed, oversized, negative or incorrectly typed clock brackets;
- summary/witness begin/parameter/process disagreement, changed loaded
executable device/inode/hash, process start/boot, helper source or build hash;
- every identity's original created sequence for every scheduled second,
without a missing worker/identity, duplicate, extra sequence or early stamp;
- wrong source/bundle/build/toolchain/stop, any canonical helper substitution
and every added/deleted/changed non-helper compilation input.
Created-event coverage supplements the unchanged source/rate/delivery oracles;
it does not establish body correctness or actual thread count on its own. The
canonical-source control pins the original guard, which must remain unchanged
after native implementation too. The changed helper is admitted by a separate
source record while its original bytes remain pinned as the canonical input.
Initial source execution is expected to report one named missing
`simulator_exposure.py` availability failure, eight literal/static positives, and seven explicit
mechanism-dependent skips. That red is **mechanism absence**, not a demonstrated
Rust timing or product defect. After root records it, a separate production
correction may supply the bounded checker; unchanged controls must then run.
No literal record, source grep, shortened timer or Python check proves that the
compiled simulator held its native lifetime.
## Native prerequisites and execution limits
Before any compile, freeze a cold-build command and complete reservation from
actual cold-build footprint data, including tools/copies/output/margin. The
obsolete 4 GiB estimate is forbidden. Use the default enforced resource
launcher and fresh namespace census below 95 GB/100 GB; build once unless a
real mismatch requires another construction. No compile is admitted here.
After a separate pre-flight, required evidence includes the named example
tests, fast/extended checks of the exact helper compilation inputs, real short
native begin/lifetime/existing-destination/changed-witness controls, loaded
executable identity and host monotonic/realtime observation controls. Exercise
unchanged canonical helper refusal and additional admission with real frozen
receipt files. Bind every command, raw bytes, failure, resource/stop/cleanup and
observer hash. Preserve original failures. Source controls and new helper CI
cannot be reused as shipped-product migration evidence.
Root alone may run the source-only registration cell after exact pre-flight,
default 1800 seconds and full 1 GiB reservation; **not run at registration**:
```sh
python3 -B tools/resource_group.py -- env PYTHONPATH=tools/qualification:tools \
python3 -B -m unittest -v test_simulator_exposure
No native process or Cargo command is part of this cell. Full R3 still needs fresh #41/#42/#45/#43/#46, complete runtime integration, admitted full-rate smoke, real S1 setup/transition and other phase maxima with 25% margin, stopped immutable checkpoint and separate grading. If measured values do not fit the owner's 7,500-second deadline, request a concrete larger deadline with the numbers; never shave the 7,200-second offered interval.
## scratch/simulator-exposure-witness/docs/experiments/benchmarks/simulator-native-witness-canonical.json
SHA-256 `23f3c7f259e5a4f3f3cfd36e59f20426f0ad62c9510fa2e2fe10a4f2e36445d1`, 604 bytes.
```json
{
"binary_sha256": "606272bfbaec86900a928f2936d79b0ba4f6d5ed900556473bc3345a63283f47",
"source_commit": "73ff77867d10ef521ca985b094e1d177f7786b77",
"source_tree": "9248c7bc174592566bc55360e73576f01f9a85ef",
"source_manifest_sha256": "534b601f904ce80f50cc545be8b8b40f47f8940975fd4cbf2e2e8c8cb54f2cff",
"source_bundle_sha256": "fc83ed1435b6ef8afadade2b7978c433d47d6cbdb9ad4a95c9ff57b25a07f1d0",
"build_receipt_sha256": "b10a4e4c2d83d8dbed7c1d6e74673fd377a83123fc1bce31fffc97e034beb9af",
"canonical_helper_manifest_sha256": "604fd0b90f80f061859967f967347375f1da20417fd576519485e8d7c58c43e6"
}
scratch/simulator-exposure-witness/docs/experiments/benchmarks/simulator-native-witness-protocol.md
SHA-256 f39fe53721ad43ad08935c60ccc6c05d32bfdc3fb7c2f2ac6bfa71490ded026f, 12915 bytes.
# Registered finite native simulator witness controls
Prospective trust registration, 2026-10-13. This extends the
[source/lifetime protocol](simulator-exposure-witness-protocol.md) under
[C-081](https://github.com/kmosoti/FabricO11y/issues/59#issuecomment-6138310799).
[C-093](https://github.com/kmosoti/FabricO11y/issues/59#issuecomment-6139196487)
admitted earlier source cells only. This registration admits no source cell,
compile, native process, smoke, S1 or full acceptance execution. No result is
recorded here. Root freezes the complete command/receipts/resources, gets Pip's
preflight and checks #59 before every later cell and after every run.
## Invariant, fixture and scope
The opt-in native helper must publish a complete, exclusive pre-offer begin
file and keep successful native lifetime through both conservative end bounds.
Only `examples/spindle_sim.rs` may differ among Rust compilation inputs from
candidate `8fb6f413179b094288316e25845c137440ba23fa`. At this registration its
SHA-256 stays `2b2828fed73cfe654fadc6739e31c51b9004a42a5174f51be2cb08b161385264`.
Initial missing-begin red uses sealed native bytes without rebuilding them.
Preserve legacy summary, original events/transcript, finite offers, payloads,
ACK interpretation, TLS, retry behavior and option-absent behavior. In opt-in
mode pending/undelivered work must explicitly refuse successful completion.
[`simulator_native_controls.py`](../../../tools/qualification/simulator_native_controls.py)
is an explicitly invoked **loopback TLS test sink**, not a Fabric server. It
uses the existing certificate fixture, verifies bearer tokens, accepts actual
raw Batch protobuf, decodes with the unchanged independent query decoder,
checks two 512-byte logs plus the original short metric shape, retains exact
bytes and ACKs each stream in order. Configuration GET receives 304. Positive
cells use seed `0xA11FA001`, two seconds, two identities and two requested workers;
all four original sources, created events, responses and final ACK cursors are
checked against accepted raw-byte SHA-256. It keeps native logs unmodified.
The sink ACKs volatile diagnostic bytes. It makes no durable ACK, journal,
browser enrollment, control-plane, query, production network, rate precision,
7,200-second exposure or qualification claim. It does not append fake recovered
records or reinterpret the delivery oracle. The existing source/rate/delivery
oracles remain separate, unchanged prerequisites for candidate acceptance.
The controller holds the executable descriptor, hashes it, launches that held
ELF via `/proc/self/fd`, and independently observes `/proc/PID/exe` hash/device/
inode, PID/start ticks and boot ID while alive. It refuses preload/audit/library
override variables. Positive controls hold a live witness descriptor and bind
complete bounded JSON, mode 0400, regular single-link inode and unchanged final
bytes. Complete source/build/sysroot admission happens **before** this fixture;
its small authority tuple is an external expectation, not source proof.
## Separate source authority and intended cells
The [canonical expected tuple](simulator-native-witness-canonical.json) binds
DEB A's original source commit/tree/manifest/bundle, build receipt, sealed
simulator and original three-helper manifest. Its SHA-256 is
`23f3c7f259e5a4f3f3cfd36e59f20426f0ad62c9510fa2e2fe10a4f2e36445d1`.
Root checks actual canonical files/manifest and the unchanged cross-family
guard first. A rebuilt helper uses a different separately admitted JSON with
exactly the same seven field names and original canonical helper-manifest hash.
Root pins its actual bytes and the real build receipt. Complete compilation
path sets/bytes, commit/tree/bundle, environment/toolchain/dependency/sysroot
fingerprints and `validate_source_build` must agree with an independently
frozen expected record. None of the three canonical helper bytes is replaced.
Per-file registration budgets: native fixture at most 360 lines; new source
controls at most 100 lines; canonical JSON at most 16 lines; this protocol at
most 200 lines; existing protocol addition at most 6 lines. No production Rust,
Cargo/dependency/core, canonical guard, dump helper or existing oracle edits.
The eight new source methods check finite wire positives, every canonical pin,
separate authority, malformed authority, duplicate/truncated/unknown/invalid
wire, body and metric defects. They start no native process or server. The
existing 16-method suite retains literal 1 ns early-end, missing/unloaded/
changed identity, added/deleted compilation input and original-guard controls.
The literal 1 ns mutations are receipt arithmetic, not clock precision evidence.
Intended source-only cell, **not run**, expects 24 methods, zero skips/failures:
```sh
python3 -B tools/resource_group.py -- env PYTHONPATH=tools/qualification:tools \
python3 -B -m unittest -v test_simulator_exposure test_simulator_native_controls
Root separately runs the normal documentation check/tests/hooks through the same launcher. Source import, source tests and documentation results cannot establish native lifetime. Every source cell reserves the full 1 GiB owned allowance; native cells below separately reserve 1 GiB each and keep the default 1,800-second outer deadline. Root's namespace/free-space preflight remains mandatory. Fixture subprocess waits are 10 seconds, or 75 for pending drain; certificate creation has the existing 60-second per-call bound. The resource launcher contains the entire descendant tree; no uncapped fallback is allowed.
After separate admission, exact initial native cell from the registered tree:
python3 -B tools/resource_group.py -- env PYTHONPATH=tools/qualification:tools \
python3 -B tools/qualification/simulator_native_controls.py --case canonical-red \
--binary /run/media/kmosoti/data/FabricO11y/results/installation-package-build/fresh-8fb6f413179b-01-deb-a/qualification-helpers/spindle_sim \
--authority docs/experiments/benchmarks/simulator-native-witness-canonical.json \
--authority-sha256 23f3c7f259e5a4f3f3cfd36e59f20426f0ad62c9510fa2e2fe10a4f2e36445d1 \
--build-receipt /run/media/kmosoti/data/FabricO11y/results/installation-package-build/fresh-8fb6f413179b-01-deb-a/receipt.json \
--out /run/media/kmosoti/data/FabricO11y/results/simulator-native-missing-begin-red-01
Expected red is exit 1 with receipt status
expected-red: sealed-native-missing-begin-after-real-ACK, only after native
exit 0, undelivered 0, loaded binding and four successful original ACKs. Exit 2,
setup failure, timeout, missing/malformed ledgers or incorrect source is
inconclusive, never that red. Preserve the actual red before any Rust edit.
After rebuilt-source admission, freeze eight explicit fixture commands with
the same launcher/options, separate helper ELF/build/authority hashes and
fresh per-cell output paths. Select --case as follows; controls expect fixture
exit 0 only when their registered condition is observed:
| Case | Required real observation |
|---|---|
positive |
Four ACKs, live/final bound witness, native elapsed >= 2 s and monotonic end >= upper begin bracket + 2 s. |
legacy |
No option/file; successful four ACKs and exact original five-key summary. |
duplicate |
Two --begin-witness arguments refuse before any request, with neither file published. |
existing |
Existing 0400 destination remains byte-identical; refuse before any request. |
workers |
Five identities/requested four partitions into three today; opt-in refuses before publication/offers rather than claiming four workers. |
pending |
Real TLS 503 retains both sequences per identity; native exit 1 and summary undelivered 4 after the original watchdog. |
early |
After actual live witness/offer, SIGTERM before boundary produces native nonzero; no successful trial. |
changed |
Deliberately alter held witness while native is alive; native nonzero. |
Four separate preflight refusal cells retain the positive command's frozen
expected hashes: alter authority bytes, point to an altered binary copy, point
to an altered build-receipt copy, or add LD_PRELOAD= inside its env command.
Each expects exit 2 before any helper launch; no library is injected by the
empty preload variable. Preserve stderr and the outer containment receipt.
Do not preload a clock shim, alter host time or use shortened 7,200-second
receipts. Such preflight cells test rejection only. Rejected-argument cells may
exit too quickly for /proc inspection; they prove refusal on the held pinned
ELF, while the independent loaded-process observation belongs to live cells.
Atomic publication and order remain independent obligations
Polling sees complete bytes and final metadata; it does not prove atomic
no-replace publication or pre-offer order. The fixture explicitly records that
gap and does not fabricate loaded.publication flags for validate_native.
Before full admission, register and execute native file-operation controls
with raw observer/syscall evidence and explicit fault points: complete private
staging before hard-link publication, existing-destination refusal, final
0400/nlink1 after owned staging unlink, no final partial JSON while writing,
staging collision/symlink refusal, changed held descriptor, injected write/
sync/link/unlink failure, and publication completed before the first created
event. A transient two-link stage must not be graded as completed publication.
Intended Rust example tests, not present/run at registration, use prefix
native_witness_ for these file/parse/order controls plus reversed/oversized
clock brackets, zero-duration and exact actual-partition refusal. Only the
sole helper Rust file may add them. Root must review a concrete syscall/order
observer and failure-injection patch before its separately admitted native
test command (cargo test --offline --locked --example spindle_sim native_witness_ -- --test-threads=1). Read-only mode and equal hashes under an
owned-directory assumption are not adversarial immutability proof. A native
clock read and observed conservative lifetime establish neither exact anchor
precision nor arbitrary-run timing. Full true Fabric TLS/protocol/S1 remains
separate; this diagnosed test sink never replaces it.
Cold helper build prerequisites and cleanup
Do not invoke the package builder: it rebuilds canonical packages. A separate
helper-only builder uses exclusive owned DATA source/target/registry/out and
Podman graph/run/tmp, a read-only Rust 1.99.0 toolchain, empty release target,
two Cargo jobs and cargo build --offline --locked --release --workspace --example spindle_sim. Epoch is 1791841113; no inherited RUSTFLAGS. Rustc
commit is b940084d7eb6a299eb4bfeb8e34901bc051e7ac4, LLVM 23.1.1. Debian 12 base
digest is 7c7b2c966bc9ee8cedfeef67e0e279108992c77681fa595db4a9d65c06ccc587.
Registry copy is 438,223,080 bytes, inventory SHA-256
47646ea10bb1e5fe179fc11ce36e0fe11acb6f5dacd9aa7d09c0c9a6d18577ce.
Before compilation, separately prepare/freeze the complete Debian installed package versions, package archive hashes, installed files/symlinks/modes and tool/loader/sysroot fingerprints; the historical complete sysroot hash is missing. Bind an owned immutable prepared image and environment. Root/Pip review its exact helper-only builder, source census and image fingerprints. Use network-none/read-only build image with explicitly owned writable mounts, verified 7/8 GiB high/max, no swap, inner 1,500/outer 1,800-second deadlines. All preparation/download/build growth belongs to the full owned reservation.
Planning reserve is 9,663,676,416 bytes (8 GiB construction plus 1 GiB output/margin), not a proven cold peak. Historical A/B complete broader cold constructions had final owned 1,948,722,650 bytes after transient sysroot removal; maximum 30-second sampled DATA growth was 2,888,070,285/2,919,914,225 bytes, not transient upper bounds or target-only peaks. Interrupted host-dev growth exceeded 10.1 GB; the obsolete 4 GiB estimate remains invalid. Complete apt/sysroot hashes and an owned/full-DATA growth guard are prerequisites; if a strict transient byte bound is required, quota or new measurement is still missing. Stop below 95 GB; preserve the 100 GB ceiling and record sampled gaps.
Archive raw failures and actual source/build/observer/resource/stop receipts before deleting only marker-owned staging, target/cache/sysroot and fixture credentials. Keep minimal frozen ELF/provenance/evidence, verify all descendants and TLS threads stopped and owned cleanup postconditions, then record DATA/free space/RAM. Never touch frozen A/B, canonical manifests/packages, quarantine, shared caches or another helper's branch. No build or cleanup is executed by this registration. Native controls and source-only green do not authorize S1 or advance any candidate acceptance gate.
## scratch/simulator-exposure-witness/tools/qualification/simulator_native_controls.py
SHA-256 `f5b5b68d02aa66560a4f62030a2495e1705bf1eb43809416f23780e3dee00b4b`, 20229 bytes.
```python
"""Registered finite native diagnostics; explicit CLI only, never auto-run.
The loopback TLS sink ACKs volatile test bytes. It is not a Fabric server,
durability oracle, full-rate workload, S1 trial or qualification result.
"""
import argparse
import base64
import hashlib
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import json
import os
from pathlib import Path
import re
import signal
import ssl
import stat
import subprocess
import sys
import threading
import time
from query_oracle import decode_batch, decode_logs_request, decode_metrics_request, parse_fields
DATA = Path('/run/media/kmosoti/data/FabricO11y')
SEALED = '606272bfbaec86900a928f2936d79b0ba4f6d5ed900556473bc3345a63283f47'
SEALED_SOURCE = '73ff77867d10ef521ca985b094e1d177f7786b77'
SEALED_BUILD = 'b10a4e4c2d83d8dbed7c1d6e74673fd377a83123fc1bce31fffc97e034beb9af'
CANONICAL = dict(binary_sha256=SEALED, source_commit=SEALED_SOURCE,
source_tree='9248c7bc174592566bc55360e73576f01f9a85ef',
source_manifest_sha256='534b601f904ce80f50cc545be8b8b40f47f8940975fd4cbf2e2e8c8cb54f2cff',
source_bundle_sha256='fc83ed1435b6ef8afadade2b7978c433d47d6cbdb9ad4a95c9ff57b25a07f1d0',
build_receipt_sha256=SEALED_BUILD,
canonical_helper_manifest_sha256='604fd0b90f80f061859967f967347375f1da20417fd576519485e8d7c58c43e6')
CASES = ('canonical-red', 'positive', 'legacy', 'duplicate', 'existing', 'workers',
'pending', 'early', 'changed')
def require(ok, message):
if not ok:
raise ValueError(message)
def file_hash(path):
with open(path, 'rb') as stream:
return hashlib.file_digest(stream, 'sha256').hexdigest()
def read_json(path, limit=131072):
with open(path, 'rb') as stream:
raw = stream.read(limit + 1)
require(len(raw) <= limit, 'bounded JSON exceeded')
def unique(pairs):
result = {}
for key, value in pairs:
require(key not in result, 'duplicate JSON key')
result[key] = value
return result
return json.loads(raw, object_pairs_hook=unique)
def binding(authority, case):
keys = ('binary_sha256', 'source_commit', 'source_tree', 'source_manifest_sha256',
'source_bundle_sha256', 'build_receipt_sha256', 'canonical_helper_manifest_sha256')
require(set(authority) == set(keys), 'expected authority fields')
for key in keys:
require(type(authority[key]) is str and re.fullmatch(
'[0-9a-f]{' + str(40 if key in ('source_commit', 'source_tree') else 64) + '}',
authority[key]) is not None, 'expected authority digest')
if case == 'canonical-red':
require(authority == CANONICAL, 'sealed canonical binding')
else:
require(authority['binary_sha256'] != SEALED and authority['canonical_helper_manifest_sha256']
== CANONICAL['canonical_helper_manifest_sha256'], 'separate helper required')
return authority
def batch_identity(raw):
require(0 < len(raw) <= 131072, 'bounded Batch')
fields = parse_fields(raw)
require(set(fields) <= {1, 2, 3, 4, 5, 6} and all(len(values) == 1 for values in fields.values()),
'short fixture singular fields')
batch = decode_batch(raw)
require(batch['version'] == 1 and batch['generation'] == 1
and len(batch['node_id']) == 16 and batch['sequence'] in (1, 2), 'Batch identity')
logs = decode_logs_request(batch['logs_bytes'])
metrics = decode_metrics_request(batch['metrics_bytes'])
require(len(logs) == 2 and all(len(log['body'].encode('ascii')) == 512 for log in logs),
'two original 512-byte logs')
require(len(metrics) == (32 if batch['sequence'] == 1 else 0)
and all(metric['kind'] == 'gauge' and len(metric['points']) == 1 for metric in metrics),
'original short metric shape')
return batch['node_id'].hex(), 1, batch['sequence']
def process_identity(pid, expected_stat, expected_hash):
proc = Path('/proc') / str(pid)
first = (proc / 'stat').read_text()
with open(proc / 'exe', 'rb') as stream:
loaded_stat = os.fstat(stream.fileno())
loaded_hash = hashlib.file_digest(stream, 'sha256').hexdigest()
last = (proc / 'stat').read_text()
# comm can contain spaces and ')'; starttime is field 22, after its last ')'.
ticks = lambda text: int(text[text.rfind(')') + 2:].split()[19])
require(ticks(first) == ticks(last) and loaded_hash == expected_hash
and (loaded_stat.st_dev, loaded_stat.st_ino) == (expected_stat.st_dev, expected_stat.st_ino),
'actual loaded ELF binding')
return dict(pid=pid, start_ticks=ticks(last), boot_id=Path('/proc/sys/kernel/random/boot_id').read_text().strip(),
exe_device=loaded_stat.st_dev, exe_inode=loaded_stat.st_ino)
class Sink(ThreadingHTTPServer):
daemon_threads = False
def __init__(self, root, identities, pending):
self.root, self.tokens, self.pending = root, {f'diagnostic-token-{i}' for i in range(identities)}, pending
self.lock, self.raw, self.streams, self.errors, self.requests = threading.Lock(), {}, {}, [], 0
super().__init__(('127.0.0.1', 0), Handler)
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.minimum_version = ssl.TLSVersion.TLSv1_2
context.load_cert_chain(root / 'server.pem', root / 'server.key')
self.socket = context.wrap_socket(self.socket, server_side=True)
class Handler(BaseHTTPRequestHandler):
def setup(self):
super().setup()
self.connection.settimeout(3)
def log_message(self, *args):
pass
def respond(self, code, value=None):
raw = b'' if value is None else json.dumps(value).encode()
self.send_response(code)
self.send_header('Content-Length', str(len(raw)))
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(raw)
def do_GET(self):
if self.path == '/v1/config' and self.headers.get('Authorization') in {'Bearer ' + token for token in self.server.tokens}:
self.respond(304)
else:
self.server.errors.append('unexpected configuration request/auth')
self.respond(400)
def do_POST(self):
try:
token = self.headers.get('Authorization', '').removeprefix('Bearer ')
require(self.path == '/v1/batches' and token in self.server.tokens
and self.headers.get('Authorization') == 'Bearer ' + token
and self.headers.get('Content-Type') == 'application/x-protobuf'
and not self.headers.get('Transfer-Encoding'), 'real authenticated Batch request')
size = int(self.headers.get('Content-Length', '0'))
require(0 < size <= 131072, 'bounded request')
raw = self.rfile.read(size)
require(len(raw) == size, 'complete request')
identity = batch_identity(raw)
with self.server.lock:
self.server.requests += 1
require(self.server.requests <= 10000, 'finite request allowance')
stream, sequence = identity[:2], identity[2]
node, through = self.server.streams.get(token, (stream, 0))
require(node == stream and sequence in (through, through + 1), 'per-token stream and ordered ACK')
require(identity not in self.server.raw or self.server.raw[identity] == raw, 'exact retry bytes')
if identity not in self.server.raw:
self.server.raw[identity] = raw
(self.server.root / ('batch-' + identity[0] + '-' + str(sequence))).write_bytes(raw)
self.server.streams[token] = (stream, through if self.server.pending else sequence)
self.respond(503 if self.server.pending else 200,
{'status': 'unavailable'} if self.server.pending else {'status': 'ack', 'committed_through': sequence})
except Exception as error:
self.server.errors.append(str(error))
self.respond(400)
def original_records(root, sink, identities, pending=False):
def lines(name):
with open(root / name) as stream:
for n, line in enumerate(stream):
require(n < 25000 and len(line) <= 16384, 'bounded original ledger')
yield json.loads(line)
events = list(lines('events.jsonl'))
created = [(item['id'], item['seq']) for item in events if item.get('e') == 'created']
require(len(created) == identities * 2 and set(created) == {(i, s) for i in range(identities) for s in (1, 2)},
'real finite original offers')
transcript = list(lines('transcript.jsonl'))
sources, responses, states = {}, [], []
for item in transcript:
if item['type'] in ('source', 'attempt'):
key = item['node_id'], item['generation'], item['sequence']
raw = sink.raw.get(key)
if item['type'] == 'source':
require(key not in sources, 'duplicate original source')
sources[key] = item['bytes']
if raw is not None:
require(item['bytes'] == base64.b64encode(hashlib.sha256(raw).digest()).decode(), 'original wire hash')
elif item['type'] == 'response':
responses.append(item)
elif item['type'] == 'node_state':
states.append(item)
require(len(sources) == identities * 2 and len(states) == identities and not sink.errors, 'complete original streams/setup')
if pending:
require(len(sink.raw) == identities and responses and all(item['kind'] == 'unavailable' for item in responses)
and all(item['ack_cursor'] == 0 and item['retained_sequences'] == [1, 2] for item in states), 'real undelivered fixture')
else:
require(len(sink.raw) == identities * 2 and len(responses) == identities * 2
and all(item['kind'] == 'ack' and item['committed_through'] == item['sequence'] for item in responses)
and all(item['ack_cursor'] == 2 and item['retained_sequences'] == [] for item in states), 'real finite ACK prerequisite')
return events
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--case', choices=CASES, required=True)
for name in ('binary', 'authority', 'build-receipt', 'out'):
parser.add_argument('--' + name, type=Path, required=True)
parser.add_argument('--authority-sha256', required=True)
args = parser.parse_args()
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from resource_group import require_limits, require_storage, STORAGE
from delivery_faults import make_certs
group = require_limits()
require(STORAGE == DATA and require_storage() == DATA, 'mounted DATA storage only')
require(not any(name in os.environ for name in ('LD_PRELOAD', 'LD_AUDIT', 'LD_LIBRARY_PATH')), 'unpreloaded native process required')
require(file_hash(args.authority) == args.authority_sha256, 'external expected authority hash')
authority = binding(read_json(args.authority), args.case)
require(file_hash(args.build_receipt) == authority['build_receipt_sha256'], 'actual build receipt bytes')
root = args.out.absolute()
require(root.parent.resolve().is_relative_to(DATA) and root.parent.resolve() == root.parent and not root.exists(), 'fresh owned DATA path')
root.mkdir(mode=0o700)
report = dict(case=args.case, classification='volatile TLS diagnostic; no candidate qualification',
authority=authority, authority_sha256=args.authority_sha256, cgroup=str(group), status='inconclusive')
sink = thread = proc = None
fd = witness_fd = None
result = 2
try:
fd = os.open(args.binary, os.O_RDONLY | os.O_NOFOLLOW)
binary_stat = os.fstat(fd)
with os.fdopen(os.dup(fd), 'rb') as stream:
require(stat.S_ISREG(binary_stat.st_mode) and hashlib.file_digest(stream, 'sha256').hexdigest()
== authority['binary_sha256'], 'held binary bytes')
identities, workers = (5, 4) if args.case == 'workers' else (2, 2)
make_certs(root)
tokens = root / 'tokens'
tokens.write_text(''.join(f'diagnostic-token-{i}\n' for i in range(identities)))
tokens.chmod(0o600)
sink = Sink(root, identities, args.case == 'pending')
thread = threading.Thread(target=sink.serve_forever, kwargs={'poll_interval': 0.05})
thread.start()
begin = root / 'begin.json'
if args.case == 'existing':
begin.write_bytes(b'never replace this destination\n')
begin.chmod(0o400)
command = [f'/proc/self/fd/{fd}', '--server-url', f'https://127.0.0.1:{sink.server_port}',
'--ca', str(root / 'ca.pem'), '--tokens', str(tokens), '--seed', '0xA11FA001',
'--seconds', '2', '--workers', str(workers), '--out', str(root)]
if args.case != 'legacy':
command += ['--begin-witness', str(begin)]
if args.case == 'duplicate':
command += ['--begin-witness', str(root / 'other.json')]
report['command'], report['launch_monotonic_ns'] = command, time.monotonic_ns()
with open(root / 'stdout', 'wb') as stdout, open(root / 'stderr', 'wb') as stderr:
proc = subprocess.Popen(command, pass_fds=(fd,), stdout=stdout, stderr=stderr)
if args.case not in ('duplicate', 'existing', 'workers'):
report['process'] = process_identity(proc.pid, binary_stat, authority['binary_sha256'])
if args.case in ('positive', 'pending', 'early', 'changed'):
until = time.monotonic() + 1
while not (begin.exists() and sink.raw) and proc.poll() is None and time.monotonic() < until:
time.sleep(0.002)
require(begin.exists() and sink.raw and proc.poll() is None, 'live witness/offer prerequisite')
witness_fd = os.open(begin, os.O_RDONLY | os.O_NOFOLLOW)
live_stat = os.fstat(witness_fd)
live_raw = os.read(witness_fd, 131073)
require(len(live_raw) <= 131072 and stat.S_ISREG(live_stat.st_mode) and live_stat.st_nlink == 1
and stat.S_IMODE(live_stat.st_mode) == 0o400, 'live complete private witness')
live_value = read_json(Path('/proc/self/fd') / str(witness_fd))
report['live_begin'] = dict(sha256=hashlib.sha256(live_raw).hexdigest(), value=live_value,
observed_monotonic_ns=time.monotonic_ns(), device=live_stat.st_dev, inode=live_stat.st_ino)
if args.case == 'early':
proc.send_signal(signal.SIGTERM)
elif args.case == 'changed':
begin.chmod(0o600)
with open(begin, 'ab') as stream:
stream.write(b'changed-by-registered-control')
begin.chmod(0o400)
code = proc.wait(timeout=75 if args.case == 'pending' else 10)
report['exit'], report['stop_confirmed'], report['stopped_monotonic_ns'] = code, True, time.monotonic_ns()
sink.shutdown(); thread.join(timeout=5); sink.server_close()
require(not thread.is_alive(), 'test sink stopped')
if args.case in ('duplicate', 'existing', 'workers'):
require(code in (1, 2) and not sink.raw and not sink.errors, 'refusal before any native request')
require(not (root / 'other.json').exists(), 'no duplicate-option publication')
if args.case == 'existing':
require(begin.read_bytes() == b'never replace this destination\n' and stat.S_IMODE(begin.stat().st_mode) == 0o400, 'destination preserved')
else:
require(not begin.exists(), 'no refused witness publication')
elif args.case in ('early', 'changed'):
require(code != 0, 'real native failure must refuse success')
else:
events = original_records(root, sink, identities, args.case == 'pending')
summary = read_json(root / 'sim-summary.json')
require(summary['identities'] == identities and summary['seconds'] == 2
and summary['seed'] == 0xA11FA001, 'original summary parameters')
if args.case == 'pending':
require(code == 1 and summary['undelivered'] == 4, 'native undelivered refuses success')
else:
require(code == 0 and summary['undelivered'] == 0, 'successful finite ACK drain')
if args.case == 'canonical-red':
require(not begin.exists(), 'sealed source changed: unexpected witness')
report['status'], result = 'expected-red: sealed-native-missing-begin-after-real-ACK', 1
elif args.case == 'legacy':
require(set(summary) == {'identities', 'seconds', 'seed', 'began_unix_ns', 'undelivered'} and not begin.exists(), 'legacy summary compatibility')
else:
witness_stat = begin.lstat()
witness = read_json(begin)
require(stat.S_ISREG(witness_stat.st_mode) and witness_stat.st_nlink == 1
and stat.S_IMODE(witness_stat.st_mode) == 0o400
and (witness_stat.st_dev, witness_stat.st_ino) == (live_stat.st_dev, live_stat.st_ino)
and file_hash(begin) == report['live_begin']['sha256'], 'unchanged complete private single-link witness')
require(witness['process'] == report['process'] and witness['binary_sha256'] == authority['binary_sha256']
and witness['parameters'] == dict(seconds=2, identities=2, workers=2, seed=0xA11FA001), 'actual native identity/parameters')
lo, hi = witness['mono_before_ns'], witness['mono_after_ns']
require(type(lo) is int and type(hi) is int and report['launch_monotonic_ns'] <= lo <= hi <= lo + 1000000
and hi <= report['live_begin']['observed_monotonic_ns'], 'native bounded bracket')
require(summary['began_unix_ns'] == witness['began_unix_ns'] and summary['process'] == report['process']
and summary['begin_witness_sha256'] == file_hash(begin) and summary['workers'] == 2
and summary['elapsed_ns'] >= 2000000000
and hi + 2000000000 <= summary['ended_monotonic_ns'] <= report['stopped_monotonic_ns'],
'real conservative native end')
require(all(item['t'] >= witness['began_unix_ns'] and item['generated_ns'] >= item['t']
for item in events if item.get('e') == 'created'), 'original offer anchor')
report['publication_certification'] = 'not established: separate atomic/no-replace/pre-offer controls required'
if args.case != 'canonical-red':
report['status'], result = 'diagnostic-control-satisfied', 0
except Exception as error:
report['error'] = str(error)
finally:
if proc is not None and proc.poll() is None:
proc.kill(); proc.wait(timeout=10)
if sink is not None and thread is not None and thread.is_alive():
sink.shutdown(); thread.join(timeout=5); sink.server_close()
if fd is not None:
os.close(fd)
if witness_fd is not None:
os.close(witness_fd)
# Retain original failures/raw batches/receipts; discard only fixture credentials.
for name in ('ca.key', 'server.key', 'tokens', *(f'token-{i}' for i in range(5))):
(root / name).unlink(missing_ok=True)
report['helper_stopped'] = proc is None or proc.poll() is not None
report['sink_stopped'] = thread is None or not thread.is_alive()
(root / 'control-receipt.json').write_text(json.dumps(report, indent=2) + '\n')
return result
if __name__ == '__main__':
try:
sys.exit(main())
except Exception as error:
print(json.dumps({'status': 'inconclusive-preflight-refusal', 'error': str(error)}), file=sys.stderr)
sys.exit(2)
scratch/simulator-exposure-witness/tools/qualification/test_simulator_native_controls.py
SHA-256 853eee22df310e2f966b2fbb807c2f64f0b17a443ac3174474c9b5e7d1271b07, 3642 bytes.
"""Hand-written finite wire/authority controls; no native process or clock runs."""
import copy
from pathlib import Path
import unittest
from query_oracle import ProtoError
from release_fixture import integer, message
from simulator_native_controls import CANONICAL, binding, batch_identity, read_json
def wire(sequence=1, body=b'R' * 512, points=32):
# Independent finite protobuf literal construction, not Rust offer code.
record = message(5, message(1, body))
logs = message(1, message(2, message(2, record) + message(2, record)))
metric = message(1, b'diagnostic') + message(5, message(1, b''))
metrics = message(1, message(2, b''.join(message(2, metric) for _ in range(points))))
return (integer(1, 1) + message(2, bytes(range(16))) + integer(3, 1) + integer(4, sequence)
+ (message(5, metrics) if sequence == 1 else b'') + message(6, logs))
class NativeRegistrationTests(unittest.TestCase):
def test_exact_canonical_expected_tuple(self):
literal = Path(__file__).resolve().parents[2] / 'docs/experiments/benchmarks/simulator-native-witness-canonical.json'
self.assertEqual(binding(read_json(literal), 'canonical-red'), CANONICAL)
def test_every_canonical_pin_is_independent(self):
for key in CANONICAL:
mutant = copy.deepcopy(CANONICAL)
mutant[key] = '0' * len(mutant[key])
with self.assertRaisesRegex(ValueError, 'sealed canonical binding'):
binding(mutant, 'canonical-red')
def test_separate_binary_keeps_original_helper_authority(self):
expected = CANONICAL | {'binary_sha256': 'a' * 64, 'source_commit': 'b' * 40,
'source_tree': 'c' * 40, 'build_receipt_sha256': 'd' * 64}
self.assertEqual(binding(expected, 'positive'), expected)
with self.assertRaisesRegex(ValueError, 'separate helper required'):
binding(CANONICAL, 'positive')
with self.assertRaisesRegex(ValueError, 'separate helper required'):
binding(expected | {'canonical_helper_manifest_sha256': 'e' * 64}, 'positive')
def test_malformed_missing_or_extra_authority_refused(self):
for mutant in (CANONICAL | {'source_commit': ''}, CANONICAL | {'binary_sha256': True},
CANONICAL | {'extra': 'x'}, {k: v for k, v in CANONICAL.items() if k != 'source_tree'}):
with self.assertRaises(ValueError):
binding(mutant, 'canonical-red')
def test_two_seconds_use_original_finite_shapes(self):
for sequence in (1, 2):
self.assertEqual(batch_identity(wire(sequence)), (bytes(range(16)).hex(), 1, sequence))
def test_duplicate_truncated_unknown_and_identity_wire_refused(self):
for mutant in (wire() + integer(4, 1), wire()[:-1], wire() + message(9, b'trace'),
wire().replace(message(2, bytes(range(16))), message(2, b'short'), 1),
wire().replace(integer(4, 1), integer(4, 3), 1)):
with self.assertRaises((ValueError, ProtoError)):
batch_identity(mutant)
def test_payload_shape_failure_cannot_be_missing_begin_red(self):
for body in (b'R' * 511, b'R' * 513):
with self.assertRaisesRegex(ValueError, 'two original 512-byte logs'):
batch_identity(wire(body=body))
def test_first_second_requires_all_original_metric_points(self):
for points in (0, 31, 33):
with self.assertRaisesRegex(ValueError, 'original short metric shape'):
batch_identity(wire(points=points))
if __name__ == '__main__':
unittest.main()