1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
# 45 — GSP RPC capture ingestion and replay prep (in development)
> **Status: in development (2026-10-06, capture-ingestion wave).** This page
> documents `harness/rm_capture.py`, a stdlib-only harness that turns the
> **supervised real-client GSP RPC capture** (the tag contract produced by the
> send-path instrumentation runbook) into structured, replayable artifacts:
> a decoded capture document, a per-record comparison report, and a replay
> **stimulus** document for the simulator's B4/B5 CSB/message-queue seam.
>
> Development-only: the tool reads files and writes reports. It never touches
> a GPU, kernel module, mdev, guest or network, and it never runs or schedules
> the capture itself. The capture is a supervised, human-run physical action
> (RUNBOOK P1/P7); the tool only ingests its log.
>
> **See also:** `06-ACCURACY.md` (fidelity levels, M1–M6),
> `17-RM-HARNESS.md` (read-only RM oracle policy),
> `36-GSP-DEVICE-MODEL.md` (the S1 device model and boot ladder),
> `38-GSP-EM-API.md` (TLV boundary),
> `44-GMMU-ORACLE-AND-WORKFLOW.md` (the same offline compare discipline for
> GMMU/FBIF registers).
## 1. What this is and why
The open GR question is *what the real host client actually sends* while it
creates and commits a GR context (the golden-image sequence and its promote
controls). The authored capture runbook obtains that sequence from an
instrumented reference kernel driver; this harness consumes the resulting log
and prepares it for two workflows:
1. **Compare** — the real client's captured sequence vs. the open-iov host
ladder's replay (or two driver/firmware versions), per record, with explicit
unmatched lists.
2. **Replay** — an ordered stimulus document that the simulator's next rung
(B4/B5: host-traffic doorbell + first CSB/TRANSCOM poll served + one
scripted RM message end-to-end) can feed into the modelled firmware, so the
server side of the captured sequence can be observed off-hardware and
deterministically.
The simulator consumes captured truth; it does not replace the capture.
Known limitation up front: the capture runbook's hex helper currently caps a
payload dump at 192 bytes. Payloads larger than that (for example a 560-byte
`PROMOTE_CTX` control) decode as **`truncated`** and are **not replayable**
until the helper is extended to emit chunked blocks. The decoder flags this
per record and in the summary; it never pads a payload to look complete.
## 2. The capture log contract
Lines are matched anywhere in the line, so dmesg/NVRM/timestamp prefixes are
fine. Tags (exact grammar: `python3 harness/rm_capture.py --print-capture-hints`):
```
GE-GOLDEN-TRIGGER gspclient=<0|1> mig=<0|1>
GE-GOLDEN-BEGIN
GE-GOLDEN-END status=0x...
GE-SEND fn=0x... len=0x... ret=0x...
GE-CTRL cmd=0x... hClient=0x... hObject=0x... size=0x... paramp=0x... ret=0x...
GE-ALLOC cls=0x... hClient=0x... hParent=0x... hObject=0x... size=0x... paramp=0x... ret=0x...
GE-CTRL-DONE cmd=0x... rpc_status=0x... params_status=0x...
GE-<TAG> <offset-hex>: <hex bytes...> # attaches to the newest record of that tag
```
* Hex blocks attach to the most recent record **of their own tag**; an orphan
block is reported as a warning, never guessed onto another record.
* A `GE-SEND` payload's named id is derived when no named control line was
captured: function `76` (`GSP_RM_CONTROL`) carries the control id at payload
offset 8; function `103` (`GSP_RM_ALLOC`) carries the class id at offset 12.
* `ret=` is the caller return address: recorded as-is, capture-specific.
## 3. Schemas
* `greeneye-rm-rpc-capture/1` — `{format, source, sha256, records[], summary,
warnings, limits}`. Each record: `{index, kind, line, ts?, fn?, length?,
size?, cmd?, hclass?, hclient?, hobject?, hparent?, caller?, caller_raw?,
marker?, gspclient?, mig?, status?, rpc_status?, params_status?,
params_hex?, params_bytes, params_size_expected?, truncated?, anomalies?}`.
* `greeneye-rm-rpc-compare/1` — inputs + `summary` (matched / agree /
shape-agree / partial / mismatch / A-only / B-only / agreement % /
coverage % / mean byte agreement %), `rows[]` (per aligned record, with
byte agreement and first-difference offset), `a_only[]`, `b_only[]`,
`fidelity`, `limits`, `warnings`.
* `greeneye-rm-rpc-stimulus/1` — `markers[]` (golden slice boundaries) and
`messages[]` (`fn`/`cmd`/`hclass`/`wire_id`, `params_hex`, sizes, truncation
flag). Handles, physical addresses and caller addresses are **omitted** on
purpose: a replay must allocate/re-map them.
## 4. Commands
```bash
python3 harness/rm_capture.py --print-capture-hints # prints only
python3 harness/rm_capture.py decode --log capture.log --out dumps/rm-capture
python3 harness/rm_capture.py compare --a real.json --b replay.json --out dumps/rm-compare
python3 harness/rm_capture.py stimulus --capture real.json --out dumps/rm-stimulus.json
python3 harness/rm_capture.py demo --out /tmp/rm-capture-demo # synthetic, measured
```
Inputs to `compare`/`stimulus` may be decoded JSON documents or raw logs; the
loader auto-detects. A non-capture JSON format is a clean error.
## 5. Simulator linkage (B4/B5) — not wired yet
The stimulus document is the intended input for the simulator's
host-traffic rung: once the doorbell path and the first CSB/TRANSCOM poll are
served and a scripted message can be delivered end-to-end (handoff-simulator
§17.5), the captured golden-image sequence is the natural first real message
set. Until then this tool stays offline: `stimulus` states the pending wiring
in its `limits`, and nothing in `sim/` imports it yet.
Ordering honesty: the capture is **send-side only**; server replies were not
captured by the probes. A replay therefore reproduces the stimulus, not the
reply sequence.
## 6. Admission record (draft — pending maintainer filing)
Per the project admission rule (`docs/eng-ops.md` §2): all five fields. This
record is a draft, like the simulator program's `gpgpu-sim/ADMISSION.md`
records; a maintainer files it.
| Field | Value |
|---|---|
| Scenario | RE/porting loop: ingest a supervised real-client GSP RPC capture into the workflow — decode the golden-image sequence, compare it with the open-iov ladder's replay or another version, and prepare a replay stimulus for the simulator's message-loop rung. No hardware access. |
| Measurable outcome | Decode/compare/stimulus wall time vs. manual baseline; record and parameter integrity (no silent loss; truncation flagged); deterministic outputs (two runs byte-identical apart from timing). |
| Baseline | Manual decode-by-eye of one golden sequence from a capture log: grep tags, count records, walk each parameter blob against the RPC structs, transcribe a replay table. Conservative estimate **1800 s** (not measured on a human). |
| Evaluation threshold | Tool path ≤ **5%** of the baseline (≤90 s); demo `ok`; deterministic reports; new tests plus the full suite green. |
| Failure signal | Silent record/parameter loss; truncation unflagged; non-deterministic reports; demo above threshold; or any physical action executed/scheduled by the tool → disable the feature and record it as a failed experiment. |
Measured proof (2026-10-06, synthetic demo on this host): 15/14 records,
13 agree + 1 shape-agree (flipped parameter byte) + 1 A-only (dropped alloc),
**wall ≈ 0.02 s** vs the 90 s threshold; artifacts under the `demo --out`
directory; 27 new tests, full suite 444 green (twice).
## 7. Limits and deferrals
* No hardware, module, mdev, guest or network action; the tool never runs the
capture.
* The 192-byte helper cap: extend the runbook helper to chunk before any large
payload (promote entries) is considered replayable.
* Handles/addresses are capture-specific and explicitly omitted from stimuli.
* Send-side only; no reply/event ordering.
* B4/B5 stimulus wiring, a captured-sequence vs. simulated-firmware accuracy
loop, and symbol/`addr2line` mapping of captured caller addresses are
deferred (the `gmmu_debug.py` static↔dynamic join is the pattern to reuse).
* L0/L1 fidelity only; no timing claim.
|